unity还原three导出的json——基本模型,位移,旋转,缩放
GameObject.CreatePrimitive(PrimitiveType.Cube);
GameObject.CreatePrimitive(PrimitiveType.Plane);
GameObject.CreatePrimitive(PrimitiveType.Sphere);
GameObject.CreatePrimitive(PrimitiveType.Cylinder);
然后设置transform组件:
using System; using UnityEngine; using UnityEditor; public class MatrixArray { private Vector3 scale; private Vector3 angle; private Matrix4x4 m_Materix; private Quaternion m_Quaternion; private double[] init = { -7.143478,3.521163,-7.232108,0,-1.87758,1.747491,2.705387,0,2.692082,3.996646,-0.713207,0,5.061553,4.274189,5.206913,1 }; public MatrixArray() { SetScaleAndAngle(); } public Vector3 GetPosition() { float[] arr = DoubleToFloat(init); Vector3 position = new Vector3(arr[12], arr[13], arr[14]); return position; } public Vector3 GetScale() { return scale; } public Vector3 GetAngle() { return angle; } private float[] DoubleToFloat(double[] arrs) { float[] outs = new float[arrs.Length]; float b = 0; int index = 0; foreach (var a in arrs) { b = (float) a; outs[index] = b; index++; } return outs; } private void SetScaleAndAngle() { float[] arr = DoubleToFloat(init); var te = arr; var sx = Length(new Vector3(te[0], te[1], te[2])); var sy = Length(new Vector3(te[4], te[5], te[6])); var sz = Length(new Vector3(te[8], te[9], te[10])); var det = Determinant(); if (det < 0) { sx = -sx; } scale.x = sx; scale.y = sy; scale.z = sz; var invSX = 1 / sx; var invSY = 1 / sy; var invSZ = 1 / sz; Vector4 v4; for (int j = 0; j < arr.Length; j++) { if (j % 4 == 3) { v4 = new Vector4(arr[j - 3], arr[j - 2], arr[j - 1], arr[j]); m_Materix.SetColumn((int) (j / 4), v4); } } m_Materix[0] *= invSX; m_Materix[1] *= invSX; m_Materix[2] *= invSX; m_Materix[4] *= invSY; m_Materix[5] *= invSY; m_Materix[6] *= invSY; m_Materix[8] *= invSZ; m_Materix[9] *= invSZ; m_Materix[10] *= invSZ; QuaternionSetFromMatrix(m_Materix); } private void QuaternionSetFromMatrix(Matrix4x4 m) { var trace = m.m00 + m.m11 + m.m22; var s = 0f; if (trace > 0) { s = 0.5f / Mathf.Sqrt(trace + 1.0f); m_Quaternion.w = 0.25f / s; m_Quaternion.x = (m.m21 - m.m12) * s; m_Quaternion.y = (m.m02 - m.m20) * s; m_Quaternion.z = (m.m10 - m.m01) * s; } else if (m.m00 > m.m11 && m.m00 > m.m22) { s = 2.0f * Mathf.Sqrt(1.0f + m.m00 - m.m11 - m.m22); m_Quaternion.w = (m.m21 - m.m12) / s; m_Quaternion.x = 0.25f * s; m_Quaternion.y = (m.m10 + m.m01) / s; m_Quaternion.z = (m.m20 + m.m02) / s; } else if (m.m11 > m.m22) { s = 2.0f * Mathf.Sqrt(1.0f + m.m11 - m.m00 - m.m22); m_Quaternion.w = (m.m02 - m.m20) / s; m_Quaternion.x = (m.m10 + m.m01) / s; m_Quaternion.y = 0.25f * s; m_Quaternion.z = (m.m21 + m.m12) / s; } else { s = 2.0f * Mathf.Sqrt(1.0f + m.m22 - m.m00 - m.m11); m_Quaternion.w = (m.m10 - m.m01) / s; m_Quaternion.x = (m.m20 + m.m02) / s; m_Quaternion.y = (m.m21 + m.m12) / s; m_Quaternion.z = 0.25f * s; } SetFromRotationMatrix(MakeRotationFromQuaternion(m_Quaternion)); } private float[] MakeRotationFromQuaternion(Quaternion q) { float[] te = new float[16]; te[0] = te[5] = te[10] = te[15] = 1; var x = q.x; var y = q.y; var z = q.z; var w = q.w; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var xy = x * y2; var xz = x * z2; var yy = y * y2; var yz = y * z2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; te[0] = 1 - (yy + zz); te[4] = xy - wz; te[8] = xz + wy; te[1] = xy + wz; te[5] = 1 - (xx + zz); te[9] = yz - wx; te[2] = xz - wy; te[6] = yz + wx; te[10] = 1 - (xx + yy); // last column te[3] = 0; te[7] = 0; te[11] = 0; // bottom row te[12] = 0; te[13] = 0; te[14] = 0; te[15] = 1; return te; } private void SetFromRotationMatrix(float[] m) { var te = m; var m11 = te[0]; var m12 = te[4]; var m13 = te[8]; var m21 = te[1]; var m22 = te[5]; var m23 = te[9]; var m31 = te[2]; var m32 = te[6]; var m33 = te[10]; angle.y = Mathf.Asin(Mathf.Clamp(m13, -1, 1)); if (Mathf.Abs(m13) < 0.99999) { angle.x = Mathf.Atan2(-m23, m33); angle.z = Mathf.Atan2(-m12, m11); } else { angle.x = Mathf.Atan2(m32, m22); angle.z = 0; } angle.x = angle.x * 180f / Mathf.PI; angle.y = angle.y * 180f / Mathf.PI; angle.z = angle.z * 180f / Mathf.PI; m_Quaternion = Quaternion.Euler(angle); } private float Length(Vector3 vector3) { return Mathf.Sqrt(vector3.x * vector3.x + vector3.y * vector3.y + vector3.z * vector3.z); } private float Determinant() { float[] arr = DoubleToFloat(init); var te = arr; var n11 = te[0]; var n12 = te[4]; var n13 = te[8]; var n14 = te[12]; var n21 = te[1]; var n22 = te[5]; var n23 = te[9]; var n24 = te[13]; var n31 = te[2]; var n32 = te[6]; var n33 = te[10]; var n34 = te[14]; var n41 = te[3]; var n42 = te[7]; var n43 = te[11]; var n44 = te[15]; return ( n41 * ( +n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34 ) + n42 * ( +n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31 ) + n43 * ( +n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31 ) + n44 * ( -n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31 ) ); } }
MatrixArray类是解析
"matrix": [0.015579,0,0.999879,0,0,1,0,0,-0.999879,0,0.015579,0,-30.749359,4.370426,0,1]用的;
private void SetTransform(GameObject game) { MatrixArray matrix = new MatrixArray(); game.transform.position = matrix.GetPosition(); game.transform.localScale = matrix.GetScale(); game.transform.Rotate(new Vector3(matrix.GetAngle().x,0,0),Space.Self); game.transform.Rotate(new Vector3(0,matrix.GetAngle().y,0),Space.Self); game.transform.Rotate(new Vector3(0,0,matrix.GetAngle().z),Space.Self); game.transform.parent = gameObject.transform; Reverse(game.transform,matrix); }
上面代码为unity的对象还原位移旋转缩放。
private void Reverse(Transform form,MatrixArray matrixParse) { //反转 Vector3 pos = matrixParse.GetPosition(); form.position = new Vector3(-pos.x,pos.y,pos.z); Vector3 scale = matrixParse.GetScale(); form.localScale = new Vector3(scale.x,-scale.y,-scale.z); form.Rotate(new Vector3(180,0,0),Space.World); }
由于three.js是右手坐标系,unity是左手坐标系,摄像机看到的场景会反向,上述代码解决。