Browse Source

add Matrix4x4 as attribute

Bert Temme 2 years ago
parent
commit
c24b072f43

+ 36 - 1
src/SharpGLTF.Cesium/BinaryTable.cs

@@ -41,6 +41,10 @@ namespace SharpGLTF
             {
                 return Vector4ToBytes(values);
             }
+            else if(typeof(T) == typeof(Matrix4x4))
+            {
+                return Matrix4x4ToBytes(values);
+            }
             else if (typeof(T).IsPrimitive)
             {
                 if (typeof(T) == typeof(bool))
@@ -58,12 +62,43 @@ namespace SharpGLTF
             }
             else
             {
-                // other types (like mat2, mat3, mat4) are not implemented
+                // other types (like datetime, mat2, mat3) are not implemented
                 // see https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata#binary-table-format
                 throw new NotImplementedException();
             }
         }
 
+        private static byte[] Matrix4x4ToBytes<T>(IReadOnlyList<T> values)
+        {
+            var result = new byte[values.Count * 64];
+
+            for (int i = 0; i < values.Count; i++)
+            {
+                var mat = (Matrix4x4)(object)values[i];
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M11), 0, result, i * 64, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M12), 0, result, i * 64 + 4, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M13), 0, result, i * 64 + 8, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M14), 0, result, i * 64 + 12, 4);
+
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M21), 0, result, i * 64 + 16, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M22), 0, result, i * 64 + 20, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M23), 0, result, i * 64 + 24, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M24), 0, result, i * 64 + 28, 4);
+
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M31), 0, result, i * 64 + 32, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M32), 0, result, i * 64 + 36, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M33), 0, result, i * 64 + 40, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M34), 0, result, i * 64 + 44, 4);
+
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M41), 0, result, i * 64 + 48, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M42), 0, result, i * 64 + 52, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M43), 0, result, i * 64 + 56, 4);
+                Buffer.BlockCopy(BitConverter.GetBytes(mat.M44), 0, result, i * 64 + 60, 4);
+            }
+
+            return result;
+        }
+
         private static byte[] Vector2ToBytes<T>(IReadOnlyList<T> values)
         {
             var result = new byte[values.Count * 8];

+ 15 - 0
tests/SharpGLTF.Cesium.Tests/BinaryTableTests.cs

@@ -37,6 +37,21 @@ namespace SharpGLTF
             Assert.That(bytes.Length, Is.EqualTo(BinaryTable.GetSize<System.Numerics.Vector4>() * 2));
         }
 
+        [Test]
+        public void ConvertMatrix4x4ToBytes()
+        {
+            // create list of identity matrices
+            var values = new List<System.Numerics.Matrix4x4>();
+            values.Add(System.Numerics.Matrix4x4.Identity);
+
+            // convert to bytes
+            var bytes = BinaryTable.GetBytes(values);
+
+            // check size
+            Assert.That(bytes.Length, Is.EqualTo(BinaryTable.GetSize<System.Numerics.Matrix4x4>()));
+
+        }
+
         [Test]
         public void TestGetArrayOffset()
         {

+ 15 - 0
tests/SharpGLTF.Cesium.Tests/ExtStructuralMetadataTests.cs

@@ -2,6 +2,7 @@
 using SharpGLTF.Geometry;
 using SharpGLTF.Geometry.VertexTypes;
 using SharpGLTF.Materials;
+using SharpGLTF.Memory;
 using SharpGLTF.Scenes;
 using SharpGLTF.Schema2;
 using SharpGLTF.Validation;
@@ -59,6 +60,14 @@ namespace SharpGLTF.Cesium
 
             exampleMetadataClass.Properties.Add("example_VEC3_FLOAT32", vector3Property);
 
+            var matrix4x4Property = new ClassProperty();
+            matrix4x4Property.Name = "Example MAT4 FLOAT32 property";
+            matrix4x4Property.Description = "An example property, with type MAT4, with component type FLOAT32";
+            matrix4x4Property.Type = ElementType.MAT4;
+            matrix4x4Property.ComponentType = DataType.FLOAT32;
+
+            exampleMetadataClass.Properties.Add("example_MAT4_FLOAT32", matrix4x4Property);
+
             schema.Classes.Add("exampleMetadataClass", exampleMetadataClass);
 
             var vector3List = new List<Vector3>() { new Vector3(3, 3.0999999046325684f, 3.200000047683716f) };
@@ -69,6 +78,12 @@ namespace SharpGLTF.Cesium
 
             examplePropertyTable.Properties.Add("example_VEC3_FLOAT32", vector3PropertyTableProperty);
 
+            var matrix4x4List = new List<Matrix4x4>() { Matrix4x4.Identity };
+
+            var matrix4x4PropertyTableProperty = model.GetPropertyTableProperty(matrix4x4List);
+
+            examplePropertyTable.Properties.Add("example_MAT4_FLOAT32", matrix4x4PropertyTableProperty);
+            
             model.SetPropertyTable(examplePropertyTable, schema);
 
             var ctx = new ValidationResult(model, ValidationMode.Strict, true);