简体   繁体   中英

Three.js: Switching between Cameras and Controls

I have a Three.js v72dev scene composed of objects imported through THREE.ObjectLoader. This works well.

I am now importing cameras that are translated to Three.js cameras from my CAD package. I start to get issues when I move the camera with OrbitControls. With one camera, one does not notice the difference, but with multiple cameras, you start to see that moving the camera, affects the other cameras. You can see the effect of this here: http://datable.net/WebGL/Iris0.3.0_Demo/

After the scene loads, you can open the views to switch between the different cameras. Move one camera around, switch to another camera, move that around, switch back, etc. You will see that the cameras affect each other.

I guess the issue is the manner which I am setting the main camera variable when I change cameras:

camera = someOtherCameraStoredInArrayOrObject;

I do have a working sample, but I am wondering if there is a more concise way to go about it. Here is an example that works: http://datable.net/WebGL/Cameras/

I took a different approach here and when I switch cameras I do something like this:

camera = new THREE.PerspectiveCamera(camera1.fov, window.innerWidth/window.innerHeight, camera1.near, camera1.far  );
camera.position.copy(camera1.position);
camera.rotation.copy(camera1.rotation);
controls = new THREE.OrbitControls(camera);

The issue is that each time I change the view through the OrbitControls, I need to update the stored cameras like this:

function camUpdate(otherCam){
        otherCam.position.copy(camera.position);
        otherCam.rotation.copy(camera.rotation);
}

Just seems a bit cumbersome to me. Any other elegant solutions to handle switching control and view between various cameras?

After trying several different approaches, I have something that seems to be working from all cases. In this approach I keep one main camera and one set of controls (this app only has one 'viewport'). The cameras I want to switch through are imported with THREE.ObjectLoader . Each has a unique id, and I save that in a currentCamera variable. I have an event that returns the desired camera. This event triggers the following function:

function onViewChange(event) {

//save current camera params
    var cam = scene.getObjectByName( currentCamera );
    cam.position.copy(camera.position);
    cam.rotation.copy(camera.rotation);
    cam.userData[0].tX = controls.target.x;
    cam.userData[0].tY = controls.target.y;
    cam.userData[0].tZ = controls.target.z;

//set next camera positions
    var cam = scene.getObjectByName( event.detail.view );

    currentCamera = event.detail.view;

    camera = new THREE.PerspectiveCamera(cam.fov, window.innerWidth / window.innerHeight, cam.near, cam.far);
    camera.position.copy(cam.position);
    camera.rotation.copy(cam.rotation);

    controls = new THREE.OrbitControls(camera);
    controls.target = new THREE.Vector3( cam.userData[0].tX, cam.userData[0].tY, cam.userData[0].tZ );

}

I guess I could clean up how I store the control target data, but for now, this seems to answer what I wanted to do which is switch between imported cameras and not have the controls get out of whack.

Here is an updated demo which is working how I desire: http://datable.net/WebGL/camTest5/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM