private void ValidateBounds(Validation.ValidationContext result) { result = result.GetContext(this); if (_min.Count != _max.Count) { result.AddDataError("Max", $"Min and Max bounds dimension mismatch Min:{_min.Count} Max:{_max.Count}"); } if (_min.Count == 0 && _max.Count == 0) { return; } var dimensions = this.Dimensions.DimCount(); if (_min.Count != dimensions) { result.AddLinkError("Min", $"size mismatch; expected {dimensions} but found {_min.Count}"); return; } if (_max.Count != dimensions) { result.AddLinkError("Max", $"size mismatch; expected {dimensions} but found {_max.Count}"); return; } for (int i = 0; i < _min.Count; ++i) { // if (_min[i] > _max[i]) result.AddError(this, $"min[{i}] is larger than max[{i}]"); } if (this.Encoding != EncodingType.FLOAT) { return; } var current = new float[dimensions]; var minimum = this._min.ConvertAll(item => (float)item); var maximum = this._max.ConvertAll(item => (float)item); var array = new MultiArray(this.SourceBufferView.Content, this.ByteOffset, this.Count, this.SourceBufferView.ByteStride, dimensions, this.Encoding, false); for (int i = 0; i < array.Count; ++i) { array.CopyItemTo(i, current); for (int j = 0; j < current.Length; ++j) { var v = current[j]; // if (!v._IsFinite()) result.AddError(this, $"Item[{j}][{i}] is not a finite number: {v}"); var min = minimum[j]; var max = maximum[j]; // if (v < min || v > max) result.AddError(this, $"Item[{j}][{i}] is out of bounds. {min} <= {v} <= {max}"); } } }
internal void ValidateBufferUsageData(Validation.ValidationContext result) { if (this.ByteStride != 0) { result.AddLinkError("BufferView", "Unexpected ByteStride found. Expected 0"); } result = result.GetContext(this); if (!this._target.HasValue) { return; } result.AddLinkError("Device Buffer Target", $"is set as {this._target.Value}. But an accessor wants to use it as a plain data buffer."); }
internal void ValidateBufferUsageGPU(Validation.ValidationContext result, BufferMode usingMode) { result = result.GetContext(this); if (!this._target.HasValue) { return; } if (usingMode == this._target.Value) { return; } result.AddLinkError("Device Buffer Target", $"is set as {this._target.Value}. But an accessor wants to use it as '{usingMode}'."); }
public static void ValidateWeightsSum(Validation.ValidationContext result, MemoryAccessor weights0, MemoryAccessor weights1) { int idx = 0; if (weights1 == null) { if (weights0 == null) { return; } foreach (var item in weights0.GetItemsAsRawBytes()) { if (!_CheckWeightSum(item, weights0.Attribute.Encoding)) { result.AddDataError($"Weight Sum invalid at Index {idx}"); } ++idx; } return; } if (weights0 == null) { result.AddLinkError(""); return; } var len = weights0.Attribute.ItemByteLength; Span <Byte> dst = stackalloc byte[len * 2]; var zip = weights0.GetItemsAsRawBytes().Zip(weights1.GetItemsAsRawBytes(), (a, b) => (a, b)); foreach (var(a, b) in zip) { a.AsSpan().CopyTo(dst); b.AsSpan().CopyTo(dst.Slice(len)); if (!_CheckWeightSum(dst, weights0.Attribute.Encoding)) { result.AddDataError($"Weight Sum invalid at Index {idx}"); } ++idx; } }
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); }