using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Nxr.Internal
{
public static class ARUtilityFunctions
{
///
/// Returns the named camera or null if not found.
///
/// Camera name to search for.
/// The named or null if not found.
public static Camera FindCameraByName(string name)
{
foreach (Camera c in Camera.allCameras)
{
if (c.gameObject.name == name) return c;
}
return null;
}
///
/// Creates a Unity matrix from an array of floats.
///
/// Array of 16 floats to populate the matrix.
/// A new with the given values.
public static Matrix4x4 MatrixFromFloatArray(float[] values)
{
if (values == null || values.Length < 16) throw new ArgumentException("Expected 16 elements in values array", "values");
Matrix4x4 mat = new Matrix4x4();
for (int i = 0; i < 16; i++) mat[i] = values[i];
return mat;
}
#if false
// Posted on: http://answers.unity3d.com/questions/11363/converting-matrix4x4-to-quaternion-vector3.html
public static Quaternion QuaternionFromMatrix(Matrix4x4 m)
{
// Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
Quaternion q = new Quaternion();
q.w = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] + m[1, 1] + m[2, 2])) / 2;
q.x = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] - m[1, 1] - m[2, 2])) / 2;
q.y = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] + m[1, 1] - m[2, 2])) / 2;
q.z = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] - m[1, 1] + m[2, 2])) / 2;
q.x *= Mathf.Sign(q.x * (m[2, 1] - m[1, 2]));
q.y *= Mathf.Sign(q.y * (m[0, 2] - m[2, 0]));
q.z *= Mathf.Sign(q.z * (m[1, 0] - m[0, 1]));
return q;
}
#else
public static Quaternion QuaternionFromMatrix(Matrix4x4 m)
{
if(float.IsNaN(m[0]) || float.IsNaN(m[5]))
{
Debug.LogError("QuaternionFromMatrix is NaN !!!");
return Quaternion.identity;
}
// Trap the case where the matrix passed in has an invalid rotation submatrix.
if (m.GetColumn(2) == Vector4.zero)
{
return Quaternion.identity;
}
return Quaternion.LookRotation(m.GetColumn(2), m.GetColumn(1));
}
#endif
public static Vector3 PositionFromMatrix(Matrix4x4 m)
{
Vector3 posVec = m.GetColumn(3);
if(float.IsNaN(posVec.x) || float.IsNaN(posVec.y) || float.IsNaN(posVec.z))
{
Debug.LogError("PositionFromMatrix is NaN !!!");
return Vector3.zero;
}
return posVec;
}
// Convert from right-hand coordinate system with in direction of +x,
// in direction of +y, and in direction of +z,
// to Unity's left-hand coordinate system with in direction of +x,
// in direction of +y, and in direction of +z.
// This is equivalent to negating row 2, and then negating column 2.
public static Matrix4x4 LHMatrixFromRHMatrix(Matrix4x4 rhm)
{
Matrix4x4 lhm = new Matrix4x4(); ;
// Column 0.
lhm[0, 0] = rhm[0, 0];
lhm[1, 0] = rhm[1, 0];
lhm[2, 0] = -rhm[2, 0];
lhm[3, 0] = rhm[3, 0];
// Column 1.
lhm[0, 1] = rhm[0, 1];
lhm[1, 1] = rhm[1, 1];
lhm[2, 1] = -rhm[2, 1];
lhm[3, 1] = rhm[3, 1];
// Column 2.
lhm[0, 2] = -rhm[0, 2];
lhm[1, 2] = -rhm[1, 2];
lhm[2, 2] = rhm[2, 2];
lhm[3, 2] = -rhm[3, 2];
// Column 3.
lhm[0, 3] = rhm[0, 3];
lhm[1, 3] = rhm[1, 3];
lhm[2, 3] = -rhm[2, 3];
lhm[3, 3] = rhm[3, 3];
return lhm;
}
//test
//float[] cameraMatrix = new float[] { 678.29388f, 637.77411f, 318.29779f, 237.90047f };
//projectionMatrix = ARUtilityFunctions.GetGLProjectionMatrix(0.01f, 1000f, cameraMatrix, 1920, 1080);
//test
// 相机内部矩阵转换成GL投影矩阵
public static Matrix4x4 GetGLProjectionMatrix(float near, float far, float[] cameraMatrix, int cameraPreviewWidth, int cameraPreviewHeight)
//-----------------------------------------------------------------------------
{
// float near = 0.01; // Near clipping distance
// float far = 1000; // Far clipping distance
float f_x = cameraMatrix[0]; // Focal length in x axis
float f_y = cameraMatrix[1]; // Focal length in y axis (usually the same?)
float c_x = cameraMatrix[2]; // Camera primary point x
float c_y = cameraMatrix[3]; // Camera primary point y
float[] glMatrix = new float[16];
glMatrix[0] = 2.0f * f_x / cameraPreviewWidth;
glMatrix[1] = 0.0f;
glMatrix[2] = 0.0f;
glMatrix[3] = 0.0f;
glMatrix[4] = 0.0f;
glMatrix[5] = 2.0f * f_y / cameraPreviewHeight;
glMatrix[6] = 0.0f;
glMatrix[7] = 0.0f;
glMatrix[8] = 1.0f - 2.0f * c_x / cameraPreviewWidth;
glMatrix[9] = -1.0f + 2.0f * c_y / cameraPreviewHeight;
glMatrix[10] = -(far + near) / (far - near);
glMatrix[11] = -1.0f;
glMatrix[12] = 0.0f;
glMatrix[13] = 0.0f;
glMatrix[14] = -2.0f * far * near / (far - near);
glMatrix[15] = 0.0f;
return MatrixFromFloatArray(glMatrix);
}
}
}