mirror of
https://github.com/SK8-ENGINE/skate-3-rust-engine.git
synced 2026-10-26 19:47:44 +00:00
Add ramp-friendly vehicle collision, throttle engine audio and Mixamo SDK guide
This commit is contained in:
1 parent
fb0dd98e83
commit
a97c9157e6
16 files changed
+421
-21
No files matched your search
@@ -0,0 +1,122 @@
|
||||
# Mixamo to native vehicle animations
|
||||
|
||||
This is the workflow used for the working Mario Kart rider. The game plays a native
|
||||
Skate skeleton pose on the currently selected compatible character. It does not swap
|
||||
the rider to the mesh bundled in the Mixamo download. Other characters must first be
|
||||
converted to the supported native render rig; arbitrary skeletons are not interchangeable.
|
||||
Different proportions may still need contact adjustments to reach a wheel or pedals.
|
||||
|
||||
## 1. Keep a matched calibration pair
|
||||
|
||||
Use your owned stock `assets/private/skater.glb` as the native reference. Upload the
|
||||
same stock character mesh to Mixamo, rig it there, and retain its returned rest/T-pose
|
||||
with skin and skeleton. Convert that returned reference FBX to GLB without altering
|
||||
its bind pose (Blender import FBX, export glTF/GLB with skin). This paired stock return
|
||||
is the calibration source, not a Mario mesh or a posed entry/exit frame.
|
||||
|
||||
The converter's `--calibrate` path accepts a GLB. It verifies mesh bounds and records
|
||||
the reference hash, source hash, scale and Mixamo bind transforms. Example:
|
||||
|
||||
```powershell
|
||||
python tools/mixamo_to_skate/main.py returned-stock.glb --reference assets/private/skater.glb --profile calibration.json --calibrate --noninteractive
|
||||
```
|
||||
|
||||
Keep calibration.json with that exact stock reference. For this local kart, the matched
|
||||
profile is `C:/Users/Daddy/Documents/Mixamo-to-Skate/calibration.json`. Do not replace it
|
||||
with a profile built from another character. Calibration transfers the change from a
|
||||
Mixamo bind pose into the original native bind basis; copying raw rotations ignores
|
||||
bone axes and is what produced the forward shoulders in the earlier attempt.
|
||||
|
||||
## 2. Download the animations from the same Mixamo character
|
||||
|
||||
Select Entering Car and Exiting Car on that same uploaded stock character. Download FBX
|
||||
**with skin** for this pipeline, retaining its skeleton. The skin is useful for verifying
|
||||
the reference and is not used as the in-game rider. Use consistent frame rate and no
|
||||
keyframe reduction. Preserve root motion; these clips need to move between standing
|
||||
and seated positions. Keep the original downloads untouched.
|
||||
|
||||
The accepted local inputs were `Entering Car (2).fbx` and `Exiting Car (2).fbx` in Downloads.
|
||||
The earlier `(1)` files used another character and are not the calibrated source.
|
||||
|
||||
## 3. Verify the raw transfer before fitting a vehicle
|
||||
|
||||
Run Blender in background mode with the stock GLB and matched profile. Use fresh output
|
||||
directories: the tools refuse to overwrite existing preview folders.
|
||||
|
||||
```powershell
|
||||
& $blender -b --python tools/preview_mixamo_animation.py -- --source 'Entering Car (2).fbx' --reference assets/private/skater.glb --profile calibration.json --output .local/raw-enter
|
||||
& $blender -b --python tools/preview_mixamo_animation.py -- --source 'Exiting Car (2).fbx' --reference assets/private/skater.glb --profile calibration.json --output .local/raw-exit
|
||||
```
|
||||
|
||||
`$blender` is the path to your Blender executable. Open each `Raw-Skate-Animation.blend`.
|
||||
Check the first, middle and final frames, especially shoulders, wrists, hips and feet.
|
||||
The tool checks the calibration hash and source bind compatibility. Do not bypass a
|
||||
mismatch by forcing rotation offsets into the native rest skeleton. Native rest bones
|
||||
and skin inverse-bind matrices must remain unchanged. Fix the calibration/source first.
|
||||
|
||||
## 4. Fit the approved poses to the kart
|
||||
|
||||
```powershell
|
||||
& $blender -b --python tools/fit_kart_animation_preview.py -- --raw .local/raw-enter/Raw-Skate-Animation.blend --kart mods/mario-kart/kart.glb --mode enter --output .local/fit-enter
|
||||
& $blender -b --python tools/fit_kart_animation_preview.py -- --raw .local/raw-exit/Raw-Skate-Animation.blend --kart mods/mario-kart/kart.glb --mode exit --output .local/fit-exit
|
||||
```
|
||||
|
||||
This example script aligns the seated hips, eases torso lean and solves arms/legs to
|
||||
wheel and footwell targets. It bakes a separate fitted action, retains the raw action,
|
||||
checks unchanged rest bones and writes a fit report. Review both .blend files before
|
||||
export. Feet need clearance over the side pod, hands need a reachable wheel position,
|
||||
and the last entry pose should match the first exit pose. The seated pose is also
|
||||
used for the driving loop. Fingers are limited by the native character's hand rig.
|
||||
|
||||
Targets in this script use Blender Z-up: seat `(0, .20, .73)`, wheel grips
|
||||
`(+/-.19, -.36, .90)`, feet `(+/-.17, -.55, .33)`; the preview kart is raised `.55`.
|
||||
These are **kart example values**. For another vehicle adjust alignment, contact targets,
|
||||
clearance and torso lean in the authoring script or bake equivalent edits in Blender.
|
||||
Do not change rest bones, and keep the fitted armature object transform identity.
|
||||
|
||||
## 5. Export in the game's exact skeleton order
|
||||
|
||||
Obtain the order from the installed native bank (or `sdk.animation.info().bone_names`).
|
||||
Do not use the larger reference list in the vendor importer: this build's bank has 36
|
||||
bones, including reparented helpers. Generate the JSON list with the provided utility:
|
||||
|
||||
```powershell
|
||||
cargo run --locked -p skate-data --example vehicle_bone_names -- assets/private/stock/data/anim/OnBoard.abin .local/bone-names.json
|
||||
& $blender -b --python tools/export_kart_rider.py -- --enter .local/fit-enter/Kart-enter.blend --exit .local/fit-exit/Kart-exit.blend --reference assets/private/skater.glb --bone-names .local/bone-names.json --output mods/mario-kart/rider.json
|
||||
```
|
||||
|
||||
The exporter preserves the glTF skin bind basis while converting Blender poses into
|
||||
column-major native matrices. It subtracts the preview seat, exports enter/exit clips,
|
||||
uses the final entry pose as drive, and generates left/right steering endpoints with
|
||||
length-preserving arm reach. It renders both endpoints for inspection. The host blends
|
||||
between them continuously with steering input. For another cockpit, change the exporter
|
||||
seat, steering-wheel centre/axis and steering angle alongside the fitted scene targets.
|
||||
|
||||
The example's game seat is `[0, .18, -.20]`: convert the Blender seat to Y-up and subtract
|
||||
the preview kart's .55 m lift. Model fitting offsets are not an excuse to alter native
|
||||
bone axes. Export fps comes from each scene; retain its timing instead of relabelling
|
||||
frames with a different rate. The output is a full native pose, not additive rotations.
|
||||
|
||||
## 6. Package, validate and playtest
|
||||
|
||||
Put `rider.json`, the embedded `kart.glb`, `vehicle.json`, `mod.json` and `main.lua` in the
|
||||
executable-adjacent mod folder. Set animations.file to rider.json, enter/exit to their
|
||||
names, idle/drive/reverse/brake to drive for this example, and steer_left/steer_right to
|
||||
the corresponding endpoints. See vehicle-sdk.md for limits, schema and lifecycle.
|
||||
|
||||
The host validates names, frame counts, finite rigid transforms and clip references at
|
||||
load. The source loader tests cover malformed inputs; local validation also checked the
|
||||
export against the actual stock bank and matched the final entry pose to drive. The
|
||||
runtime applies the same native pose to whichever compatible character is selected.
|
||||
|
||||
`Build-VehicleSDK.ps1` stages a build and documentation. It preserves differing local
|
||||
mod files; copy your approved changed files into the playable mod directory explicitly
|
||||
when it reports them. Reload/disable-enable the mod to load changed animation files.
|
||||
Use PLAY-MARIO-KART.bat for a manual session. Check entry/exit from multiple vanilla
|
||||
stances, steering in both directions, ramps, braking, reset, Escape, and mod disable.
|
||||
Also try characters with different proportions; native-rig compatibility does not
|
||||
promise exact contact for every body size. Gameplay is never launched by these tools.
|
||||
|
||||
Source code and authoring scripts are reusable. Proprietary FBX, GLB, .blend and exported
|
||||
rider data remain local and ignored by Git. Distribute only assets you have permission
|
||||
to redistribute; the SDK source itself does not include the stock mesh or these clips.
|
||||
+55
-8
@@ -65,7 +65,7 @@ Do not pass the full input table to `control`; copy only its four control fields
|
||||
and a parking brake is applied. Controls are ignored during enter/exit animations.
|
||||
|
||||
`tune` supports optional engine_force (0..100000 N), max_speed (1..100 m/s),
|
||||
brake_impulse (0..10000), steering_angle (0.01..1.2 radians), tire_grip (0.1..20).
|
||||
engine_volume (0..1), brake_impulse (0..10000), steering_angle (0.01..1.2 radians), tire_grip (0.1..20).
|
||||
Maximum speed limits engine application; it is not an absolute downhill speed cap.
|
||||
|
||||
Events passed to `on_event`: `vehicle_spawned`, `vehicle_entering`, `vehicle_entered`,
|
||||
@@ -77,8 +77,8 @@ mod errors; they retire the mod's vehicles instead of crashing the game.
|
||||
## Vehicle definition
|
||||
|
||||
See `mods/mario-kart/vehicle.json` for a complete working definition. Coordinates
|
||||
are metres, +Y up, +Z forward, +X right, with heading in radians around +Y.
|
||||
`half_extents` describes the chassis cuboid. `mass` is kilograms. `model_scale`,
|
||||
are metres, +Y up, +Z forward, +X driver-left, with heading in radians around +Y.
|
||||
`half_extents` describes the outer chassis collision bounds. `mass` is kilograms. `model_scale`,
|
||||
`model_offset` and `model_yaw` affect the model only, not its collider.
|
||||
|
||||
Each wheel defines a chassis-local suspension mounting `position`, radius,
|
||||
@@ -96,7 +96,7 @@ A package may total 64 MiB; a model is limited to 32 MiB and an animation file t
|
||||
|
||||
## Rider animation support
|
||||
|
||||
No animations are supplied. All animation slots default to null. Without a matching
|
||||
The local kart package supplies fitted clips. Other definitions default their animation slots to null. Without a matching
|
||||
clip, the skater is hidden and entering/exiting completes immediately. This avoids
|
||||
showing an unrelated standing/skating pose on the kart.
|
||||
|
||||
@@ -143,9 +143,10 @@ when exiting. Files with a mismatched skeleton, invalid matrices or missing name
|
||||
clips are rejected. Maximum 32 clips, 3600 frames per clip, 1..120 fps.
|
||||
|
||||
Enter/exit clips play once and their frame count/fps determines transition duration.
|
||||
Driving slots loop; brake, reverse and steering states select their respective clips,
|
||||
with drive as fallback. Missing optional driving slots use the drive clip when
|
||||
available. Slot switching currently cuts between clips; cross-fades are not included.
|
||||
Driving slots loop; brake and reverse select their respective base clips, with drive
|
||||
as fallback. Steering continuously blends that base towards the left/right pose.
|
||||
Vehicle phase changes blend with native bone-local interpolation; brake/reverse
|
||||
base-clip changes currently cut, so author compatible seated poses.
|
||||
Edit vehicle.json or rider.json and reload the mod to install new clips.
|
||||
|
||||
## Current boundaries
|
||||
@@ -156,7 +157,7 @@ and session-marker controls are blocked while driving. Vehicle motion is not
|
||||
recorded in skating replays. Native skater-versus-vehicle impact forces are not
|
||||
bridged yet: vehicles collide with the map and one another, but parked vehicles
|
||||
are not native skating obstacles. This API does not include weapons, damage,
|
||||
network synchronization, engine audio or a racing ruleset.
|
||||
network synchronization or a racing ruleset.
|
||||
|
||||
Verification uses headless Rapier tests and window-free Lua tests. The game is
|
||||
not launched automatically; rendering, entry/exit and handling need manual playtesting.
|
||||
@@ -172,3 +173,49 @@ jitter from separate camera damping. Resets discard the old motion sample.
|
||||
The board root is scaled away during vehicle playback and restored by the vanilla blend.
|
||||
The local Mario Kart package supplies fitted entry/exit, seated and steering clips;
|
||||
its proprietary rider.json is generated locally and is not included in source control.
|
||||
|
||||
## Ramp clearance and mass distribution
|
||||
These are shared definition fields, available to any mod, not Mario-specific code:
|
||||
|
||||
| Field | Meaning | Default |
|
||||
| --- | --- | --- |
|
||||
| `collider_offset` | Chassis-local collision centre, metres | `[0,0,0]` |
|
||||
| `collider_rounding` | Rounded edge radius; below 95% of smallest half extent | `0` |
|
||||
| `chassis_friction` | Body contact friction, 0..2 | `0.3` |
|
||||
| `center_of_mass` | Chassis-local mass centre, metres | `[0,0,0]` |
|
||||
| `inertia_half_extents` | Box dimensions used for mass distribution, independent of contact shape | null: use half_extents |
|
||||
|
||||
Rounding stays inside half_extents. Shorten low front/rear overhangs so wheel contact
|
||||
can lift the chassis before the body catches the ramp. Keep the collider large enough
|
||||
to protect the cockpit; the visual model does not define collision. Inertia dimensions
|
||||
let a shorter collision shape retain stable pitching/rolling behaviour. A lower centre
|
||||
of mass helps resist nose-diving under braking. These fields require respawning.
|
||||
The example passes headless 20/30/40-degree incline tests plus braking and steering tests;
|
||||
this does not guarantee every map seam or vertical ledge is traversable. Wheels remain
|
||||
raycasts, and vertical walls remain obstacles. No teleporting or artificial ramp boost is used.
|
||||
|
||||
## Engine sound
|
||||
Opt in per definition:
|
||||
|
||||
```json
|
||||
"engine_audio": { "enabled": true, "volume": 0.45, "idle_pitch": 0.7, "max_pitch": 2.8 }
|
||||
```
|
||||
|
||||
The host synthesizes an original layered exhaust pulse with filtered noise. No downloaded
|
||||
sound asset or extra file is required. It plays for the occupied vehicle; parked engines
|
||||
are silent. Pitch follows speed and absolute throttle, including reverse and free revving
|
||||
while stopped. Full throttle increases volume; releasing it smoothly drops the engine back
|
||||
towards idle. Pitch/volume changes are smoothed, Escape/replay fades it silent, and exiting
|
||||
or disabling the mod fades/removes the voice. This is a driver-focused mono sound, not a
|
||||
spatial multi-car mixer or a simulated gearbox. There is currently no custom sample slot.
|
||||
|
||||
Volume is 0..1, idle_pitch 0.25..2, max_pitch idle_pitch..5 (multipliers of the 80 Hz
|
||||
synth fundamental). All are validated. `sdk.vehicle.tune(key,{engine_volume=0.5})`
|
||||
changes volume live; use zero to mute. Mario Kart exposes this in its mod settings.
|
||||
|
||||
## Authoring and reuse
|
||||
See [Mixamo vehicle animation workflow](mixamo-vehicle-workflow.md) for the full sequence,
|
||||
calibration, Blender fitting, native export and packaging commands. The host's animation
|
||||
slots, steering blend, stance hand-offs, board hiding and shared motion interpolation
|
||||
apply automatically to every vehicle definition. The example fitting scripts contain
|
||||
kart geometry targets; adjust those targets for another vehicle without changing the host.
|
||||
Reference in new issue
Block a user