I have a Three.js v72dev scene posed 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: .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: /
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?
I have a Three.js v72dev scene posed 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/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/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?
Share Improve this question edited Jun 10, 2015 at 18:09 WestLangley 105k11 gold badges287 silver badges283 bronze badges asked Jun 9, 2015 at 12:01 Luis E. FraguadaLuis E. Fraguada 5291 gold badge9 silver badges28 bronze badges 4- having the same issue with trackballs. i havent found time to work on it yet but i think it es from movements stored in the same variables in the controls : when you switch cameras it uses the values for the previous one, that is why reseting controls solves it. In my case im thinking about 2 solutions : create as much controls as cameras, set a variable to define the current ones and update only the right controls in the loop. Otherwise, store position when camera changes and set it back when it is used again. – Mouloud85 Commented Jun 9, 2015 at 14:00
- @Astrak , I took that approach as well, but it did not solve it.. I made an array of controls for each camera, and when I switched cameras I would switch controls, but I get the same effect. The only thing that has worked is the method I describe, copying the positions and rotations of the stored cameras to a new cam. – Luis E. Fraguada Commented Jun 9, 2015 at 15:29
- Actually, this method I posted only sorf of works. If the one pans around, the camera position, lookAt, etc is not preserved when resetting the control. Does anyone have any working examples of working with multiple cameras and controls? – Luis E. Fraguada Commented Jun 15, 2015 at 9:01
- To fix this a bit, one can store the controls.target vector for each camera. When the controls are updated, this should also save the current control target. When the camera is switched, the control.target should go back to the stored target. This works, but I feel it could be cleaner. I am now trying to abstract this in order to roll it out for a system with a variable number of cameras... – Luis E. Fraguada Commented Jun 15, 2015 at 9:56
1 Answer
Reset to default 2After 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/WebGL/camTest5/