holopy3/Assets/PlattarExporter/UnityGLTF/Scripts/Extensions/SchemaExtensions.cs
Lena Biresch 490ef558ef CleanUp
2021-01-28 13:07:52 +01:00

300 lines
8.7 KiB
C#

using GLTF.Schema;
using UnityEngine;
namespace UnityGLTF.Extensions
{
public static class SchemaExtensions
{
public static void GetUnityTRSProperties(this Node node, out Vector3 position, out Quaternion rotation,
out Vector3 scale)
{
Vector3 localPosition, localScale;
Quaternion localRotation;
if (!node.UseTRS)
{
GetTRSProperties(node.Matrix, out localPosition, out localRotation, out localScale);
}
else
{
localPosition = node.Translation.ToUnityVector3();
localRotation = node.Rotation.ToUnityQuaternion();
localScale = node.Scale.ToUnityVector3();
}
position = localPosition.switchHandedness();
rotation = localRotation.switchHandedness();
scale = new Vector3(localScale.x, localScale.y, localScale.z);
}
public static void SetUnityTransform(this Node node, Transform transform, bool useLocal=true)
{
Vector3 position = useLocal ? transform.localPosition : transform.position;
node.Translation = new GLTF.Math.Vector3(position.x, position.y, -position.z);
Quaternion rotation = useLocal ? transform.localRotation : transform.rotation;
node.Rotation = new GLTF.Math.Quaternion(rotation.x, rotation.y, -rotation.z, -rotation.w);
Vector3 scale = useLocal ? transform.localScale : transform.lossyScale;
node.Scale = new GLTF.Math.Vector3(scale.x, scale.y, scale.z);
}
// todo: move to utility class
public static void GetTRSProperties(GLTF.Math.Matrix4x4 mat, out Vector3 position, out Quaternion rotation,
out Vector3 scale)
{
position = mat.GetColumnV3(3);
scale = new Vector3(
mat.GetColumnV3(0).magnitude,
mat.GetColumnV3(1).magnitude,
mat.GetColumnV3(2).magnitude
);
rotation = Quaternion.LookRotation(mat.GetColumnV3(2), mat.GetColumnV3(1));
}
#if false
public static SamplerId GetSamplerId(this GLTFRoot root, UnityEngine.Texture textureObj)
{
for (var i = 0; i < root.Samplers.Count; i++)
{
bool filterIsNearest = root.Samplers[i].MinFilter == MinFilterMode.Nearest
|| root.Samplers[i].MinFilter == MinFilterMode.NearestMipmapNearest
|| root.Samplers[i].MinFilter == MinFilterMode.LinearMipmapNearest;
bool filterIsLinear = root.Samplers[i].MinFilter == MinFilterMode.Linear
|| root.Samplers[i].MinFilter == MinFilterMode.NearestMipmapLinear;
bool filterMatched = textureObj.filterMode == FilterMode.Point && filterIsNearest
|| textureObj.filterMode == FilterMode.Bilinear && filterIsLinear
|| textureObj.filterMode == FilterMode.Trilinear && root.Samplers[i].MinFilter == MinFilterMode.LinearMipmapLinear;
bool wrapMatched =
textureObj.wrapMode == TextureWrapMode.Clamp && root.Samplers[i].WrapS == GLTFSerialization.WrapMode.ClampToEdge
|| textureObj.wrapMode == TextureWrapMode.Repeat && root.Samplers[i].WrapS != GLTFSerialization.WrapMode.ClampToEdge;
if(filterMatched && wrapMatched)
{
return new SamplerId
{
Id = i,
Root = root
};
}
}
return null;
}
//todo blgross unity
public static ImageId GetImageId(this GLTFRoot root, UnityEngine.Texture textureObj)
{
for (var i = 0; i < Images.Count; i++)
{
if (Images[i].Contents == textureObj)
{
return new ImageId
{
Id = i,
Root = this
};
}
}
return null;
}
#endif
public static Vector4 GetColumn(this GLTF.Math.Matrix4x4 mat, uint columnNum)
{
switch (columnNum)
{
case 0:
{
return new Vector4(mat.M11, mat.M12, mat.M13, mat.M14);
}
case 1:
{
return new Vector4(mat.M21, mat.M22, mat.M23, mat.M24);
}
case 2:
{
return new Vector4(mat.M31, mat.M32, mat.M33, mat.M34);
}
case 3:
{
return new Vector4(mat.M41, mat.M42, mat.M43, mat.M44);
}
default:
throw new System.Exception("column num is out of bounds");
}
}
public static Vector3 GetColumnV3(this GLTF.Math.Matrix4x4 mat, uint columnNum)
{
switch (columnNum)
{
case 0:
{
return new Vector3(mat.M11, mat.M21, mat.M31);
}
case 1:
{
return new Vector3(mat.M12, mat.M22, mat.M32);
}
case 2:
{
return new Vector3(mat.M13, mat.M23, mat.M33);
}
case 3:
{
return new Vector3(mat.M14, mat.M24, mat.M34);
}
default:
throw new System.Exception("column num is out of bounds");
}
}
public static Vector2 ToUnityVector2(this GLTF.Math.Vector2 vec3)
{
return new Vector2(vec3.X, vec3.Y);
}
public static Vector2[] ToUnityVector2(this GLTF.Math.Vector2[] inVecArr)
{
Vector2[] outVecArr = new Vector2[inVecArr.Length];
for (int i = 0; i < inVecArr.Length; ++i)
{
outVecArr[i] = inVecArr[i].ToUnityVector2();
}
return outVecArr;
}
public static Vector3 ToUnityVector3(this GLTF.Math.Vector3 vec3)
{
return new Vector3(vec3.X, vec3.Y, vec3.Z);
}
public static Vector3[] ToUnityVector3(this GLTF.Math.Vector3[] inVecArr, bool switchHandedness=false)
{
Vector3[] outVecArr = new Vector3[inVecArr.Length];
for (int i = 0; i < inVecArr.Length; ++i)
{
outVecArr[i] = inVecArr[i].ToUnityVector3();
if (switchHandedness)
outVecArr[i] = outVecArr[i].switchHandedness();
}
return outVecArr;
}
public static GLTF.Math.Vector4 ToGLTFVector4(this Vector4 vec4)
{
return new GLTF.Math.Vector4(vec4.x, vec4.y, vec4.z, vec4.w);
}
public static Vector4 ToUnityVector4(this GLTF.Math.Vector4 vec4)
{
return new Vector4(vec4.X, vec4.Y, vec4.Z, vec4.W);
}
public static Vector4[] ToUnityVector4(this GLTF.Math.Vector4[] inVecArr, bool switchHandedness = false)
{
Vector4[] outVecArr = new Vector4[inVecArr.Length];
for (int i = 0; i < inVecArr.Length; ++i)
{
outVecArr[i] = inVecArr[i].ToUnityVector4();
if (switchHandedness)
outVecArr[i] = outVecArr[i].switchHandedness();
}
return outVecArr;
}
public static UnityEngine.Color ToUnityColor(this GLTF.Math.Color color)
{
return new UnityEngine.Color(color.R, color.G, color.B, color.A);
}
public static GLTF.Math.Color ToNumericsColor(this UnityEngine.Color color)
{
return new GLTF.Math.Color(color.r, color.g, color.b, color.a);
}
public static UnityEngine.Color[] ToUnityColor(this GLTF.Math.Color[] inColorArr)
{
UnityEngine.Color[] outColorArr = new UnityEngine.Color[inColorArr.Length];
for (int i = 0; i < inColorArr.Length; ++i)
{
outColorArr[i] = inColorArr[i].ToUnityColor();
}
return outColorArr;
}
public static Quaternion ToUnityQuaternion(this GLTF.Math.Quaternion quaternion)
{
return new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
}
public static Matrix4x4 ToUnityMatrix(this GLTF.Math.Matrix4x4 matrix)
{
Matrix4x4 mat = new Matrix4x4();
mat.SetColumn(0, matrix.GetColumn(0));
mat.SetColumn(1, matrix.GetColumn(1));
mat.SetColumn(2, matrix.GetColumn(2));
mat.SetColumn(3, matrix.GetColumn(3));
return mat;
}
public static GLTF.Math.Matrix4x4 ToGLTFMAtrix(this Matrix4x4 matrix)
{
return new GLTF.Math.Matrix4x4(
matrix.GetColumn(0).ToGLTFVector4(),
matrix.GetColumn(1).ToGLTFVector4(),
matrix.GetColumn(2).ToGLTFVector4(),
matrix.GetColumn(3).ToGLTFVector4()
);
}
public static Vector3 switchHandedness(this Vector3 input)
{
return new Vector3(input.x, input.y, -input.z);
}
public static Vector4 switchHandedness(this Vector4 input)
{
return new Vector4(input.x, input.y, -input.z, -input.w);
}
public static Quaternion switchHandedness(this Quaternion input)
{
return new Quaternion(input.x, input.y, -input.z, -input.w);
}
public static Matrix4x4 switchHandedness(this Matrix4x4 matrix)
{
Vector3 position = matrix.GetColumn(3).switchHandedness();
Quaternion rotation = Quaternion.LookRotation(matrix.GetColumn(2), matrix.GetColumn(1)).switchHandedness();
Vector3 scale = new Vector3(matrix.GetColumn(0).magnitude, matrix.GetColumn(1).magnitude, matrix.GetColumn(2).magnitude);
float epsilon = 0.00001f;
// Some issues can occurs with non uniform scales
if (Mathf.Abs(scale.x - scale.y) > epsilon || Mathf.Abs(scale.y - scale.z) > epsilon || Mathf.Abs(scale.x - scale.z) > epsilon)
{
Debug.LogWarning("A matrix with non uniform scale is being converted from left to right handed system. This code is not working correctly in this case");
}
// Handle negative scale component in matrix decomposition
if (Matrix4x4.Determinant(matrix) < 0)
{
Quaternion rot = Quaternion.LookRotation(matrix.GetColumn(2), matrix.GetColumn(1));
Matrix4x4 corr = Matrix4x4.TRS(matrix.GetColumn(3), rot, Vector3.one).inverse;
Matrix4x4 extractedScale = corr * matrix;
scale = new Vector3(extractedScale.m00, extractedScale.m11, extractedScale.m22);
}
// convert transform values from left handed to right handed
return Matrix4x4.TRS(position, rotation, scale);
}
}
}