- ExplodedModel.createParts now descends recursively through single
mesh-bearing wrapper nodes (e.g. Scene > Moto > Eclatement) until
reaching a node with multiple mesh-bearing children. Previously the
first wrapper was used as root, so models with extra Empty/group
parents fell back to flat leaf meshes lerping in local space.
- Add optional modelRotation field on RepairMissionConfig so fragmented
+ repairing models can match the world-space rotation of the source
inspection model (parked Ebike).
- Ebike mission now uses EBIKE_WORLD_ROTATION_Y/EBIKE_WORLD_SCALE
directly so the fragmented bike lines up with the parked bike.
The Physique test scene now mounts the real Ebike component for the
ebike repair zone, mirroring GameStageContent so the bike model and
its interactions (mount/dismount, parked position tracking) are
available when testing the repair flow.
RepairGame derives its live world position from
window.ebikeParkedPosition once the ebike mission leaves the
locked/waiting phase, so the repair sequence happens wherever the
player parked the bike rather than at the static zone anchor.
Render the exploded mission model during the repairing step so broken
nodes (e.g. ebike refroidisseur) stay visible in the world, and surface
their world positions to RepairRepairingStep so broken pieces spawn
from where they belong on the model rather than from a static offset.
- ExplodableModel: add hideNodeNames (mesh visibility off, restored on
unmount) and nodeAnchorNames + onNodeAnchorsChange (per-frame world
positions debounced via signature so React state updates only when
the values actually move).
- RepairGame: render ExplodableModel during 'repairing' with the broken
node names hidden + anchors forwarded; threads brokenAnchors state
to RepairRepairingStep.
- RepairScanSequence + RepairRepairingStep: propagate targetNodeName
through scanned and fallback broken-part lists.
- RepairRepairingStep: broken parts spawn at brokenAnchors[targetNodeName]
when set, falling back to legacy BROKEN_PART_START_OFFSETS otherwise.
- Ebike replacement parts: cooling core (correct, anchored at refroidisseur)
+ four distractors anchored at cabledroit/cablegauche/pucehaut/pucebas.
Removes the ad-hoc gant_l/talkie distractors in favor of consistent
case-anchored visuals.
- Pylon replacement parts: cable1 + cable2 (alternative correct, both with
caseLockGroup 'pylon-cable' for upcoming soft-lock) + refroidisseur and
two puce distractors anchored to packderelance.
- Farm replacement parts kept as-is (caseAnchor undefined falls back to
placeholder slot positions for backward compatibility).
- RepairGame threads anchors from RepairCaseModel through RepairMissionCase
to RepairRepairingStep; replacement-part initial position now resolves
to the anchor world position when caseAnchor is set, falling back to the
legacy slot index otherwise.