Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Unity transforms to THREE.js rotations

How can I match the rotation of a THREE.js camera or object to a transform from a Unity GameObject?

Unity uses a left-handed system with a ZXY euler order. THREE.js uses a right-handed system with an XYZ euler order.

What transformations need to be made to convert GameObject.transform.rotation (Quaternion) to Object3D.rotation (THREE.Vector3)?

like image 786
Simon Cave Avatar asked Aug 05 '13 19:08

Simon Cave


People also ask

How do I change rotations in Unity?

To rotate a Transform, use Transform. Rotate, which uses Euler Angles. If you want to match values you see in the Inspector, use the Quaternion. eulerAngles property on the returned Quaternion.

What is quaternion rotation in Unity?

Quaternions are used to represent rotations. They are compact, don't suffer from gimbal lock and can easily be interpolated. Unity internally uses Quaternions to represent all rotations. They are based on complex numbers and are not easy to understand intuitively.

How do rotations work in Unity?

Rotation in Unity typically works by specifying an amount of rotation in degrees around the X, Y or Z axis of an object. In the same way that a game object's position in the world can be set using its Transform component…


2 Answers

We ended up fixing this as follows:

Assuming you get qx, qy, qz and qw from Unity's quaternion, we apply the conversion below in JavaScript / Three.JS:

// convert Quaternion from Left-handed coordinate system to Right-handed

var q = new THREE.Quaternion( -qx, qy, qz, -qw );

var v = new THREE.Euler();  
v.setFromQuaternion( q );

v.y += Math.PI; // Y is 180 degrees off

v.z *= -1; // flip Z

object.rotation.copy( v );

That worked correctly in all axis rotations and directions.

three.js r.59

like image 194
jocabola Avatar answered Oct 27 '22 03:10

jocabola


The key is to match the initial loading positions of the model between unity and threejs. The accepted answer probably will only work for 1 of those matches; but not all.

Below are 2 examples:

Sample 1: Unity initial loading position is x-left, y-up, and z-forward

Sample 1

To convert to three.js:

Position: flip the x because that's the only axis that's different.

Rotation: If you have a quaternion, convert it to Euler, then flip the y and z components of the rotation, then set the order to "ZXY". The reason we have to flip y and z is because in this sample, unity and threejs y and z axes are in the same directions, so they rotate in the opposite directions; flipping ensures they rotate in the same directions. The order is set to "ZXY" because that is the order unity is rotating.

Sample 2: Unity initial loading position is x-right, y-up, and z-backward

enter image description here

To convert to three.js:

Position: flip the z because that's the only axis that's different.

Rotation: Quaternion -> Euler, flip x, and y, set order to "ZXY". Same reasoning as above.

As you can see from the two examples, the starting positions of the model in unity and three.js affects how we convert the positions and rotations between them.

like image 32
Michael Nguyen Avatar answered Oct 27 '22 02:10

Michael Nguyen