简体   繁体   中英

Convert object rotation from Three.js to Unity3D

I'm creating a Three.js Scene exporter from Three.js to Unity3D. My problem is in converting Euler angles from Three.js to Unity.

I know that:

  • Three.js is right-handed space and Unity3D is left-handed;
  • In Unity3D the plane is constructed being flat on the floor, while in Three.js is standing facing to positive z.

Can somebody please give me an example on how to do that?

UPDATE

I tried to follow @StefanDragnev advice but i can't make it work.This is my Three.JS code to obtain matrix for Unity:

var originalMatrix = object3D.matrix.clone();
var mirrorMatrix = new THREE.Matrix4().makeScale(1, 1, -1);
var leftHandMatrix = new THREE.Matrix4();

leftHandMatrix.multiplyMatrices(originalMatrix,mirrorMatrix);

var rotationMatrix = new THREE.Matrix4().makeRotationX(Math.PI / 2);
var unityMatrix =  new THREE.Matrix4();

unityMatrix.multiplyMatrices(leftHandMatrix,rotationMatrix);

jsonForUnity.object.worldMatrix = unityMatrix.toArray();

I tried mirrorMatrix (-1,1,1),too, or makeRotationX(Math.PI / 2) but it didn't work, either. Unity doesn't allow to set the object transformation from object's world matrix directly. I had to extract quaternion from matrix. This is my Unity code:

Vector4 row0 = new Vector4 (threeObject.matrix[0],threeObject.matrix[4],threeObject.matrix[8],threeObject.matrix[12]);
Vector4 row1 = new Vector4 (threeObject.matrix[1],threeObject.matrix[5],threeObject.matrix[9],threeObject.matrix[13]);
Vector4 row2 = new Vector4 (threeObject.matrix[2],threeObject.matrix[6],threeObject.matrix[10],threeObject.matrix[14]);
Vector4 row3 = new Vector4 (threeObject.matrix[3],threeObject.matrix[7],threeObject.matrix[11],threeObject.matrix[15]);

Matrix4x4 matrix = new Matrix4x4();
matrix.SetRow (0,row0);
matrix.SetRow (1,row1);
matrix.SetRow (2,row2);
matrix.SetRow (3,row3);

Quaternion qr = Quaternion.LookRotation(matrix.GetColumn(2), matrix.GetColumn(1));
gameObject.transform.localRotation = qr;

Where am I failing?

It's not just angles that you need to convert. You'll also need to convert the translations. Euler angles are not very confortable to use when doing general transformations. It's much easier to work with the object's world matrix directly.

Converting from right-handed to left-handed - you need to mirror the object's matrix along an axis, say Z in your case. Multiply the object's matrix by Matrix4().makeScale(1, 1, -1) .

Then going from XY to XZ being parallel to the viewport, you need to rotate the object along the X axis by 90 degrees (or -90 degrees, if rotations are clockwise). Multiply the object's matrix by Matrix4().makeRotationX(Math.PI / 2) .

Then, you need to import the final matrix into Unity. In case you can't just import the matrix wholesale, you can try to first decompose it into scaling, rotation and translation parts, but if at all possible, avoid that.

You can do it like this

let position = new THREE.Vector3();
let rotation = new THREE.Quaternion();
let scale = new THREE.Vector3();

(new THREE.Matrix4().makeScale(1, 1, -1).multiply(this.el.object3D.matrix.clone())).multiply(new THREE.Matrix4().makeRotationX(Math.PI/2)).decompose(position, rotation, scale);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM