0
votes

I am parenting an Object3D to another Object3D that changes position, rotation, and scale through an animation. I want the child Object3D to be moved relative to the parent's position and rotation, but I do not want the child to scale at all. Is this possible? Is there some way I can "lock" the scale of the child, or override it so it is always a constant scale regardless of the parents?

Worst case, is there some sort of hook or callback for when an object's scale or transform is updated that I can listen to and then rescale the object?

I am parenting using parent.add(child) and then updating the child's position to a certain offset.

Thanks in advance!

1

1 Answers

1
votes

Something like that:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 5, 10);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

scene.add(new THREE.GridHelper(10, 10));

var parentObj = new THREE.Mesh(new THREE.SphereBufferGeometry(1, 16, 8), new THREE.MeshBasicMaterial({
  color: "red",
  wireframe: true
}));
scene.add(parentObj);

var childObj = new THREE.Mesh(new THREE.SphereBufferGeometry(1, 16, 8), new THREE.MeshBasicMaterial({
  color: "blue",
  wireframe: true
}));
childObj.position.set(2, 0, 0);
parentObj.add(childObj);

var clock = new THREE.Clock();
var time = 0;
var scale = 1;
var invScale = 1;


renderer.setAnimationLoop(() => {
  time = clock.getElapsedTime();

  scale = 1 + Math.sin(time) * 0.5 + 0.5;
  invScale = 1 / scale;

  parentObj.scale.setScalar(scale);
  childObj.scale.setScalar(invScale);

  renderer.render(scene, camera)
});
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>