I have a camera and an box. I want to get the camera's rotation as if it were a child of the box, without actually parenting the camera.
THREE.js has object.worldToLocal(position) which will correctly get the camera's position relative to the box, but that function will of course not work for euler rotations, so I'm looking for the equivalent for euler or quaternion rotation.
Unity has transform.InverseTransformDirection(vector), and I'm looking for something similar.
Thanks!
Ok, I think I got it!
var rot = camera.getWorldQuaternion();
rot.multiply(box.getWorldQuaternion().inverse());
var euler = new THREE.Euler().setFromQuaternion(rot);
Related
I have some planes, parented to an empty Object3D. Those planes are always facing the camera,like sprites. It works fine unless I rotate the parent. Three.js documentation says that .lookAt doesn't support transformed parents
So I am trying to figure out how to solve it manually.
Here is what I have now:
plane.onBeforeRender = function( renderer, scene, camera,
geometry, material, group ){
var worldCamPos = new THREE.Vector3();
camera.getWorldPosition(worldCamPos);
this.worldToLocal(worldCamPos);
this.lookAt(worldCamPos);
// this.quaternion.copy(camera.quaternion);//this one rotates in local space of the container
};
So I a m trying to convert camera's position to the space inside which the plane lives,and use it as lookAt target.
The problem is,the plane is sort of looking at the camera,but it constantly flickering as if swapping rotations from default to the desired one,back and forth. I don't concatenate here anything,so I don't understand why it happens.
I would appreciate if someone could point out to more elegant solution,maybe with quaternions.
I am currently creating a VR web app using three.js. As the camera controls I am using the device orientation controls used here in the google cardboard three.js demo.
What I need to do is add keyboard controls to this(e.g Up arrow to go forward etc). I've fiddled around with moving the camera on the two axis (x and z) here:
if (e.keyCode == '38') {
camera.position.set(0, 10, camera.position.z+4);
controls.target.set(
camera.position.x +4,
camera.position.y,
camera.position.z
);
effect.render(scene, camera);
...
However I want to make the character move relative to where they are looking (e.g You look one way and press the Up arrow and the character moves the way you looking). Like a first person view.
Does anyone have any ideas on how this is done? Ive tried using the first person controls from three.js but this eliminates the head tracking which is essential for a VR game.
Any answers would be greatly appreciated. (My source code is practically just the Google cardboard three.js demo code with a function added in too detect key presses)
I solved this by different approach. I created an object3d which is moving in scene. Model and camera are child of this object.
I'm rotating object 3d with camera and in the same time rotate model in opposite direction. When i rotate camera object looks keeping direction. when i want to move object, just translateX object with camera and make model rotation to 0. That did the trick.
On long distances (I have millions of units) started to be jerky. Reason is lost precision.
I solved it by keeping position of object at 0,0,0 and move all other things in opposite direction. That makes your model is still on 0,0,0 coords with right rotation and world is moving around.
Most simple example:
you trying something like
scene.add(character_model);
scene.add(camera);
//camera.rotate ....
character_model.translateX(1);
character_model.rotateX(1);
//etc ...
and now you trying to move camera around the pivot (character_model), but this is overcomplicated mathematics.
Try:
var controls_dimension = new THREE.Object3D();
scene.add(controls_dimension);
controls_dimension.add(character_model);
controls_dimension.add(camera);
//use controls to rotate with this object, not with character_model
controls_dimension.rotateX(2);
// in the same rotate model to opposite direction. You can make
// illusion of rotating camera, not a model.
character_model.rotateX(2*-1);
/*
when you want to go in camera direction=controls_dimension=controls_dimension.translateX(1)
and we moving (you most only animate model rotation to controls_dimension.rotation)
*/
I'm newbie in three.js and WebGL.
In my application, there is 3D scene in which the two objects.
object - it is a big sphere;
object - a smaller sphere, which is located on the surface of the first object.
Big sphere rotates around its axis. And also there is the possibility to rotate the camera around the spheres.
So as a small sphere on the surface of a large sphere, it also rotates with it. Small sphere will be visible to us as large sphere turns to the camera and it will not be visible when a large sphere is in front of it.
The question is, how do I determine when a small sphere is visible to the camera, and when it is not visible?
Also, I need to get the coordinates in 2d for small sphere where it is visible. How can I do this?
This can be accomplished with three.js's built-in raycaster and projector functionalities. To start, try taking a look at this demo and its source code. Here is another example. In this way you can determine which objects are closer to an invisible line that is emitted from the camera's position.
Otherwise, if you are simply interested in which of the two objects is closer to the camera, you can simply check to see which of their position values have a lesser distance to the camera's coordinates. The three-dimensional distance formula would come in handy:
bigSphereDistance = Math.sqrt( Math.pow(camera.position.x - big.position.x,2) +
Math.pow(camera.position.y - big.position.y,2) +
Math.pow(camera.position.z - big.position.z,2) );
smallSphereDistance = Math.sqrt( Math.pow(camera.position.x - small.position.x,2) +
Math.pow(camera.position.y - small.position.y,2) +
Math.pow(camera.position.z - small.position.z,2) );
//then check...
bigSphereDistance > smallSphereDistance ? /*case*/ : /*case*/;
Intuitively, the small sphere is visible when its distance is less than that of the big sphere, with a buffer of the small sphere's radius.
To answer your second question, finding any object's 2D coordinates can accomplished like this.
When we add a CustomGeometry to the scene with defining vertices and not setting the position, how can we get it to rotate around its own center point?
Fiddle : http://jsfiddle.net/tezcancirakoglu/Ldt7z
In the sample code, object is rotating around Scenes X axis. I need to rotate it around its center point.
Hint: The red cube mesh is the initial centerpoint of the object which is rotating. I need to rotate it around x axis of red cube... I tried alot but failed anyway.
One solution is to translate the mesh geometry, and compensate by changing the mesh position, like so:
var offset = objMesh.centroid.clone();
objMesh.geometry.applyMatrix(new THREE.Matrix4().makeTranslation( -offset.x, -offset.y, -offset.z ) );
objMesh.position.copy( objMesh.centroid );
updated fiddle: http://jsfiddle.net/Ldt7z/165/
P.S. You do not need to save your fiddle before running it. There is no reason to have so many versions.
three.js r.55
You can use the center of the bounding box, which would basically be the 'average' of your vertices but it is not guaranteed to fall onto the red cube.
I have an object that is using a quaternion. This quaternion gets updated on a user's keypress to allow the object to rotate it's internal axis. The rotations are working fantastic. When in it's default state (before a user adjusts the rotation) my quaternion reads w:1, x:0, y:0, z:0
I want this object to always move forward in space via it's internal z-axis - THREE.Vector3(0,0,-1). How can I use the quat to know where it's z-axis is and move it forward?
For example - when my quaternion reads w:0.7, x:0.7, y:0, z:0 - the object is rotated to have it's z-axis pointed upward. Is there a way to move an object via it's internal axis?
Here's a jsfiddle example: http://bitly.com/RXPy5w - I want the square to always move forward in relation to it's z-axis
Any help would be greatly appreciated.
All you have to do is add the following line in your render loop:
airplane.translateZ( 1 );
Updated Fiddle: http://jsfiddle.net/Lc8gH/21/ Enjoy!
And by the way, you can't "translate a quaternion". Keep studying until you understand what this code is doing.
A quaternion here represents a rotation in three-space. You need to first specify what initial orientation you're rotating from. Make that a unit vector in the direction of your starting orientation.
Now, to travel in the direction of your current orientation, you can rotate the initial-orientation vector through the rotation described by your current quaternion. Now you have a unit vector pointing in the right direction.
Finally, of course, you can scale that unit vector to represent a motion by a non-unit distance, add it to your current position, and you're done.