问题
I am trying to make a 3D viewer for building models. We have the model loaded and are trying to make some sort of interaction with the model. Therefor we are using OrbiControls for rotating, panning and zooming the model.
We want to have the behaviour in the viewer that when a user clicks and drags (thus rotating), the rotation center is at the point of the building where the user clicks.
I thought I was wise by changing the target of the OrbitControl as such:
control.target.set(newX, newY, newZ);
However, what I found in the source of the OrbitControl.js file, is that when the control updates, the
camera.lookAt()
function is called, which results the camera jumping to a new position.
Is there any way to get around this? I've been trying for a few hours now, and nothing seemed to be working.
Tried changing target0, then calling reset() on the control. Also tried changing the camera back to the old position (this might be how its done, but I might have tried it poorly.
回答1:
Is there any way to get around this?
Short answer is "Yes, but it's not using a standard version OrbitControls.js".
Read on for my detailed reasoning....
I have just spent some time looking at the source code of OrbitControls.js
(r87) considering the idea of implementing an enhancement that would allow you to provide an optional 2nd point that it would use as the camera target.
However after exploring the code I think this would be a bad feature to add to the standard public version. There are many features of OrbitControls such as the ability to limit viewing angle, min and max rotation and dolly distance that assume camera and orbit center are the same. If there was an option 2nd camera tagret these would all need to be modified to use either the center of orbit or the camera target or to have a configurable parameter that switches which one it uses. That would add hundreds of extra lines of code, making it harder to understand and all for a very niche feature.
So... The solution:
Because you are building a technical tool, I suspect you don't care about limited viewing angle, distance or rotation so if I were you I would copy OrbitControls.js
into your project, rename it to OrbitControls_customised.js
and make the changes you need:
Add 2 new parameters below this.target
called this.cameraTarget
and this.coupleCenters
// "target" sets the location of focus, where the object orbits around
this.target = new THREE.Vector3();
// "cameraTarget" is where the camera is looking (by default the same as target
this.cameraTarget = new THREE.Vector3();
// Whether the camera should be locked to the orbit center
this.coupleCenters = true;
And on the line where it instructs the camera to look at the center...
scope.object.lookAt( scope.target );
...change it so it only updates the camera when coupleCenters is true...
if( scope.coupleCenters ){
scope.cameraTarget = scope.target;
}
scope.object.lookAt( scope.cameraTarget );
Now, with those changes made, you can put an onMouseDown
event that uses RayCasting to find the point on your object, sets controls.decoupleCenters
to false
and sets controls.target
to the intersecting/crossing point of the raycast. Then an onMouseUp
event that sets the controls.target
back to the controls.cameraTarget
to allow it to behave as normal.
I hope that answers your question and gives you some rough road-map to work towards.
回答2:
Try this:
First set the position of the control to:
control.center.set(0, 0, 0);
Then do this:
camera.position.copy(control.center).add(new THREE.Vector3(x, y, z+10));
where x, y, and z is the position of your building model.
Notice I've added +10 to z, so that the camera is in front of the model. Change +10 to some other value to get closer/farther to/from the model.
回答3:
The following is Martin Joiner's solution (THANKS!!!) implemented in this codepen:
Change line 45 from this:
controls.coupleCenters = false;
to this:
controls.coupleCenters = true;
and then press any key (or click left mouse) to see the original behavior described by Wouter Coebergh before Martin's recommended logic is added to the customized orbital controls.
来源:https://stackoverflow.com/questions/35657231/threejs-orbit-controls-set-target-without-lookat