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是左手坐标系,摄像机看到的场景会反向,上述代码解决。

原文地址:https://www.cnblogs.com/leeplogs/p/6813462.html