Normalize ghost models to exact cm height (setHeight API, feet at origin, manifest scale multiplier)
This commit is contained in:
@@ -83,7 +83,6 @@ export async function buildGhost(ghost, gradients, manifest) {
|
|||||||
if (!url) continue;
|
if (!url) continue;
|
||||||
group.add(await loadOBJ(url));
|
group.add(await loadOBJ(url));
|
||||||
}
|
}
|
||||||
if (model.scale) group.scale.setScalar(model.scale);
|
|
||||||
if (!group.children.length) group = proceduralWisp();
|
if (!group.children.length) group = proceduralWisp();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('ghost model load failed, using wisp fallback', e);
|
console.warn('ghost model load failed, using wisp fallback', e);
|
||||||
@@ -103,8 +102,20 @@ export async function buildGhost(ghost, gradients, manifest) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
group.userData.material = mat;
|
// Normalize: wrap so feet sit at the group origin, then expose setHeight(cm) that
|
||||||
group.userData.setOpacity = (v) => { mat.uniforms.opacity.value = v; };
|
// scales the whole ghost (any source units) to an exact world height. Minifigure ≈ 4 cm.
|
||||||
group.userData.tick = (t) => { mat.uniforms.uTime.value = t; };
|
const outer = new THREE.Group();
|
||||||
return group;
|
const inner = new THREE.Group();
|
||||||
|
inner.position.y = -box.min.y; // feet -> origin
|
||||||
|
inner.add(group);
|
||||||
|
outer.add(inner);
|
||||||
|
const rawH = Math.max(box.max.y - box.min.y, 1e-6);
|
||||||
|
const modelScale = model?.scale || 1; // per-model fine-tune multiplier from the manifest
|
||||||
|
outer.userData.setHeight = (cm) => outer.scale.setScalar((cm / rawH) * modelScale);
|
||||||
|
outer.userData.setHeight(4);
|
||||||
|
|
||||||
|
outer.userData.material = mat;
|
||||||
|
outer.userData.setOpacity = (v) => { mat.uniforms.opacity.value = v; };
|
||||||
|
outer.userData.tick = (t) => { mat.uniforms.uTime.value = t; };
|
||||||
|
return outer;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user