Browse Source

Refactored Accessor.Type to use internally a string instead of an enumeration, to support custom types like MAT4x3

Vicente Penades 4 years ago
parent
commit
0a1da6761f

+ 14 - 4
build/SharpGLTF.CodeGen/Program.cs

@@ -92,11 +92,21 @@ namespace SharpGLTF
                 .SetDefaultValue("Vector4.One")
                 .SetDefaultValue("Vector4.One")
                 .SetItemsRange(0);
                 .SetItemsRange(0);
 
 
-            var tex1 = ctx1.FindEnum("LINEAR-NEAREST");
-            tex1.SetValue("DEFAULT",0);
+            ctx1.FindEnum("LINEAR-NEAREST")
+                .SetValue("DEFAULT",0);
 
 
-            var tex2 = ctx1.FindEnum("LINEAR-LINEAR_MIPMAP_LINEAR-LINEAR_MIPMAP_NEAREST-NEAREST-NEAREST_MIPMAP_LINEAR-NEAREST_MIPMAP_NEAREST");
-            tex2.SetValue("DEFAULT", 0);
+            ctx1.FindEnum("LINEAR-LINEAR_MIPMAP_LINEAR-LINEAR_MIPMAP_NEAREST-NEAREST-NEAREST_MIPMAP_LINEAR-NEAREST_MIPMAP_NEAREST")
+                .SetValue("DEFAULT", 0);
+
+            // Accessor.type is declared as AnyOfEnum, but also as a STRING,
+            // which can be used by extensions to store non standard values like MAT4x3
+            ctx1.FindClass("Accessor")
+                .GetField("type").SetDataType(typeof(string), true);
+
+            // Since DimensionType can have additional values other than the ones defined by the schema
+            // we need a "special" value to define it
+            ctx1.FindEnum("MAT2-MAT3-MAT4-SCALAR-VEC2-VEC3-VEC4")
+                .SetValue("CUSTOM", 0);
 
 
             ProcessSchema("gltf.g", ctx1);
             ProcessSchema("gltf.g", ctx1);
         }
         }

+ 2 - 0
build/SharpGLTF.CodeGen/SchemaReflection/SchemaTypes.cs

@@ -263,6 +263,8 @@ namespace SharpGLTF.SchemaReflection
 
 
         public FieldInfo SetDataType(Type type, bool isNullable)
         public FieldInfo SetDataType(Type type, bool isNullable)
         {
         {
+            if (type == typeof(string)) { _FieldType = DeclaringClass.Owner.UseString(); return this; }
+
             _FieldType = DeclaringClass.Owner.UseBlittable(type.GetTypeInfo(), isNullable);
             _FieldType = DeclaringClass.Owner.UseBlittable(type.GetTypeInfo(), isNullable);
             return this;
             return this;
         }
         }

+ 14 - 0
src/SharpGLTF.Core/Memory/MemoryAccessor.cs

@@ -462,6 +462,20 @@ namespace SharpGLTF.Memory
             return new QuaternionArray(_Data, _Slicer.ByteOffset, _Slicer.ItemsCount, _Slicer.ByteStride, _Slicer.Encoding, _Slicer.Normalized);
             return new QuaternionArray(_Data, _Slicer.ByteOffset, _Slicer.ItemsCount, _Slicer.ByteStride, _Slicer.Encoding, _Slicer.Normalized);
         }
         }
 
 
+        public Matrix2x2Array AsMatrix2x2Array()
+        {
+            Guard.IsTrue(_Slicer.IsValidVertexAttribute, nameof(_Slicer));
+            Guard.IsTrue(_Slicer.Dimensions == DIMENSIONS.MAT2, nameof(_Slicer));
+            return new Matrix2x2Array(_Data, _Slicer.ByteOffset, _Slicer.ItemsCount, _Slicer.ByteStride, _Slicer.Encoding, _Slicer.Normalized);
+        }
+
+        public Matrix3x3Array AsMatrix3x3Array()
+        {
+            Guard.IsTrue(_Slicer.IsValidVertexAttribute, nameof(_Slicer));
+            Guard.IsTrue(_Slicer.Dimensions == DIMENSIONS.MAT3, nameof(_Slicer));
+            return new Matrix3x3Array(_Data, _Slicer.ByteOffset, _Slicer.ItemsCount, _Slicer.ByteStride, _Slicer.Encoding, _Slicer.Normalized);
+        }
+
         public Matrix4x4Array AsMatrix4x4Array()
         public Matrix4x4Array AsMatrix4x4Array()
         {
         {
             Guard.IsTrue(_Slicer.IsValidVertexAttribute, nameof(_Slicer));
             Guard.IsTrue(_Slicer.IsValidVertexAttribute, nameof(_Slicer));

+ 4 - 3
src/SharpGLTF.Core/Schema2/Generated/gltf.g.cs

@@ -64,6 +64,7 @@ namespace SharpGLTF.Schema2
 		MAT2,
 		MAT2,
 		MAT3,
 		MAT3,
 		MAT4,
 		MAT4,
+		CUSTOM,
 	}
 	}
 
 
 
 
@@ -331,7 +332,7 @@ namespace SharpGLTF.Schema2
 		
 		
 		private AccessorSparse _sparse;
 		private AccessorSparse _sparse;
 		
 		
-		private DimensionType _type;
+		private String _type;
 		
 		
 	
 	
 		protected override void SerializeProperties(Utf8JsonWriter writer)
 		protected override void SerializeProperties(Utf8JsonWriter writer)
@@ -345,7 +346,7 @@ namespace SharpGLTF.Schema2
 			SerializeProperty(writer, "min", _min, _minMinItems);
 			SerializeProperty(writer, "min", _min, _minMinItems);
 			SerializeProperty(writer, "normalized", _normalized, _normalizedDefault);
 			SerializeProperty(writer, "normalized", _normalized, _normalizedDefault);
 			SerializePropertyObject(writer, "sparse", _sparse);
 			SerializePropertyObject(writer, "sparse", _sparse);
-			SerializePropertyEnumSymbol<DimensionType>(writer, "type", _type);
+			SerializeProperty(writer, "type", _type);
 		}
 		}
 	
 	
 		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
 		protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
@@ -360,7 +361,7 @@ namespace SharpGLTF.Schema2
 				case "min": DeserializePropertyList<Double>(ref reader, _min); break;
 				case "min": DeserializePropertyList<Double>(ref reader, _min); break;
 				case "normalized": _normalized = DeserializePropertyValue<Boolean?>(ref reader); break;
 				case "normalized": _normalized = DeserializePropertyValue<Boolean?>(ref reader); break;
 				case "sparse": _sparse = DeserializePropertyValue<AccessorSparse>(ref reader); break;
 				case "sparse": _sparse = DeserializePropertyValue<AccessorSparse>(ref reader); break;
-				case "type": _type = DeserializePropertyValue<DimensionType>(ref reader); break;
+				case "type": _type = DeserializePropertyValue<String>(ref reader); break;
 				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 				default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
 			}
 			}
 		}
 		}

+ 25 - 10
src/SharpGLTF.Core/Schema2/gltf.Accessors.cs

@@ -41,49 +41,54 @@ namespace SharpGLTF.Schema2
         /// <summary>
         /// <summary>
         /// Gets the <see cref="BufferView"/> buffer that contains the items as an encoded byte array.
         /// Gets the <see cref="BufferView"/> buffer that contains the items as an encoded byte array.
         /// </summary>
         /// </summary>
-        public BufferView SourceBufferView      => this._bufferView.HasValue ? this.LogicalParent.LogicalBufferViews[this._bufferView.Value] : null;
+        public BufferView SourceBufferView => this._bufferView.HasValue ? this.LogicalParent.LogicalBufferViews[this._bufferView.Value] : null;
 
 
         /// <summary>
         /// <summary>
         /// Gets the number of items.
         /// Gets the number of items.
         /// </summary>
         /// </summary>
-        public int Count                        => this._count;
+        public int Count => this._count;
 
 
         /// <summary>
         /// <summary>
         /// Gets the starting byte offset within <see cref="SourceBufferView"/>.
         /// Gets the starting byte offset within <see cref="SourceBufferView"/>.
         /// </summary>
         /// </summary>
-        public int ByteOffset                   => this._byteOffset.AsValue(0);
+        public int ByteOffset => this._byteOffset.AsValue(0);
 
 
         /// <summary>
         /// <summary>
         /// Gets the number of bytes, starting at <see cref="ByteOffset"/> use by this <see cref="Accessor"/>
         /// Gets the number of bytes, starting at <see cref="ByteOffset"/> use by this <see cref="Accessor"/>
         /// </summary>
         /// </summary>
-        public int ByteLength                   => SourceBufferView.GetAccessorByteLength(Format, Count);
+        public int ByteLength => SourceBufferView.GetAccessorByteLength(Format, Count);
 
 
         /// <summary>
         /// <summary>
         /// Gets the <see cref="DimensionType"/> of an item.
         /// Gets the <see cref="DimensionType"/> of an item.
         /// </summary>
         /// </summary>
-        public DimensionType Dimensions           => this._type;
+        public DimensionType Dimensions => _GetDimensions();
 
 
         /// <summary>
         /// <summary>
         /// Gets the <see cref="EncodingType"/> of an item.
         /// Gets the <see cref="EncodingType"/> of an item.
         /// </summary>
         /// </summary>
-        public EncodingType Encoding           => this._componentType;
+        public EncodingType Encoding => this._componentType;
 
 
         /// <summary>
         /// <summary>
         /// Gets a value indicating whether the items values are normalized.
         /// Gets a value indicating whether the items values are normalized.
         /// </summary>
         /// </summary>
-        public Boolean Normalized               => this._normalized.AsValue(false);
+        public Boolean Normalized => this._normalized.AsValue(false);
 
 
         /// <summary>
         /// <summary>
         /// Gets a value indicating whether this <see cref="Accessor"/> has a sparse structure.
         /// Gets a value indicating whether this <see cref="Accessor"/> has a sparse structure.
         /// </summary>
         /// </summary>
-        public Boolean IsSparse                 => this._sparse != null;
+        public Boolean IsSparse => this._sparse != null;
 
 
-        public AttributeFormat Format => new AttributeFormat(_type, _componentType, this._normalized.AsValue(false));
+        public AttributeFormat Format => new AttributeFormat(this.Dimensions, _componentType, this._normalized.AsValue(false));
 
 
         #endregion
         #endregion
 
 
         #region API
         #region API
 
 
+        private DimensionType _GetDimensions()
+        {
+            return Enum.TryParse<DimensionType>(this._type, out var r) ? r : DimensionType.CUSTOM;
+        }
+
         internal MemoryAccessor _GetMemoryAccessor(string name = null)
         internal MemoryAccessor _GetMemoryAccessor(string name = null)
         {
         {
             var view = SourceBufferView;
             var view = SourceBufferView;
@@ -165,13 +170,23 @@ namespace SharpGLTF.Schema2
             this._byteOffset = bufferByteOffset.AsNullable(_byteOffsetDefault, _byteOffsetMinimum, int.MaxValue);
             this._byteOffset = bufferByteOffset.AsNullable(_byteOffsetDefault, _byteOffsetMinimum, int.MaxValue);
             this._count = itemCount;
             this._count = itemCount;
 
 
-            this._type = dimensions;
+            this._type = Enum.GetName(typeof(DimensionType), dimensions);
             this._componentType = encoding;
             this._componentType = encoding;
             this._normalized = normalized.AsNullable(_normalizedDefault);
             this._normalized = normalized.AsNullable(_normalizedDefault);
 
 
             UpdateBounds();
             UpdateBounds();
         }
         }
 
 
+        public Matrix2x2Array AsMatrix2x2Array()
+        {
+            return _GetMemoryAccessor().AsMatrix2x2Array();
+        }
+
+        public Matrix3x3Array AsMatrix3x3Array()
+        {
+            return _GetMemoryAccessor().AsMatrix3x3Array();
+        }
+
         public Matrix4x4Array AsMatrix4x4Array()
         public Matrix4x4Array AsMatrix4x4Array()
         {
         {
             return _GetMemoryAccessor().AsMatrix4x4Array();
             return _GetMemoryAccessor().AsMatrix4x4Array();