Merge pull request #2571 from rolfbjarne/xcode9-matrix

Add Simd matrix types and use them to bind native Simd matrices. Fixes #58599
This commit is contained in:
Rolf Bjarne Kvinge 2017-09-05 15:33:02 +02:00 коммит произвёл GitHub
Родитель c453776ac0 977a976959
Коммит 15808c4693
40 изменённых файлов: 3907 добавлений и 39 удалений

Просмотреть файл

@ -1991,6 +1991,26 @@ namespace Xamarin.BindingMethods.Generator
}
);
data.Add (
new FunctionData {
Comment = " // void func (MatrixFloat2x2)",
Prefix = "simd__",
Variants = Variants.NonStret,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.MatrixFloat2x2 },
},
}
);
data.Add (
new FunctionData {
Comment = " // MatrixFloat2x2 func ()",
Prefix = "simd__",
Variants = Variants.All,
ReturnType = Types.MatrixFloat2x2,
}
);
data.Add (
new FunctionData {
Comment = " // IntPtr func (IntPtr, ref MPSImageHistogramInfo)",
@ -2004,6 +2024,42 @@ namespace Xamarin.BindingMethods.Generator
}
);
data.Add (
new FunctionData {
Comment = " // IntPtr func (IntPtr, MatrixFloat2x2)",
Prefix = "simd__",
Variants = Variants.NonStret,
ReturnType = Types.IntPtr,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.IntPtr },
new ParameterData { TypeData = Types.MatrixFloat2x2 },
},
}
);
data.Add (
new FunctionData {
Comment = " // void func (MatrixFloat3x3)",
Prefix = "simd__",
Variants = Variants.NonStret,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.MatrixFloat3x3 },
},
}
);
data.Add (
new FunctionData {
Comment = " // IntPtr func (MatrixFloat3x3)",
Prefix = "simd__",
Variants = Variants.NonStret,
ReturnType = Types.IntPtr,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.MatrixFloat3x3 },
},
}
);
data.Add (
new FunctionData {
Comment = " // MDLVoxelIndexExtent2 func ()",
@ -2013,6 +2069,15 @@ namespace Xamarin.BindingMethods.Generator
}
);
data.Add (
new FunctionData {
Comment = " // MatrixFloat3x3 func ()",
Prefix = "simd__",
Variants = Variants.All,
ReturnType = Types.MatrixFloat3x3,
}
);
data.Add (
new FunctionData {
Comment = " // void func (MDLVoxelIndexExtent2)",
@ -2020,6 +2085,67 @@ namespace Xamarin.BindingMethods.Generator
Variants = Variants.NonStret,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.MDLVoxelIndexExtent2 },
}
}
);
data.Add (
new FunctionData {
Comment = " // IntPtr func (IntPtr, MatrixFloat3x3)",
Prefix = "simd__",
Variants = Variants.NonStret,
ReturnType = Types.IntPtr,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.IntPtr },
new ParameterData { TypeData = Types.MatrixFloat3x3 },
},
}
);
data.Add (
new FunctionData {
Comment = " // void func (MatrixFloat4x4)",
Prefix = "simd__",
Variants = Variants.NonStret,
Parameters = new ParameterData[] {
new ParameterData { TypeData = Types.MatrixFloat4x4 },
},
}
);
data.Add (
new FunctionData {
Comment = " // IntPtr func (MatrixFloat4x4)",
Prefix = "simd__",
Variants = Variants.NonStret,
ReturnType = Types.IntPtr,
Parameters = new ParameterData[] {
new ParameterData { TypeData = Types.MatrixFloat4x4 },
},
}
);
data.Add (
new FunctionData {
Comment = " // void func (MatrixFloat4x4, double)",
Prefix = "simd__",
Variants = Variants.NonStret,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.MatrixFloat4x4 },
new ParameterData { TypeData = Types.Double },
},
}
);
data.Add (
new FunctionData {
Comment = " // IntPtr func (MatrixFloat4x4, bool)",
Prefix = "simd__",
Variants = Variants.NonStret,
ReturnType = Types.IntPtr,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.MatrixFloat4x4 },
new ParameterData { TypeData = Types.Bool },
},
}
);
@ -2036,6 +2162,111 @@ namespace Xamarin.BindingMethods.Generator
}
);
data.Add (
new FunctionData {
Comment = " // IntPtr func (IntPtr, nuint, MatrixFloat4x4)",
Prefix = "simd__",
Variants = Variants.NonStret,
ReturnType = Types.IntPtr,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.IntPtr },
new ParameterData { TypeData = Types.NUInt },
new ParameterData { TypeData = Types.MatrixFloat4x4 },
},
}
);
data.Add (
new FunctionData {
Comment = " // MatrixFloat4x4 func ()",
Prefix = "simd__",
Variants = Variants.All,
ReturnType = Types.MatrixFloat4x4,
}
);
data.Add (
new FunctionData {
Comment = " // MatrixFloat4x4 func (int, CGSize, nfloat, nfloat)",
Prefix = "simd__",
Variants = Variants.All,
ReturnType = Types.MatrixFloat4x4,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.Int32 },
new ParameterData { TypeData = Types.CGSize },
new ParameterData { TypeData = Types.NFloat },
new ParameterData { TypeData = Types.NFloat },
},
}
);
data.Add (
new FunctionData {
Comment = " // MatrixFloat4x4 func (Int64, CGSize, nfloat, nfloat)",
Prefix = "simd__",
Variants = Variants.All,
ReturnType = Types.MatrixFloat4x4,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.Int64 },
new ParameterData { TypeData = Types.CGSize },
new ParameterData { TypeData = Types.NFloat },
new ParameterData { TypeData = Types.NFloat },
},
}
);
data.Add (
new FunctionData {
Comment = " // MatrixFloat4x4 func (double)",
Prefix = "simd__",
Variants = Variants.All,
ReturnType = Types.MatrixFloat4x4,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.Double },
},
}
);
data.Add (
new FunctionData {
Comment = " // MatrixFloat4x4 func (nint)",
Prefix = "simd__",
Variants = Variants.All,
ReturnType = Types.MatrixFloat4x4,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.NInt },
},
}
);
data.Add (
new FunctionData {
Comment = " // IntPtr func (IntPtr, nint, MatrixFloat4x4)",
Prefix = "simd__",
Variants = Variants.NonStret,
ReturnType = Types.IntPtr,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.IntPtr },
new ParameterData { TypeData = Types.NInt },
new ParameterData { TypeData = Types.MatrixFloat4x4 },
},
}
);
data.Add (
new FunctionData {
Comment = " // IntPtr func (IntPtr, MatrixFloat4x4)",
Prefix = "simd__",
Variants = Variants.NonStret,
ReturnType = Types.IntPtr,
Parameters = new ParameterData [] {
new ParameterData { TypeData = Types.IntPtr },
new ParameterData { TypeData = Types.MatrixFloat4x4 },
},
}
);
// We must expand functions with native types to their actual type as well.
for (int i = data.Count - 1; i >= 0; i--) {
if (!data [i].HasNativeType)
@ -2087,12 +2318,14 @@ namespace Xamarin.BindingMethods.Generator
}
break;
case "Matrix2":
case "MatrixFloat2x2":
writer.WriteLine ("\tfor (int i = 0; i < 2; i++) {");
writer.WriteLine ("\t\t{0}{2}columns [i].a = {1}.columns [i] [0];", managedVariable, nativeVariable, accessor);
writer.WriteLine ("\t\t{0}{2}columns [i].b = {1}.columns [i] [1];", managedVariable, nativeVariable, accessor);
writer.WriteLine ("\t}");
break;
case "Matrix3":
case "MatrixFloat3x3":
writer.WriteLine ("\tfor (int i = 0; i < 3; i++) {");
writer.WriteLine ("\t\t{0}{2}columns [i].a = {1}.columns [i] [0];", managedVariable, nativeVariable, accessor);
writer.WriteLine ("\t\t{0}{2}columns [i].b = {1}.columns [i] [1];", managedVariable, nativeVariable, accessor);
@ -2100,6 +2333,7 @@ namespace Xamarin.BindingMethods.Generator
writer.WriteLine ("\t}");
break;
case "Matrix4":
case "MatrixFloat4x4":
writer.WriteLine ("\tfor (int i = 0; i < 4; i++) {");
writer.WriteLine ("\t\t{0}{2}columns [i].a = {1}.columns [i] [0];", managedVariable, nativeVariable, accessor);
writer.WriteLine ("\t\t{0}{2}columns [i].b = {1}.columns [i] [1];", managedVariable, nativeVariable, accessor);
@ -2203,12 +2437,14 @@ namespace Xamarin.BindingMethods.Generator
}
break;
case "Matrix2":
case "MatrixFloat2x2":
writer.WriteLine ("\tfor (int i = 0; i < 2; i++) {");
writer.WriteLine ("\t\t{0}.columns [i][0] = {1}{2}columns [i].a;", nativeVariable, managedVariable, accessor);
writer.WriteLine ("\t\t{0}.columns [i][1] = {1}{2}columns [i].b;", nativeVariable, managedVariable, accessor);
writer.WriteLine ("\t}");
break;
case "Matrix3":
case "MatrixFloat3x3":
writer.WriteLine ("\tfor (int i = 0; i < 3; i++) {");
writer.WriteLine ("\t\t{0}.columns [i][0] = {1}{2}columns [i].a;", nativeVariable, managedVariable, accessor);
writer.WriteLine ("\t\t{0}.columns [i][1] = {1}{2}columns [i].b;", nativeVariable, managedVariable, accessor);
@ -2216,6 +2452,7 @@ namespace Xamarin.BindingMethods.Generator
writer.WriteLine ("\t}");
break;
case "Matrix4":
case "MatrixFloat4x4":
writer.WriteLine ("\tfor (int i = 0; i < 4; i++) {");
writer.WriteLine ("\t\t{0}.columns [i][0] = {1}{2}columns [i].a;", nativeVariable, managedVariable, accessor);
writer.WriteLine ("\t\t{0}.columns [i][1] = {1}{2}columns [i].b;", nativeVariable, managedVariable, accessor);
@ -2736,6 +2973,15 @@ namespace Xamarin.BindingMethods.Generator
IsX86Stret = true,
IsX64Stret = false,
};
public static TypeData MatrixFloat2x2 = new TypeData {
ManagedType = "MatrixFloat2x2",
NativeType = "matrix_float2x2",
NativeWrapperType = "struct MatrixFloat2x2",
RequireMarshal = true,
IsARMStret = true,
IsX86Stret = true,
IsX64Stret = false,
};
public static TypeData Matrix3f = new TypeData {
ManagedType = "Matrix3",
NativeType = "matrix_float3x3",
@ -2745,6 +2991,15 @@ namespace Xamarin.BindingMethods.Generator
IsX86Stret = true,
IsX64Stret = true,
};
public static TypeData MatrixFloat3x3 = new TypeData {
ManagedType = "MatrixFloat3x3",
NativeType = "matrix_float3x3",
NativeWrapperType = "struct MatrixFloat3x3",
RequireMarshal = true,
IsARMStret = true,
IsX86Stret = true,
IsX64Stret = true,
};
public static TypeData Matrix4f = new TypeData {
ManagedType = "Matrix4",
NativeType = "matrix_float4x4",
@ -2754,6 +3009,15 @@ namespace Xamarin.BindingMethods.Generator
IsX86Stret = true,
IsX64Stret = true,
};
public static TypeData MatrixFloat4x4 = new TypeData {
ManagedType = "MatrixFloat4x4",
NativeType = "matrix_float4x4",
NativeWrapperType = "struct MatrixFloat4x4",
RequireMarshal = true,
IsARMStret = true,
IsX86Stret = true,
IsX64Stret = true,
};
public static TypeData Double = new TypeData {
ManagedType = "Double",
NativeType = "double",

Просмотреть файл

@ -158,14 +158,26 @@ struct Matrix2f {
Vector2f columns [2];
};
struct MatrixFloat2x2 {
Vector2f columns [2];
};
struct Matrix3f {
Vector3f columns [3];
};
struct MatrixFloat3x3 {
Vector4f columns [3];
};
struct Matrix4f {
Vector4f columns [4];
};
struct MatrixFloat4x4 {
Vector4f columns [4];
};
struct QuatF {
Vector4f vector;
};

Просмотреть файл

@ -0,0 +1,16 @@
#if XAMCORE_2_0 || !MONOMAC
using System;
using Simd;
namespace XamCore.ModelIO {
public partial class MDLTransform {
#if !XAMCORE_4_0
// Inlined from the MDLTransformComponent protocol.
public static MatrixFloat4x4 CreateGlobalTransform4x4 (MDLObject obj, double atTime)
{
return MatrixFloat4x4.Transpose ((MatrixFloat4x4) CreateGlobalTransform (obj, atTime));
}
#endif
}
}
#endif

Просмотреть файл

@ -0,0 +1,33 @@
#if XAMCORE_2_0 && !XAMCORE_4_0
using OpenTK;
using Simd;
namespace XamCore.ModelIO {
public partial class MDLTransformComponent_Extensions {
public static MatrixFloat4x4 GetMatrix4x4 (this IMDLTransformComponent self)
{
return MatrixFloat4x4.Transpose ((MatrixFloat4x4) self.Matrix);
}
public static void SetMatrix4x4 (this IMDLTransformComponent self, MatrixFloat4x4 value)
{
self.Matrix = (Matrix4) MatrixFloat4x4.Transpose (value);
}
public static MatrixFloat4x4 GetLocalTransform4x4(this IMDLTransformComponent This, double time)
{
return MatrixFloat4x4.Transpose ((MatrixFloat4x4) GetLocalTransform (This, time));
}
public static void SetLocalTransform4x4 (this IMDLTransformComponent This, MatrixFloat4x4 transform, double time)
{
SetLocalTransform (This, (Matrix4) MatrixFloat4x4.Transpose (transform), time);
}
public static void SetLocalTransform4x4 (this IMDLTransformComponent This, MatrixFloat4x4 transform)
{
SetLocalTransform (This, (Matrix4) MatrixFloat4x4.Transpose (transform));
}
}
}
#endif

146
src/Simd/MatrixFloat2x2.cs Normal file
Просмотреть файл

@ -0,0 +1,146 @@
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright (c) 2017 Microsoft Inc
//
//
// This represents the native matrix_float2x2 type, which has a column-major layout
// (as opposed to OpenTK.Matrix2, which has a row-major layout).
//
using System;
using System.Runtime.InteropServices;
using VectorFloat2=global::OpenTK.Vector2;
namespace Simd
{
[StructLayout (LayoutKind.Sequential)]
public struct MatrixFloat2x2 : IEquatable<MatrixFloat2x2>
{
public float M11;
public float M21;
public float M12;
public float M22;
public readonly static MatrixFloat2x2 Identity = new MatrixFloat2x2 (
1, 0,
0, 1);
public MatrixFloat2x2 (VectorFloat2 column0, VectorFloat2 column1)
{
M11 = column0.X;
M21 = column0.Y;
M12 = column1.X;
M22 = column1.Y;
}
public MatrixFloat2x2 (
float m11, float m12,
float m21, float m22)
{
M11 = m11;
M21 = m21;
M12 = m12;
M22 = m22;
}
public float Determinant {
get {
return M11 * M22 - M21 * M12;
}
}
public void Transpose ()
{
this = Transpose (this);
}
public static MatrixFloat2x2 Transpose (MatrixFloat2x2 mat)
{
return new MatrixFloat2x2 (mat.M11, mat.M21, mat.M12, mat.M22);
}
public static void Transpose (ref MatrixFloat2x2 mat, out MatrixFloat2x2 result)
{
result.M11 = mat.M11;
result.M12 = mat.M21;
result.M21 = mat.M12;
result.M22 = mat.M22;
}
public static MatrixFloat2x2 Multiply (MatrixFloat2x2 left, MatrixFloat2x2 right)
{
MatrixFloat2x2 result;
Multiply (ref left, ref right, out result);
return result;
}
public static void Multiply (ref MatrixFloat2x2 left, ref MatrixFloat2x2 right, out MatrixFloat2x2 result)
{
result.M11 = left.M11 * right.M11 + left.M12 * right.M21;
result.M12 = left.M11 * right.M12 + left.M12 * right.M22;
result.M21 = left.M21 * right.M11 + left.M22 * right.M21;
result.M22 = left.M21 * right.M12 + left.M22 * right.M22;
}
public static MatrixFloat2x2 operator * (MatrixFloat2x2 left, MatrixFloat2x2 right)
{
return Multiply (left, right);
}
public static bool operator == (MatrixFloat2x2 left, MatrixFloat2x2 right)
{
return left.Equals (right);
}
public static bool operator != (MatrixFloat2x2 left, MatrixFloat2x2 right)
{
return !left.Equals (right);
}
public static explicit operator global::OpenTK.Matrix2 (MatrixFloat2x2 value)
{
return new global::OpenTK.Matrix2 (
value.M11, value.M12,
value.M21, value.M22);
}
public static explicit operator MatrixFloat2x2 (global::OpenTK.Matrix2 value)
{
return new MatrixFloat2x2 (
value.R0C0, value.R0C1,
value.R1C0, value.R1C1);
}
public override string ToString ()
{
return $"({M11}, {M12})\n({M21}, {M22})";
}
public override int GetHashCode ()
{
return M11.GetHashCode () ^ M12.GetHashCode () ^ M21.GetHashCode () ^ M22.GetHashCode ();
}
public override bool Equals (object obj)
{
if (!(obj is MatrixFloat2x2))
return false;
return Equals ((MatrixFloat2x2) obj);
}
public bool Equals (MatrixFloat2x2 other)
{
return
M11 == other.M11 &&
M12 == other.M12 &&
M21 == other.M21 &&
M22 == other.M22;
}
}
}

207
src/Simd/MatrixFloat3x3.cs Normal file
Просмотреть файл

@ -0,0 +1,207 @@
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright (c) 2017 Microsoft Inc
//
//
// This represents the native matrix_float3x3 type, which has a column-major layout
// (as opposed to OpenTK.Matrix3, which has a row-major layout).
//
using System;
using System.Runtime.InteropServices;
using VectorFloat3=global::OpenTK.Vector3;
namespace Simd
{
[StructLayout (LayoutKind.Sequential)]
public struct MatrixFloat3x3 : IEquatable<MatrixFloat3x3>
{
/* Due to memory alignment, vectors of length 3 are
* represented as vectors of length 4, so we pad here
* with dummy fields.
* See top of /usr/include/simd/matrix_types.h for more information. */
public float M11;
public float M21;
public float M31;
float dummy0;
public float M12;
public float M22;
public float M32;
float dummy1;
public float M13;
public float M23;
public float M33;
float dummy2;
public readonly static MatrixFloat3x3 Identity = new MatrixFloat3x3
{
M11 = 1f,
M22 = 1f,
M33 = 1f,
};
public MatrixFloat3x3 (VectorFloat3 column0, VectorFloat3 column1, VectorFloat3 column2)
{
M11 = column0.X;
M21 = column0.Y;
M31 = column0.Z;
M12 = column1.X;
M22 = column1.Y;
M32 = column1.Z;
M13 = column2.X;
M23 = column2.Y;
M33 = column2.Z;
dummy0 = 0;
dummy1 = 0;
dummy2 = 0;
}
public MatrixFloat3x3 (
float m11, float m12, float m13,
float m21, float m22, float m23,
float m31, float m32, float m33)
{
M11 = m11;
M21 = m21;
M31 = m31;
M12 = m12;
M22 = m22;
M32 = m32;
M13 = m13;
M23 = m23;
M33 = m33;
dummy0 = 0;
dummy1 = 0;
dummy2 = 0;
}
public float Determinant {
get {
return
M11 * (M22 * M33 - M23 * M32) -
M12 * (M21 * M33 - M23 * M31) +
M13 * (M21 * M32 - M22 * M31);
}
}
public void Transpose ()
{
this = Transpose (this);
}
public static MatrixFloat3x3 Transpose (MatrixFloat3x3 mat)
{
MatrixFloat3x3 result = new MatrixFloat3x3 ();
Transpose (ref mat, out result);
return result;
}
public static void Transpose (ref MatrixFloat3x3 mat, out MatrixFloat3x3 result)
{
result.M11 = mat.M11;
result.M21 = mat.M12;
result.M31 = mat.M13;
result.M12 = mat.M21;
result.M22 = mat.M22;
result.M32 = mat.M23;
result.M13 = mat.M31;
result.M23 = mat.M32;
result.M33 = mat.M33;
result.dummy0 = 0;
result.dummy1 = 0;
result.dummy2 = 0;
}
public static MatrixFloat3x3 Multiply (MatrixFloat3x3 left, MatrixFloat3x3 right)
{
MatrixFloat3x3 result;
Multiply (ref left, ref right, out result);
return result;
}
public static void Multiply (ref MatrixFloat3x3 left, ref MatrixFloat3x3 right, out MatrixFloat3x3 result)
{
result.M11 = left.M11 * right.M11 + left.M12 * right.M21 + left.M13 * right.M31;
result.M12 = left.M11 * right.M12 + left.M12 * right.M22 + left.M13 * right.M32;
result.M13 = left.M11 * right.M13 + left.M12 * right.M23 + left.M13 * right.M33;
result.dummy0 = 0;
result.M21 = left.M21 * right.M11 + left.M22 * right.M21 + left.M23 * right.M31;
result.M22 = left.M21 * right.M12 + left.M22 * right.M22 + left.M23 * right.M32;
result.M23 = left.M21 * right.M13 + left.M22 * right.M23 + left.M23 * right.M33;
result.dummy1 = 0;
result.M31 = left.M31 * right.M11 + left.M32 * right.M21 + left.M33 * right.M31;
result.M32 = left.M31 * right.M12 + left.M32 * right.M22 + left.M33 * right.M32;
result.M33 = left.M31 * right.M13 + left.M32 * right.M23 + left.M33 * right.M33;
result.dummy2 = 0;
}
public static MatrixFloat3x3 operator * (MatrixFloat3x3 left, MatrixFloat3x3 right)
{
return Multiply (left, right);
}
public static bool operator == (MatrixFloat3x3 left, MatrixFloat3x3 right)
{
return left.Equals (right);
}
public static bool operator != (MatrixFloat3x3 left, MatrixFloat3x3 right)
{
return !left.Equals (right);
}
public static explicit operator global::OpenTK.Matrix3 (MatrixFloat3x3 value)
{
return new global::OpenTK.Matrix3 (
value.M11, value.M12, value.M13,
value.M21, value.M22, value.M23,
value.M31, value.M32, value.M33);
}
public static explicit operator MatrixFloat3x3 (global::OpenTK.Matrix3 value)
{
return new MatrixFloat3x3 (
value.R0C0, value.R0C1, value.R0C2,
value.R1C0, value.R1C1, value.R1C2,
value.R2C0, value.R2C1, value.R2C2);
}
public override string ToString ()
{
return
$"({M11}, {M12}, {M13})\n" +
$"({M21}, {M22}, {M23})\n" +
$"({M31}, {M32}, {M33})";
}
public override int GetHashCode ()
{
return
M11.GetHashCode () ^ M12.GetHashCode () ^ M13.GetHashCode () ^
M21.GetHashCode () ^ M22.GetHashCode () ^ M23.GetHashCode () ^
M31.GetHashCode () ^ M32.GetHashCode () ^ M33.GetHashCode ();
}
public override bool Equals (object obj)
{
if (!(obj is MatrixFloat3x3))
return false;
return Equals ((MatrixFloat3x3) obj);
}
public bool Equals (MatrixFloat3x3 other)
{
return
M11 == other.M11 && M12 == other.M12 && M13 == other.M13 &&
M21 == other.M21 && M22 == other.M22 && M23 == other.M23 &&
M31 == other.M31 && M32 == other.M32 && M33 == other.M33;
}
}
}

240
src/Simd/MatrixFloat4x4.cs Normal file
Просмотреть файл

@ -0,0 +1,240 @@
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright (c) 2017 Microsoft Inc
//
//
// This represents the native matrix_float4x4 type, which has a column-major layout
// (as opposed to OpenTK.Matrix4, which has a row-major layout).
//
using System;
using System.Runtime.InteropServices;
using VectorFloat4=global::OpenTK.Vector4;
namespace Simd
{
[StructLayout (LayoutKind.Sequential)]
public struct MatrixFloat4x4 : IEquatable<MatrixFloat4x4>
{
public float M11;
public float M21;
public float M31;
public float M41;
public float M12;
public float M22;
public float M32;
public float M42;
public float M13;
public float M23;
public float M33;
public float M43;
public float M14;
public float M24;
public float M34;
public float M44;
public readonly static MatrixFloat4x4 Identity = new MatrixFloat4x4 {
M11 = 1f,
M22 = 1f,
M33 = 1f,
M44 = 1f,
};
public MatrixFloat4x4 (VectorFloat4 column0, VectorFloat4 column1, VectorFloat4 column2, VectorFloat4 column3)
{
M11 = column0.X;
M21 = column0.Y;
M31 = column0.Z;
M41 = column0.W;
M12 = column1.X;
M22 = column1.Y;
M32 = column1.Z;
M42 = column1.W;
M13 = column2.X;
M23 = column2.Y;
M33 = column2.Z;
M43 = column2.W;
M14 = column3.X;
M24 = column3.Y;
M34 = column3.Z;
M44 = column3.W;
}
public MatrixFloat4x4 (
float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44)
{
M11 = m11;
M21 = m21;
M31 = m31;
M41 = m41;
M12 = m12;
M22 = m22;
M32 = m32;
M42 = m42;
M13 = m13;
M23 = m23;
M33 = m33;
M43 = m43;
M14 = m14;
M24 = m24;
M34 = m34;
M44 = m44;
}
public float Determinant {
get {
float a = M33 * M44 - M34 * M43;
float b = M32 * M44 - M34 * M42;
float c = M32 * M43 - M33 * M42;
float d = M31 * M44 - M34 * M41;
float e = M31 * M43 - M33 * M41;
float f = M31 * M42 - M32 * M41;
return
M11 * (M22 * a - M23 * b + M24 * c) -
M12 * (M21 * a - M23 * d + M24 * e) +
M13 * (M21 * b - M22 * d + M24 * f) -
M14 * (M21 * c - M22 * e + M23 * f);
}
}
public void Transpose ()
{
this = Transpose (this);
}
public static MatrixFloat4x4 Transpose (MatrixFloat4x4 mat)
{
MatrixFloat4x4 result;
Transpose (ref mat, out result);
return result;
}
public static void Transpose (ref MatrixFloat4x4 mat, out MatrixFloat4x4 result)
{
result.M11 = mat.M11;
result.M21 = mat.M12;
result.M31 = mat.M13;
result.M41 = mat.M14;
result.M12 = mat.M21;
result.M22 = mat.M22;
result.M32 = mat.M23;
result.M42 = mat.M24;
result.M13 = mat.M31;
result.M23 = mat.M32;
result.M33 = mat.M33;
result.M43 = mat.M34;
result.M14 = mat.M41;
result.M24 = mat.M42;
result.M34 = mat.M43;
result.M44 = mat.M44;
}
public static MatrixFloat4x4 Multiply (MatrixFloat4x4 left, MatrixFloat4x4 right)
{
MatrixFloat4x4 result;
Multiply (ref left, ref right, out result);
return result;
}
public static void Multiply (ref MatrixFloat4x4 left, ref MatrixFloat4x4 right, out MatrixFloat4x4 result)
{
result.M11 = left.M11 * right.M11 + left.M12 * right.M21 + left.M13 * right.M31 + left.M14 * right.M41;
result.M12 = left.M11 * right.M12 + left.M12 * right.M22 + left.M13 * right.M32 + left.M14 * right.M42;
result.M13 = left.M11 * right.M13 + left.M12 * right.M23 + left.M13 * right.M33 + left.M14 * right.M43;
result.M14 = left.M11 * right.M14 + left.M12 * right.M24 + left.M13 * right.M34 + left.M14 * right.M44;
result.M21 = left.M21 * right.M11 + left.M22 * right.M21 + left.M23 * right.M31 + left.M24 * right.M41;
result.M22 = left.M21 * right.M12 + left.M22 * right.M22 + left.M23 * right.M32 + left.M24 * right.M42;
result.M23 = left.M21 * right.M13 + left.M22 * right.M23 + left.M23 * right.M33 + left.M24 * right.M43;
result.M24 = left.M21 * right.M14 + left.M22 * right.M24 + left.M23 * right.M34 + left.M24 * right.M44;
result.M31 = left.M31 * right.M11 + left.M32 * right.M21 + left.M33 * right.M31 + left.M34 * right.M41;
result.M32 = left.M31 * right.M12 + left.M32 * right.M22 + left.M33 * right.M32 + left.M34 * right.M42;
result.M33 = left.M31 * right.M13 + left.M32 * right.M23 + left.M33 * right.M33 + left.M34 * right.M43;
result.M34 = left.M31 * right.M14 + left.M32 * right.M24 + left.M33 * right.M34 + left.M34 * right.M44;
result.M41 = left.M41 * right.M11 + left.M42 * right.M21 + left.M43 * right.M31 + left.M44 * right.M41;
result.M42 = left.M41 * right.M12 + left.M42 * right.M22 + left.M43 * right.M32 + left.M44 * right.M42;
result.M43 = left.M41 * right.M13 + left.M42 * right.M23 + left.M43 * right.M33 + left.M44 * right.M43;
result.M44 = left.M41 * right.M14 + left.M42 * right.M24 + left.M43 * right.M34 + left.M44 * right.M44;
}
public static MatrixFloat4x4 operator * (MatrixFloat4x4 left, MatrixFloat4x4 right)
{
return Multiply (left, right);
}
public static bool operator == (MatrixFloat4x4 left, MatrixFloat4x4 right)
{
return left.Equals (right);
}
public static bool operator != (MatrixFloat4x4 left, MatrixFloat4x4 right)
{
return !left.Equals (right);
}
public static explicit operator global::OpenTK.Matrix4 (MatrixFloat4x4 value)
{
return new global::OpenTK.Matrix4 (
value.M11, value.M12, value.M13, value.M14,
value.M21, value.M22, value.M23, value.M24,
value.M31, value.M32, value.M33, value.M34,
value.M41, value.M42, value.M43, value.M44);
}
public static explicit operator MatrixFloat4x4 (global::OpenTK.Matrix4 value)
{
return new MatrixFloat4x4 (value.Column0, value.Column1, value.Column2, value.Column3);
}
public override string ToString ()
{
return
$"({M11}, {M12}, {M13}, {M14})\n" +
$"({M21}, {M22}, {M23}, {M24})\n" +
$"({M31}, {M32}, {M33}, {M34})\n" +
$"({M41}, {M42}, {M43}, {M44})";
}
public override int GetHashCode ()
{
return
M11.GetHashCode () ^ M12.GetHashCode () ^ M13.GetHashCode () ^ M14.GetHashCode () ^
M21.GetHashCode () ^ M22.GetHashCode () ^ M23.GetHashCode () ^ M24.GetHashCode () ^
M31.GetHashCode () ^ M32.GetHashCode () ^ M33.GetHashCode () ^ M34.GetHashCode () ^
M41.GetHashCode () ^ M42.GetHashCode () ^ M43.GetHashCode () ^ M44.GetHashCode ();
}
public override bool Equals (object obj)
{
if (!(obj is MatrixFloat4x4))
return false;
return Equals ((MatrixFloat4x4) obj);
}
public bool Equals (MatrixFloat4x4 other)
{
return
M11 == other.M11 && M12 == other.M12 && M13 == other.M13 && M14 == other.M14 &&
M21 == other.M21 && M22 == other.M22 && M23 == other.M23 && M24 == other.M24 &&
M31 == other.M31 && M32 == other.M32 && M33 == other.M33 && M34 == other.M34 &&
M41 == other.M41 && M42 == other.M42 && M43 == other.M43 && M44 == other.M44;
}
}
}

Просмотреть файл

@ -11,6 +11,8 @@ using System;
using XamCore.Foundation;
using XamCore.ObjCRuntime;
using Simd;
using Vector2 = global::OpenTK.Vector2;
using Vector3 = global::OpenTK.Vector3;
using Vector4 = global::OpenTK.Vector4;
@ -71,9 +73,18 @@ namespace XamCore.SpriteKit {
InitializeHandle (InitWithNameFloatVector4 (name, value), "initWithName:floatVector4:");
}
#if !XAMCORE_4_0
// Apple deprecated initWithName:floatMatrix2: in macOS10.12/iOS10.0
// and made available initWithName:matrixFloat2x2: so we invoke
// the right one at runtime depending on which OS version we are running
//
// Unfortunately our 'initWithName:matrixFloat2x2:' implementation is
// incorrect (the matrix is transposed), but changing it would be a
// breaking change, so we obsolete this constructor and provide a new
// one which implements (only) 'initWithName:matrixFloat2x2:'
// correctly. However, this constructor still does the right thing for
// < macOS 10.12 / iOS 10.0
[Obsolete ("Use the '(string, MatrixFloat2x2)' overload instead.")]
public SKUniform (string name, Matrix2 value)
{
if (CheckSystemVersion ())
@ -85,6 +96,14 @@ namespace XamCore.SpriteKit {
// Apple deprecated initWithName:floatMatrix3: in macOS10.12/iOS10.0
// and made available initWithName:matrixFloat3x3: so we invoke
// the right one at runtime depending on which OS version we are running
//
// Unfortunately our 'initWithName:matrixFloat3x3:' implementation is
// incorrect (the matrix is transposed), but changing it would be a
// breaking change, so we obsolete this constructor and provide a new
// one which implements (only) 'initWithName:matrixFloat3x3:'
// correctly. However, this constructor still does the right thing for
// < macOS 10.12 / iOS 10.0
[Obsolete ("Use the '(string, MatrixFloat3x3)' overload instead.")]
public SKUniform (string name, Matrix3 value)
{
if (CheckSystemVersion ())
@ -96,6 +115,14 @@ namespace XamCore.SpriteKit {
// Apple deprecated initWithName:floatMatrix4: in macOS10.12/iOS10.0
// and made available initWithName:matrixFloat4x4: so we invoke
// the right one at runtime depending on which OS version we are running
//
// Unfortunately our 'initWithName:matrixFloat4x4:' implementation is
// incorrect (the matrix is transposed), but changing it would be a
// breaking change, so we obsolete this constructor and provide a new
// one which implements (only) 'initWithName:matrixFloat4x4:'
// correctly. However, this constructor still does the right thing for
// < macOS 10.12 / iOS 10.0
[Obsolete ("Use the '(string, MatrixFloat4x4)' overload instead.")]
public SKUniform (string name, Matrix4 value)
{
if (CheckSystemVersion ())
@ -103,6 +130,7 @@ namespace XamCore.SpriteKit {
else
InitializeHandle (InitWithNameFloatMatrix4 (name, value), "initWithName:floatMatrix4:");
}
#endif // !XAMCORE_4_0
// Apple deprecated floatVector2Value in macOS10.12/iOS10.0
// and made available vectorFloat2Value so we invoke
@ -161,20 +189,29 @@ namespace XamCore.SpriteKit {
}
}
#if !XAMCORE_4_0
// Apple deprecated floatMatrix2Value in macOS10.12/iOS10.0
// and made available matrixFloat2x2Value so we invoke
// the right one at runtime depending on which OS version we are running
//
// Unfortunately our 'matrixFloat2x2Value' implementation is incorrect
// (we return a transposed matrix), but changing it would be a
// breaking change, so we obsolete this property and provide a new one
// which implements (only) 'matrixFloat4x4Value' correctly. However,
// this property still returns the correct matrix for < macOS 10.12 /
// iOS 10.0
[Obsolete ("Use 'MatrixFloat2x2Value' instead.")]
public virtual Matrix2 FloatMatrix2Value
{
get {
if (CheckSystemVersion ())
return _MatrixFloat2x2Value;
return (Matrix2) MatrixFloat2x2.Transpose (MatrixFloat2x2Value);
else
return _FloatMatrix2Value;
}
set {
if (CheckSystemVersion ())
_MatrixFloat2x2Value = value;
MatrixFloat2x2Value = MatrixFloat2x2.Transpose ((MatrixFloat2x2) value);
else
_FloatMatrix2Value = value;
}
@ -183,17 +220,25 @@ namespace XamCore.SpriteKit {
// Apple deprecated floatMatrix3Value in macOS10.12/iOS10.0
// and made available matrixFloat3x3Value so we invoke
// the right one at runtime depending on which OS version we are running
//
// Unfortunately our 'matrixFloat3x3Value' implementation is incorrect
// (we return a transposed matrix), but changing it would be a
// breaking change, so we obsolete this property and provide a new one
// which implements (only) 'matrixFloat3x3Value' correctly. However,
// this property still returns the correct matrix for < macOS 10.12 /
// iOS 10.0
[Obsolete ("Use 'MatrixFloat3x3Value' instead.")]
public virtual Matrix3 FloatMatrix3Value
{
get {
if (CheckSystemVersion ())
return _MatrixFloat3x3Value;
return (Matrix3) MatrixFloat3x3.Transpose (MatrixFloat3x3Value);
else
return _FloatMatrix3Value;
}
set {
if (CheckSystemVersion ())
_MatrixFloat3x3Value = value;
MatrixFloat3x3Value = MatrixFloat3x3.Transpose ((MatrixFloat3x3) value);
else
_FloatMatrix3Value = value;
}
@ -202,21 +247,30 @@ namespace XamCore.SpriteKit {
// Apple deprecated floatMatrix4Value in macOS10.12/iOS10.0
// and made available matrixFloat4x4Value so we invoke
// the right one at runtime depending on which OS version we are running
//
// Unfortunately our 'matrixFloat4x4Value' implementation is incorrect
// (we return a transposed matrix), but changing it would be a
// breaking change, so we obsolete this property and provide a new one
// which implements (only) 'matrixFloat4x4Value' correctly. However,
// this property still returns the correct matrix for < macOS 10.12 /
// iOS 10.0
[Obsolete ("Use 'MatrixFloat4x4Value' instead.")]
public virtual Matrix4 FloatMatrix4Value
{
get {
if (CheckSystemVersion ())
return _MatrixFloat4x4Value;
return (Matrix4) MatrixFloat4x4.Transpose (MatrixFloat4x4Value);
else
return _FloatMatrix4Value;
}
set {
if (CheckSystemVersion ())
_MatrixFloat4x4Value = value;
MatrixFloat4x4Value = MatrixFloat4x4.Transpose ((MatrixFloat4x4) value);
else
_FloatMatrix4Value = value;
}
}
#endif // !XAMCORE_4_0
}
}
#endif // XAMCORE_2_0

Просмотреть файл

@ -22,8 +22,8 @@ using XamCore.SceneKit;
using XamCore.UIKit;
using Vector3 = global::OpenTK.Vector3;
using Matrix3 = global::OpenTK.Matrix3;
using Matrix4 = global::OpenTK.Matrix4;
using Matrix3 = global::Simd.MatrixFloat3x3;
using Matrix4 = global::Simd.MatrixFloat4x4;
namespace XamCore.ARKit {

Просмотреть файл

@ -1008,6 +1008,8 @@ MODELIO_CORE_SOURCES = \
MODELIO_SOURCES = \
ModelIO/MDLAsset.cs \
ModelIO/MDLNoiseTexture.cs \
ModelIO/MDLTransform.cs \
ModelIO/MDLTransformComponent.cs \
ModelIO/MDLVertexDescriptor.cs \
ModelIO/MDLMesh.cs \
@ -1523,6 +1525,9 @@ SHARED_CORE_SOURCES = \
ObjCRuntime/Protocol.cs \
ObjCRuntime/Registrar.core.cs \
ObjCRuntime/Selector.cs \
Simd/MatrixFloat2x2.cs \
Simd/MatrixFloat3x3.cs \
Simd/MatrixFloat4x4.cs \
SHARED_SOURCES = \
../runtime/Delegates.generated.cs \

Просмотреть файл

@ -18,6 +18,7 @@ using Vector2i = global::OpenTK.Vector2i;
using Vector3 = global::OpenTK.Vector3;
using Vector3d = global::OpenTK.Vector3d;
using Matrix3 = global::OpenTK.Matrix3;
using Simd;
#if MONOMAC
using SKColor = XamCore.AppKit.NSColor;
@ -132,6 +133,8 @@ namespace XamCore.GameplayKit {
[Export ("rightHanded")]
bool RightHanded { get; set; }
#if !XAMCORE_4_0
[Obsolete ("Use 'Rotation3x3' instead.")]
[Export ("rotation", ArgumentSemantic.Assign)]
Matrix3 Rotation {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
@ -139,6 +142,20 @@ namespace XamCore.GameplayKit {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
set;
}
#endif
[Export ("rotation", ArgumentSemantic.Assign)]
#if XAMCORE_4_0
MatrixFloat3x3 Rotation {
#else
[Sealed]
MatrixFloat3x3 Rotation3x3 {
#endif
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
set;
}
[Export ("updateWithDeltaTime:")]
void Update (double deltaTimeInSeconds);

Просмотреть файл

@ -22,9 +22,16 @@ using Vector3 = global::OpenTK.Vector3;
using Vector3i = global::OpenTK.Vector3i;
using Vector4 = global::OpenTK.Vector4;
using Vector4i = global::OpenTK.Vector4i;
#if XAMCORE_4_0
using Matrix2 = global::Simd.Matrix2;
using Matrix3 = global::Simd.Matrix3;
using Matrix4 = global::Simd.Matrix4;
#else
using Matrix2 = global::OpenTK.Matrix2;
using Matrix3 = global::OpenTK.Matrix3;
using Matrix4 = global::OpenTK.Matrix4;
using Simd;
#endif
using Quaternion = global::OpenTK.Quaternion;
using MathHelper = global::OpenTK.MathHelper;
#if MONOMAC
@ -212,10 +219,21 @@ namespace XamCore.ModelIO {
interface MDLCamera
{
[Export ("projectionMatrix")]
#if !XAMCORE_4_0
[Obsolete ("Use 'ProjectionMatrix4x4' instead.")]
#endif
Matrix4 ProjectionMatrix {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
}
#if !XAMCORE_4_0
[Sealed]
[Export ("projectionMatrix")]
MatrixFloat4x4 ProjectionMatrix4x4 {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
}
#endif
[iOS (10,0)]
[Mac (10,12)]
[TV (10,0)]
@ -515,8 +533,19 @@ namespace XamCore.ModelIO {
[Export ("initWithName:semantic:matrix4x4:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
#if !XAMCORE_4_0
[Obsolete ("Use the '(string, MDLMaterialSemantic, MatrixFloat4x4)' overload instead.")]
#endif
IntPtr Constructor (string name, MDLMaterialSemantic semantic, Matrix4 value);
#if !XAMCORE_4_0
[Sealed]
[Export ("initWithName:semantic:matrix4x4:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
IntPtr Constructor (string name, MDLMaterialSemantic semantic, MatrixFloat4x4 value);
#endif
[Export ("initWithName:semantic:URL:")]
IntPtr Constructor (string name, MDLMaterialSemantic semantic, [NullAllowed] NSUrl url);
@ -572,12 +601,24 @@ namespace XamCore.ModelIO {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
#if !XAMCORE_4_0
[Obsolete ("Use 'MatrixFloat4x4' instead.")]
#endif
[Export ("matrix4x4", ArgumentSemantic.Assign)]
Matrix4 Matrix4x4 {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
#if !XAMCORE_4_0
[Sealed]
[Export ("matrix4x4", ArgumentSemantic.Assign)]
MatrixFloat4x4 MatrixFloat4x4 {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
#endif
[iOS (10,0)]
[Mac (10,12)]
[TV (10,0)]
@ -1362,29 +1403,77 @@ namespace XamCore.ModelIO {
[Export ("overlap")]
float Overlap { get; set; }
#if !XAMCORE_4_0
[Obsolete ("Use 'LeftViewMatrix4x4' instead.")]
#endif
[Export ("leftViewMatrix")]
Matrix4 LeftViewMatrix {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
#if !XAMCORE_4_0
[Sealed]
[Export ("leftViewMatrix")]
MatrixFloat4x4 LeftViewMatrix4x4 {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
#endif
#if !XAMCORE_4_0
[Obsolete ("Use 'RightViewMatrix4x4' instead.")]
#endif
[Export ("rightViewMatrix")]
Matrix4 RightViewMatrix {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
#if !XAMCORE_4_0
[Sealed]
[Export ("rightViewMatrix")]
MatrixFloat4x4 RightViewMatrix4x4 {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
#endif
#if !XAMCORE_4_0
[Obsolete ("Use 'LeftProjectionMatrix4x4' instead.")]
#endif
[Export ("leftProjectionMatrix")]
Matrix4 LeftProjectionMatrix {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
#if !XAMCORE_4_0
[Sealed]
[Export ("leftProjectionMatrix")]
MatrixFloat4x4 LeftProjectionMatrix4x4 {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
#endif
#if !XAMCORE_4_0
[Obsolete ("Use 'RightProjectionMatrix4x4' instead.")]
#endif
[Export ("rightProjectionMatrix")]
Matrix4 RightProjectionMatrix {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
#if !XAMCORE_4_0
[Sealed]
[Export ("rightProjectionMatrix")]
MatrixFloat4x4 RightProjectionMatrix4x4 {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
#endif
}
[iOS (9,0), Mac(10,11, onlyOn64 : true)]
@ -1576,10 +1665,23 @@ namespace XamCore.ModelIO {
[Export ("initWithTransformComponent:resetsTransform:")]
IntPtr Constructor (IMDLTransformComponent component, bool resetsTransform);
#if !XAMCORE_4_0
[Obsolete ("Use the '(MatrixFloat4x4)' overload instead.")]
#endif
[Export ("initWithMatrix:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
IntPtr Constructor (Matrix4 matrix);
#if !XAMCORE_4_0
[Sealed]
[Export ("initWithMatrix:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
IntPtr Constructor (MatrixFloat4x4 matrix);
#endif
#if !XAMCORE_4_0
[Obsolete ("Use the '(MatrixFloat4x4, bool)' overload instead.")]
#endif
[iOS (10,0)]
[Mac (10,12)]
[TV (10,0)]
@ -1587,6 +1689,14 @@ namespace XamCore.ModelIO {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
IntPtr Constructor (Matrix4 matrix, bool resetsTransform);
#if !XAMCORE_4_0
[Sealed]
[iOS (10,0), Mac (10,12), TV (10,0)]
[Export ("initWithMatrix:resetsTransform:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
IntPtr Constructor (MatrixFloat4x4 matrix, bool resetsTransform);
#endif
[Export ("setIdentity")]
void SetIdentity ();
@ -1606,10 +1716,20 @@ namespace XamCore.ModelIO {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
Vector3 GetRotation (double atTime);
#if !XAMCORE_4_0
[Obsolete ("Use 'GetRotationMatrix4x4' instead.")]
#endif
[Export ("rotationMatrixAtTime:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
Matrix4 GetRotationMatrix (double atTime);
#if !XAMCORE_4_0
[Sealed]
[Export ("rotationMatrixAtTime:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
MatrixFloat4x4 GetRotationMatrix4x4 (double atTime);
#endif
[Export ("setShear:forTime:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
void SetShear (Vector3 scale, double time);
@ -1629,8 +1749,19 @@ namespace XamCore.ModelIO {
[iOS (10,3), TV (10,2), Mac (10,12,4)]
[Export ("setMatrix:forTime:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
#if !XAMCORE_4_0
[Obsolete ("Use 'SetMatrix4x4' instead.")]
#endif
void SetMatrix (Matrix4 matrix, double time);
#if !XAMCORE_4_0
[Sealed]
[iOS (10,3), TV (10,2), Mac (10,12,4)]
[Export ("setMatrix:forTime:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
void SetMatrix4x4 (MatrixFloat4x4 matrix, double time);
#endif
[Export ("shear", ArgumentSemantic.Assign)]
Vector3 Shear {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
@ -1713,6 +1844,9 @@ namespace XamCore.ModelIO {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
Matrix4 GetLocalTransform (double atTime);
#if !XAMCORE_4_0
[Obsolete ("Use 'CreateGlobalTransform4x4' instead.")]
#endif
[Static]
[Export ("globalTransformWithObject:atTime:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]

Просмотреть файл

@ -30,6 +30,7 @@ using Vector3 = global::OpenTK.Vector3;
using Matrix2 = global::OpenTK.Matrix2;
using Matrix3 = global::OpenTK.Matrix3;
using Matrix4 = global::OpenTK.Matrix4;
using Simd;
using Vector4 = global::OpenTK.Vector4;
using Quaternion = global::OpenTK.Quaternion;
@ -1777,14 +1778,19 @@ namespace XamCore.SpriteKit {
IntPtr InitWithNameVectorFloat4 (string name, Vector4 value);
#endif
#if !XAMCORE_4_0
[Internal]
[NoWatch]
[Availability (Deprecated = Platform.iOS_10_0 | Platform.Mac_10_12)]
[Export ("initWithName:floatMatrix2:")]
IntPtr InitWithNameFloatMatrix2 (string name, Matrix2 value);
#endif
#if !XAMCORE_4_0
[Obsolete ("Use the '(string, MatrixFloat2x2)' overload instead.")]
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Sealed]
[Export ("initWithName:matrixFloat2x2:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
#if WATCH
@ -1793,15 +1799,25 @@ namespace XamCore.SpriteKit {
[Internal]
IntPtr InitWithNameMatrixFloat2x2 (string name, Matrix2 value);
#endif
#endif // !XAMCORE_4_0
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("initWithName:matrixFloat2x2:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
IntPtr Constructor (string name, MatrixFloat2x2 value);
#if !XAMCORE_4_0
[Internal]
[NoWatch]
[Availability (Deprecated = Platform.iOS_10_0 | Platform.Mac_10_12)]
[Export ("initWithName:floatMatrix3:")]
IntPtr InitWithNameFloatMatrix3 (string name, Matrix3 value);
[Obsolete ("Use the '(string, MatrixFloat3x3)' overload instead.")]
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Sealed]
[Export ("initWithName:matrixFloat3x3:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
#if WATCH
@ -1809,17 +1825,29 @@ namespace XamCore.SpriteKit {
#else
[Internal]
IntPtr InitWithNameMatrixFloat3x3 (string name, Matrix3 value);
#endif
#endif
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("initWithName:matrixFloat3x3:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
IntPtr Constructor (string name, MatrixFloat3x3 value);
#if !XAMCORE_4_0
[Internal]
[NoWatch]
[Availability (Deprecated = Platform.iOS_10_0 | Platform.Mac_10_12)]
[Export ("initWithName:floatMatrix4:")]
IntPtr InitWithNameFloatMatrix4 (string name, Matrix4 value);
#endif
#if !XAMCORE_4_0
[Obsolete ("Use the '(string, MatrixFloat4x4)' overload instead.")]
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("initWithName:matrixFloat4x4:")]
[Sealed]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
#if WATCH
IntPtr Constructor (string name, Matrix4 value);
@ -1827,6 +1855,13 @@ namespace XamCore.SpriteKit {
[Internal]
IntPtr InitWithNameMatrixFloat4x4 (string name, Matrix4 value);
#endif
#endif
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("initWithName:matrixFloat4x4:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
IntPtr Constructor (string name, MatrixFloat4x4 value);
[Export ("name")]
string Name { get; }
@ -1897,59 +1932,92 @@ namespace XamCore.SpriteKit {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
#if !XAMCORE_4_0
[Internal]
[Availability (Deprecated = Platform.iOS_10_0 | Platform.Mac_10_12)]
[NoWatch]
[Export ("floatMatrix2Value")]
Matrix2 _FloatMatrix2Value { get; set; }
#endif
#if !XAMCORE_4_0 && WATCH
[Obsolete ("Use 'MatrixFloat2x2Value' instead.")]
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("matrixFloat2x2Value", ArgumentSemantic.Assign)]
#if WATCH
Matrix2 FloatMatrix2x2Value {
#else
[Internal]
Matrix2 _MatrixFloat2x2Value {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
#endif
#if !XAMCORE_4_0 && WATCH
[Sealed] // The selector is already used in the 'FloatMatrix2x2Value' property.
#endif
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("matrixFloat2x2Value", ArgumentSemantic.Assign)]
MatrixFloat2x2 MatrixFloat2x2Value {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
#if !XAMCORE_4_0
[Internal]
[NoWatch]
[Availability (Deprecated = Platform.iOS_10_0 | Platform.Mac_10_12)]
[Export ("floatMatrix3Value")]
Matrix3 _FloatMatrix3Value { get; set; }
#endif
#if !XAMCORE_4_0 && WATCH
[Obsolete ("Use 'MatrixFloat3x3Value' instead.")]
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("matrixFloat3x3Value", ArgumentSemantic.Assign)]
#if WATCH
Matrix3 FloatMatrix3x3Value {
#else
[Internal]
Matrix3 _MatrixFloat3x3Value {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
#endif
#if !XAMCORE_4_0 && WATCH
[Sealed] // The selector is already used in the 'FloatMatrix3x3Value' property.
#endif
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("matrixFloat3x3Value", ArgumentSemantic.Assign)]
MatrixFloat3x3 MatrixFloat3x3Value {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
#if !XAMCORE_4_0
[Internal]
[NoWatch]
[Availability (Deprecated = Platform.iOS_10_0 | Platform.Mac_10_12)]
[Export ("floatMatrix4Value")]
Matrix4 _FloatMatrix4Value { get; set; }
#endif
#if !XAMCORE_4_0 && WATCH
[Obsolete ("Use 'FloatMatrix4x4Value' instead.")]
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("matrixFloat4x4Value", ArgumentSemantic.Assign)]
#if WATCH
Matrix4 FloatMatrix4x4Value {
#else
[Internal]
Matrix4 _MatrixFloat4x4Value {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
#endif
#if !XAMCORE_4_0 && WATCH
[Sealed] // The selector is already used in the 'FloatMatrix4x4Value' property.
#endif
[iOS (10,0)][Mac (10,12)]
[TV (10,0)]
[Export ("matrixFloat4x4Value", ArgumentSemantic.Assign)]
MatrixFloat4x4 MatrixFloat4x4Value {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}
@ -1981,23 +2049,50 @@ namespace XamCore.SpriteKit {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
SKUniform Create (string name, Vector4 value);
#if !XAMCORE_4_0
[Obsolete ("Use the '(string, MatrixFloat2x2)' overload instead.")]
[iOS (10,0)][Mac (10,12)]
[Static]
[Export ("uniformWithName:matrixFloat2x2:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
SKUniform Create (string name, Matrix2 value);
#endif
[iOS (10,0)][Mac (10,12)]
[Static]
[Export ("uniformWithName:matrixFloat2x2:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
SKUniform Create (string name, MatrixFloat2x2 value);
#if !XAMCORE_4_0
[Obsolete ("Use the '(string, MatrixFloat3x3)' overload instead.")]
[iOS (10,0)][Mac (10,12)]
[Static]
[Export ("uniformWithName:matrixFloat3x3:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
SKUniform Create (string name, Matrix3 value);
#endif
[iOS (10,0)][Mac (10,12)]
[Static]
[Export ("uniformWithName:matrixFloat3x3:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
SKUniform Create (string name, MatrixFloat3x3 value);
#if !XAMCORE_4_0
[Obsolete ("Use 'the '(string, MatrixFloat4x4)' overload instead.")]
[iOS (10,0)][Mac (10,12)]
[Static]
[Export ("uniformWithName:matrixFloat4x4:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
SKUniform Create (string name, Matrix4 value);
#endif
[iOS (10,0)][Mac (10,12)]
[Static]
[Export ("uniformWithName:matrixFloat4x4:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
SKUniform Create (string name, MatrixFloat4x4 value);
}
delegate void SKActionDurationHandler (SKNode node, nfloat elapsedTime);
@ -3358,7 +3453,7 @@ namespace XamCore.SpriteKit {
}
[Export ("rotationMatrix")]
Matrix3 RotationMatrix {
MatrixFloat3x3 RotationMatrix {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] get;
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")] set;
}

Просмотреть файл

@ -21,7 +21,7 @@ using XamCore.ObjCRuntime;
using XamCore.ImageIO;
using Vector2 = global::OpenTK.Vector2;
using Matrix3 = global::OpenTK.Matrix3;
using Matrix3 = global::Simd.MatrixFloat3x3;
namespace XamCore.Vision {

Просмотреть файл

@ -7,7 +7,16 @@ using MonoTouch.ObjCRuntime;
using System.Runtime.InteropServices;
#if __UNIFIED__
[assembly: LinkWith ("XTest.framework")]
[assembly: LinkWith ("XStaticObjectTest.framework", LinkerFlags = "-lz")]
[assembly: LinkWith ("XStaticArTest.framework")]
[assembly: LinkWith ("XTest.framework", Frameworks = LinkWithConstants.Frameworks)]
[assembly: LinkWith ("XStaticObjectTest.framework", LinkerFlags = "-lz", Frameworks = LinkWithConstants.Frameworks)]
[assembly: LinkWith ("XStaticArTest.framework", Frameworks = LinkWithConstants.Frameworks)]
#endif
static class LinkWithConstants
{
#if __WATCHOS__
public const string Frameworks = "";
#else
public const string Frameworks = "ModelIO";
#endif
}

Просмотреть файл

@ -3,13 +3,103 @@ using System.Runtime.InteropServices;
#if !__UNIFIED__
using nint=System.Int32;
#else
using Foundation;
using ObjCRuntime;
#endif
using Simd;
namespace Bindings.Test
{
public static class CFunctions {
[DllImport ("__Internal")]
public static extern int theUltimateAnswer ();
[DllImport ("__Internal")]
public static extern void x_get_matrix_float2x2 (IntPtr self, string sel, out float r0c0, out float r0c1, out float r1c0, out float r1c1);
[DllImport ("__Internal")]
public static extern void x_get_matrix_float3x3 (IntPtr self, string sel, out float r0c0, out float r0c1, out float r0c2, out float r1c0, out float r1c1, out float r1c2, out float r2c0, out float r2c1, out float r2c2);
[DllImport ("__Internal")]
public static extern void x_get_matrix_float4x4 (IntPtr self, string sel, out float r0c0, out float r0c1, out float r0c2, out float r0c3, out float r1c0, out float r1c1, out float r1c2, out float r1c3, out float r2c0, out float r2c1, out float r2c2, out float r2c3, out float r3c0, out float r3c1, out float r3c2, out float r3c3);
public static MatrixFloat2x2 GetMatrixFloat2x2 (NSObject obj, string selector)
{
float r0c0, r0c1, r1c0, r1c1;
x_get_matrix_float2x2 (obj.Handle, selector, out r0c0, out r0c1, out r1c0, out r1c1);
return new MatrixFloat2x2 (
r0c0, r0c1,
r1c0, r1c1);
}
public static MatrixFloat3x3 GetMatrixFloat3x3 (NSObject obj, string selector)
{
float r0c0, r0c1, r0c2, r1c0, r1c1, r1c2, r2c0, r2c1, r2c2;
x_get_matrix_float3x3 (obj.Handle, selector, out r0c0, out r0c1, out r0c2, out r1c0, out r1c1, out r1c2, out r2c0, out r2c1, out r2c2);
return new MatrixFloat3x3 (
r0c0, r0c1, r0c2,
r1c0, r1c1, r1c2,
r2c0, r2c1, r2c2);
}
public static MatrixFloat4x4 GetMatrixFloat4x4 (NSObject obj, string selector)
{
float r0c0, r0c1, r0c2, r0c3, r1c0, r1c1, r1c2, r1c3, r2c0, r2c1, r2c2, r2c3, r3c0, r3c1, r3c2, r3c3;
x_get_matrix_float4x4 (obj.Handle, selector, out r0c0, out r0c1, out r0c2, out r0c3, out r1c0, out r1c1, out r1c2, out r1c3, out r2c0, out r2c1, out r2c2, out r2c3, out r3c0, out r3c1, out r3c2, out r3c3);
return new MatrixFloat4x4 (
r0c0, r0c1, r0c2, r0c3,
r1c0, r1c1, r1c2, r1c3,
r2c0, r2c1, r2c2, r2c3,
r3c0, r3c1, r3c2, r3c3);
}
#if !__WATCHOS__
[DllImport ("__Internal")]
public static extern void x_mdltransformcomponent_get_local_transform (IntPtr self, double time, out float r0c0, out float r0c1, out float r0c2, out float r0c3, out float r1c0, out float r1c1, out float r1c2, out float r1c3, out float r2c0, out float r2c1, out float r2c2, out float r2c3, out float r3c0, out float r3c1, out float r3c2, out float r3c3);
public static MatrixFloat4x4 MDLTransformComponent_GetLocalTransform (INativeObject obj, double time)
{
float r0c0, r0c1, r0c2, r0c3, r1c0, r1c1, r1c2, r1c3, r2c0, r2c1, r2c2, r2c3, r3c0, r3c1, r3c2, r3c3;
x_mdltransformcomponent_get_local_transform (obj.Handle, time, out r0c0, out r0c1, out r0c2, out r0c3, out r1c0, out r1c1, out r1c2, out r1c3, out r2c0, out r2c1, out r2c2, out r2c3, out r3c0, out r3c1, out r3c2, out r3c3);
return new MatrixFloat4x4 (
r0c0, r0c1, r0c2, r0c3,
r1c0, r1c1, r1c2, r1c3,
r2c0, r2c1, r2c2, r2c3,
r3c0, r3c1, r3c2, r3c3);
}
[DllImport ("__Internal")]
public static extern void x_mdltransform_create_global_transform (IntPtr obj, double time, out float r0c0, out float r0c1, out float r0c2, out float r0c3, out float r1c0, out float r1c1, out float r1c2, out float r1c3, out float r2c0, out float r2c1, out float r2c2, out float r2c3, out float r3c0, out float r3c1, out float r3c2, out float r3c3);
public static MatrixFloat4x4 MDLTransform_CreateGlobalTransform (INativeObject obj, double time)
{
float r0c0, r0c1, r0c2, r0c3, r1c0, r1c1, r1c2, r1c3, r2c0, r2c1, r2c2, r2c3, r3c0, r3c1, r3c2, r3c3;
x_mdltransform_create_global_transform (obj.Handle, time, out r0c0, out r0c1, out r0c2, out r0c3, out r1c0, out r1c1, out r1c2, out r1c3, out r2c0, out r2c1, out r2c2, out r2c3, out r3c0, out r3c1, out r3c2, out r3c3);
return new MatrixFloat4x4 (
r0c0, r0c1, r0c2, r0c3,
r1c0, r1c1, r1c2, r1c3,
r2c0, r2c1, r2c2, r2c3,
r3c0, r3c1, r3c2, r3c3);
}
[DllImport ("__Internal")]
public static extern void x_mdltransform_get_rotation_matrix (IntPtr obj, double time, out float r0c0, out float r0c1, out float r0c2, out float r0c3, out float r1c0, out float r1c1, out float r1c2, out float r1c3, out float r2c0, out float r2c1, out float r2c2, out float r2c3, out float r3c0, out float r3c1, out float r3c2, out float r3c3);
public static MatrixFloat4x4 MDLTransform_GetRotationMatrix (INativeObject obj, double time)
{
float r0c0, r0c1, r0c2, r0c3, r1c0, r1c1, r1c2, r1c3, r2c0, r2c1, r2c2, r2c3, r3c0, r3c1, r3c2, r3c3;
x_mdltransform_get_rotation_matrix (obj.Handle, time, out r0c0, out r0c1, out r0c2, out r0c3, out r1c0, out r1c1, out r1c2, out r1c3, out r2c0, out r2c1, out r2c2, out r2c3, out r3c0, out r3c1, out r3c2, out r3c3);
return new MatrixFloat4x4 (
r0c0, r0c1, r0c2, r0c3,
r1c0, r1c1, r1c2, r1c3,
r2c0, r2c1, r2c2, r2c3,
r3c0, r3c1, r3c2, r3c3);
}
#endif
}
}

Просмотреть файл

@ -6,9 +6,18 @@ using MonoTouch.ObjCRuntime;
#endif
using System.Runtime.InteropServices;
[assembly: LinkWith ("libtest.a", LinkTarget.Simulator | LinkTarget.ArmV6 | LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Arm64 | LinkTarget.Simulator64, SmartLink = true, Frameworks = "Foundation" , LinkerFlags = "-lz")]
[assembly: LinkWith ("libtest.a", LinkTarget.Simulator | LinkTarget.ArmV6 | LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Arm64 | LinkTarget.Simulator64, SmartLink = true, Frameworks = LinkWithConstants.Frameworks, LinkerFlags = "-lz")]
public static class LibTest {
[DllImport ("__Internal")]
public static extern int theUltimateAnswer ();
}
static class LinkWithConstants
{
#if __WATCHOS__
public const string Frameworks = "Foundation";
#else
public const string Frameworks = "Foundation ModelIO";
#endif
}

Просмотреть файл

@ -233,6 +233,10 @@ namespace Introspection {
if (methodinfo == null && constructorinfo == null)
return;
// Don't check obsolete methods, it could be obsoleted because it was broken.
if (m.GetCustomAttributes<ObsoleteAttribute> () != null)
return;
if (m.DeclaringType != t)
return;
@ -388,9 +392,9 @@ namespace Introspection {
case "Vector4":
case "Vector4i":
case "Vector4d":
case "Matrix2":
case "Matrix3":
case "Matrix4":
case "MatrixFloat2x2":
case "MatrixFloat3x3":
case "MatrixFloat4x4":
case "MDLAxisAlignedBoundingBox": // struct { Vector3, Vector3 }
return true;
default:

Просмотреть файл

@ -10,11 +10,11 @@ using MetalPerformanceShaders;
using MonoTouch.ModelIO;
#endif
using OpenTK;
using Simd;
using NUnit.Framework;
public static class Asserts
{
#if !__WATCHOS__
public static void AreEqual (bool expected, bool actual, string message)
{
Assert.AreEqual (expected, actual, message + " (M)");
@ -25,6 +25,11 @@ public static class Asserts
Assert.AreEqual (expected, actual, message + " (M)");
}
public static void AreEqual (float expected, float actual, float delta, string message)
{
Assert.AreEqual (expected, actual, delta, message);
}
public static void AreEqual (Vector2 expected, Vector2 actual, string message)
{
Assert.AreEqual (expected.X, actual.X, message + " (X)");
@ -38,6 +43,13 @@ public static class Asserts
Assert.AreEqual (expected.Z, actual.Z, 0.001, message + " (Z)");
}
public static void AreEqual (Vector3 expected, Vector3 actual, float delta, string message)
{
Assert.AreEqual (expected.X, actual.X, delta, message + " (X)");
Assert.AreEqual (expected.Y, actual.Y, delta, message + " (Y)");
Assert.AreEqual (expected.Z, actual.Z, delta, message + " (Z)");
}
public static void AreEqual (Vector4 expected, Vector4 actual, string message)
{
Assert.AreEqual (expected.X, actual.X, message + " (X)");
@ -46,6 +58,14 @@ public static class Asserts
Assert.AreEqual (expected.W, actual.W, message + " (W)");
}
public static void AreEqual (Vector4 expected, Vector4 actual, float delta, string message)
{
Assert.AreEqual (expected.X, actual.X, delta, message + " (X)");
Assert.AreEqual (expected.Y, actual.Y, delta, message + " (Y)");
Assert.AreEqual (expected.Z, actual.Z, delta, message + " (Z)");
Assert.AreEqual (expected.W, actual.W, delta, message + " (W)");
}
public static void AreEqual (Matrix2 expected, Matrix2 actual, string message)
{
AreEqual (expected.R0C0, actual.R0C0, message + " (R0C0)");
@ -67,6 +87,19 @@ public static class Asserts
AreEqual (expected.R2C2, actual.R2C2, message + " (R2C2)");
}
public static void AreEqual (Matrix3 expected, Matrix3 actual, float delta, string message)
{
AreEqual (expected.R0C0, actual.R0C0, delta, message + " (R0C0)");
AreEqual (expected.R0C1, actual.R0C1, delta, message + " (R0C1)");
AreEqual (expected.R0C2, actual.R0C2, delta, message + " (R0C2)");
AreEqual (expected.R1C0, actual.R1C0, delta, message + " (R1C0)");
AreEqual (expected.R1C1, actual.R1C1, delta, message + " (R1C1)");
AreEqual (expected.R1C2, actual.R1C2, delta, message + " (R1C2)");
AreEqual (expected.R2C0, actual.R2C0, delta, message + " (R2C0)");
AreEqual (expected.R2C1, actual.R2C1, delta, message + " (R2C1)");
AreEqual (expected.R2C2, actual.R2C2, delta, message + " (R2C2)");
}
public static void AreEqual (Matrix4 expected, Matrix4 actual, string message)
{
AreEqual (expected.Column0, actual.Column0, message + " (Col0)");
@ -75,17 +108,27 @@ public static class Asserts
AreEqual (expected.Column3, actual.Column3, message + " (Col3)");
}
public static void AreEqual (Matrix4 expected, Matrix4 actual, float delta, string message)
{
AreEqual (expected.Column0, actual.Column0, delta, message + " (Col0)");
AreEqual (expected.Column1, actual.Column1, delta, message + " (Col1)");
AreEqual (expected.Column2, actual.Column2, delta, message + " (Col2)");
AreEqual (expected.Column3, actual.Column3, delta, message + " (Col3)");
}
public static void AreEqual (Vector2i expected, Vector2i actual, string message)
{
Assert.AreEqual (expected.X, actual.X, message + " (X)");
Assert.AreEqual (expected.Y, actual.Y, message + " (Y)");
}
#if !__WATCHOS__
public static void AreEqual (MDLAxisAlignedBoundingBox expected, MDLAxisAlignedBoundingBox actual, string message)
{
AreEqual (expected.MaxBounds, actual.MaxBounds, message + " (MaxBounds)");
AreEqual (expected.MinBounds, actual.MinBounds, message + " (MinBounds)");
}
#endif // !__WATCHOS__
public static void AreEqual (Quaternion expected, Quaternion actual, string message)
{
@ -95,7 +138,7 @@ public static class Asserts
Assert.AreEqual (expected.W, actual.W, message + " (W)");
}
#if !MONOMAC
#if !MONOMAC && !__WATCHOS__
public static void AreEqual (MPSImageHistogramInfo expected, MPSImageHistogramInfo actual, string message)
{
Assert.AreEqual (expected.HistogramForAlpha, actual.HistogramForAlpha, message + " HistogramForAlpha");
@ -103,7 +146,190 @@ public static class Asserts
Asserts.AreEqual (expected.MinPixelValue, actual.MinPixelValue, message + " MinPixelValue");
Assert.AreEqual (expected.NumberOfHistogramEntries, actual.NumberOfHistogramEntries, message + " NumberOfHistogramEntries");
}
#endif // !MONOMAC
#endif // !__WATCHOS__
#endif // !MONOMAC && !__WATCHOS__
public static void AreEqual (MatrixFloat2x2 expected, MatrixFloat2x2 actual, string message)
{
AreEqual (expected.M11, actual.M11, message + " (M11)");
AreEqual (expected.M21, actual.M21, message + " (M21)");
AreEqual (expected.M12, actual.M12, message + " (M12)");
AreEqual (expected.M22, actual.M22, message + " (M22)");
}
public static void AreEqual (MatrixFloat2x2 expected, MatrixFloat2x2 actual, float delta, string message)
{
AreEqual (expected.M11, actual.M11, delta, message + " (M11)");
AreEqual (expected.M21, actual.M21, delta, message + " (M21)");
AreEqual (expected.M12, actual.M12, delta, message + " (M12)");
AreEqual (expected.M22, actual.M22, delta, message + " (M22)");
}
public static void AreEqual (Matrix2 expected, MatrixFloat2x2 actual, string message)
{
AreEqual (expected.R0C0, actual.M11, message + " (M11)");
AreEqual (expected.R0C1, actual.M12, message + " (M12)");
AreEqual (expected.R1C0, actual.M21, message + " (M21)");
AreEqual (expected.R1C1, actual.M22, message + " (M22)");
}
public static void AreEqual (MatrixFloat2x2 expected, Matrix2 actual, string message)
{
AreEqual (expected.M11, actual.R0C0, message + " (M11)");
AreEqual (expected.M12, actual.R0C1, message + " (M12)");
AreEqual (expected.M21, actual.R1C0, message + " (M21)");
AreEqual (expected.M22, actual.R1C1, message + " (M22)");
}
public static void AreEqual (MatrixFloat3x3 expected, MatrixFloat3x3 actual, string message)
{
AreEqual (expected.M11, actual.M11, message + " (M11)");
AreEqual (expected.M21, actual.M21, message + " (M21)");
AreEqual (expected.M31, actual.M31, message + " (M31)");
AreEqual (expected.M12, actual.M12, message + " (M12)");
AreEqual (expected.M22, actual.M22, message + " (M22)");
AreEqual (expected.M32, actual.M32, message + " (M32)");
AreEqual (expected.M13, actual.M13, message + " (M13)");
AreEqual (expected.M23, actual.M23, message + " (M23)");
AreEqual (expected.M33, actual.M33, message + " (M33)");
}
public static void AreEqual (MatrixFloat3x3 expected, MatrixFloat3x3 actual, float delta, string message)
{
AreEqual (expected.M11, actual.M11, delta, message + " (M11)");
AreEqual (expected.M21, actual.M21, delta, message + " (M21)");
AreEqual (expected.M31, actual.M31, delta, message + " (M31)");
AreEqual (expected.M12, actual.M12, delta, message + " (M12)");
AreEqual (expected.M22, actual.M22, delta, message + " (M22)");
AreEqual (expected.M32, actual.M32, delta, message + " (M32)");
AreEqual (expected.M13, actual.M13, delta, message + " (M13)");
AreEqual (expected.M23, actual.M23, delta, message + " (M23)");
AreEqual (expected.M33, actual.M33, delta, message + " (M33)");
}
public static void AreEqual (Matrix3 expected, MatrixFloat3x3 actual, string message)
{
AreEqual (expected.R0C0, actual.M11, message + " (M11)");
AreEqual (expected.R0C1, actual.M12, message + " (M12)");
AreEqual (expected.R0C2, actual.M13, message + " (M13)");
AreEqual (expected.R1C0, actual.M21, message + " (M21)");
AreEqual (expected.R1C1, actual.M22, message + " (M22)");
AreEqual (expected.R1C2, actual.M23, message + " (M23)");
AreEqual (expected.R2C0, actual.M31, message + " (M31)");
AreEqual (expected.R2C1, actual.M32, message + " (M32)");
AreEqual (expected.R2C2, actual.M33, message + " (M33)");
}
public static void AreEqual (MatrixFloat3x3 expected, Matrix3 actual, string message)
{
AreEqual (expected.M11, actual.R0C0, message + " (M11)");
AreEqual (expected.M12, actual.R0C1, message + " (M12)");
AreEqual (expected.M13, actual.R0C2, message + " (M13)");
AreEqual (expected.M21, actual.R1C0, message + " (M21)");
AreEqual (expected.M22, actual.R1C1, message + " (M22)");
AreEqual (expected.M23, actual.R1C2, message + " (M23)");
AreEqual (expected.M31, actual.R2C0, message + " (M31)");
AreEqual (expected.M32, actual.R2C1, message + " (M32)");
AreEqual (expected.M33, actual.R2C2, message + " (M33)");
}
public static void AreEqual (MatrixFloat4x4 expected, MatrixFloat4x4 actual, string message)
{
AreEqual (expected.M11, actual.M11, message + " (M11)");
AreEqual (expected.M21, actual.M21, message + " (M21)");
AreEqual (expected.M31, actual.M31, message + " (M31)");
AreEqual (expected.M41, actual.M41, message + " (M41)");
AreEqual (expected.M12, actual.M12, message + " (M12)");
AreEqual (expected.M22, actual.M22, message + " (M22)");
AreEqual (expected.M32, actual.M32, message + " (M32)");
AreEqual (expected.M42, actual.M42, message + " (M42)");
AreEqual (expected.M13, actual.M13, message + " (M13)");
AreEqual (expected.M23, actual.M23, message + " (M23)");
AreEqual (expected.M33, actual.M33, message + " (M33)");
AreEqual (expected.M43, actual.M43, message + " (M43)");
AreEqual (expected.M14, actual.M14, message + " (M14)");
AreEqual (expected.M24, actual.M24, message + " (M24)");
AreEqual (expected.M34, actual.M34, message + " (M34)");
AreEqual (expected.M44, actual.M44, message + " (M44)");
}
public static void AreEqual (MatrixFloat4x4 expected, MatrixFloat4x4 actual, float delta, string message)
{
AreEqual (expected.M11, actual.M11, delta, message + " (M11)");
AreEqual (expected.M21, actual.M21, delta, message + " (M21)");
AreEqual (expected.M31, actual.M31, delta, message + " (M31)");
AreEqual (expected.M41, actual.M41, delta, message + " (M41)");
AreEqual (expected.M12, actual.M12, delta, message + " (M12)");
AreEqual (expected.M22, actual.M22, delta, message + " (M22)");
AreEqual (expected.M32, actual.M32, delta, message + " (M32)");
AreEqual (expected.M42, actual.M42, delta, message + " (M42)");
AreEqual (expected.M13, actual.M13, delta, message + " (M13)");
AreEqual (expected.M23, actual.M23, delta, message + " (M23)");
AreEqual (expected.M33, actual.M33, delta, message + " (M33)");
AreEqual (expected.M43, actual.M43, delta, message + " (M43)");
AreEqual (expected.M14, actual.M14, delta, message + " (M14)");
AreEqual (expected.M24, actual.M24, delta, message + " (M24)");
AreEqual (expected.M34, actual.M34, delta, message + " (M34)");
AreEqual (expected.M44, actual.M44, delta, message + " (M44)");
}
public static void AreEqual (Matrix4 expected, MatrixFloat4x4 actual, string message)
{
AreEqual (expected.M11, actual.M11, message + " (M11)");
AreEqual (expected.M21, actual.M21, message + " (M21)");
AreEqual (expected.M31, actual.M31, message + " (M31)");
AreEqual (expected.M41, actual.M41, message + " (M41)");
AreEqual (expected.M12, actual.M12, message + " (M12)");
AreEqual (expected.M22, actual.M22, message + " (M22)");
AreEqual (expected.M32, actual.M32, message + " (M32)");
AreEqual (expected.M42, actual.M42, message + " (M42)");
AreEqual (expected.M13, actual.M13, message + " (M13)");
AreEqual (expected.M23, actual.M23, message + " (M23)");
AreEqual (expected.M33, actual.M33, message + " (M33)");
AreEqual (expected.M43, actual.M43, message + " (M43)");
AreEqual (expected.M14, actual.M14, message + " (M14)");
AreEqual (expected.M24, actual.M24, message + " (M24)");
AreEqual (expected.M34, actual.M34, message + " (M34)");
AreEqual (expected.M44, actual.M44, message + " (M44)");
}
public static void AreEqual (Matrix4 expected, MatrixFloat4x4 actual, float delta, string message)
{
AreEqual (expected.M11, actual.M11, delta, message + " (M11)");
AreEqual (expected.M21, actual.M21, delta, message + " (M21)");
AreEqual (expected.M31, actual.M31, delta, message + " (M31)");
AreEqual (expected.M41, actual.M41, delta, message + " (M41)");
AreEqual (expected.M12, actual.M12, delta, message + " (M12)");
AreEqual (expected.M22, actual.M22, delta, message + " (M22)");
AreEqual (expected.M32, actual.M32, delta, message + " (M32)");
AreEqual (expected.M42, actual.M42, delta, message + " (M42)");
AreEqual (expected.M13, actual.M13, delta, message + " (M13)");
AreEqual (expected.M23, actual.M23, delta, message + " (M23)");
AreEqual (expected.M33, actual.M33, delta, message + " (M33)");
AreEqual (expected.M43, actual.M43, delta, message + " (M43)");
AreEqual (expected.M14, actual.M14, delta, message + " (M14)");
AreEqual (expected.M24, actual.M24, delta, message + " (M24)");
AreEqual (expected.M34, actual.M34, delta, message + " (M34)");
AreEqual (expected.M44, actual.M44, delta, message + " (M44)");
}
public static void AreEqual (MatrixFloat4x4 expected, Matrix4 actual, string message)
{
AreEqual (expected.M11, actual.M11, message + " (M11)");
AreEqual (expected.M21, actual.M21, message + " (M21)");
AreEqual (expected.M31, actual.M31, message + " (M31)");
AreEqual (expected.M41, actual.M41, message + " (M41)");
AreEqual (expected.M12, actual.M12, message + " (M12)");
AreEqual (expected.M22, actual.M22, message + " (M22)");
AreEqual (expected.M32, actual.M32, message + " (M32)");
AreEqual (expected.M42, actual.M42, message + " (M42)");
AreEqual (expected.M13, actual.M13, message + " (M13)");
AreEqual (expected.M23, actual.M23, message + " (M23)");
AreEqual (expected.M33, actual.M33, message + " (M33)");
AreEqual (expected.M43, actual.M43, message + " (M43)");
AreEqual (expected.M14, actual.M14, message + " (M14)");
AreEqual (expected.M24, actual.M24, message + " (M24)");
AreEqual (expected.M34, actual.M34, message + " (M34)");
AreEqual (expected.M44, actual.M44, message + " (M44)");
}
}

Просмотреть файл

@ -0,0 +1,62 @@
//
// Unit tests for GKAgent3D
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
//
// Copyright 2017 Microsoft Inc. All rights reserved.
//
#if !__WATCHOS__
using System;
using OpenTK;
#if XAMCORE_2_0
using Foundation;
using GameplayKit;
#else
using MonoTouch.Foundation;
using MonoTouch.GameplayKit;
#endif
using Simd;
using Bindings.Test;
using NUnit.Framework;
namespace MonoTouchFixtures.GamePlayKit
{
[TestFixture]
[Preserve (AllMembers = true)]
public class GKAgent3DTest
{
[Test]
public void RotationTest ()
{
using (var obj = new GKAgent3D ()) {
var initial = new Matrix3 (0, 0, 1,
0, 1, 0,
1, 0, 0);
Asserts.AreEqual (initial, obj.Rotation, "Rotation");
Asserts.AreEqual ((MatrixFloat3x3) initial, obj.Rotation3x3, "Rotation3x3");
var mat = new Matrix3 (1, 2, 3,
4, 5, 6,
7, 8, 9);
var mat3x3 = (MatrixFloat3x3) mat;
obj.Rotation = mat;
Asserts.AreEqual (mat, obj.Rotation, "Rotation after setter");
var transposed3x3 = MatrixFloat3x3.Transpose ((MatrixFloat3x3) mat);
Asserts.AreEqual (transposed3x3, obj.Rotation3x3, "Rotation3x3 after setter");
Asserts.AreEqual (transposed3x3, CFunctions.GetMatrixFloat3x3 (obj, "rotation"), "Rotation3x3 after setter native");
obj.Rotation3x3 = mat3x3;
Asserts.AreEqual (mat3x3, obj.Rotation3x3, "Rotation3x3 after setter 3x3");
Asserts.AreEqual (mat3x3, CFunctions.GetMatrixFloat3x3 (obj, "rotation"), "Rotation3x3 after setter native 3x3");
}
}
}
}
#endif // __WATCHOS__

Просмотреть файл

@ -0,0 +1,86 @@
//
// MDLCamera Unit Tests
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright 2017 Microsoft Inc.
//
#if !__WATCHOS__
using System;
#if XAMCORE_2_0
using CoreGraphics;
using Foundation;
#if !MONOMAC
using UIKit;
#endif
#if !__TVOS__
using MultipeerConnectivity;
#endif
using ModelIO;
using ObjCRuntime;
#else
using MonoTouch.CoreGraphics;
using MonoTouch.Foundation;
#if !__TVOS__
using MonoTouch.MultipeerConnectivity;
#endif
using MonoTouch.UIKit;
using MonoTouch.ModelIO;
using MonoTouch.ObjCRuntime;
#endif
using OpenTK;
using Simd;
using Bindings.Test;
using NUnit.Framework;
namespace MonoTouchFixtures.ModelIO
{
[TestFixture]
// we want the test to be available if we use the linker
[Preserve (AllMembers = true)]
public class MDCameraTest
{
[TestFixtureSetUp]
public void Setup ()
{
TestRuntime.AssertXcodeVersion (7, 0);
}
[Test]
public void ProjectionMatrix ()
{
using (var obj = new MDLCamera ()) {
Assert.AreEqual (0.1f, obj.NearVisibilityDistance, 0.0001f, "NearVisibilityDistance");
Assert.AreEqual (1000f, obj.FarVisibilityDistance, 0.0001f, "FarVisibilityDistance");
Assert.AreEqual (54f, obj.FieldOfView, 0.0001f, "FieldOfView");
var initialProjectionMatrix = new Matrix4 (
1.308407f, 0, 0, 0,
0, 1.962611f, 0, 0,
0, 0, -1.0002f, -1,
0, 0, -0.20002f, 0
);
Asserts.AreEqual (initialProjectionMatrix, obj.ProjectionMatrix, 0.0001f, "Initial");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) initialProjectionMatrix), obj.ProjectionMatrix4x4, 0.0001f, "Initial 4x4");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) initialProjectionMatrix), CFunctions.GetMatrixFloat4x4 (obj, "projectionMatrix"), 0.0001f, "Initial native");
obj.NearVisibilityDistance = 1.0f;
var modifiedProjectionMatrix = new Matrix4 (
1.308407f, 0, 0, 0,
0, 1.962611f, 0, 0,
0, 0, -1.002002f, -1,
0, 0, -2.002002f, 0
);
Asserts.AreEqual (modifiedProjectionMatrix, obj.ProjectionMatrix, 0.0001f, "Second");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) modifiedProjectionMatrix), obj.ProjectionMatrix4x4, 0.0001f, "Second 4x4");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) modifiedProjectionMatrix), CFunctions.GetMatrixFloat4x4 (obj, "projectionMatrix"), 0.0001f, "Second native");
}
}
}
}
#endif // !__WATCHOS__

Просмотреть файл

@ -33,6 +33,10 @@ using MonoTouch.ModelIO;
using MonoTouch.ObjCRuntime;
#endif
using OpenTK;
using Simd;
#if !TEST_BINDINGS_UNAVAILABLE
using Bindings.Test;
#endif
using NUnit.Framework;
namespace MonoTouchFixtures.ModelIO {
@ -101,6 +105,7 @@ namespace MonoTouchFixtures.ModelIO {
Vector3 V3;
Vector4 V4;
Matrix4 M4;
MatrixFloat4x4 M4x4;
MDLTextureSampler tsv;
NSUrl url;
@ -122,6 +127,7 @@ namespace MonoTouchFixtures.ModelIO {
V3 = new Vector3 (3, 4, 5);
V4 = new Vector4 (6, 7, 8, 9);
M4 = new Matrix4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
M4x4 = new MatrixFloat4x4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
tsv = new MDLTextureSampler ();
url = new NSUrl ("http://xamarin.com");
@ -187,6 +193,17 @@ namespace MonoTouchFixtures.ModelIO {
using (var obj = new MDLMaterialProperty ("name", MDLMaterialSemantic.AmbientOcclusion, M4)) {
Asserts.AreEqual (M4, obj.Matrix4x4, "7 Matrix4x4");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (CFunctions.GetMatrixFloat4x4 (obj, "matrix4x4"), obj.MatrixFloat4x4, "7b MatrixFloat4x4");
#endif
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) M4), obj.MatrixFloat4x4, "7c MatrixFloat4x4");
}
using (var obj = new MDLMaterialProperty ("name", MDLMaterialSemantic.AmbientOcclusion, M4x4)) {
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (CFunctions.GetMatrixFloat4x4 (obj, "matrix4x4"), obj.MatrixFloat4x4, "7' MatrixFloat4x4");
#endif
Asserts.AreEqual (M4x4, obj.MatrixFloat4x4, "7'b MatrixFloat4x4");
}
using (var obj = new MDLMaterialProperty ("name", MDLMaterialSemantic.AmbientOcclusion, V4)) {

Просмотреть файл

@ -0,0 +1,96 @@
//
// MDLStereoscopicCamera Unit Tests
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright 2017 Microsoft Inc.
//
#if !__WATCHOS__
using System;
#if XAMCORE_2_0
using CoreGraphics;
using Foundation;
#if !MONOMAC
using UIKit;
#endif
#if !__TVOS__
using MultipeerConnectivity;
#endif
using ModelIO;
using ObjCRuntime;
#else
using MonoTouch.CoreGraphics;
using MonoTouch.Foundation;
#if !__TVOS__
using MonoTouch.MultipeerConnectivity;
#endif
using MonoTouch.UIKit;
using MonoTouch.ModelIO;
using MonoTouch.ObjCRuntime;
#endif
using OpenTK;
using Simd;
using Bindings.Test;
using NUnit.Framework;
namespace MonoTouchFixtures.ModelIO
{
[TestFixture]
// we want the test to be available if we use the linker
[Preserve (AllMembers = true)]
public class MDLStereoscopicCameraTest
{
[TestFixtureSetUp]
public void Setup ()
{
TestRuntime.AssertXcodeVersion (7, 0);
}
[Test]
public void Properties ()
{
using (var obj = new MDLStereoscopicCamera ()) {
Assert.AreEqual (63f, obj.InterPupillaryDistance, "InterPupillaryDistance");
Assert.AreEqual (0f, obj.LeftVergence, "LeftVergence");
Assert.AreEqual (0f, obj.RightVergence, "RightVergence");
Assert.AreEqual (0f, obj.Overlap, "Overlap");
var mat1 = new Matrix4 (
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
-0.63f, 0, 0, 1);
Asserts.AreEqual (mat1, obj.LeftViewMatrix, "LeftViewMatrix");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) mat1), obj.LeftViewMatrix4x4, "LeftViewMatrix4x4");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) mat1), CFunctions.GetMatrixFloat4x4 (obj, "leftViewMatrix"), "LeftViewMatrix4x4 native");
var mat2 = new Matrix4 (
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0.63f, 0, 0, 1);
Asserts.AreEqual (mat2, obj.RightViewMatrix, "RightViewMatrix");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) mat2), obj.RightViewMatrix4x4, "RightViewMatrix4x4");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) mat2), CFunctions.GetMatrixFloat4x4 (obj, "rightViewMatrix"), "RightViewMatrix4x4 native");
var mat3 = new Matrix4 (
1.308407f, 0, 0, 0,
0, 1.962611f, 0, 0,
0, 0, -1.0002f, -1,
0, 0, -0.20002f, 0);
Asserts.AreEqual (mat3, obj.LeftProjectionMatrix, 0.0001f, "LeftProjectionMatrix");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) mat3), obj.LeftProjectionMatrix4x4, 0.0001f, "LeftProjectionMatrix4x4");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) mat3), CFunctions.GetMatrixFloat4x4 (obj, "leftProjectionMatrix"), 0.0001f, "LeftProjectionMatrix4x4 native");
Asserts.AreEqual (mat3, obj.RightProjectionMatrix, 0.0001f, "RightProjectionMatrix");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) mat3), obj.RightProjectionMatrix4x4, 0.0001f, "RightProjectionMatrix4x4");
Asserts.AreEqual (MatrixFloat4x4.Transpose ((MatrixFloat4x4) mat3), CFunctions.GetMatrixFloat4x4 (obj, "rightProjectionMatrix"), 0.0001f, "RightProjectionMatrix4x4 native");
}
}
}
}
#endif // !__WATCHOS__

Просмотреть файл

@ -30,6 +30,10 @@ using MonoTouch.ModelIO;
using MonoTouch.ObjCRuntime;
#endif
using OpenTK;
using Simd;
#if !TEST_BINDINGS_UNAVAILABLE
using Bindings.Test;
#endif
using NUnit.Framework;
namespace MonoTouchFixtures.ModelIO {
@ -120,6 +124,33 @@ namespace MonoTouchFixtures.ModelIO {
obj.Rotation = V3;
Asserts.AreEqual (V3, obj.Rotation, "Rotation 2");
}
var m4 = new Matrix4 (
4, 0, 0, 0,
0, 3, 0, 0,
0, 0, 2, 0,
2, 3, 4, 1);
using (var obj = new MDLTransform (m4)) {
Asserts.AreEqual (Vector3.Zero, obj.Rotation, "Rotation 3");
Asserts.AreEqual (new Vector3 (4, 3, 2), obj.Scale, "Scale 3");
Asserts.AreEqual (new Vector3 (2, 3, 4), obj.Translation, "Translation 3");
Asserts.AreEqual (m4, obj.Matrix, 0.0001f, "Matrix 3");
}
var m4x4 = new MatrixFloat4x4 (
4, 0, 0, 2,
0, 3, 0, 3,
0, 0, 2, 4,
0, 0, 0, 1);
using (var obj = new MDLTransform (m4x4)) {
Asserts.AreEqual (Vector3.Zero, obj.Rotation, "Rotation 4");
Asserts.AreEqual (new Vector3 (4, 3, 2), obj.Scale, "Scale 4");
Asserts.AreEqual (new Vector3 (2, 3, 4), obj.Translation, "Translation 4");
Asserts.AreEqual (m4x4, obj.GetMatrix4x4 (), 0.0001f, "Matrix4x4 4");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (m4x4, CFunctions.GetMatrixFloat4x4 (obj, "matrix"), 0.0001f, "Matrix4x4-native 4");
#endif
}
}
[Test]
@ -157,6 +188,28 @@ namespace MonoTouchFixtures.ModelIO {
Asserts.AreEqual (V3, obj.GetRotation (0), "RotationAtTime");
}
}
[Test]
public void GetRotationMatrixTest ()
{
var matrix = Matrix4.Identity;
var V3 = new Vector3 (1, 0, 0);
using (var obj = new MDLTransform (matrix)) {
obj.SetRotation (V3, 0);
var expected = new MatrixFloat4x4 (
1, 0, 0, 0,
0, (float) Math.Cos (1.0f), (float) -Math.Sin(1.0f), 0,
0, (float) Math.Sin (1.0f), (float) Math.Cos(1.0f), 0,
0, 0, 0, 1
);
Asserts.AreEqual ((Matrix4) MatrixFloat4x4.Transpose (expected), obj.GetRotationMatrix (0), 0.00001f, "GetRotationMatrix");
Asserts.AreEqual (expected, obj.GetRotationMatrix4x4 (0), 0.00001f, "GetRotationMatrix4x4");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (expected, CFunctions.MDLTransform_GetRotationMatrix (obj, 0), 0.00001f, "GetRotationMatrix4x4 native");
#endif
}
}
}
}

Просмотреть файл

@ -0,0 +1,207 @@
//
// MDLTransformComponent Unit Tests
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright 2017 Microsoft inc
//
#if !__WATCHOS__
using System;
#if XAMCORE_2_0
using Foundation;
#if !MONOMAC
using UIKit;
#endif
#if !__TVOS__
using MultipeerConnectivity;
#endif
using ModelIO;
using ObjCRuntime;
#else
using MonoTouch.Foundation;
#if !__TVOS__
using MonoTouch.MultipeerConnectivity;
#endif
using MonoTouch.UIKit;
using MonoTouch.ModelIO;
using MonoTouch.ObjCRuntime;
#endif
using OpenTK;
using Simd;
using Bindings.Test;
using NUnit.Framework;
namespace MonoTouchFixtures.ModelIO
{
[TestFixture]
// we want the test to be available if we use the linker
[Preserve (AllMembers = true)]
public class MDLTransformComponentTest
{
[TestFixtureSetUp]
public void Setup ()
{
TestRuntime.AssertXcodeVersion (7, 0);
}
[Test]
public void MatrixTest ()
{
var m4 = new Matrix4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m4x4 = (MatrixFloat4x4) m4;
using (var obj = new MDLTransform ()) {
// identity
Asserts.AreEqual (Matrix4.Identity, obj.Matrix, "Initial identity");
Asserts.AreEqual (MatrixFloat4x4.Identity, obj.GetMatrix4x4 (), "Initial identity 4x4");
Asserts.AreEqual (MatrixFloat4x4.Identity, CFunctions.GetMatrixFloat4x4 (obj, "matrix"), "Initial identity native");
// translate the transform somewhere
obj.SetTranslation (new Vector3 (2, 2, 2), 0);
// the matrix should now be a translation matrix like this:
// 1 0 0 0 2
// 0 1 0 0 2
// 0 0 1 0 2
// 0 0 0 1 0
// but since Matrix4 is transposed when compared to MatrixFloat4x4, we get this:
Asserts.AreEqual (new Matrix4 (
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
2, 2, 2, 1
), obj.Matrix, "Translated");
// The 4x4 version is correct:
Asserts.AreEqual (new Matrix4 (
1, 0, 0, 2,
0, 1, 0, 2,
0, 0, 1, 2,
0, 0, 0, 1
), obj.GetMatrix4x4 (), "Translated 4x4");
// Let's set the matrix to something (different from the identity matrix)
obj.Matrix = m4;
// And the matrix resets to the identify matrix.
Asserts.AreEqual (Matrix4.Identity, obj.Matrix, "After set_Matrix");
// Translate again
obj.SetTranslation (new Vector3 (3, 3, 3), 0);
// Set the matrix using a 4x4 matrix
obj.SetMatrix4x4 (m4x4);
// And we still get the identity matrix back
Asserts.AreEqual (MatrixFloat4x4.Identity, obj.GetMatrix4x4 (), "After set_Matrix 2");
}
}
[Test]
public void LocalTransformTest ()
{
var m4 = new Matrix4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m4x4 = (MatrixFloat4x4) m4;
using (var obj = new MDLTransform ()) {
var component = (IMDLTransformComponent) obj;
// identity
Asserts.AreEqual (Matrix4.Identity, component.GetLocalTransform (0), "Initial identity");
Asserts.AreEqual (MatrixFloat4x4.Identity, component.GetLocalTransform4x4 (0), "Initial identity 4x4");
Asserts.AreEqual (MatrixFloat4x4.Identity, CFunctions.MDLTransformComponent_GetLocalTransform (component, 0), "Initial identity native");
// translate the transform somewhere
obj.SetTranslation (new Vector3 (2, 2, 2), 0);
// the local transform should now be a translation matrix like this:
// 1 0 0 0 2
// 0 1 0 0 2
// 0 0 1 0 2
// 0 0 0 1 0
// but since Matrix4 is transposed when compared to MatrixFloat4x4, we get this:
Asserts.AreEqual (new Matrix4 (
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
2, 2, 2, 1
), component.GetLocalTransform (0), "Translated");
// The 4x4 version is correct:
Asserts.AreEqual (new Matrix4 (
1, 0, 0, 2,
0, 1, 0, 2,
0, 0, 1, 2,
0, 0, 0, 1
), component.GetLocalTransform4x4 (0), "Translated 4x4");
// Let's set the local transform at time 1 to something (different from the identity matrix)
component.SetLocalTransform (m4, 1);
// At time 1 the transform matrix is now the identity matrix
Asserts.AreEqual (Matrix4.Identity, component.GetLocalTransform (1), "After SetLocalTransform at 1");
// At time 0.5 we get a middle ground
Asserts.AreEqual (new Matrix4 (
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
1, 1, 1, 1
), component.GetLocalTransform (0.5), 0.00001f, "AfterSetLocalTransform at 0.5");
// And at time 0 we still have the translated matrix.
Asserts.AreEqual (new Matrix4 (
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
2, 2, 2, 1
), component.GetLocalTransform (0), 0.00001f, "AfterSetLocalTransform at 0");
// Let's set the local transform at all times
component.SetLocalTransform (m4);
// And we get the identity matrix back at all times
Asserts.AreEqual (Matrix4.Identity, component.GetLocalTransform (0), "Second identity at 0");
Asserts.AreEqual (Matrix4.Identity, component.GetLocalTransform (1), "Second identity at 1");
// Translate again
obj.SetTranslation (new Vector3 (3, 3, 3), 0);
// Set the local transform using a 4x4 matrix
component.SetLocalTransform4x4 (m4x4, 1);
// And at time 0.5 we still get a middle ground
// The numbers are different now because the translation matrix was different,
// and the matrix is correct because we're checking the 4x4 version.
Asserts.AreEqual (new MatrixFloat4x4 (
1, 0, 0, 1.5f,
0, 1, 0, 1.5f,
0, 0, 1, 1.5f,
0, 0, 0, 1
), component.GetLocalTransform4x4 (0.5), 0.00001f, "AfterSetLocalTransform4x4 at 0.5");
}
}
[Test]
public void CreateGlobalTransformTest ()
{
Matrix4 m4;
MatrixFloat4x4 m4x4;
using (var obj = new MDLObject ()) {
m4 = MDLTransform.CreateGlobalTransform (obj, 0);
Asserts.AreEqual ((Matrix4) MatrixFloat4x4.Transpose (CFunctions.MDLTransform_CreateGlobalTransform (obj, 0)), m4, "CreateGlobalTransform");
m4x4 = MDLTransform.CreateGlobalTransform4x4 (obj, 0);
Asserts.AreEqual (CFunctions.MDLTransform_CreateGlobalTransform (obj, 0), m4, "CreateGlobalTransform4x4");
}
}
}
}
#endif // !__WATCHOS__

Просмотреть файл

@ -0,0 +1,315 @@

using System;
using System.Diagnostics;
using Foundation;
using ObjCRuntime;
using OpenTK;
using Simd;
using NUnit.Framework;
namespace MonoTouchFixtures.Simd
{
[TestFixture]
[Preserve (AllMembers = true)]
public class MatrixFloat2x2Test
{
[Test]
public void Identity ()
{
var identity = new MatrixFloat2x2 {
M11 = 1f,
M22 = 1f,
};
Asserts.AreEqual (identity, MatrixFloat2x2.Identity, "identity");
Asserts.AreEqual (Matrix2.Identity, MatrixFloat2x2.Identity, "opentk identity");
}
[Test]
public void ColumnConstructor ()
{
var expected = GetTestMatrix ();
var actual = new MatrixFloat2x2 (
new Vector2 (expected.R0C0, expected.R1C0),
new Vector2 (expected.R0C1, expected.R1C1)
);
Asserts.AreEqual (expected, actual, "ctor 1");
}
[Test]
public void ElementConstructor ()
{
var expected = GetTestMatrix ();
var actual = new MatrixFloat2x2 (expected.R0C0, expected.R0C1,
expected.R1C0, expected.R1C1);
Asserts.AreEqual (expected, actual, "ctor 1");
}
[Test]
public void Determinant ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat2x2) expected;
Assert.AreEqual (expected.Determinant, actual.Determinant, 0.000001f, "determinant\n" + actual);
}
[Test]
public void Elements ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat2x2) expected;
Assert.AreEqual (expected.R0C0, actual.M11, "m11 getter");
Assert.AreEqual (expected.R0C1, actual.M12, "m12 getter");
Assert.AreEqual (expected.R1C0, actual.M21, "m21 getter");
Assert.AreEqual (expected.R1C1, actual.M22, "m22 getter");
var newExpected = GetTestMatrix ();
actual.M11 = newExpected.R0C0;
actual.M12 = newExpected.R0C1;
actual.M21 = newExpected.R1C0;
actual.M22 = newExpected.R1C1;
Assert.AreEqual (newExpected.R0C0, actual.M11, "m11 setter");
Assert.AreEqual (newExpected.R0C1, actual.M12, "m12 setter");
Assert.AreEqual (newExpected.R1C0, actual.M21, "m21 setter");
Assert.AreEqual (newExpected.R1C1, actual.M22, "m22 setter");
}
[Test]
public void TransposeInstance ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat2x2) expected;
expected.Transpose ();
actual.Transpose ();
Asserts.AreEqual (expected, actual, "transpose");
}
[Test]
public void TransposeStatic ()
{
var input = GetTestMatrix ();
var inputSimd = (MatrixFloat2x2) input;
Matrix2 expected;
Matrix2.Transpose (ref input, out expected);
var actual = MatrixFloat2x2.Transpose (inputSimd);
Asserts.AreEqual (expected, actual, "transpose");
input = GetTestMatrix ();
inputSimd = (MatrixFloat2x2) input;
Matrix2.Transpose (ref input, out expected);
MatrixFloat2x2.Transpose (ref inputSimd, out actual);
Asserts.AreEqual (expected, actual, "transpose out/ref");
}
[Test]
public void TransposeStatic_ByRef ()
{
var input = GetTestMatrix ();
var inputSimd = (MatrixFloat2x2) input;
Matrix2 expected;
MatrixFloat2x2 actual;
Matrix2.Transpose (ref input, out expected);
MatrixFloat2x2.Transpose (ref inputSimd, out actual);
Asserts.AreEqual (expected, actual, "transpose out/ref");
}
[Test]
public void Multiply ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat2x2) inputL;
var inputSimdR = (MatrixFloat2x2) inputR;
Matrix2 expected;
Matrix2.Multiply (ref inputR, ref inputL, out expected); // OpenTK.Matrix2 got left/right mixed up...
var actual = MatrixFloat2x2.Multiply (inputSimdL, inputSimdR);
Asserts.AreEqual (expected, actual, "multiply");
}
[Test]
public void Multiply_ByRef ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat2x2) inputL;
var inputSimdR = (MatrixFloat2x2) inputR;
Matrix2 expected;
MatrixFloat2x2 actual;
Matrix2.Multiply (ref inputR, ref inputL, out expected); // OpenTK.Matrix2 got left/right mixed up...
MatrixFloat2x2.Multiply (ref inputSimdL, ref inputSimdR, out actual);
Asserts.AreEqual (expected, actual, "multiply");
}
[Test]
public void Multiply_Operator ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat2x2) inputL;
var inputSimdR = (MatrixFloat2x2) inputR;
Matrix2 expected;
Matrix2.Multiply (ref inputR, ref inputL, out expected); // OpenTK.Matrix2 got left/right mixed up...
var actual = inputSimdL * inputSimdR;
Asserts.AreEqual (expected, actual, "multiply");
}
[Test]
public void Equality_Operator ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat2x2) inputL;
var inputSimdR = (MatrixFloat2x2) inputR;
// matrices are different
Assert.AreEqual (inputL.Equals (inputR), inputSimdL == inputSimdR, "inequality");
Assert.IsFalse (inputL.Equals (inputR), "inequality 2 expected");
Assert.IsFalse (inputSimdL == inputSimdR, "inequality 2 actual");
inputL = inputR;
inputSimdL = inputSimdR;
// matrices are identical
Assert.AreEqual (inputL.Equals (inputR), inputSimdL == inputSimdR, "equality");
Assert.IsTrue (inputL.Equals (inputR), "equality 2 expected");
Assert.IsTrue (inputSimdL == inputSimdR, "equality 2 actual");
Assert.IsTrue (MatrixFloat2x2.Identity == (MatrixFloat2x2) Matrix2.Identity, "identity equality");
}
[Test]
public void Inequality_Operator ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat2x2) inputL;
var inputSimdR = (MatrixFloat2x2) inputR;
// matrices are different
Assert.AreEqual (!inputL.Equals (inputR), inputSimdL != inputSimdR, "inequality");
Assert.IsTrue (!inputL.Equals (inputR), "inequality 2 expected");
Assert.IsTrue (inputSimdL != inputSimdR, "inequality 2 actual");
inputL = inputR;
inputSimdL = inputSimdR;
// matrices are identical
Assert.AreEqual (!inputL.Equals (inputR), inputSimdL != inputSimdR, "equality");
Assert.IsFalse (!inputL.Equals (inputR), "equality 2 expected");
Assert.IsFalse (inputSimdL != inputSimdR, "equality 2 actual");
Assert.IsFalse (MatrixFloat2x2.Identity != (MatrixFloat2x2) Matrix2.Identity, "identity equality");
}
[Test]
public void Explicit_Operator_ToMatrix2 ()
{
var expected = (MatrixFloat2x2) GetTestMatrix ();
var actual = (Matrix2) expected;
Asserts.AreEqual (expected, actual, "tomatrix2");
actual = (Matrix2) MatrixFloat2x2.Identity;
Asserts.AreEqual (MatrixFloat2x2.Identity, actual, "tomatrix2 identity");
Asserts.AreEqual (Matrix2.Identity, actual, "tomatrix2 identity2");
}
[Test]
public void Explicit_Operator_FromMatrix2 ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat2x2) expected;
Asserts.AreEqual (expected, actual, "frommatrix2");
actual = (MatrixFloat2x2) Matrix2.Identity;
Asserts.AreEqual (MatrixFloat2x2.Identity, actual, "tomatrix2 identity");
Asserts.AreEqual (Matrix2.Identity, actual, "tomatrix2 identity2");
}
[Test]
public void ToStringTest ()
{
var actual = new MatrixFloat2x2 (1, 2, 3, 4);
Assert.AreEqual ("(1, 2)\n(3, 4)", actual.ToString (), "tostring");
}
// GetHashCode doesn't have to be identical, so no need to test
[Test]
public void Equals_Object ()
{
var expectedA = GetTestMatrix ();
var expectedB = GetTestMatrix ();
var actualA = (MatrixFloat2x2) expectedA;
var actualB = (MatrixFloat2x2) expectedB;
Assert.IsTrue (actualA.Equals ((object) actualA), "self");
Assert.IsFalse (actualA.Equals ((object) actualB), "other");
Assert.IsFalse (actualA.Equals (null), "null");
Assert.IsFalse (actualA.Equals (expectedA), "other type");
}
[Test]
public void Equals_Matrix ()
{
var expectedA = GetTestMatrix ();
var expectedB = GetTestMatrix ();
var actualA = (MatrixFloat2x2) expectedA;
var actualB = (MatrixFloat2x2) expectedB;
Assert.IsTrue (actualA.Equals (actualA), "self");
Assert.IsFalse (actualA.Equals (actualB), "other");
}
// A collection of test matrices.
//
// I initially tried randomly generating test matrices, but it turns out
// there are accumulative computational differences in the different algorithms
// between Matrix2 and MatrixFloat2x2. Since the differences are accumulative,
// I couldn't find a minimal sensible delta values when comparing
// matrices.
//
// So I just serialized a few matrices that were randomly generated, and
// these have been tested to not produce accumulative computational differences.
//
static Matrix2 [] test_matrices = new [] {
new Matrix2 (3, 5, 7, 11),
new Matrix2 (5, 7, 11, 13),
new Matrix2 (7, 11, 13, 17),
new Matrix2 (0.1532144f, 0.5451511f, 0.2004739f, 0.8351463f),
new Matrix2 (0.7717745f, 0.559364f, 0.00918373f, 0.6579159f),
new Matrix2 (0.2023053f, 0.4701468f, 0.6618567f, 0.7685714f),
new Matrix2 (9.799572E+08f, 1.64794E+09f, 1.117296E+09f, 1.239858E+09f),
new Matrix2 (1.102396E+09f, 3.082477E+08f, 1.126484E+09f, 5.022931E+08f),
new Matrix2 (2.263112E+08f, 8.79644E+08f, 1.303282E+09f, 1.654159E+09f),
new Matrix2 (0.4904693f, 0.841727f, 0.2294401f, 0.5736054f),
new Matrix2 (0.1252193f, 0.08986127f, 0.3407605f, 0.9144857f),
new Matrix2 (8.176959E+08f, 1.386156E+09f, 5.956444E+08f, 4.210506E+08f),
new Matrix2 (0.006755914f, 0.07464754f, 0.287938f, 0.3724834f),
};
static int counter;
internal static Matrix2 GetTestMatrix ()
{
counter++;
if (counter == test_matrices.Length)
counter = 0;
return test_matrices [counter];
}
}
}

Просмотреть файл

@ -0,0 +1,333 @@

using System;
using System.Diagnostics;
using Foundation;
using ObjCRuntime;
using OpenTK;
using Simd;
using NUnit.Framework;
namespace MonoTouchFixtures.Simd
{
[TestFixture]
[Preserve (AllMembers = true)]
public class MatrixFloat3x3Test
{
[Test]
public void Identity ()
{
var identity = new MatrixFloat3x3 {
M11 = 1f,
M22 = 1f,
M33 = 1f,
};
Asserts.AreEqual (identity, MatrixFloat3x3.Identity, "identity");
Asserts.AreEqual (Matrix3.Identity, MatrixFloat3x3.Identity, "opentk identity");
}
[Test]
public void ColumnConstructor ()
{
var expected = GetTestMatrix ();
var actual = new MatrixFloat3x3 (
new Vector3 (expected.R0C0, expected.R1C0, expected.R2C0),
new Vector3 (expected.R0C1, expected.R1C1, expected.R2C1),
new Vector3 (expected.R0C2, expected.R1C2, expected.R2C2)
);
Asserts.AreEqual (expected, actual, "ctor 1");
}
[Test]
public void ElementConstructor ()
{
var expected = GetTestMatrix ();
var actual = new MatrixFloat3x3 (expected.R0C0, expected.R0C1, expected.R0C2,
expected.R1C0, expected.R1C1, expected.R1C2,
expected.R2C0, expected.R2C1, expected.R2C2);
Asserts.AreEqual (expected, actual, "ctor 1");
}
[Test]
public void Determinant ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat3x3) expected;
Assert.AreEqual (expected.Determinant, actual.Determinant, 0.000001f, "determinant\n" + actual);
}
[Test]
public void Elements ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat3x3) expected;
Assert.AreEqual (expected.R0C0, actual.M11, "m11 getter");
Assert.AreEqual (expected.R0C1, actual.M12, "m12 getter");
Assert.AreEqual (expected.R0C2, actual.M13, "m13 getter");
Assert.AreEqual (expected.R1C0, actual.M21, "m21 getter");
Assert.AreEqual (expected.R1C1, actual.M22, "m22 getter");
Assert.AreEqual (expected.R1C2, actual.M23, "m23 getter");
Assert.AreEqual (expected.R2C0, actual.M31, "m31 getter");
Assert.AreEqual (expected.R2C1, actual.M32, "m32 getter");
Assert.AreEqual (expected.R2C2, actual.M33, "m33 getter");
var newExpected = GetTestMatrix ();
actual.M11 = newExpected.R0C0;
actual.M12 = newExpected.R0C1;
actual.M13 = newExpected.R0C2;
actual.M21 = newExpected.R1C0;
actual.M22 = newExpected.R1C1;
actual.M23 = newExpected.R1C2;
actual.M31 = newExpected.R2C0;
actual.M32 = newExpected.R2C1;
actual.M33 = newExpected.R2C2;
Assert.AreEqual (newExpected.R0C0, actual.M11, "m11 setter");
Assert.AreEqual (newExpected.R0C1, actual.M12, "m12 setter");
Assert.AreEqual (newExpected.R0C2, actual.M13, "m13 setter");
Assert.AreEqual (newExpected.R1C0, actual.M21, "m21 setter");
Assert.AreEqual (newExpected.R1C1, actual.M22, "m22 setter");
Assert.AreEqual (newExpected.R1C2, actual.M23, "m23 setter");
Assert.AreEqual (newExpected.R2C0, actual.M31, "m31 setter");
Assert.AreEqual (newExpected.R2C1, actual.M32, "m32 setter");
Assert.AreEqual (newExpected.R2C2, actual.M33, "m33 setter");
}
[Test]
public void TransposeInstance ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat3x3) expected;
expected.Transpose ();
actual.Transpose ();
Asserts.AreEqual (expected, actual, "transpose");
}
[Test]
public void TransposeStatic ()
{
var input = GetTestMatrix ();
var inputSimd = (MatrixFloat3x3) input;
Matrix3 expected;
Matrix3.Transpose (ref input, out expected);
var actual = MatrixFloat3x3.Transpose (inputSimd);
Asserts.AreEqual (expected, actual, "transpose");
input = GetTestMatrix ();
inputSimd = (MatrixFloat3x3) input;
Matrix3.Transpose (ref input, out expected);
MatrixFloat3x3.Transpose (ref inputSimd, out actual);
Asserts.AreEqual (expected, actual, "transpose out/ref");
}
[Test]
public void TransposeStatic_ByRef ()
{
var input = GetTestMatrix ();
var inputSimd = (MatrixFloat3x3) input;
Matrix3 expected;
MatrixFloat3x3 actual;
Matrix3.Transpose (ref input, out expected);
MatrixFloat3x3.Transpose (ref inputSimd, out actual);
Asserts.AreEqual (expected, actual, "transpose out/ref");
}
[Test]
public void Multiply ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat3x3) inputL;
var inputSimdR = (MatrixFloat3x3) inputR;
Matrix3 expected;
Matrix3.Multiply (ref inputR, ref inputL, out expected); // OpenTK.Matrix3 got left/right mixed up...
var actual = MatrixFloat3x3.Multiply (inputSimdL, inputSimdR);
Asserts.AreEqual (expected, actual, "multiply");
}
[Test]
public void Multiply_ByRef ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat3x3) inputL;
var inputSimdR = (MatrixFloat3x3) inputR;
Matrix3 expected;
MatrixFloat3x3 actual;
Matrix3.Multiply (ref inputR, ref inputL, out expected); // OpenTK.Matrix3 got left/right mixed up...
MatrixFloat3x3.Multiply (ref inputSimdL, ref inputSimdR, out actual);
Asserts.AreEqual (expected, actual, "multiply");
}
[Test]
public void Multiply_Operator ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat3x3) inputL;
var inputSimdR = (MatrixFloat3x3) inputR;
Matrix3 expected;
Matrix3.Multiply (ref inputR, ref inputL, out expected); // OpenTK.Matrix3 got left/right mixed up...
var actual = inputSimdL * inputSimdR;
Asserts.AreEqual (expected, actual, "multiply");
}
[Test]
public void Equality_Operator ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat3x3) inputL;
var inputSimdR = (MatrixFloat3x3) inputR;
// matrices are different
Assert.AreEqual (inputL.Equals (inputR), inputSimdL == inputSimdR, "inequality");
Assert.IsFalse (inputL.Equals (inputR), "inequality 2 expected");
Assert.IsFalse (inputSimdL == inputSimdR, "inequality 2 actual");
inputL = inputR;
inputSimdL = inputSimdR;
// matrices are identical
Assert.AreEqual (inputL.Equals (inputR), inputSimdL == inputSimdR, "equality");
Assert.IsTrue (inputL.Equals (inputR), "equality 2 expected");
Assert.IsTrue (inputSimdL == inputSimdR, "equality 2 actual");
Assert.IsTrue (MatrixFloat3x3.Identity == (MatrixFloat3x3) Matrix3.Identity, "identity equality");
}
[Test]
public void Inequality_Operator ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat3x3) inputL;
var inputSimdR = (MatrixFloat3x3) inputR;
// matrices are different
Assert.AreEqual (!inputL.Equals (inputR), inputSimdL != inputSimdR, "inequality");
Assert.IsTrue (!inputL.Equals (inputR), "inequality 2 expected");
Assert.IsTrue (inputSimdL != inputSimdR, "inequality 2 actual");
inputL = inputR;
inputSimdL = inputSimdR;
// matrices are identical
Assert.AreEqual (!inputL.Equals (inputR), inputSimdL != inputSimdR, "equality");
Assert.IsFalse (!inputL.Equals (inputR), "equality 2 expected");
Assert.IsFalse (inputSimdL != inputSimdR, "equality 2 actual");
Assert.IsFalse (MatrixFloat3x3.Identity != (MatrixFloat3x3) Matrix3.Identity, "identity equality");
}
[Test]
public void Explicit_Operator_ToMatrix3 ()
{
var expected = (MatrixFloat3x3) GetTestMatrix ();
var actual = (Matrix3) expected;
Asserts.AreEqual (expected, actual, "tomatrix4");
actual = (Matrix3) MatrixFloat3x3.Identity;
Asserts.AreEqual (MatrixFloat3x3.Identity, actual, "tomatrix4 identity");
Asserts.AreEqual (Matrix3.Identity, actual, "tomatrix4 identity2");
}
[Test]
public void Explicit_Operator_FromMatrix3 ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat3x3) expected;
Asserts.AreEqual (expected, actual, "frommatrix4");
actual = (MatrixFloat3x3) Matrix3.Identity;
Asserts.AreEqual (MatrixFloat3x3.Identity, actual, "tomatrix4 identity");
Asserts.AreEqual (Matrix3.Identity, actual, "tomatrix4 identity2");
}
[Test]
public void ToStringTest ()
{
var actual = new MatrixFloat3x3 (1, 2, 3, 4, 5, 6, 7, 8, 9);
Assert.AreEqual ("(1, 2, 3)\n(4, 5, 6)\n(7, 8, 9)", actual.ToString (), "tostring");
}
// GetHashCode doesn't have to be identical, so no need to test
[Test]
public void Equals_Object ()
{
var expectedA = GetTestMatrix ();
var expectedB = GetTestMatrix ();
var actualA = (MatrixFloat3x3) expectedA;
var actualB = (MatrixFloat3x3) expectedB;
Assert.IsTrue (actualA.Equals ((object) actualA), "self");
Assert.IsFalse (actualA.Equals ((object) actualB), "other");
Assert.IsFalse (actualA.Equals (null), "null");
Assert.IsFalse (actualA.Equals (expectedA), "other type");
}
[Test]
public void Equals_Matrix ()
{
var expectedA = GetTestMatrix ();
var expectedB = GetTestMatrix ();
var actualA = (MatrixFloat3x3) expectedA;
var actualB = (MatrixFloat3x3) expectedB;
Assert.IsTrue (actualA.Equals (actualA), "self");
Assert.IsFalse (actualA.Equals (actualB), "other");
}
// A collection of test matrices.
//
// I initially tried randomly generating test matrices, but it turns out
// there are accumulative computational differences in the different algorithms
// between Matrix3 and MatrixFloat3x3. Since the differences are accumulative,
// I couldn't find a minimal sensible delta values when comparing
// matrices.
//
// So I just serialized a few matrices that were randomly generated, and
// these have been tested to not produce accumulative computational differences.
//
static Matrix3 [] test_matrices = new [] {
new Matrix3 (3, 5, 7, 11, 13, 17, 19, 23, 29),
new Matrix3 (5, 7, 11, 13, 17, 19, 23, 29, 31),
new Matrix3 (7, 11, 13, 17, 19, 23, 29, 31, 37),
new Matrix3 (0.1532144f, 0.5451511f, 0.2004739f, 0.8351463f, 0.9884372f, 0.1313103f, 0.3327205f, 0.01164342f, 0.6563147f),
new Matrix3 (0.7717745f, 0.559364f, 0.00918373f, 0.6579159f, 0.123461f, 0.9993145f, 0.5487496f, 0.2823398f, 0.9710717f),
new Matrix3 (0.2023053f, 0.4701468f, 0.6618567f, 0.7685714f, 0.8561344f, 0.009231919f, 0.6150167f, 0.7542298f, 0.550727f),
new Matrix3 (9.799572E+08f, 1.64794E+09f, 1.117296E+09f, 1.239858E+09f, 6.389504E+07f, 1.172175E+09f, 1.399567E+09f, 1.187143E+09f, 3.729208E+07f),
new Matrix3 (1.102396E+09f, 3.082477E+08f, 1.126484E+09f, 5.022931E+08f, 1.966322E+09f, 1.1814E+09f, 8.464673E+08f, 1.940651E+09f, 1.229937E+09f),
new Matrix3 (2.263112E+08f, 8.79644E+08f, 1.303282E+09f, 1.654159E+09f, 3.705524E+08f, 1.984941E+09f, 2.175935E+07f, 4.633518E+08f, 1.801243E+09f),
new Matrix3 (0.4904693f, 0.841727f, 0.2294401f, 0.5736054f, 0.5406881f, 0.2172498f, 0.1261143f, 0.6736677f, 0.4570194f),
new Matrix3 (0.1252193f, 0.08986127f, 0.3407605f, 0.9144857f, 0.340791f, 0.2192288f, 0.5144276f, 0.01813344f, 0.07687104f),
new Matrix3 (8.176959E+08f, 1.386156E+09f, 5.956444E+08f, 4.210506E+08f, 1.212676E+09f, 4.131035E+08f, 1.032453E+09f, 2.074689E+08f, 1.536594E+09f),
new Matrix3 (0.006755914f, 0.07464754f, 0.287938f, 0.3724834f, 0.1496783f, 0.6224982f, 0.7150125f, 0.5554719f, 0.4638171f),
};
static int counter;
internal static Matrix3 GetTestMatrix ()
{
counter++;
if (counter == test_matrices.Length)
counter = 0;
return test_matrices [counter];
}
}
}

Просмотреть файл

@ -0,0 +1,348 @@

using System;
using System.Diagnostics;
using Foundation;
using ObjCRuntime;
using OpenTK;
using Simd;
using NUnit.Framework;
namespace MonoTouchFixtures.Simd
{
[TestFixture]
[Preserve (AllMembers = true)]
public class MatrixFloat4x4Test
{
[Test]
public void Identity ()
{
var identity = new MatrixFloat4x4 {
M11 = 1f,
M22 = 1f,
M33 = 1f,
M44 = 1f,
};
Asserts.AreEqual (identity, MatrixFloat4x4.Identity, "identity");
Asserts.AreEqual (Matrix4.Identity, MatrixFloat4x4.Identity, "opentk identity");
}
[Test]
public void ColumnConstructor ()
{
var expected = GetTestMatrix ();
var actual = new MatrixFloat4x4 (expected.Column0, expected.Column1, expected.Column2, expected.Column3);
Asserts.AreEqual (expected, actual, "ctor 1");
}
[Test]
public void ElementConstructor ()
{
var expected = GetTestMatrix ();
var actual = new MatrixFloat4x4 (expected.M11, expected.M12, expected.M13, expected.M14,
expected.M21, expected.M22, expected.M23, expected.M24,
expected.M31, expected.M32, expected.M33, expected.M34,
expected.M41, expected.M42, expected.M43, expected.M44);
Asserts.AreEqual (expected, actual, "ctor 1");
}
[Test]
public void Determinant ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat4x4) expected;
Assert.AreEqual (expected.Determinant, actual.Determinant, 0.000001f, "determinant\n" + actual);
}
[Test]
public void Elements ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat4x4) expected;
Assert.AreEqual (expected.M11, actual.M11, "m11 getter");
Assert.AreEqual (expected.M12, actual.M12, "m12 getter");
Assert.AreEqual (expected.M13, actual.M13, "m13 getter");
Assert.AreEqual (expected.M14, actual.M14, "m14 getter");
Assert.AreEqual (expected.M21, actual.M21, "m21 getter");
Assert.AreEqual (expected.M22, actual.M22, "m22 getter");
Assert.AreEqual (expected.M23, actual.M23, "m23 getter");
Assert.AreEqual (expected.M24, actual.M24, "m24 getter");
Assert.AreEqual (expected.M31, actual.M31, "m31 getter");
Assert.AreEqual (expected.M32, actual.M32, "m32 getter");
Assert.AreEqual (expected.M33, actual.M33, "m33 getter");
Assert.AreEqual (expected.M34, actual.M34, "m34 getter");
Assert.AreEqual (expected.M41, actual.M41, "m41 getter");
Assert.AreEqual (expected.M42, actual.M42, "m42 getter");
Assert.AreEqual (expected.M43, actual.M43, "m43 getter");
Assert.AreEqual (expected.M44, actual.M44, "m44 getter");
var newExpected = GetTestMatrix ();
actual.M11 = newExpected.M11;
actual.M12 = newExpected.M12;
actual.M13 = newExpected.M13;
actual.M14 = newExpected.M14;
actual.M21 = newExpected.M21;
actual.M22 = newExpected.M22;
actual.M23 = newExpected.M23;
actual.M24 = newExpected.M24;
actual.M31 = newExpected.M31;
actual.M32 = newExpected.M32;
actual.M33 = newExpected.M33;
actual.M34 = newExpected.M34;
actual.M41 = newExpected.M41;
actual.M42 = newExpected.M42;
actual.M43 = newExpected.M43;
actual.M44 = newExpected.M44;
Assert.AreEqual (newExpected.M11, actual.M11, "m11 setter");
Assert.AreEqual (newExpected.M12, actual.M12, "m12 setter");
Assert.AreEqual (newExpected.M13, actual.M13, "m13 setter");
Assert.AreEqual (newExpected.M14, actual.M14, "m14 setter");
Assert.AreEqual (newExpected.M21, actual.M21, "m21 setter");
Assert.AreEqual (newExpected.M22, actual.M22, "m22 setter");
Assert.AreEqual (newExpected.M23, actual.M23, "m23 setter");
Assert.AreEqual (newExpected.M24, actual.M24, "m24 setter");
Assert.AreEqual (newExpected.M31, actual.M31, "m31 setter");
Assert.AreEqual (newExpected.M32, actual.M32, "m32 setter");
Assert.AreEqual (newExpected.M33, actual.M33, "m33 setter");
Assert.AreEqual (newExpected.M34, actual.M34, "m34 setter");
Assert.AreEqual (newExpected.M41, actual.M41, "m41 setter");
Assert.AreEqual (newExpected.M42, actual.M42, "m42 setter");
Assert.AreEqual (newExpected.M43, actual.M43, "m43 setter");
Assert.AreEqual (newExpected.M44, actual.M44, "m44 setter");
}
[Test]
public void TransposeInstance ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat4x4) expected;
expected.Transpose ();
actual.Transpose ();
Asserts.AreEqual (expected, actual, "transpose");
}
[Test]
public void TransposeStatic ()
{
var input = GetTestMatrix ();
var inputSimd = (MatrixFloat4x4) input;
var expected = Matrix4.Transpose (input);
var actual = MatrixFloat4x4.Transpose (inputSimd);
Asserts.AreEqual (expected, actual, "transpose");
input = GetTestMatrix ();
inputSimd = (MatrixFloat4x4) input;
Matrix4.Transpose (ref input, out expected);
MatrixFloat4x4.Transpose (ref inputSimd, out actual);
Asserts.AreEqual (expected, actual, "transpose out/ref");
}
[Test]
public void TransposeStatic_ByRef ()
{
var input = GetTestMatrix ();
var inputSimd = (MatrixFloat4x4) input;
Matrix4 expected;
MatrixFloat4x4 actual;
Matrix4.Transpose (ref input, out expected);
MatrixFloat4x4.Transpose (ref inputSimd, out actual);
Asserts.AreEqual (expected, actual, "transpose out/ref");
}
[Test]
public void Multiply ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat4x4) inputL;
var inputSimdR = (MatrixFloat4x4) inputR;
var expected = Matrix4.Mult (inputL, inputR);
var actual = MatrixFloat4x4.Multiply (inputSimdL, inputSimdR);
Asserts.AreEqual (expected, actual, "multiply");
}
[Test]
public void Multiply_ByRef ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat4x4) inputL;
var inputSimdR = (MatrixFloat4x4) inputR;
Matrix4 expected;
MatrixFloat4x4 actual;
Matrix4.Mult (ref inputL, ref inputR, out expected);
MatrixFloat4x4.Multiply (ref inputSimdL, ref inputSimdR, out actual);
Asserts.AreEqual (expected, actual, "multiply");
}
[Test]
public void Multiply_Operator ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat4x4) inputL;
var inputSimdR = (MatrixFloat4x4) inputR;
var expected = inputL * inputR;
var actual = inputSimdL * inputSimdR;
Asserts.AreEqual (expected, actual, "multiply");
}
[Test]
public void Equality_Operator ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat4x4) inputL;
var inputSimdR = (MatrixFloat4x4) inputR;
// matrices are different
Assert.AreEqual (inputL == inputR, inputSimdL == inputSimdR, "inequality");
Assert.IsFalse (inputL == inputR, "inequality 2 expected");
Assert.IsFalse (inputSimdL == inputSimdR, "inequality 2 actual");
inputL = inputR;
inputSimdL = inputSimdR;
// matrices are identical
Assert.AreEqual (inputL == inputR, inputSimdL == inputSimdR, "equality");
Assert.IsTrue (inputL == inputR, "equality 2 expected");
Assert.IsTrue (inputSimdL == inputSimdR, "equality 2 actual");
Assert.IsTrue (MatrixFloat4x4.Identity == (MatrixFloat4x4) Matrix4.Identity, "identity equality");
}
[Test]
public void Inequality_Operator ()
{
var inputL = GetTestMatrix ();
var inputR = GetTestMatrix ();
var inputSimdL = (MatrixFloat4x4) inputL;
var inputSimdR = (MatrixFloat4x4) inputR;
// matrices are different
Assert.AreEqual (inputL != inputR, inputSimdL != inputSimdR, "inequality");
Assert.IsTrue (inputL != inputR, "inequality 2 expected");
Assert.IsTrue (inputSimdL != inputSimdR, "inequality 2 actual");
inputL = inputR;
inputSimdL = inputSimdR;
// matrices are identical
Assert.AreEqual (inputL != inputR, inputSimdL != inputSimdR, "equality");
Assert.IsFalse (inputL != inputR, "equality 2 expected");
Assert.IsFalse (inputSimdL != inputSimdR, "equality 2 actual");
Assert.IsFalse (MatrixFloat4x4.Identity != (MatrixFloat4x4) Matrix4.Identity, "identity equality");
}
[Test]
public void Explicit_Operator_ToMatrix4 ()
{
var expected = (MatrixFloat4x4) GetTestMatrix ();
var actual = (Matrix4) expected;
Asserts.AreEqual (expected, actual, "tomatrix4");
actual = (Matrix4) MatrixFloat4x4.Identity;
Asserts.AreEqual (MatrixFloat4x4.Identity, actual, "tomatrix4 identity");
Asserts.AreEqual (Matrix4.Identity, actual, "tomatrix4 identity2");
}
[Test]
public void Explicit_Operator_FromMatrix4 ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat4x4) expected;
Asserts.AreEqual (expected, actual, "frommatrix4");
actual = (MatrixFloat4x4) Matrix4.Identity;
Asserts.AreEqual (MatrixFloat4x4.Identity, actual, "tomatrix4 identity");
Asserts.AreEqual (Matrix4.Identity, actual, "tomatrix4 identity2");
}
[Test]
public void ToStringTest ()
{
var expected = GetTestMatrix ();
var actual = (MatrixFloat4x4) expected;
Assert.AreEqual (expected.ToString (), actual.ToString (), "tostring");
}
// GetHashCode doesn't have to be identical, so no need to test
[Test]
public void Equals_Object ()
{
var expectedA = GetTestMatrix ();
var expectedB = GetTestMatrix ();
var actualA = (MatrixFloat4x4) expectedA;
var actualB = (MatrixFloat4x4) expectedB;
Assert.IsTrue (actualA.Equals ((object) actualA), "self");
Assert.IsFalse (actualA.Equals ((object) actualB), "other");
Assert.IsFalse (actualA.Equals (null), "null");
Assert.IsFalse (actualA.Equals (expectedA), "other type");
}
[Test]
public void Equals_Matrix ()
{
var expectedA = GetTestMatrix ();
var expectedB = GetTestMatrix ();
var actualA = (MatrixFloat4x4) expectedA;
var actualB = (MatrixFloat4x4) expectedB;
Assert.IsTrue (actualA.Equals (actualA), "self");
Assert.IsFalse (actualA.Equals (actualB), "other");
}
// A collection of test matrices.
//
// I initially tried randomly generating test matrices, but it turns out
// there are accumulative computational differences in the different algorithms
// between Matrix4 and MatrixFloat4x4. Since the differences are accumulative,
// I couldn't find a minimal sensible delta values when comparing
// matrices.
//
// So I just serialized a few matrices that were randomly generated, and
// these have been tested to not produce accumulative computational differences.
//
static Matrix4 [] test_matrices = new [] {
new Matrix4 (0.1532144f, 0.5451511f, 0.2004739f, 0.8351463f, 0.9884372f, 0.1313103f, 0.3327205f, 0.01164342f, 0.6563147f, 0.7923161f, 0.6764754f, 0.07481737f, 0.03239552f, 0.7156482f, 0.6136858f, 0.1864168f),
new Matrix4 (0.7717745f, 0.559364f, 0.00918373f, 0.6579159f, 0.123461f, 0.9993145f, 0.5487496f, 0.2823398f, 0.9710717f, 0.8750508f, 0.472472f, 0.2608089f, 0.5771761f, 0.5617125f, 0.176998f, 0.1271691f),
new Matrix4 (0.2023053f, 0.4701468f, 0.6618567f, 0.7685714f, 0.8561344f, 0.009231919f, 0.6150167f, 0.7542298f, 0.550727f, 0.3625788f, 0.6639862f, 0.5763468f, 0.9717328f, 0.003812184f, 0.985266f, 0.7540002f),
new Matrix4 (9.799572E+08f, 1.64794E+09f, 1.117296E+09f, 1.239858E+09f, 6.389504E+07f, 1.172175E+09f, 1.399567E+09f, 1.187143E+09f, 3.729208E+07f, 5.50313E+08f, 1.847369E+09f, 1.612405E+09f, 1.699488E+08f, 4.952176E+08f, 1.07262E+09f, 2.035059E+09f),
new Matrix4 (1.102396E+09f, 3.082477E+08f, 1.126484E+09f, 5.022931E+08f, 1.966322E+09f, 1.1814E+09f, 8.464673E+08f, 1.940651E+09f, 1.229937E+09f, 1.367379E+09f, 1.900015E+09f, 1.516109E+09f, 2.146064E+09f, 1.870971E+09f, 1.046267E+09f, 1.088363E+09f),
new Matrix4 (2.263112E+08f, 8.79644E+08f, 1.303282E+09f, 1.654159E+09f, 3.705524E+08f, 1.984941E+09f, 2.175935E+07f, 4.633518E+08f, 1.801243E+09f, 1.616996E+09f, 1.620852E+09f, 7291498f, 1.012728E+09f, 2.834145E+08f, 3.5328E+08f, 1.35012E+09f),
new Matrix4 (0.4904693f, 0.841727f, 0.2294401f, 0.5736054f, 0.5406881f, 0.2172498f, 0.1261143f, 0.6736677f, 0.4570194f, 0.9091009f, 0.7669608f, 0.8468134f, 0.01802658f, 0.3850208f, 0.3730424f, 0.2440258f),
new Matrix4 (0.1252193f, 0.08986127f, 0.3407605f, 0.9144857f, 0.340791f, 0.2192288f, 0.5144276f, 0.01813344f, 0.07687104f, 0.7971596f, 0.6393988f, 0.9002907f, 0.1011457f, 0.5047605f, 0.7202546f, 0.07729452f),
new Matrix4 (8.176959E+08f, 1.386156E+09f, 5.956444E+08f, 4.210506E+08f, 1.212676E+09f, 4.131035E+08f, 1.032453E+09f, 2.074689E+08f, 1.536594E+09f, 3.266183E+07f, 5.222072E+08f, 7.923175E+08f, 1.762531E+09f, 7.901702E+08f, 8.1975E+08f, 1.630734E+09f),
new Matrix4 (0.006755914f, 0.07464754f, 0.287938f, 0.3724834f, 0.1496783f, 0.6224982f, 0.7150125f, 0.5554719f, 0.4638171f, 0.4200902f, 0.4867154f, 0.773377f, 0.3558737f, 0.4043404f, 0.04670618f, 0.7695189f),
};
static int counter;
internal static Matrix4 GetTestMatrix ()
{
counter++;
if (counter == test_matrices.Length)
counter = 0;
return test_matrices [counter];
}
}
}

Просмотреть файл

@ -15,6 +15,8 @@ using MonoTouch.UIKit;
using MonoTouch.ObjCRuntime;
#endif
using OpenTK;
using Simd;
using Bindings.Test;
using NUnit.Framework;
namespace MonoTouchFixtures.SpriteKit {
@ -48,9 +50,30 @@ namespace MonoTouchFixtures.SpriteKit {
public void RotationMatrix ()
{
using (var obj = new SKTransformNode ()) {
obj.RotationMatrix = Matrix3.Zero;
var zero = new MatrixFloat3x3 ();
obj.RotationMatrix = zero;
// In Swift, a rotated zero matrice also becomes the identity matrice.
Asserts.AreEqual (Matrix3.Identity, obj.RotationMatrix, "RotationMatrix");
Asserts.AreEqual (MatrixFloat3x3.Identity, obj.RotationMatrix, "RotationMatrix");
// Changing XRotation (or YRotation for that matter), makes the RotationMatrix change too
obj.XRotation = (nfloat) (Math.PI / 2);
var rotatedMatrix = new MatrixFloat3x3 (
1, 0, 0,
0, 0, -1,
0, 1, 0
);
Asserts.AreEqual (rotatedMatrix, obj.RotationMatrix, 0.000001f, "RotationMatrix a");
Asserts.AreEqual (rotatedMatrix, CFunctions.GetMatrixFloat3x3 (obj, "rotationMatrix"), 0.000001f, "RotationMatrix native a");
// Got this matrix after setting both XRotation and YRotation to Pi/2
rotatedMatrix = new MatrixFloat3x3 (
0, 1, 0,
0, 0, -1,
-1, 0, 0
);
obj.RotationMatrix = rotatedMatrix;
Asserts.AreEqual (rotatedMatrix, obj.RotationMatrix, 0.000001f, "RotationMatrix b");
Assert.AreEqual ((nfloat) (Math.PI / 2), obj.XRotation, 0.000001f, "XRotation b");
Assert.AreEqual (0, obj.YRotation, 0.000001f, "YRotation b"); // Setting YRotation changes RotationMatrix, but setting RotationMatrix doesn't change YRotation.
}
}

Просмотреть файл

@ -15,7 +15,11 @@ using MonoTouch.UIKit;
using MonoTouch.ObjCRuntime;
#endif
using OpenTK;
using Simd;
using NUnit.Framework;
#if !TEST_BINDINGS_UNAVAILABLE
using Bindings.Test;
#endif
namespace MonoTouchFixtures.SpriteKit
{
@ -76,6 +80,9 @@ namespace MonoTouchFixtures.SpriteKit
Matrix2 M2;
Matrix3 M3;
Matrix4 M4;
MatrixFloat2x2 M2x2;
MatrixFloat3x3 M3x3;
MatrixFloat4x4 M4x4;
using (var obj = new SKUniform ("name")) {
var M4Zero = new Matrix4 (Vector4.Zero, Vector4.Zero, Vector4.Zero, Vector4.Zero);
@ -97,6 +104,9 @@ namespace MonoTouchFixtures.SpriteKit
M2 = new Matrix2 (1, 2, 3, 4);
M3 = new Matrix3 (1, 2, 3, 4, 5, 6, 7, 8, 9);
M4 = new Matrix4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
M2x2 = (MatrixFloat2x2) M2;
M3x3 = (MatrixFloat3x3) M3;
M4x4 = (MatrixFloat4x4) M4;
obj.TextureValue = texture;
Assert.AreEqual (texture, obj.TextureValue, "2 TextureValue");
@ -123,6 +133,7 @@ namespace MonoTouchFixtures.SpriteKit
Asserts.AreEqual (M4, obj.FloatMatrix4Value, "2 FloatMatrix4Value");
}
bool hasSimdConstructors = TestRuntime.CheckXcodeVersion (8, 0);
using (var obj = new SKUniform ("name", texture)) {
Assert.AreEqual (texture, obj.TextureValue, "3 TextureValue");
}
@ -145,14 +156,109 @@ namespace MonoTouchFixtures.SpriteKit
using (var obj = new SKUniform ("name", M2)) {
Asserts.AreEqual (M2, obj.FloatMatrix2Value, "8 FloatMatrix2Value");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (M2, MatrixFloat2x2.Transpose (CFunctions.GetMatrixFloat2x2 (obj, "matrixFloat2x2Value")), "8b FloatMatrix2Value");
#endif
}
using (var obj = new SKUniform ("name", M3)) {
Asserts.AreEqual (M3, obj.FloatMatrix3Value, "9 FloatMatrix3Value");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (M3, MatrixFloat3x3.Transpose (CFunctions.GetMatrixFloat3x3 (obj, "matrixFloat3x3Value")), "9b FloatMatrix3Value");
#endif
}
using (var obj = new SKUniform ("name", M4)) {
Asserts.AreEqual (M4, obj.FloatMatrix4Value, "10 FloatMatrix4Value");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (M4, MatrixFloat4x4.Transpose (CFunctions.GetMatrixFloat4x4 (obj, "matrixFloat4x4Value")), "10b FloatMatrix4Value");
#endif
}
using (var obj = new SKUniform ("name", M2x2)) {
Asserts.AreEqual (M2x2, obj.MatrixFloat2x2Value, "11 MatrixFloat2x2Value");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (M2x2, CFunctions.GetMatrixFloat2x2 (obj, "matrixFloat2x2Value"), "11b MatrixFloat2x2Value");
#endif
var tmp2 = new MatrixFloat2x2 (9, 8, 7, 6);
obj.MatrixFloat2x2Value = tmp2;
Asserts.AreEqual (tmp2, obj.MatrixFloat2x2Value, "11 MatrixFloat2x2Value second");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (tmp2, CFunctions.GetMatrixFloat2x2 (obj, "matrixFloat2x2Value"), "11b MatrixFloat2x2Value second");
#endif
}
using (var obj = new SKUniform ("name", M3x3)) {
Asserts.AreEqual (M3x3, obj.MatrixFloat3x3Value, "12 MatrixFloat3x3Value");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (M3x3, CFunctions.GetMatrixFloat3x3 (obj, "matrixFloat3x3Value"), "12b MatrixFloat3x3Value");
#endif
var tmp3 = new MatrixFloat3x3 (9, 8, 7, 6, 5, 4, 3, 2, 1);
obj.MatrixFloat3x3Value = tmp3;
Asserts.AreEqual (tmp3, obj.MatrixFloat3x3Value, "12 MatrixFloat3x3Value second");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (tmp3, CFunctions.GetMatrixFloat3x3 (obj, "matrixFloat3x3Value"), "12b MatrixFloat3x3Value second");
#endif
}
using (var obj = new SKUniform ("name", M4x4)) {
Asserts.AreEqual (M4x4, obj.MatrixFloat4x4Value, "13 MatrixFloat4x4Value");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (M4x4, CFunctions.GetMatrixFloat4x4 (obj, "matrixFloat4x4Value"), "13b FloatMatrix4Value");
#endif
var tmp4 = new MatrixFloat4x4 (9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6);
obj.MatrixFloat4x4Value = tmp4;
Asserts.AreEqual (tmp4, obj.MatrixFloat4x4Value, "13 MatrixFloat4x4Value second");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (tmp4, CFunctions.GetMatrixFloat4x4 (obj, "matrixFloat4x4Value"), "13b MatrixFloat4x4Value second");
#endif
}
}
[Test]
public void Create ()
{
var M2x2 = new MatrixFloat2x2 (1, 2, 3, 4);
var M3x3 = new MatrixFloat3x3 (1, 2, 3, 4, 5, 6, 7, 8, 9);
var M4x4 = new MatrixFloat4x4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
using (var obj = SKUniform.Create ("name", M2x2)) {
Asserts.AreEqual (M2x2, obj.MatrixFloat2x2Value, "11 MatrixFloat2x2Value");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (M2x2, CFunctions.GetMatrixFloat2x2 (obj, "matrixFloat2x2Value"), "11b MatrixFloat2x2Value");
#endif
var tmp2 = new MatrixFloat2x2 (9, 8, 7, 6);
obj.MatrixFloat2x2Value = tmp2;
Asserts.AreEqual (tmp2, obj.MatrixFloat2x2Value, "11 MatrixFloat2x2Value second");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (tmp2, CFunctions.GetMatrixFloat2x2 (obj, "matrixFloat2x2Value"), "11b MatrixFloat2x2Value second");
#endif
}
using (var obj = SKUniform.Create ("name", M3x3)) {
Asserts.AreEqual (M3x3, obj.MatrixFloat3x3Value, "12 MatrixFloat3x3Value");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (M3x3, CFunctions.GetMatrixFloat3x3 (obj, "matrixFloat3x3Value"), "12b MatrixFloat3x3Value");
#endif
var tmp3 = new MatrixFloat3x3 (9, 8, 7, 6, 5, 4, 3, 2, 1);
obj.MatrixFloat3x3Value = tmp3;
Asserts.AreEqual (tmp3, obj.MatrixFloat3x3Value, "12 MatrixFloat3x3Value second");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (tmp3, CFunctions.GetMatrixFloat3x3 (obj, "matrixFloat3x3Value"), "12b MatrixFloat3x3Value second");
#endif
}
using (var obj = SKUniform.Create ("name", M4x4)) {
Asserts.AreEqual (M4x4, obj.MatrixFloat4x4Value, "13 MatrixFloat4x4Value");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (M4x4, CFunctions.GetMatrixFloat4x4 (obj, "matrixFloat4x4Value"), "13b FloatMatrix4Value");
#endif
var tmp4 = new MatrixFloat4x4 (9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6);
obj.MatrixFloat4x4Value = tmp4;
Asserts.AreEqual (tmp4, obj.MatrixFloat4x4Value, "13 MatrixFloat4x4Value second");
#if !TEST_BINDINGS_UNAVAILABLE
Asserts.AreEqual (tmp4, CFunctions.GetMatrixFloat4x4 (obj, "matrixFloat4x4Value"), "13b MatrixFloat4x4Value second");
#endif
}
}
}

Просмотреть файл

@ -635,6 +635,7 @@
<Compile Include="UIKit\GraphicsRendererTest.cs" />
<Compile Include="Intents\INIntentResolutionResultTests.cs" />
<Compile Include="MessageUI\MessageComposeViewControllerTest.cs" />
<Compile Include="GameplayKit\GKAgent3DTest.cs" />
<Compile Include="GameplayKit\GKOctreeTests.cs" />
<Compile Include="GameplayKit\GKQuadTreeTests.cs" />
<Compile Include="GameplayKit\GKMeshGraphTests.cs" />
@ -647,6 +648,9 @@
<Compile Include="PassKit\LabeledValueTest.cs" />
<Compile Include="System.Net.Http\MessageHandlers.cs" />
<Compile Include="AVFoundation\PlayerItemVideoOutputTest.cs" />
<Compile Include="Simd\MatrixFloat2x2Test.cs" />
<Compile Include="Simd\MatrixFloat3x3Test.cs" />
<Compile Include="Simd\MatrixFloat4x4Test.cs" />
<Compile Include="mono\ConfigTest.cs" />
<Compile Include="OpenGLES\EAGLContext.cs" />
<Compile Include="CoreText\CTParagraphStyleTests.cs" />
@ -669,6 +673,9 @@
<Compile Include="MetalPerformanceShaders\MPSImageHistogramSpecificationTest.cs" />
<Compile Include="ModelIO\MDLAssetTest.cs" />
<Compile Include="ModelIO\MDLVoxelArrayTest.cs" />
<Compile Include="ModelIO\MDLTransformComponentTest.cs" />
<Compile Include="ModelIO\MDLCameraTest.cs" />
<Compile Include="ModelIO\MDLStereoscopicCameraTest.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<ItemGroup>
@ -722,6 +729,7 @@
<Folder Include="VideoToolbox\" />
<Folder Include="shared\" />
<Folder Include="shared\ObjCRuntime\" />
<Folder Include="Simd\" />
<Folder Include="PushKit\" />
<Folder Include="ModelIO\" />
<Folder Include="GameplayKit\" />

Просмотреть файл

@ -1,7 +1,12 @@
#import <Foundation/Foundation.h>
#include <simd/simd.h>
#include "rename.h"
#if !TARGET_OS_WATCH
#import <ModelIO/ModelIO.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -9,6 +14,16 @@ extern "C" {
int theUltimateAnswer ();
void useZLib ();
void x_get_matrix_float2x2 (id self, const char *sel, float* r0c0, float* r0c1, float* r1c0, float* r1c1);
void x_get_matrix_float3x3 (id self, const char *sel, float* r0c0, float* r0c1, float* r0c2, float* r1c0, float* r1c1, float* r1c2, float* r2c0, float* r2c1, float* r2c2);
void x_get_matrix_float4x4 (id self, const char *sel, float* r0c0, float* r0c1, float* r0c2, float* r0c3, float* r1c0, float* r1c1, float* r1c2, float* r1c3, float* r2c0, float* r2c1, float* r2c2, float* r2c3, float* r3c0, float* r3c1, float* r3c2, float* r3c3);
#if !TARGET_OS_WATCH
void x_mdltransformcomponent_get_local_transform (id<MDLTransformComponent> self, NSTimeInterval time, float* r0c0, float* r0c1, float* r0c2, float* r0c3, float* r1c0, float* r1c1, float* r1c2, float* r1c3, float* r2c0, float* r2c1, float* r2c2, float* r2c3, float* r3c0, float* r3c1, float* r3c2, float* r3c3);
void x_mdltransform_create_global_transform (MDLObject *object, NSTimeInterval time, float* r0c0, float* r0c1, float* r0c2, float* r0c3, float* r1c0, float* r1c1, float* r1c2, float* r1c3, float* r2c0, float* r2c1, float* r2c2, float* r2c3, float* r3c0, float* r3c1, float* r3c2, float* r3c3);
void x_mdltransform_get_rotation_matrix (MDLTransform *self, NSTimeInterval time, float* r0c0, float* r0c1, float* r0c2, float* r0c3, float* r1c0, float* r1c1, float* r1c2, float* r1c3, float* r2c0, float* r2c1, float* r2c2, float* r2c3, float* r3c0, float* r3c1, float* r3c2, float* r3c3);
#endif
/*
* Various structs used in ObjCRegistrarTest
*/

Просмотреть файл

@ -1,6 +1,8 @@
#import <Foundation/Foundation.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/message.h>
#include <zlib.h>
#include "libtest.h"
@ -15,6 +17,198 @@ void useZLib ()
printf ("ZLib version: %s\n", zlibVersion ());
}
typedef matrix_float2x2 (*func_x_get_matrix_float2x2_msgSend) (id self, SEL sel);
void
x_get_matrix_float2x2 (id self, const char *sel,
float* r0c0, float* r0c1,
float* r1c0, float* r1c1)
{
matrix_float2x2 rv;
#if __i386__
IMP msgSend = (IMP) objc_msgSend_stret;
#elif __x86_64__
IMP msgSend = (IMP) objc_msgSend;
#elif __arm64__
IMP msgSend = (IMP) objc_msgSend;
#elif __arm__
IMP msgSend = (IMP) objc_msgSend_stret;
#else
#error unknown architecture
#endif
rv = ((func_x_get_matrix_float2x2_msgSend) msgSend) (self, sel_registerName (sel));
*r0c0 = rv.columns[0][0];
*r0c1 = rv.columns[1][0];
*r1c0 = rv.columns[0][1];
*r1c1 = rv.columns[1][1];
}
typedef matrix_float3x3 (*func_x_get_matrix_float3x3_msgSend) (id self, SEL sel);
void
x_get_matrix_float3x3 (id self, const char *sel,
float* r0c0, float* r0c1, float* r0c2,
float* r1c0, float* r1c1, float* r1c2,
float* r2c0, float* r2c1, float* r2c2)
{
matrix_float3x3 rv;
#if __i386__
IMP msgSend = (IMP) objc_msgSend_stret;
#elif __x86_64__
IMP msgSend = (IMP) objc_msgSend_stret;
#elif __arm64__
IMP msgSend = (IMP) objc_msgSend;
#elif __arm__
IMP msgSend = (IMP) objc_msgSend_stret;
#else
#error unknown architecture
#endif
rv = ((func_x_get_matrix_float3x3_msgSend) msgSend) (self, sel_registerName (sel));
*r0c0 = rv.columns[0][0];
*r0c1 = rv.columns[1][0];
*r0c2 = rv.columns[2][0];
*r1c0 = rv.columns[0][1];
*r1c1 = rv.columns[1][1];
*r1c2 = rv.columns[2][1];
*r2c0 = rv.columns[0][2];
*r2c1 = rv.columns[1][2];
*r2c2 = rv.columns[2][2];
}
typedef matrix_float4x4 (*func_x_get_matrix_float4x4_msgSend) (id self, SEL sel);
void
x_get_matrix_float4x4 (id self, const char *sel,
float* r0c0, float* r0c1, float* r0c2, float* r0c3,
float* r1c0, float* r1c1, float* r1c2, float* r1c3,
float* r2c0, float* r2c1, float* r2c2, float* r2c3,
float* r3c0, float* r3c1, float* r3c2, float* r3c3)
{
matrix_float4x4 rv;
#if __i386__
IMP msgSend = (IMP) objc_msgSend_stret;
#elif __x86_64__
IMP msgSend = (IMP) objc_msgSend_stret;
#elif __arm64__
IMP msgSend = (IMP) objc_msgSend;
#elif __arm__
IMP msgSend = (IMP) objc_msgSend_stret;
#else
#error unknown architecture
#endif
rv = ((func_x_get_matrix_float4x4_msgSend) msgSend) (self, sel_registerName (sel));
*r0c0 = rv.columns[0][0];
*r0c1 = rv.columns[1][0];
*r0c2 = rv.columns[2][0];
*r0c3 = rv.columns[3][0];
*r1c0 = rv.columns[0][1];
*r1c1 = rv.columns[1][1];
*r1c2 = rv.columns[2][1];
*r1c3 = rv.columns[3][1];
*r2c0 = rv.columns[0][2];
*r2c1 = rv.columns[1][2];
*r2c2 = rv.columns[2][2];
*r2c3 = rv.columns[3][2];
*r3c0 = rv.columns[0][3];
*r3c1 = rv.columns[1][3];
*r3c2 = rv.columns[2][3];
*r3c3 = rv.columns[3][3];
}
#if !TARGET_OS_WATCH
void
x_mdltransformcomponent_get_local_transform (id<MDLTransformComponent> self, NSTimeInterval time,
float* r0c0, float* r0c1, float* r0c2, float* r0c3,
float* r1c0, float* r1c1, float* r1c2, float* r1c3,
float* r2c0, float* r2c1, float* r2c2, float* r2c3,
float* r3c0, float* r3c1, float* r3c2, float* r3c3)
{
matrix_float4x4 rv;
rv = [self localTransformAtTime: time];
*r0c0 = rv.columns[0][0];
*r0c1 = rv.columns[1][0];
*r0c2 = rv.columns[2][0];
*r0c3 = rv.columns[3][0];
*r1c0 = rv.columns[0][1];
*r1c1 = rv.columns[1][1];
*r1c2 = rv.columns[2][1];
*r1c3 = rv.columns[3][1];
*r2c0 = rv.columns[0][2];
*r2c1 = rv.columns[1][2];
*r2c2 = rv.columns[2][2];
*r2c3 = rv.columns[3][2];
*r3c0 = rv.columns[0][3];
*r3c1 = rv.columns[1][3];
*r3c2 = rv.columns[2][3];
*r3c3 = rv.columns[3][3];
}
void
x_mdltransform_create_global_transform (MDLObject *object, NSTimeInterval time,
float* r0c0, float* r0c1, float* r0c2, float* r0c3,
float* r1c0, float* r1c1, float* r1c2, float* r1c3,
float* r2c0, float* r2c1, float* r2c2, float* r2c3,
float* r3c0, float* r3c1, float* r3c2, float* r3c3)
{
matrix_float4x4 rv;
rv = [MDLTransform globalTransformWithObject: object atTime: time];
*r0c0 = rv.columns[0][0];
*r0c1 = rv.columns[1][0];
*r0c2 = rv.columns[2][0];
*r0c3 = rv.columns[3][0];
*r1c0 = rv.columns[0][1];
*r1c1 = rv.columns[1][1];
*r1c2 = rv.columns[2][1];
*r1c3 = rv.columns[3][1];
*r2c0 = rv.columns[0][2];
*r2c1 = rv.columns[1][2];
*r2c2 = rv.columns[2][2];
*r2c3 = rv.columns[3][2];
*r3c0 = rv.columns[0][3];
*r3c1 = rv.columns[1][3];
*r3c2 = rv.columns[2][3];
*r3c3 = rv.columns[3][3];
}
void
x_mdltransform_get_rotation_matrix (MDLTransform *self, NSTimeInterval time,
float* r0c0, float* r0c1, float* r0c2, float* r0c3,
float* r1c0, float* r1c1, float* r1c2, float* r1c3,
float* r2c0, float* r2c1, float* r2c2, float* r2c3,
float* r3c0, float* r3c1, float* r3c2, float* r3c3)
{
matrix_float4x4 rv;
rv = [self rotationMatrixAtTime: time];
*r0c0 = rv.columns[0][0];
*r0c1 = rv.columns[1][0];
*r0c2 = rv.columns[2][0];
*r0c3 = rv.columns[3][0];
*r1c0 = rv.columns[0][1];
*r1c1 = rv.columns[1][1];
*r1c2 = rv.columns[2][1];
*r1c3 = rv.columns[3][1];
*r2c0 = rv.columns[0][2];
*r2c1 = rv.columns[1][2];
*r2c2 = rv.columns[2][2];
*r2c3 = rv.columns[3][2];
*r3c0 = rv.columns[0][3];
*r3c1 = rv.columns[1][3];
*r3c2 = rv.columns[2][3];
*r3c3 = rv.columns[3][3];
}
#endif // !TARGET_OS_WATCH
@interface UltimateMachine : NSObject {
}

Просмотреть файл

@ -53,6 +53,12 @@
#define CtorChaining1 object_CtorChaining1
#define ObjCExceptionTest object_ObjCExceptionTest
#define ObjCProtocolClassTest object_ObjCProtocolClassTest
#define x_mdltransform_get_rotation_matrix object_x_mdltransform_get_rotation_matrix
#define x_mdltransformcomponent_get_local_transform object_x_mdltransformcomponent_get_local_transform
#define x_mdltransform_create_global_transform object_x_mdltransform_create_global_transform
#define x_get_matrix_float4x4 object_x_get_matrix_float4x4
#define x_get_matrix_float3x3 object_x_get_matrix_float3x3
#define x_get_matrix_float2x2 object_x_get_matrix_float2x2
#elif PREFIX == 2
#define theUltimateAnswer ar_theUltimateAnswer
#define useZLib ar_useZLib
@ -107,6 +113,12 @@
#define CtorChaining1 ar_CtorChaining1
#define ObjCExceptionTest ar_ObjCExceptionTest
#define ObjCProtocolClassTest ar_ObjCProtocolClassTest
#define x_mdltransform_get_rotation_matrix ar_x_mdltransform_get_rotation_matrix
#define x_mdltransformcomponent_get_local_transform ar_x_mdltransformcomponent_get_local_transform
#define x_mdltransform_create_global_transform ar_x_mdltransform_create_global_transform
#define x_get_matrix_float4x4 ar_x_get_matrix_float4x4
#define x_get_matrix_float3x3 ar_x_get_matrix_float3x3
#define x_get_matrix_float2x2 ar_x_get_matrix_float2x2
#else
// keep original names
#endif

Просмотреть файл

@ -17,7 +17,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\x86\Debug</OutputPath>
<DefineConstants>__UNIFIED__;DEBUG;MONOMAC;XAMCORE_2_0</DefineConstants>
<DefineConstants>__UNIFIED__;DEBUG;MONOMAC;XAMCORE_2_0;TEST_BINDINGS_UNAVAILABLE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<EnableCodeSigning>false</EnableCodeSigning>
@ -38,7 +38,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\x86\Release</OutputPath>
<DefineConstants>__UNIFIED__;MONOMAC;XAMCORE_2_0</DefineConstants>
<DefineConstants>__UNIFIED__;MONOMAC;XAMCORE_2_0;TEST_BINDINGS_UNAVAILABLE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<EnableCodeSigning>false</EnableCodeSigning>

Просмотреть файл

@ -248,5 +248,47 @@ namespace Extrospection {
{
return self.Selector.ToString () ?? (self.IsPropertyAccessor ? self.Name : null);
}
public static bool IsObsolete (this ICustomAttributeProvider provider)
{
if (provider.HasCustomAttributes) {
foreach (var attrib in provider.CustomAttributes) {
var attribType = attrib.Constructor.DeclaringType;
if (attribType.Namespace == "System" && attribType.Name == "ObsoleteAttribute")
return true;
}
}
// If we're a property accessor, check the property as well.
var prop = FindProperty (provider as MethodReference);
if (prop != null)
return IsObsolete (prop);
return false;
}
public static PropertyDefinition FindProperty (this MethodReference method)
{
var def = method?.Resolve ();
if (def == null)
return null;
if (!def.IsSpecialName)
return null;
if (!def.DeclaringType.HasProperties)
return null;
if (!method.Name.StartsWith ("get_", StringComparison.Ordinal) && !method.Name.StartsWith ("set_", StringComparison.Ordinal))
return null;
var propName = method.Name.Substring (4);
foreach (var prop in def.DeclaringType.Properties) {
if (prop.Name == propName)
return prop;
}
return null;
}
}
}

Просмотреть файл

@ -25,6 +25,7 @@ namespace Extrospection {
new ObjCInterfaceCheck (),
new ObjCProtocolCheck (),
new SelectorCheck (),
new SimdCheck (),
// new ListNative (), // for debug
};
foreach (var assemblyName in assemblyNames) {

Просмотреть файл

@ -0,0 +1,385 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Clang.Ast;
namespace Extrospection
{
class SimdCheck : BaseVisitor
{
bool very_strict = false;
bool strict = false;
// A dictionary of native type -> managed type mapping.
class NativeSimdInfo
{
public string Managed;
public string InvalidManaged;
}
static Dictionary<string, NativeSimdInfo> type_mapping = new Dictionary<string, NativeSimdInfo> () {
{ "matrix_double2x2", new NativeSimdInfo { Managed ="MatrixDouble2x2", InvalidManaged = "Matrix2d" }},
{ "matrix_double3x3", new NativeSimdInfo { Managed = "MatrixDouble3x3", InvalidManaged = "Matrix3d" }},
{ "matrix_double4x4", new NativeSimdInfo { Managed = "MatrixDouble4x4", InvalidManaged = "Matrix4d" }},
{ "matrix_float2x2", new NativeSimdInfo { Managed = "MatrixFloat2x2", InvalidManaged = "Matrix2", }},
{ "matrix_float3x3", new NativeSimdInfo { Managed = "MatrixFloat3x3", InvalidManaged = "Matrix3", }},
{ "matrix_float4x3", new NativeSimdInfo { Managed = "MatrixFloat4x3", }},
{ "matrix_float4x4", new NativeSimdInfo { Managed = "MatrixFloat4x4", InvalidManaged = "Matrix4", }},
{ "simd_quatd", new NativeSimdInfo { Managed = "Quaternion4d", }},
{ "simd_quatf", new NativeSimdInfo { Managed = "Quaternion4", }},
{ "vector_double2", new NativeSimdInfo { Managed = "Vector2d", }},
{ "vector_double3", new NativeSimdInfo { Managed = "Vector3d", }},
{ "vector_double4", new NativeSimdInfo { Managed = "Vector4d", }},
{ "vector_float2", new NativeSimdInfo { Managed = "Vector2", }},
{ "vector_float3", new NativeSimdInfo { Managed = "Vector3", }},
{ "vector_float4", new NativeSimdInfo { Managed = "Vector4", }},
{ "vector_int2", new NativeSimdInfo { Managed = "Vector2i", }},
{ "vector_int3", new NativeSimdInfo { Managed = "Vector3i", }},
{ "vector_int4", new NativeSimdInfo { Managed = "Vector4i", }},
{ "vector_uint2", new NativeSimdInfo { Managed = "Vector2i", }},
{ "vector_uint3", new NativeSimdInfo { Managed = "Vector3i", }},
{ "vector_uint4", new NativeSimdInfo { Managed = "Vector4i", }},
// simd_floatX is typedefed to vector_floatX
{ "simd_float2", new NativeSimdInfo { Managed = "Vector2" }},
{ "simd_float3", new NativeSimdInfo { Managed = "Vector3" }},
{ "simd_float4", new NativeSimdInfo { Managed = "Vector4" }},
{ "simd_float4x4", new NativeSimdInfo { Managed = "MatrixFloat4x4", InvalidManaged = "Matrix4" }},
// The native definition is two 'vector_float2' fields.
// The managed definition matches this (two 'Vector2' fields), and should work fine.
{ "GKQuad", new NativeSimdInfo { Managed = "GKQuad" }},
// The native definition is two 'vector_float3' fields.
// In this case each element uses 16 bytes (4 floats) due to padding.
// The managed definition is two Vector3 fields, and does *not*
// match the native definition (missing the padding).
// It still works because we're marshalling this struct manually ([MarshalDirective]).
{ "GKBox", new NativeSimdInfo { Managed = "GKBox", }},
// The native definition is 'vector_float3 points[3]' - an array of three vector_float3.
// In this case each element uses 16 bytes (4 floats) due to padding.
// The managed definition is just an array of Vector3, but luckily
// it's a private field, so we might be able to improve this later. Right now we're marshalling
// this struct manually ([MarshalDirective]), so managed code should get correct
// results.
{ "GKTriangle", new NativeSimdInfo { Managed = "GKTriangle", }},
// This is a 'vector_int4, represented by a Vector4i in managed code,
// which means it's matching the native definition.
{ "MDLVoxelIndex", new NativeSimdInfo { Managed = "MDLVoxelIndex" }},
// In managed code this is struct of two Vector4, so it's matching the native definition.
{ "MDLVoxelIndexExtent", new NativeSimdInfo { Managed = "MDLVoxelIndexExtent" }},
// In managed code this is a struct of two Vector3, so it's *not* matching
// the native definition. However, since we're manually marshalling this type
// (using [MarshalDirective]), managed code doesn't get incorrect results.
{ "MDLAxisAlignedBoundingBox", new NativeSimdInfo { Managed = "MDLAxisAlignedBoundingBox", }},
// The managed definition is identical to the native definition
{ "MPSImageHistogramInfo", new NativeSimdInfo { Managed = "MPSImageHistogramInfo" }},
};
static Dictionary<string, bool> managed_simd_types; // bool: invalid_for_simd
static SimdCheck ()
{
managed_simd_types = new Dictionary<string, bool> ();
foreach (var kvp in type_mapping) {
managed_simd_types [kvp.Value.Managed] = false;
if (!string.IsNullOrEmpty (kvp.Value.InvalidManaged))
managed_simd_types [kvp.Value.InvalidManaged] = true;
}
}
class ManagedSimdInfo
{
public MethodDefinition Method;
public bool ContainsInvalidMappingForSimd;
}
Dictionary<string, ManagedSimdInfo> managed_methods = new Dictionary<string, ManagedSimdInfo> ();
public override void VisitManagedMethod (MethodDefinition method)
{
var type = method.DeclaringType;
if (!type.IsNested && type.IsNotPublic)
return;
if (type.IsNested && (type.IsNestedPrivate || type.IsNestedAssembly || type.IsNestedFamilyAndAssembly))
return;
if (method.IsPrivate || method.IsAssembly || method.IsFamilyAndAssembly)
return; // Don't care about non-visible types
if (type.Namespace == "Simd" || type.Namespace.StartsWith ("OpenTK", StringComparison.Ordinal))
return; // We're assuming everything in the Simd and OpenTK namespaces can be ignored (the former because it's correctly written, the latter because it doesn't map to native simd types).
if (method.HasCustomAttributes && method.CustomAttributes.Where ((v) => v.Constructor.DeclaringType.Name == "ExtensionAttribute").Any ())
return; // Extension methods can't be mapped.
var invalid_simd_type = false;
var contains_simd_types = ContainsSimdTypes (method, ref invalid_simd_type);
var key = method.GetName ();
if (key == null) {
if (method.IsObsolete ())
return; // Don't care about obsolete API.
if (contains_simd_types && very_strict) {
// We can't map this method to a native function.
Console.WriteLine ($"!missing-simd-native-signature! {method}");
}
return;
}
ManagedSimdInfo existing;
if (managed_methods.TryGetValue (key, out existing)) {
if (very_strict)
Console.WriteLine ($"!duplicate-type-mapping! same key '{key}' for both '{existing.Method}' and '{method}'");
} else {
managed_methods [key] = new ManagedSimdInfo {
Method = method, ContainsInvalidMappingForSimd = invalid_simd_type
};
}
}
bool ContainsSimdTypes (MethodDefinition method, ref bool invalid_for_simd)
{
if (IsSimdType (method.ReturnType, ref invalid_for_simd))
return true;
if (method.HasParameters) {
foreach (var param in method.Parameters)
if (IsSimdType (param.ParameterType, ref invalid_for_simd))
return true;
}
return false;
}
bool IsSimdType (TypeReference td, ref bool invalid_for_simd)
{
return managed_simd_types.TryGetValue (td.Name, out invalid_for_simd);
}
bool ContainsSimdTypes (ObjCMethodDecl decl, ref string simd_type, ref bool requires_marshal_directive)
{
if (IsSimdType (decl.ReturnQualType, ref simd_type, ref requires_marshal_directive))
return true;
var is_simd_type = false;
foreach (var param in decl.Parameters)
is_simd_type |= IsSimdType (param.QualType, ref simd_type, ref requires_marshal_directive);
return is_simd_type;
}
bool IsExtVector (QualType type, ref string simd_type)
{
var rv = false;
var t = type.CanonicalQualType.Type;
// Unpoint the type
var pointerType = t as Clang.Ast.PointerType;
if (pointerType != null)
t = pointerType.PointeeQualType.Type;
if (t.Kind == TypeKind.ExtVector) {
rv = true;
} else {
var r = (t as RecordType)?.Decl;
if (r != null) {
foreach (var f in r.Fields) {
var qt = f.QualType.CanonicalQualType.Type;
if (qt.Kind == TypeKind.ExtVector) {
rv = true;
break;
}
var at = qt as ConstantArrayType;
if (at != null) {
if (at.ElementType.Type.Kind == TypeKind.ExtVector) {
rv = true;
break;
}
}
}
}
}
var typeName = type.ToString ();
if (!rv && typeName.Contains ("simd"))
Console.WriteLine ($"!unknown-simd-type! Could not detect that {typeName} is a Simd type, but its name contains 'simd'. Something needs fixing in SimdCheck.cs");
if (rv)
simd_type = typeName;
return rv;
}
bool IsSimdType (QualType type, ref string simd_type, ref bool requires_marshal_directive)
{
var str = Undecorate (type.ToString ());
if (type_mapping.TryGetValue (str, out var info)) {
requires_marshal_directive = true;
simd_type = str;
return true;
}
if (IsExtVector (type, ref simd_type))
Console.WriteLine ($"!unknown-simd-type-mapping! The Simd type {simd_type} does not have a mapping to a managed type. Please add one in SimdCheck.cs");
return false;
}
string Undecorate (string native_name)
{
if (native_name.StartsWith ("const ", StringComparison.Ordinal))
return Undecorate (native_name.Substring ("const ".Length));
if (native_name.StartsWith ("struct ", StringComparison.Ordinal))
return Undecorate (native_name.Substring ("struct ".Length));
const string _Nonnull = " _Nonnull";
if (native_name.EndsWith (_Nonnull, StringComparison.Ordinal))
return Undecorate (native_name.Substring (0, native_name.Length - _Nonnull.Length));
const string _Nullable = " _Nullable";
if (native_name.EndsWith (_Nullable, StringComparison.Ordinal))
return Undecorate (native_name.Substring (0, native_name.Length - _Nullable.Length));
const string _star = " *";
if (native_name.EndsWith (_star, StringComparison.Ordinal))
return Undecorate (native_name.Substring (0, native_name.Length - _star.Length));
return native_name;
}
bool HasMarshalDirective (ICustomAttributeProvider provider)
{
if (provider?.HasCustomAttributes != true)
return false;
foreach (var ca in provider.CustomAttributes)
if (ca.Constructor.DeclaringType.Name == "MarshalDirective")
return true;
return false;
}
void CheckMarshalDirective (MethodDefinition method, string simd_type)
{
if (!method.HasBody)
return;
if (method.IsObsolete ())
return;
// The [MarshalDirective] attribute isn't copied to the generated code,
// so instead apply some heuristics and detect calls to the xamarin_simd__ P/Invoke,
// and if there are any, then assume the method binding has a [MarshalDirective].
var body = method.Body;
var anyCalls = false;
foreach (var i in body.Instructions) {
switch (i.OpCode.Code) {
case Mono.Cecil.Cil.Code.Call:
case Mono.Cecil.Cil.Code.Calli:
case Mono.Cecil.Cil.Code.Callvirt:
var mr = i.Operand as MethodReference;
if (mr != null) {
if (mr.Name.StartsWith ("xamarin_simd__", StringComparison.Ordinal))
return;
if (mr.Name.StartsWith ("xamarin_vector_float3__", StringComparison.Ordinal))
return;
}
anyCalls = true;
break;
default:
break;
}
}
// If the method doesn't call anywhere, it can't be broken.
// For instance if the method just throws an exception.
if (!anyCalls)
return;
Console.WriteLine ($"!wrong-simd-missing-marshaldirective! {method}: simd type: {simd_type}");
}
public override void VisitObjCMethodDecl (ObjCMethodDecl decl, VisitKind visitKind)
{
if (visitKind != VisitKind.Enter)
return;
// don't process methods (or types) that are unavailable for the current platform
if (!decl.IsAvailable () || !(decl.DeclContext as Decl).IsAvailable ())
return;
var simd_type = string.Empty;
var requires_marshal_directive = false;
var native_simd = ContainsSimdTypes (decl, ref simd_type, ref requires_marshal_directive);
ManagedSimdInfo info;
managed_methods.TryGetValue (decl.GetName (), out info);
var method = info?.Method;
if (!native_simd) {
if (method != null) {
// The managed method uses types that were incorrectly used in place of the correct Simd types,
// but the native method doesn't use the native Simd types. This means the binding is correct.
} else {
// Neither the managed nor the native method have anything to do with Simd types.
}
return;
}
if (method == null) {
// Could not map the native method to a managed method.
// This needs investigation, to see why the native method couldn't be mapped.
// Check if this is new API, in which case it probably couldn't be mapped because we haven't bound it.
var is_new = false;
var attrs = decl.Attrs.ToList ();
var parentClass = decl.DeclContext as Decl;
if (parentClass != null)
attrs.AddRange (parentClass.Attrs);
foreach (var attr in attrs) {
var av_attr = attr as AvailabilityAttr;
if (av_attr == null)
continue;
if (av_attr.Platform.Name != "ios")
continue;
if (av_attr.Introduced.Major >= 11) {
is_new = true;
break;
}
}
if (is_new && !very_strict)
return;
if (!strict)
return;
Console.WriteLine ($"!missing-simd-managed-method! {decl}: could not find a managed method for the native method {decl.GetName ()} (selector: {decl.Selector}). Found the simd type '{simd_type}' in the native signature.");
return;
}
if (!info.ContainsInvalidMappingForSimd) {
// The managed method does not have any types that are incorrect for Simd.
if (requires_marshal_directive)
CheckMarshalDirective (method, simd_type);
return;
}
if (method.IsObsolete ()) {
// We have a potentially broken managed method, but it's obsolete. That's fine.
return;
}
if (requires_marshal_directive)
CheckMarshalDirective (method, simd_type);
// We have a potentially broken managed method. This needs fixing/investigation.
Console.WriteLine ($"!unknown-simd-type-in-signature! {method}: the native signature has a simd type ({simd_type}), while the corresponding managed method is using an incorrect (non-simd) type.");
}
}
}

Просмотреть файл

@ -1,3 +1,8 @@
# ARKit
## This method is manually bound.
!simd-missing-marshaldirective! System.IntPtr ARKit.ARPointCloud::GetRawPoints(): simd type: vector_float3
# AVFoundation
## We only bind "finished" as we cannot use [Bind] here as it would break compatibility with iOS 6.x
@ -68,7 +73,6 @@
## part of category GKScore_Deprecated
!missing-selector! GKScore::playerID not bound
# Intents
## not exposed by our API (better use the OS version)
@ -201,7 +205,6 @@
!incorrect-protocol-member! MDLMeshBufferZone::allocator is REQUIRED and should be abstract
!incorrect-protocol-member! MDLMeshBufferZone::capacity is REQUIRED and should be abstract
# Security
## part of mscorlib.dll -> mcs/class/corlib/CommonCrypto/CommonCrypto.cs to implement RNGCryptoServiceProvider

Просмотреть файл

@ -71,6 +71,7 @@
<Compile Include="FieldCheck.cs" />
<Compile Include="SelectorCheck.cs" />
<Compile Include="DesignatedInitializerCheck.cs" />
<Compile Include="SimdCheck.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Target Name="AfterBuild">