From d142d5f50d4f02bb2f66d7e791d40b46834577da Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Feb 2026 22:30:41 -0800 Subject: [PATCH] Stabilize actor position when hat changes Override centerAndScaleModel in ActorRenderer to exclude the hat part from the bounding box calculation, so switching between hats of different sizes no longer shifts the body/head position. --- src/core/rendering/ActorRenderer.js | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/core/rendering/ActorRenderer.js b/src/core/rendering/ActorRenderer.js index 869ecf8..748af5f 100644 --- a/src/core/rendering/ActorRenderer.js +++ b/src/core/rendering/ActorRenderer.js @@ -283,6 +283,36 @@ export class ActorRenderer extends BaseRenderer { } } + /** + * Center and scale the actor, excluding the hat from the bounding box + * so that changing hats doesn't shift the actor's position. + */ + centerAndScaleModel(scaleFactor) { + if (!this.modelGroup) return; + + const box = new THREE.Box3(); + for (let i = 0; i < this.partGroups.length; i++) { + if (i === 1 || !this.partGroups[i]) continue; // skip hat + box.expandByObject(this.partGroups[i]); + } + + if (box.isEmpty()) { + super.centerAndScaleModel(scaleFactor); + return; + } + + const center = box.getCenter(new THREE.Vector3()); + const size = box.getSize(new THREE.Vector3()); + + this.modelGroup.position.sub(center); + + const maxDim = Math.max(size.x, size.y, size.z); + if (maxDim > 0) { + const scale = scaleFactor / maxDim; + this.modelGroup.scale.setScalar(scale); + } + } + /** * Apply position/direction/up transform from ActorLOD data. * The game uses CalcLocalTransform with direction/up vectors.