Reputation: 81
I would like to apply the three.js script TrackballControls to a moving object in a way that preserves the ability to zoom and rotate the camera while the object moves through the scene. For example, I would like to be able to have the camera "follow" a moving planet, while the user retains the ability to zoom and rotate around the planet. Here is a basic jsfiddle:
http://jsfiddle.net/mareid/8egUM/3/
(The mouse control doesn't actually work on jsfiddle for some reason, but it does on my machine).
I would like to be able to attach the camera to the red sphere so that it moves along with it, but without losing the ability to zoom and rotate. I can get the camera to follow the sphere easily enough by adding lines like these to the render() function:
mouseControls.target = new THREE.Vector3(object.position);
camera.position.set(object.position.x,object.position.y,object.position.z+20);
But if I do that, the fixed camera.position line overrides the ability of TrackballControls to zoom, rotate, etc. Mathematically, I feel like it should be possible to shift the origin of all of the TrackballControls calculations to the centre of the red sphere, but I can't figure out how to do this. I've tried all sorts of vector additions of the position of the red sphere to the _this.target and _eye vectors in TrackballControls.js, to no avail.
Thanks for your help!
Upvotes: 4
Views: 2001
Reputation: 3837
I'd recommend OrbitControls
rather than TrackballControls
. My answer here applies primarily to OrbitControls
; the same principle might also work with TrackballControls
(I have not looked at its code in a while).
If you look at how OrbitControls
works you should notice it uses this.object
for the camera, and this.target
for where the camera is looking at, and it uses that vector (the difference between them) for some of its calculations. Movement is applied to both positions when panning; only the camera is moved when rotating. this.pan
is set to shift the camera, but out of the box it only deals with a panning perpendicular to the this.object
to this.target
vector because of the way it sets the panning vector.
Anyway, if you subtract the vector from object.position
to controls.target
and set controls.pan
to that vector, that should make it jump to that object:
Fixed example code:
Add a helper to OrbitControls.js
which has access to its local pan
variable:
function goTo( vector ) {
// Cloning given vector since it would be modified otherwise
pan.add( vector.clone().sub( this.target ) );
}
Your own code:
function animate() {
requestAnimationFrame(animate);
mouseControls.goTo( object.position ); // Call the new helper
mouseControls.update();
render();
}
You'll also probably want to set mouseControls.noPan
to true.
Upvotes: 1