protected override void OnValidateReferences(Validation.ValidationContext result) { base.OnValidateReferences(result); result.CheckArrayIndexAccess(nameof(Buffer), _buffer, this.LogicalParent.LogicalBuffers); result.CheckSchemaNonNegative("ByteOffset", _byteOffset); result.CheckSchemaIsInRange("ByteLength", _byteLength, _byteLengthMinimum, int.MaxValue); // ByteStride must be multiple of 4, between 4 and 252 if (_byteStride.HasValue) { result.CheckSchemaIsInRange(nameof(ByteStride), _byteStride.Value, _byteStrideMinimum, _byteStrideMaximum); result.CheckSchemaIsMultipleOf(nameof(ByteStride), _byteStride.Value, 4); } }
internal static void CheckAccess(Validation.ValidationContext result, BufferView bv, int accessorByteOffset, DimensionType dim, EncodingType enc, bool nrm, int count) { if (nrm) { if (enc != EncodingType.UNSIGNED_BYTE && enc != EncodingType.UNSIGNED_SHORT) { result.AddDataError("Normalized", "Only (u)byte and (u)short accessors can be normalized."); } } var elementByteSize = dim.DimCount() * enc.ByteLength(); if (bv.IsVertexBuffer) { if (bv.ByteStride == 0) { result.CheckSchemaIsMultipleOf("ElementByteSize", elementByteSize, 4); } } if (bv.IsIndexBuffer) { if (dim != DimensionType.SCALAR) { result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor dimensions is: {dim}"); } if (enc == EncodingType.BYTE) { result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor encoding is (s)byte"); } if (enc == EncodingType.SHORT) { result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor encoding is (s)short"); } if (enc == EncodingType.FLOAT) { result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor encoding is float"); } if (nrm) { result.AddLinkError(("BufferView", bv.LogicalIndex), $"is an IndexBuffer, but accessor is normalized"); } } if (bv.ByteStride > 0) { if (bv.ByteStride < elementByteSize) { result.AddLinkError("ElementByteSize", $"Referenced bufferView's byteStride value {bv.ByteStride} is less than accessor element's length {elementByteSize}."); } // "Accessor's total byteOffset {0} isn't a multiple of componentType length {1}."; return; } var accessorByteLength = bv.GetAccessorByteLength(dim, enc, count); // "Accessor(offset: {0}, length: {1}) does not fit referenced bufferView[% 3] length %4."; result.CheckArrayRangeAccess(("BufferView", bv.LogicalIndex), accessorByteOffset, accessorByteLength, bv.Content); }