Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

three.js get camera position with orbit controls

I am using the three.js orbit controls and attempting to have a skybox follow the position of the camera. Having searched the internet I've found no suitable answer.

My question is simple - how do I retrieve the coordinates of the camera when using orbit controls, the following doesn't work:

skybox.position.x = camera.position.x;  //Moving skybox with camera
skybox.position.z = camera.position.z;  //Moving skybox with camera
skybox.position.y = camera.position.y;  //Moving skybox with camera

The values of x and z coordinates are incorrect. I have also tried:

orbit_controls.object.target

instead, but this results in similar incorrect behaviour with x and z returning incorrect values.

A seemingly obvious requirement of a control mechanism seems remarkably difficult to do.

like image 571
Single Entity Avatar asked Nov 27 '15 18:11

Single Entity


3 Answers

Having had no answer on SO I did some additional testing and I've discovered there is a need for a coordinate system transformation to retrieve the correct coordinates of the camera.

The following will retrieve the camera's current position in standard world (x,y,z) space and apply it to a skybox.

newZ = -(camera.position.x * Math.cos(5.49779)) - (camera.position.z * Math.sin(5.49779));
newX = (camera.position.x * Math.cos(0.78)) + (camera.position.z * Math.sin(0.78));

skybox.position.x = newX;   //Moving skybox with camera
skybox.position.z = newZ;   //Moving skybox with camera
skybox.position.y = camera.position.y;  //Moving skybox with camera

As I couldn't find this answer anywhere else, I hope this will be useful to other people, it solved my problem.

like image 183
Single Entity Avatar answered Nov 08 '22 20:11

Single Entity


This is a 2019 answer to a 2015 question:

camera.position is the local position of the camera. You can retrieve the global position by camera.getWorldPosition().

By the way, you don't have to move the skybox with the camera. Instead, use the cube texture (or rendered cube) as scene.background.

like image 3
Elias Hasle Avatar answered Nov 08 '22 18:11

Elias Hasle


I had the same question, and what I did was include the following lines of code to the THREE.OrbitControls function, within the OrbitControls.js file.

THREE.OrbitControls = function ( object, domElement ) {

    .
    .
    .

  this.getPos = function() {
    pos = new THREE.Vector3();
    pos.copy( this.object.position );
    return  pos;
  };
  this.getCenter = function() {
    cent = new THREE.Vector3();
    cent.copy( this.center );
    return cent;
  };
    .
    .
    .
}

this.object it points to the camera Object you gave when you created the Controls object, and this.center is a THREE.Vector3() initialized as (0,0,0) that defines where your camera is looking at.

And it worked perfectly. As you can see are two getter functions, one fetches the camera position, and the other fetches the center. Then I call it from my code like this:

//Create the controls object
var controls = new THREE.OrbitControls( this.camera, this.renderer.domElement);
//get the camera position whenever you want
var cameraPosition = controls.getPos();
like image 1
Javingka Avatar answered Nov 08 '22 19:11

Javingka