Phase 4.7: in progress

This commit is contained in:
2026-10-11 22:23:43 +03:00
parent 00b2d5d1fe
commit d28fce7631
42 changed files with 3516 additions and 87 deletions
+31 -2
View File
@@ -32,7 +32,15 @@
# chassis frame). See assets/blender/vehicles/CAR_MODELING.md.
#
# Usage:
# blender <vehicle>.blend -b -Y -P gen_vehicle.py -- <out>.glb <out>.vehicle.json
# blender <vehicle>.blend -b -Y -P gen_vehicle.py -- <out>.glb \
# <out>.vehicle.json [downforce]
#
# downforce (optional, default 25): aerodynamic downforce coefficient
# (N per (m/s)^2, straight down at the COM while moving) — the
# speed-dependent grip lever: at speed it multiplies the tire normal
# load (and thus the lateral impulse budget) without adding inertia,
# which is exactly where plain tires start understeering. Higher =
# tighter turns at speed.
import os
import sys
@@ -58,6 +66,7 @@ except:
glb_file = argv[0]
json_file = argv[1]
downforce = float(argv[2]) if len(argv) > 2 else 25.0
outdir = os.path.dirname(glb_file)
base = os.path.splitext(os.path.basename(bpy.data.filepath))[0]
@@ -294,7 +303,9 @@ SUSP_MAX = 0.35
# Softer than the 1.8/0.7 starting point: gives the body some slack
# over bumps instead of pogo-stiff wheels (which also cost grip).
SUSP_FREQ = 1.3
SUSP_DAMP = 0.6
# Critical-ish damping: less and the body rocks for seconds after a
# bump (the "almost endlessly bouncy" report).
SUSP_DAMP = 1.0
SUSP_REST = SUSP_MAX - 9.81 / (2.0 * math.pi * SUSP_FREQ) ** 2
for w in sorted(wheel_info, key=lambda w: w["pos"].y):
front = w["pos"].y < axle_mid_y
@@ -320,6 +331,17 @@ for s in seat_info:
"driver": s["driver"],
})
# Center of mass: a box collider puts the COM at the box center — for
# a sedan that is ~1 m above the tire contact patches (twice the real
# value) and the car trips onto its side in hard corners (the taxi,
# with its taller box, tips even easier). Shift the COM to just above
# wheel-hub height instead (Jolt OffsetCenterOfMassShape: only the
# physics COM moves — geometry, wheel attachments and the render node
# stay put).
collider_center_ogre_y = (smx.z + smn.z) / 2.0
hub_ogre_y = sum(w["pos"].z for w in wheel_info) / len(wheel_info)
com_offset_y = round(hub_ogre_y + 0.1 - collider_center_ogre_y, 4)
driver_offset = ogre_vec3(driver_seats[0]["pos"])
children = []
@@ -410,6 +432,13 @@ vehicle = {
# soft 1.3 Hz springs a full-lock turn otherwise rolls the car past
# 45 deg onto two wheels.
"antiRollBarStiffness": 2000.0,
"centerOfMassOffset": {"x": 0.0, "y": com_offset_y, "z": 0.0},
# Aerodynamic downforce (N per (m/s)^2, straight down at the COM
# while moving): presses the car onto its suspension at speed —
# less bounce, and a bigger lateral impulse budget exactly where
# plain tires start understeering (turn radius stops growing with
# speed). Per-model value from the CMake invocation.
"downforceCoefficient": downforce,
}
if steering:
vehicle["steeringWheelMeshName"] = base + "-steering-wheel.mesh"
+5 -1
View File
@@ -28,6 +28,10 @@ endforeach()
# generated scene-entity JSON fragment (<name>.vehicle.json, see
# assets/blender/scripts/gen_vehicle.py and vehicles/CAR_MODELING.md).
set(VEHICLES_GEN_SRC sedan-v2.blend sedan-v2-taxi.blend)
# Per-model downforce coefficient (third gen_vehicle.py argument):
# heavier/taller handling gets more speed-grip.
set(DOWNFORCE_sedan-v2 35)
set(DOWNFORCE_sedan-v2-taxi 45)
foreach(VEHICLE_FILE ${VEHICLES_GEN_SRC})
get_filename_component(FILE_NAME ${VEHICLE_FILE} NAME_WE)
@@ -39,7 +43,7 @@ foreach(VEHICLE_FILE ${VEHICLES_GEN_SRC})
COMMAND ${BLENDER} ${CMAKE_CURRENT_SOURCE_DIR}/${VEHICLE_FILE}
-b -Y -P
${CMAKE_SOURCE_DIR}/assets/blender/scripts/gen_vehicle.py
-- ${VEHICLE_OUTPUT_FILE} ${VEHICLE_JSON_FILE}
-- ${VEHICLE_OUTPUT_FILE} ${VEHICLE_JSON_FILE} ${DOWNFORCE_${FILE_NAME}}
COMMAND ${CMAKE_COMMAND} -D FILE=${CMAKE_BINARY_DIR}/resources/vehicles/${FILE_NAME}.glb -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/check_file_size.cmake
COMMAND ${CMAKE_COMMAND} -D FILE=${CMAKE_BINARY_DIR}/resources/vehicles/${FILE_NAME}.scene -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/check_file_size.cmake
COMMAND touch ${VEHICLE_OUTPUT_FILE}