Rotating Mesh in world axis - THREE.js - javascript

I'm having difficulty rotating an object. I am currently using THREE.Shape to configure a custom shape, after creating the shape, I configure it as a Mesh and set the position of it to:
buildingMesh.position.set( -70, -300, levelY );
Now because of the position of the mesh as well as the camera it appears as if its standing up.
Heres what that looks like:
Now I recently added a Orbital camera that rotates around the world axis, once the camera moves, this is how it looks:
Now this makes sense because the y axis was never configured when using the Three.Shape. What I am trying to figure out now is how can I turn that object so it appears to be standing up, as shown in the first image. I have tried using rotation on the x,y,z axis's but it always seems to only rotate within the objects axis.
Any suggestions?
Heres something I tried that I found on another question:
rotateAroundWorldAxis: function(object, axis, radians) {
this.rotWorldMatrix = new THREE.Matrix4();
this.rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
this.rotWorldMatrix.multiply(object.matrix); // pre-multiply
object.matrix = this.rotWorldMatrix;
object.rotation.setFromRotationMatrix(object.matrix);
}

Try:
mesh.rotate.x = Math.PI // will rotate over x axis 180 degree
where 'mesh' is object you have created (you can rotate 'y' and 'z' too)

So the primary problem here was that the mesh was built by multiple layers. All these layers actually had to be grouped together into an Object3D Which in turn allowed me to simply do: group.rotateOnAxis(axis,Math.pow(Math.PI, 2) / 2);
Hope this helps anyone in the future.

Related

How can I set Z up coordinate system in three.js?

In three.js Y axis represent up and down and Z axis represent forward and backward. But I want Z axis to represent up and down and Y axis to forward and backward. Here is a image showing what I want:
I want to change the entire coordinate system in such a way that, if I rotate a mesh around y axis, it follows the new coordinate system not the traditional one.
Now, I have searched stack overflow and found this link:
Three.JS rotate projection so that the y axis becomes the z-axis .
It doesn't work.
THREEJS: Matrix from Z-Up Coordinate System to Y-Up Coordinate System. This method just change the object or mesh y and z vertices but if I rotate it around y axis it rotates around the traditional y axis. I have to apply the matrix to the rotation matrix also to make it rotate like the new coordinate system.
Changing a matrix from right-handed to left-handed coordinate system
Reorienting axes in three.js fails when webpage is refreshed. This doesn't work also.
Is there any way I can make three.js to work like Z up coordinate system?
You can set the up vector of the camera using
camera.up.set(0,0,1);
Then, it will work like you expect.
The answer above works in simple case, but if you wish for example to use the editor, you better set before doing anything
THREE.Object3D.DefaultUp = new THREE.Vector3(0,0,1);
So any new object will also use this convention.
Using the previous answer, I struggled in the editor on on all the implications around the controls, saving the objects etc...
Please note that if you use a grid you still have to rotate it so that it covers XY plane instead of XZ
var grid = new THREE.GridHelper( 30, 30, 0x444444, 0x888888 );
grid.rotateX(Math.PI / 2);

XTK - Toolkit.. the cube moves by should only rotating

Im a newbie in 3D computer graphics and seen an odd thing.
I used the XTK-Toolkit, witch is great with DICOM. I add a cube in the scene and translated it far from the center (http://jsfiddle.net/64L47wtd/2/).
when the cube rotate it looks like it is moving
Is this a bug in XTK, or an principle problem with 3D rendering?
window.onload = function() {
// create and initialize a 3D renderer
var r = new X.renderer3D();
r.init();
// create a cube
cube = new X.cube();
// skin it..
cube.texture.file = 'http://x.babymri.org/?xtk.png';
cube.transform.translateX(250);
cube.transform.translateY(200);
cube.transform.translateX(270);
r.add(cube); // add the cube to the renderer
r.render(); // ..and render it
// add some animation
r.onRender = function() {
// rotation by 1 degree in X and Y directions
cube.transform.rotateX(1);
cube.transform.rotateY(1);
};
};
You miss to consider the cube a compound object consisting of several vertices, edges and/or faces. As a compound object it's using local coordinate system consisting of axes X, Y, Z. The actual cube is described internally using coordinates for vertices related to that cube-local coordinate system.
By "translating" you declare those relative coordinates of vertices being adjusted prior to applying inside that local coordinate system. Rotation is then still working on the axes of that local coordinate system.
Thus, this isn't an error of X toolkit.
You might need to put the cube into another (probably fully transparent) container object to translate/move it, but keep rotating the cube itself.
I tried to extend your fiddle accordingly but didn't succeed at all. Taking obvious intentions of X Toolkit into account this might be an intended limitation of that toolkit for it doesn't obviously support programmatic construction of complex scenes consisting of multi-level object hierarchies by relying on its API only.

Rotate object on specific axis anywhere in Three.js - including outside of mesh

Trying to rotate an object around any axis.
For example like a door hinge (on edge of object) or planet around the sun (outside of object).
The problem seems to be defining the axis. The below unit vector results in axis remaining on object's origin (centre) therefor identical to standard rotation:
object2.rotateOnAxis(new THREE.Vector3(1,0,0), 0.01);
// same as
object1.rotation.x += 0.01;
See code example: JSFiddle
EDIT: Looking for a way that one can rotate around a pivot without using nested children. Rotating a child's parent provides an easy way to manipulate the child's pivot point, but modifying the pivot point is not viable.
Example below, if you wanted to rotate the cube in a figure 8 motion, it would be achievable with this method by changing the parent. But one would have to assure that the new parent's position and orientation is precisely configured to make the child seamlessly jump between parents, and complex motions that do not repeat or loop would be very complicated. Instead, I would like to (and I will paraphrase the question title) rotate an object on a specific axis without using object nesting anywhere in the scene, including outside of the object's mesh.
See code example: JSFiddle with pivots
If you want to rotate an object around an arbitrary line in world space, you can use the following method. The line is specified by a 3D point and a direction vector (axis).
THREE.Object3D.prototype.rotateAroundWorldAxis = function() {
// rotate object around axis in world space (the axis passes through point)
// axis is assumed to be normalized
// assumes object does not have a rotated parent
var q = new THREE.Quaternion();
return function rotateAroundWorldAxis( point, axis, angle ) {
q.setFromAxisAngle( axis, angle );
this.applyQuaternion( q );
this.position.sub( point );
this.position.applyQuaternion( q );
this.position.add( point );
return this;
}
}();
three.js r.85

Rotate object around the world axis

I found several different supposedly working ways to rotate an object around the world axis but all of them kept rotating the object around it's own axis instead of rotating it around the world's. So, what's the proper way to rotate an object around the world's axis?
If I wasn't clear about the problem here's a drawing that represents my problem
Edit: Sorry I should have specificated in the question as well that I'm using Three.js
Edit2:
//camera is the object I want to rotate
//I also found a method that uses Euler but the result was far from the expected
/**Method 1**/
//Found this somewhere here in so
var rotateAroundWorldAxis = function(object, axis, radians) {
var rotWorldMatrix;
rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
rotWorldMatrix.multiply(object.matrix);
object.matrix = rotWorldMatrix;
object.rotation.setFromRotationMatrix(object.matrix);
}
//this is how I call the method
rotateAroundWorldAxis(camera, new THREE.Vector3(0,1,0), movementX*-0.001);
rotateAroundWorldAxis(camera, new THREE.Vector3(1,0,0), movementY*-0.001);
/**Method 1**/
/**Method 2**/
//I've also tried this method
var q = new THREE.Quaternion();
q.setFromAxisAngle( new THREE.Vector3(0,1,0), movementX*-0.001 ); // axis must be normalized, angle in radians
camera.quaternion.multiplyQuaternions( q, camera.quaternion );
/**Method 2**/
//movementX and movementY are values provided by the mouse movement using the pointerlock.
//These values works as I've tried them using rotateOnAxis
Use quaternions.
var rotateAroundWorldAxis = function(object, axis, radians) {
var rotation = new THREE.Quaternion();
rotation.setFromAxisAngle ( axis, radians );
object.quaternion.multiply(rotation);
}
rotateAroundWorldAxis(myObject, THREE.Vector3(0,1,0), movementX*-0.001);
I believe your problem before with the quaternion method is multiplying the quaternions in the wrong order so you rotate around global the Y axis, then perform the local rotation, which ultimately rotates in the local Y axis.
I ended up using the FirstPersonControls class. I had to make a few changes to the class though

version 70 about the TrackballControls.js rotation

My question in github--
https://github.com/mrdoob/three.js/issues/6043#issuecomment-73478885
I know TrackballControls.js be used for controlling a camera, not a model.
But I want rotation model with this TrackballControls.js.When I control the model with mouse,I can pan,zoom,rotate.When I rotate the model, I won't feel in a rotating camera, but seemed to rotate the model itself. I need a mouse event.
method:
controls.target = model.position;
or controls.target.copy( model.position )
they no use;
As seen in the lao3d.com Viewer you want to rotate the object around the worlds Y and X axis independent of its translation.
So I made this little example http://jsfiddle.net/nk3977jb/1/ .
It takes into consideration that the camera might be rotated.
And therefore creates its current Up and Right vector using the quaternion of the camera to get the up and view vector to then calculate the cross product of it.
var view = new THREE.Vector3(0, 0, -1);
view.applyQuaternion(camera.quaternion);
var cross = new THREE.Vector3();
cross.crossVectors(view, camera.up);
You can think of view being -Z going into the Screen, +Y being the cameras up vector pointing upwards from whichever rotation the camera has and cross being the crossproduct of -Z and +Y therefore pointing right.
With these axis setup you can rotate the object around them.

Categories

Resources