//************************************************** // Copyright©2018 何冠峰 // Licensed under the MIT license //************************************************** namespace UnityEngine { public struct Matrix3x3 { public static readonly Matrix3x3 identity = new Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); public float[] Data; public Matrix3x3(float m0, float m1, float m2, float m3, float m4, float m5, float m6, float m7, float m8) { Data = new float[9]; Data[0] = m0; Data[3] = m3; Data[6] = m6; Data[1] = m1; Data[4] = m4; Data[7] = m7; Data[2] = m2; Data[5] = m5; Data[8] = m8; } public void SetZero() { Data[0] = 0f; Data[3] = 0f; Data[6] = 0f; Data[1] = 0f; Data[4] = 0f; Data[7] = 0f; Data[2] = 0f; Data[5] = 0f; Data[8] = 0f; //The floats are laid out // m0 m3 m6 // m1 m4 m7 // m2 m5 m8 //Data[0]=m00; Data[3]=m01; Data[6]=m02; //Data[1]=m10; Data[4]=m11; Data[7]=m12; //Data[2]=m20; Data[5]=m21; Data[8]=m22; //Get(0, 0) Get(0, 1) Get(0, 2) //Get(1, 0) Get(1, 1) Get(1, 2) //Get(2, 0) Get(2, 1) Get(2, 2) } public float Get(int row, int column) { return Data[row + (column * 3)]; } public void Set(int row, int column, float value) { Data[row + (column * 3)] = value; } public void SetOrthoNormalBasis(Vector3 inX, Vector3 inY, Vector3 inZ) { this.Set(0, 0, inX.x); this.Set(0, 1, inY.x); this.Set(0, 2, inZ.x); this.Set(1, 0, inX.y); this.Set(1, 1, inY.y); this.Set(1, 2, inZ.y); this.Set(2, 0, inX.z); this.Set(2, 1, inY.z); this.Set(2, 2, inZ.z); } public float GetDeterminant() { float fCofactor0 = Get(0, 0) * Get(1, 1) * Get(2, 2); float fCofactor1 = Get(0, 1) * Get(1, 2) * Get(2, 0); float fCofactor2 = Get(0, 2) * Get(1, 0) * Get(2, 1); float fCofactor3 = Get(0, 2) * Get(1, 1) * Get(2, 0); float fCofactor4 = Get(0, 1) * Get(1, 0) * Get(2, 2); float fCofactor5 = Get(0, 0) * Get(1, 2) * Get(2, 1); return fCofactor0 + fCofactor1 + fCofactor2 - fCofactor3 - fCofactor4 - fCofactor5; } // Right handed public static bool LookRotationToMatrix(Vector3 viewVec, Vector3 upVec, out Matrix3x3 m) { m = Matrix3x3.identity; Vector3 z = viewVec; // compute u0 float mag = z.Length(); if (mag < Mathf.Epsilon) { return false; } z /= mag; Vector3 x = Vector3.Cross(upVec, z); mag = x.Length(); if (mag < Mathf.Epsilon) { return false; } x /= mag; Vector3 y = Vector3.Cross(z, x); if (!Mathf.CompareApproximate(y.Length(), 1.0F)) return false; m.SetOrthoNormalBasis(x, y, z); return true; } } }