ThreeJS orbit controls set target without lookAt

喜你入骨 提交于 2020-02-22 04:21:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!