|
|
@@ -47,6 +47,11 @@ namespace SharpGLTF.Schema2
|
|
|
|
|
|
internal int _SourceBufferViewIndex => this._bufferView.AsValue(-1);
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Gets the number of bytes, starting at <see cref="ByteOffset"/> use by this <see cref="Accessor"/>
|
|
|
+ /// </summary>
|
|
|
+ public int ByteLength => BufferView.GetAccessorByteLength(Format, Count, SourceBufferView);
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Gets the <see cref="BufferView"/> buffer that contains the items as an encoded byte array.
|
|
|
/// </summary>
|
|
|
@@ -58,14 +63,9 @@ namespace SharpGLTF.Schema2
|
|
|
public int Count => this._count;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Gets the starting byte offset within <see cref="SourceBufferView"/>.
|
|
|
- /// </summary>
|
|
|
- public int ByteOffset => this._byteOffset.AsValue(0);
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the number of bytes, starting at <see cref="ByteOffset"/> use by this <see cref="Accessor"/>
|
|
|
+ /// Gets the starting byte offset within the byte data.
|
|
|
/// </summary>
|
|
|
- public int ByteLength => SourceBufferView.GetAccessorByteLength(Format, Count);
|
|
|
+ public int ByteOffset => this._byteOffset.AsValue(0);
|
|
|
|
|
|
/// <summary>
|
|
|
/// Gets the <see cref="DimensionType"/> of an item.
|
|
|
@@ -128,20 +128,34 @@ namespace SharpGLTF.Schema2
|
|
|
_CachedType = Enum.TryParse<DimensionType>(this._type, out var r) ? r : DimensionType.CUSTOM;
|
|
|
|
|
|
return _CachedType.Value;
|
|
|
+ }
|
|
|
+
|
|
|
+ internal bool _TryGetMemoryAccessor(out MemoryAccessor mem)
|
|
|
+ {
|
|
|
+ if (!TryGetBufferView(out var view)) { mem = default; return false; }
|
|
|
+ var info = new MemoryAccessInfo(null, ByteOffset, Count, view.ByteStride, Format);
|
|
|
+ mem = new MemoryAccessor(view.Content, info);
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- internal MemoryAccessor _GetMemoryAccessor(string name = null)
|
|
|
+ internal bool _TryGetMemoryAccessor(string name, out MemoryAccessor mem)
|
|
|
{
|
|
|
- var view = SourceBufferView;
|
|
|
+ if (!TryGetBufferView(out var view)) { mem = default; return false; }
|
|
|
var info = new MemoryAccessInfo(name, ByteOffset, Count, view.ByteStride, Format);
|
|
|
- return new MemoryAccessor(view.Content, info);
|
|
|
+ mem = new MemoryAccessor(view.Content, info);
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- internal KeyValuePair<IntegerArray, MemoryAccessor>? _GetSparseMemoryAccessor()
|
|
|
+ public bool TryGetBufferView(out BufferView bv)
|
|
|
{
|
|
|
- return this._sparse == null
|
|
|
- ? (KeyValuePair<IntegerArray, MemoryAccessor>?)null
|
|
|
- : this._sparse._CreateMemoryAccessors(this);
|
|
|
+ if (_bufferView.HasValue)
|
|
|
+ {
|
|
|
+ bv = this.LogicalParent.LogicalBufferViews[this._bufferView.Value];
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ bv = null;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
public void UpdateBounds()
|
|
|
@@ -164,20 +178,28 @@ namespace SharpGLTF.Schema2
|
|
|
this._max.Add(double.MinValue);
|
|
|
}
|
|
|
|
|
|
- var array = new MultiArray(this.SourceBufferView.Content, this.ByteOffset, this.Count, this.SourceBufferView.ByteStride, dimensions, this.Encoding, false);
|
|
|
-
|
|
|
- var current = new float[dimensions];
|
|
|
-
|
|
|
- for (int i = 0; i < array.Count; ++i)
|
|
|
+ if (this.TryGetBufferView(out var view))
|
|
|
{
|
|
|
- array.CopyItemTo(i, current);
|
|
|
+ var array = new MultiArray(view.Content, this.ByteOffset, this.Count, view.ByteStride, dimensions, this.Encoding, false);
|
|
|
+
|
|
|
+ var current = new float[dimensions];
|
|
|
|
|
|
- for (int j = 0; j < current.Length; ++j)
|
|
|
+ for (int i = 0; i < array.Count; ++i)
|
|
|
{
|
|
|
- this._min[j] = Math.Min(this._min[j], current[j]);
|
|
|
- this._max[j] = Math.Max(this._max[j], current[j]);
|
|
|
+ array.CopyItemTo(i, current);
|
|
|
+
|
|
|
+ for (int j = 0; j < current.Length; ++j)
|
|
|
+ {
|
|
|
+ this._min[j] = Math.Min(this._min[j], current[j]);
|
|
|
+ this._max[j] = Math.Max(this._max[j], current[j]);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (int i = 0; i < this._min.Count; ++i) this._min[i] = 0;
|
|
|
+ for (int i = 0; i < this._max.Count; ++i) this._max[i] = 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
@@ -213,18 +235,23 @@ namespace SharpGLTF.Schema2
|
|
|
UpdateBounds();
|
|
|
}
|
|
|
|
|
|
- public IList<Matrix3x2> AsMatrix2x2Array()
|
|
|
+ public IAccessorArray<Matrix3x2> AsMatrix2x2Array()
|
|
|
{
|
|
|
- return _GetMemoryAccessor().AsMatrix2x2Array();
|
|
|
+ return _TryGetMemoryAccessor(out var mem)
|
|
|
+ ? mem.AsMatrix2x2Array()
|
|
|
+ : new ZeroAccessorArray<Matrix3x2>(this._count);
|
|
|
}
|
|
|
|
|
|
- public IList<Matrix4x4> AsMatrix3x3Array()
|
|
|
+ public IAccessorArray<Matrix4x4> AsMatrix3x3Array()
|
|
|
{
|
|
|
- return _GetMemoryAccessor().AsMatrix3x3Array();
|
|
|
+ return _TryGetMemoryAccessor(out var mem)
|
|
|
+ ? mem.AsMatrix3x3Array()
|
|
|
+ : new ZeroAccessorArray<Matrix4x4>(this._count);
|
|
|
}
|
|
|
|
|
|
- public IList<Matrix4x4> AsMatrix4x3Array()
|
|
|
+ public IAccessorArray<Matrix4x4> AsMatrix4x3Array()
|
|
|
{
|
|
|
+ /*
|
|
|
const int dimsize = 4 * 3;
|
|
|
|
|
|
var view = SourceBufferView;
|
|
|
@@ -232,16 +259,59 @@ namespace SharpGLTF.Schema2
|
|
|
var content = view.Content.Slice(this.ByteOffset, Count * stride);
|
|
|
|
|
|
return new Matrix4x3Array(content, stride, this.Encoding, this.Normalized);
|
|
|
+ */
|
|
|
+
|
|
|
+ return _TryGetMemoryAccessor(out var mem)
|
|
|
+ ? mem.AsMatrix4x3Array()
|
|
|
+ : new ZeroAccessorArray<Matrix4x4>(this._count);
|
|
|
}
|
|
|
|
|
|
- public IList<Matrix4x4> AsMatrix4x4Array()
|
|
|
+ public IAccessorArray<Matrix4x4> AsMatrix4x4Array()
|
|
|
{
|
|
|
- return _GetMemoryAccessor().AsMatrix4x4Array();
|
|
|
+ return _TryGetMemoryAccessor(out var mem)
|
|
|
+ ? mem.AsMatrix4x4Array()
|
|
|
+ : new ZeroAccessorArray<Matrix4x4>(this._count);
|
|
|
}
|
|
|
|
|
|
+ [Obsolete("Use AsMatrix4x4Array instead", true)]
|
|
|
internal IReadOnlyList<Matrix4x4> AsMatrix4x4ReadOnlyList()
|
|
|
{
|
|
|
- return _GetMemoryAccessor().AsMatrix4x4Array();
|
|
|
+ return _TryGetMemoryAccessor(out var mem)
|
|
|
+ ? mem.AsMatrix4x4Array()
|
|
|
+ : new ZeroAccessorArray<Matrix4x4>(this._count);
|
|
|
+ }
|
|
|
+
|
|
|
+ public IAccessorArray<Quaternion> AsQuaternionArray()
|
|
|
+ {
|
|
|
+ if (_TryGetMemoryAccessor(out var memory))
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return memory.AsQuaternionArray();
|
|
|
+
|
|
|
+ throw new NotImplementedException();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return new ZeroAccessorArray<Quaternion>(this._count);
|
|
|
+
|
|
|
+ throw new NotImplementedException();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public IAccessorArray<Single[]> AsMultiArray(int dimensions)
|
|
|
+ {
|
|
|
+ if (_TryGetMemoryAccessor(out var memory))
|
|
|
+ {
|
|
|
+
|
|
|
+ if (this._sparse == null) return memory.AsMultiArray(dimensions);
|
|
|
+
|
|
|
+ throw new NotImplementedException();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return new ZeroAccessorArray<Single[]>(this._count);
|
|
|
+
|
|
|
+ throw new NotImplementedException();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
@@ -272,12 +342,14 @@ namespace SharpGLTF.Schema2
|
|
|
SetData(buffer, bufferByteOffset, itemCount, DimensionType.SCALAR, encoding.ToComponent(), false);
|
|
|
}
|
|
|
|
|
|
- public IntegerArray AsIndicesArray()
|
|
|
+ public IAccessorArray<UInt32> AsIndicesArray()
|
|
|
{
|
|
|
Guard.IsFalse(this.IsSparse, nameof(IsSparse));
|
|
|
Guard.IsTrue(this.Dimensions == DimensionType.SCALAR, nameof(Dimensions));
|
|
|
|
|
|
- return new IntegerArray(SourceBufferView.Content, this.ByteOffset, this._count, this.Encoding.ToIndex());
|
|
|
+ return _TryGetMemoryAccessor(out var mem)
|
|
|
+ ? new IntegerArray(SourceBufferView.Content, this.ByteOffset, this._count, this.Encoding.ToIndex())
|
|
|
+ : new ZeroAccessorArray<UInt32>(this._count);
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
@@ -312,83 +384,119 @@ namespace SharpGLTF.Schema2
|
|
|
SetData(buffer, bufferByteOffset, itemCount, dimensions, encoding, normalized);
|
|
|
}
|
|
|
|
|
|
- public IList<Single> AsScalarArray()
|
|
|
+ internal IAccessorArray<T> AsVertexArray<T>()
|
|
|
{
|
|
|
- var memory = _GetMemoryAccessor();
|
|
|
+ if (typeof(T) == typeof(float)) return (IAccessorArray<T>)AsScalarArray();
|
|
|
+ if (typeof(T) == typeof(Vector2)) return (IAccessorArray<T>)AsVector2Array();
|
|
|
+ if (typeof(T) == typeof(Vector3)) return (IAccessorArray<T>)AsVector3Array();
|
|
|
+ if (typeof(T) == typeof(Vector4)) return (IAccessorArray<T>)AsVector4Array();
|
|
|
|
|
|
- if (this._sparse == null) return memory.AsScalarArray();
|
|
|
-
|
|
|
- var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
- return MemoryAccessor.CreateScalarSparseArray(memory, sparseKV.Key, sparseKV.Value);
|
|
|
+ throw new NotImplementedException();
|
|
|
}
|
|
|
|
|
|
- public IList<Vector2> AsVector2Array()
|
|
|
+ public IAccessorArray<Single> AsScalarArray()
|
|
|
{
|
|
|
- var memory = _GetMemoryAccessor();
|
|
|
+ if (_TryGetMemoryAccessor(out var memory))
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return memory.AsScalarArray();
|
|
|
|
|
|
- if (this._sparse == null) return memory.AsVector2Array();
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateScalarSparseArray(memory, sparseKV.Key, sparseKV.Value);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return new ZeroAccessorArray<Single>(this._count);
|
|
|
|
|
|
- var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
- return MemoryAccessor.CreateVector2SparseArray(memory, sparseKV.Key, sparseKV.Value);
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateScalarSparseArray(this._count, sparseKV.Key, sparseKV.Value);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- public IList<Vector3> AsVector3Array()
|
|
|
+ public IAccessorArray<Vector2> AsVector2Array()
|
|
|
{
|
|
|
- var memory = _GetMemoryAccessor();
|
|
|
+ if (_TryGetMemoryAccessor(out var memory))
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return memory.AsVector2Array();
|
|
|
|
|
|
- if (this._sparse == null) return memory.AsVector3Array();
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateVector2SparseArray(memory, sparseKV.Key, sparseKV.Value);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return new ZeroAccessorArray<Vector2>(this._count);
|
|
|
|
|
|
- var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
- return MemoryAccessor.CreateVector3SparseArray(memory, sparseKV.Key, sparseKV.Value);
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateVector2SparseArray(this._count, sparseKV.Key, sparseKV.Value);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- public IList<Vector4> AsVector4Array()
|
|
|
+ public IAccessorArray<Vector3> AsVector3Array()
|
|
|
{
|
|
|
- var memory = _GetMemoryAccessor();
|
|
|
-
|
|
|
- if (this._sparse == null) return memory.AsVector4Array();
|
|
|
-
|
|
|
- var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
- return MemoryAccessor.CreateVector4SparseArray(memory, sparseKV.Key, sparseKV.Value);
|
|
|
- }
|
|
|
+ if (_TryGetMemoryAccessor(out var memory))
|
|
|
+ {
|
|
|
|
|
|
- public IList<Vector4> AsColorArray(Single defaultW = 1)
|
|
|
- {
|
|
|
- var memory = _GetMemoryAccessor();
|
|
|
+ if (this._sparse == null) return memory.AsVector3Array();
|
|
|
|
|
|
- if (this._sparse == null) return memory.AsColorArray(defaultW);
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateVector3SparseArray(memory, sparseKV.Key, sparseKV.Value);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return new ZeroAccessorArray<Vector3>(this._count);
|
|
|
|
|
|
- var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
- return MemoryAccessor.CreateColorSparseArray(memory, sparseKV.Key, sparseKV.Value, defaultW);
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateVector3SparseArray(this._count, sparseKV.Key, sparseKV.Value);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- public IList<Quaternion> AsQuaternionArray()
|
|
|
+ public IAccessorArray<Vector4> AsVector4Array()
|
|
|
{
|
|
|
- var memory = _GetMemoryAccessor();
|
|
|
+ if (_TryGetMemoryAccessor(out var memory))
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return memory.AsVector4Array();
|
|
|
|
|
|
- if (this._sparse == null) return memory.AsQuaternionArray();
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateVector4SparseArray(memory, sparseKV.Key, sparseKV.Value);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return new ZeroAccessorArray<Vector4>(this._count);
|
|
|
|
|
|
- throw new NotImplementedException();
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateVector4SparseArray(this._count, sparseKV.Key, sparseKV.Value);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- public IList<Single[]> AsMultiArray(int dimensions)
|
|
|
+ public IAccessorArray<Vector4> AsColorArray(Single defaultW = 1)
|
|
|
{
|
|
|
- var memory = _GetMemoryAccessor();
|
|
|
+ if (_TryGetMemoryAccessor(out var memory))
|
|
|
+ {
|
|
|
|
|
|
- if (this._sparse == null) return memory.AsMultiArray(dimensions);
|
|
|
+ if (this._sparse == null) return memory.AsColorArray(defaultW);
|
|
|
|
|
|
- throw new NotImplementedException();
|
|
|
- }
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateColorSparseArray(memory, sparseKV.Key, sparseKV.Value, defaultW);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (this._sparse == null) return new ZeroAccessorArray<Vector4>(this._count);
|
|
|
|
|
|
+ var sparseKV = this._sparse._CreateMemoryAccessors(this);
|
|
|
+ return MemoryAccessor.CreateColorSparseArray(this._count, sparseKV.Key, sparseKV.Value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public ArraySegment<Byte> TryGetVertexBytes(int vertexIdx)
|
|
|
{
|
|
|
if (_sparse != null) throw new InvalidOperationException("Can't be used on Acessors with Sparse Data");
|
|
|
|
|
|
+ if (!this.TryGetBufferView(out var bufferView)) return default;
|
|
|
+
|
|
|
var itemByteSz = Encoding.ByteLength() * Dimensions.DimCount();
|
|
|
- var byteStride = Math.Max(itemByteSz, SourceBufferView.ByteStride);
|
|
|
+ var byteStride = Math.Max(itemByteSz, bufferView.ByteStride);
|
|
|
var byteOffset = vertexIdx * byteStride;
|
|
|
|
|
|
- return SourceBufferView.Content.Slice(this.ByteOffset + (vertexIdx * byteStride), itemByteSz);
|
|
|
+ return bufferView.Content.Slice(this.ByteOffset + (vertexIdx * byteStride), itemByteSz);
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
@@ -400,7 +508,7 @@ namespace SharpGLTF.Schema2
|
|
|
base.OnValidateReferences(validate);
|
|
|
|
|
|
validate
|
|
|
- .IsDefined(nameof(_bufferView), _bufferView)
|
|
|
+ // .IsDefined(nameof(_bufferView), _bufferView) as per specification, this is not required to be defined.
|
|
|
.NonNegative(nameof(_byteOffset), _byteOffset)
|
|
|
.IsGreaterOrEqual(nameof(_count), _count, _countMinimum)
|
|
|
.IsNullOrIndex(nameof(_bufferView), _bufferView, this.LogicalParent.LogicalBufferViews);
|
|
|
@@ -414,9 +522,15 @@ namespace SharpGLTF.Schema2
|
|
|
// we cannot check the rest of the accessor.
|
|
|
if (this.Dimensions == DimensionType.CUSTOM) return;
|
|
|
|
|
|
- BufferView.VerifyAccess(validate, this.SourceBufferView, this.ByteOffset, this.Format, this.Count);
|
|
|
+ if (TryGetBufferView(out var bv))
|
|
|
+ {
|
|
|
+ BufferView.VerifyAccess(validate, bv, this.ByteOffset, this.Format, this.Count);
|
|
|
+ }
|
|
|
|
|
|
- validate.That(() => MemoryAccessor.VerifyAccessorBounds(_GetMemoryAccessor(), _min, _max));
|
|
|
+ if (_TryGetMemoryAccessor(out var mem))
|
|
|
+ {
|
|
|
+ validate.That(() => MemoryAccessor.VerifyAccessorBounds(mem, _min, _max));
|
|
|
+ }
|
|
|
|
|
|
// at this point we don't know which kind of data we're accessing, so it's up to the components
|
|
|
// using this accessor to validate the data.
|
|
|
@@ -426,12 +540,19 @@ namespace SharpGLTF.Schema2
|
|
|
{
|
|
|
validate = validate.GetContext(this);
|
|
|
|
|
|
- SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ELEMENT_ARRAY_BUFFER);
|
|
|
validate.IsAnyOf("Format", Format, (DimensionType.SCALAR, EncodingType.UNSIGNED_BYTE), (DimensionType.SCALAR, EncodingType.UNSIGNED_SHORT), (DimensionType.SCALAR, EncodingType.UNSIGNED_INT));
|
|
|
|
|
|
- validate.AreEqual(nameof(SourceBufferView.ByteStride), SourceBufferView.ByteStride, 0); // "bufferView.byteStride must not be defined for indices accessor.";
|
|
|
+ if (TryGetBufferView(out var bufferView))
|
|
|
+ {
|
|
|
+ bufferView.ValidateBufferUsageGPU(validate, BufferMode.ELEMENT_ARRAY_BUFFER);
|
|
|
+
|
|
|
+ validate.AreEqual(nameof(bufferView.ByteStride), bufferView.ByteStride, 0); // "bufferView.byteStride must not be defined for indices accessor.";
|
|
|
+ }
|
|
|
|
|
|
- validate.That(() => MemoryAccessor.VerifyVertexIndices(_GetMemoryAccessor(), vertexCount));
|
|
|
+ if (_TryGetMemoryAccessor(out var mem))
|
|
|
+ {
|
|
|
+ validate.That(() => MemoryAccessor.VerifyVertexIndices(mem, vertexCount));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
internal static void ValidateVertexAttributes(VALIDATIONCTX validate, IReadOnlyDictionary<string, Accessor> attributes, int skinsMaxJointCount)
|
|
|
@@ -463,7 +584,7 @@ namespace SharpGLTF.Schema2
|
|
|
{
|
|
|
validate = validate.GetContext(this);
|
|
|
|
|
|
- SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
+ if (TryGetBufferView(out var bufferView)) bufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
|
|
|
if (!this.LogicalParent.MeshQuantizationAllowed)
|
|
|
{
|
|
|
@@ -481,7 +602,7 @@ namespace SharpGLTF.Schema2
|
|
|
{
|
|
|
validate = validate.GetContext(this);
|
|
|
|
|
|
- SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
+ if (TryGetBufferView(out var bufferView)) bufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
|
|
|
if (!this.LogicalParent.MeshQuantizationAllowed)
|
|
|
{
|
|
|
@@ -501,7 +622,7 @@ namespace SharpGLTF.Schema2
|
|
|
{
|
|
|
validate = validate.GetContext(this);
|
|
|
|
|
|
- SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
+ if (TryGetBufferView(out var bufferView)) bufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
|
|
|
if (!this.LogicalParent.MeshQuantizationAllowed)
|
|
|
{
|
|
|
@@ -526,7 +647,7 @@ namespace SharpGLTF.Schema2
|
|
|
{
|
|
|
validate = validate.GetContext(this);
|
|
|
|
|
|
- SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
+ if (TryGetBufferView(out var bufferView)) bufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
|
|
|
validate
|
|
|
.IsAnyOf(nameof(Format), Format, (DimensionType.VEC4, EncodingType.UNSIGNED_BYTE), (DimensionType.VEC4, EncodingType.UNSIGNED_SHORT), DimensionType.VEC4)
|
|
|
@@ -538,8 +659,8 @@ namespace SharpGLTF.Schema2
|
|
|
weights0?._ValidateWeights(validate);
|
|
|
weights1?._ValidateWeights(validate);
|
|
|
|
|
|
- var memory0 = weights0?._GetMemoryAccessor("WEIGHTS_0");
|
|
|
- var memory1 = weights1?._GetMemoryAccessor("WEIGHTS_1");
|
|
|
+ var memory0 = (weights0?._TryGetMemoryAccessor("WEIGHTS_0", out var mem0) ?? false) ? mem0 : null;
|
|
|
+ var memory1 = (weights1?._TryGetMemoryAccessor("WEIGHTS_1", out var mem1) ?? false) ? mem1 : null;
|
|
|
|
|
|
validate.That(() => MemoryAccessor.VerifyWeightsSum(memory0, memory1));
|
|
|
}
|
|
|
@@ -548,7 +669,7 @@ namespace SharpGLTF.Schema2
|
|
|
{
|
|
|
validate = validate.GetContext(this);
|
|
|
|
|
|
- SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
+ if (TryGetBufferView(out var bufferView)) bufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER);
|
|
|
|
|
|
validate.IsAnyOf(nameof(Format), Format, (DimensionType.VEC4, EncodingType.UNSIGNED_BYTE, true), (DimensionType.VEC4, EncodingType.UNSIGNED_SHORT, true), DimensionType.VEC4);
|
|
|
}
|
|
|
@@ -557,11 +678,14 @@ namespace SharpGLTF.Schema2
|
|
|
{
|
|
|
validate = validate.GetContext(this);
|
|
|
|
|
|
- SourceBufferView.ValidateBufferUsagePlainData(validate);
|
|
|
+ if (TryGetBufferView(out var bv))
|
|
|
+ {
|
|
|
+ bv.ValidateBufferUsagePlainData(validate);
|
|
|
+ }
|
|
|
|
|
|
validate.IsAnyOf(nameof(Format), Format, (DimensionType.MAT4, EncodingType.BYTE, true), (DimensionType.MAT4, EncodingType.SHORT, true), DimensionType.MAT4);
|
|
|
|
|
|
- var matrices = this.AsMatrix4x4Array();
|
|
|
+ IReadOnlyList<Matrix4x4> matrices = this.AsMatrix4x4Array();
|
|
|
|
|
|
for (int i = 0; i < matrices.Count; ++i)
|
|
|
{
|
|
|
@@ -571,14 +695,20 @@ namespace SharpGLTF.Schema2
|
|
|
|
|
|
internal void ValidateAnimationInput(VALIDATIONCTX validate)
|
|
|
{
|
|
|
- SourceBufferView.ValidateBufferUsagePlainData(validate, false); // as per glTF specification, animation accessors must not have ByteStride
|
|
|
+ if (TryGetBufferView(out var bv))
|
|
|
+ {
|
|
|
+ bv.ValidateBufferUsagePlainData(validate, false); // as per glTF specification, animation accessors must not have ByteStride
|
|
|
+ }
|
|
|
|
|
|
validate.IsAnyOf(nameof(Dimensions), Dimensions, DimensionType.SCALAR);
|
|
|
}
|
|
|
|
|
|
internal void ValidateAnimationOutput(VALIDATIONCTX validate)
|
|
|
{
|
|
|
- SourceBufferView.ValidateBufferUsagePlainData(validate, false); // as per glTF specification, animation accessors must not have ByteStride
|
|
|
+ if (TryGetBufferView(out var bv))
|
|
|
+ {
|
|
|
+ bv.ValidateBufferUsagePlainData(validate, false); // as per glTF specification, animation accessors must not have ByteStride
|
|
|
+ }
|
|
|
|
|
|
validate.IsAnyOf(nameof(Dimensions), Dimensions, DimensionType.SCALAR, DimensionType.VEC2, DimensionType.VEC3, DimensionType.VEC4);
|
|
|
}
|