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

  • 相关阅读:
    mysql插入中文数据变成问号怎么处理
    项目第二阶段
    项目第一阶段
    项目测试
    常用mysql操作
    常用的mysql操作
    mysql操作
    土地档案管理系统需求分析
    土地档案管理系统架构图,ER图,用例图
    Load data local infile
  • 原文地址:https://www.cnblogs.com/leeplogs/p/6813462.html
Copyright © 2011-2022 走看看