diff --git a/sim/mujoco/model/walker.xml b/sim/mujoco/model/walker.xml index 6d20f41..14777f8 100644 --- a/sim/mujoco/model/walker.xml +++ b/sim/mujoco/model/walker.xml @@ -39,7 +39,7 @@ - + @@ -48,7 +48,7 @@ - + @@ -73,7 +73,7 @@ - + @@ -82,7 +82,7 @@ - + diff --git a/src/renderer.js b/src/renderer.js index d063146..9a668e7 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -15,7 +15,7 @@ const COLORS = { traceFar: '#b483ff', }; -const FOOT_OUTWARD_CM = 10; +const FOOT_OUTWARD_CM = 30; function drawLine(ctx, a, b, style = '#fff', width = 2) { ctx.beginPath(); diff --git a/src/renderer3d.js b/src/renderer3d.js index b3aee50..6ba952e 100644 --- a/src/renderer3d.js +++ b/src/renderer3d.js @@ -29,7 +29,7 @@ const SIDE_LINKS = [ const JOINT_KEYS = ['A', 'B', 'O', 'C', 'D', 'E', 'F', 'G']; const INITIAL_CAMERA_POSITION = { x: 22.744, y: -83.162, z: 120.597 }; const INITIAL_CAMERA_TARGET = { x: 98.958, y: -134.091, z: 0 }; -const FOOT_OUTWARD_CM = 10; +const FOOT_OUTWARD_CM = 30; function toVec3(point, z = 0) { return new THREE.Vector3(point.x, -point.y, z); @@ -244,10 +244,9 @@ export function create3DRenderer(mountEl) { const sideOffset = 8; - function setFootBarOutward(line, center, defaultDir) { + function setFootBarOutward(line, center, dir) { const a = center.clone(); const b = center.clone(); - const dir = Math.abs(center.z) > 1e-4 ? Math.sign(center.z) : defaultDir; b.z += dir * FOOT_OUTWARD_CM; setLinePoints(line, a, b); } @@ -304,6 +303,20 @@ export function create3DRenderer(mountEl) { const usePlayback = Boolean(playbackPose); const playbackUnits = state.mujocoPlayback?.units || 'meters'; + let playbackNearDir = 1; + let playbackFarDir = -1; + if (usePlayback) { + const nearPts = [near.C, near.F, near.G].filter(Boolean); + const farPts = [far.C, far.F, far.G].filter(Boolean); + if (nearPts.length && farPts.length) { + const nearMeanZ = nearPts.reduce((acc, p) => acc + mujocoToVec3(p, playbackUnits).z, 0) / nearPts.length; + const farMeanZ = farPts.reduce((acc, p) => acc + mujocoToVec3(p, playbackUnits).z, 0) / farPts.length; + if (nearMeanZ < farMeanZ) { + playbackNearDir = -1; + playbackFarDir = 1; + } + } + } for (const key of JOINT_KEYS) { if (usePlayback) { @@ -353,7 +366,7 @@ export function create3DRenderer(mountEl) { if (usePlayback) { const center = mujocoToVec3(p, playbackUnits); - setFootBarOutward(item.line, center, -1); + setFootBarOutward(item.line, center, playbackNearDir); } else { const center = toVec3(p, -sideOffset); setFootBarOutward(item.line, center, -1); @@ -390,7 +403,7 @@ export function create3DRenderer(mountEl) { if (usePlayback) { const center = mujocoToVec3(p, playbackUnits); - setFootBarOutward(item.line, center, 1); + setFootBarOutward(item.line, center, playbackFarDir); } else { const center = toVec3(p, sideOffset); setFootBarOutward(item.line, center, 1);