internal void ValidateIndices(VALIDATIONCTX result, uint vertexCount, PrimitiveType drawingType) { result = result.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(result, BufferMode.ELEMENT_ARRAY_BUFFER); result.CheckLinkMustBeAnyOf(nameof(Normalized), Normalized, false); result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.UNSIGNED_BYTE, EncodingType.UNSIGNED_SHORT, EncodingType.UNSIGNED_INT); result.CheckLinkMustBeAnyOf(nameof(Dimensions), Dimensions, DimensionType.SCALAR); uint restart_value = 0xff; if (this.Encoding == EncodingType.UNSIGNED_SHORT) { restart_value = 0xffff; } if (this.Encoding == EncodingType.UNSIGNED_INT) { restart_value = 0xffffffff; } var indices = this.AsIndicesArray(); for (int i = 0; i < indices.Count; ++i) { result.CheckVertexIndex(i, indices[i], vertexCount, restart_value); } }
private void _ValidateNormals(VALIDATIONCTX result) { result = result.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(result, BufferMode.ARRAY_BUFFER); result.CheckLinkMustBeAnyOf(nameof(Dimensions), Dimensions, DimensionType.VEC3); if (!this.LogicalParent.MeshQuantizationAllowed) { result.CheckLinkMustBeAnyOf(nameof(Normalized), Normalized, false); result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.FLOAT); } else { if (Normalized) { result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.BYTE, EncodingType.SHORT); } else { result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.FLOAT); } } var normals = this.AsVector3Array(); for (int i = 0; i < normals.Count; ++i) { if (result.TryFixUnitLengthOrError(i, normals[i])) { normals[i] = normals[i].SanitizeNormal(); } } }
private void _ValidateWeights(VALIDATIONCTX result) { result = result.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(result, BufferMode.ARRAY_BUFFER); result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.UNSIGNED_BYTE, EncodingType.UNSIGNED_SHORT, EncodingType.FLOAT); result.CheckLinkMustBeAnyOf(nameof(Dimensions), Dimensions, DimensionType.VEC4); }
private void _ValidateWeights(VALIDATIONCTX validate) { validate = validate.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER); validate.IsAnyOf(nameof(Format), Format, (DimensionType.VEC4, EncodingType.UNSIGNED_BYTE, true), (DimensionType.VEC4, EncodingType.UNSIGNED_SHORT, true), DimensionType.VEC4); }
private void ValidateBounds(VALIDATIONCTX 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}"); } } }
private static void _ValidateWeights(VALIDATIONCTX result, Accessor weights0, Accessor weights1) { weights0?._ValidateWeights(result); weights1?._ValidateWeights(result); var memory0 = weights0?._GetMemoryAccessor("WEIGHTS_0"); var memory1 = weights1?._GetMemoryAccessor("WEIGHTS_1"); MemoryAccessor.ValidateWeightsSum(result, memory0, memory1); }
private void _ValidateJoints(VALIDATIONCTX validate, string attributeName, int skinsMaxJointCount) { validate = validate.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER); validate .IsAnyOf(nameof(Format), Format, (DimensionType.VEC4, EncodingType.UNSIGNED_BYTE), (DimensionType.VEC4, EncodingType.UNSIGNED_SHORT), DimensionType.VEC4) .AreJoints(attributeName, this.AsVector4Array(), skinsMaxJointCount); }
private static void _ValidateWeights(VALIDATIONCTX validate, Accessor weights0, Accessor weights1) { weights0?._ValidateWeights(validate); weights1?._ValidateWeights(validate); var memory0 = weights0?._GetMemoryAccessor("WEIGHTS_0"); var memory1 = weights1?._GetMemoryAccessor("WEIGHTS_1"); validate.That(() => MemoryAccessor.VerifyWeightsSum(memory0, memory1)); }
protected override void OnValidateReferences(VALIDATIONCTX validate) { base.OnValidateReferences(validate); validate .IsDefined(nameof(_bufferView), _bufferView) .NonNegative(nameof(_byteOffset), _byteOffset) .IsGreaterOrEqual(nameof(_count), _count, _countMinimum) .IsNullOrIndex(nameof(_bufferView), _bufferView, this.LogicalParent.LogicalBufferViews); }
protected override void OnValidateContent(VALIDATIONCTX validate) { base.OnValidateContent(validate); BufferView.VerifyAccess(validate, this.SourceBufferView, this.ByteOffset, this.Format, this.Count); validate.That(() => MemoryAccessor.VerifyAccessorBounds(_GetMemoryAccessor(), _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. }
internal void ValidateIndices(VALIDATIONCTX validate, uint vertexCount, PrimitiveType drawingType) { 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."; validate.That(() => MemoryAccessor.VerifyVertexIndices(_GetMemoryAccessor(), vertexCount)); }
protected override void OnValidateReferences(VALIDATIONCTX result) { base.OnValidateReferences(result); result.CheckSchemaIsDefined("BufferView", _bufferView); result.CheckArrayIndexAccess("BufferView", _bufferView, this.LogicalParent.LogicalBufferViews); result.CheckSchemaNonNegative("ByteOffset", _byteOffset); result.CheckSchemaIsInRange("Count", _count, _countMinimum, int.MaxValue); _sparse?.ValidateReferences(result); }
protected override void OnValidate(VALIDATIONCTX result) { base.OnValidate(result); _sparse?.Validate(result); BufferView.CheckAccess(result, this.SourceBufferView, this.ByteOffset, this.Dimensions, this.Encoding, this.Normalized, this.Count); ValidateBounds(result); // 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. }
internal void ValidateMatrices(VALIDATIONCTX result) { result = result.GetContext(this); SourceBufferView.ValidateBufferUsagePlainData(result); result.CheckLinkMustBeAnyOf(nameof(Dimensions), Dimensions, DimensionType.MAT4); var matrices = this.AsMatrix4x4Array(); for (int i = 0; i < matrices.Count; ++i) { result.CheckIsMatrix(i, matrices[i]); } }
internal void ValidateMatrices(VALIDATIONCTX validate) { validate = validate.GetContext(this); SourceBufferView.ValidateBufferUsagePlainData(validate); validate.IsAnyOf(nameof(Format), Format, (DimensionType.MAT4, EncodingType.BYTE, true), (DimensionType.MAT4, EncodingType.SHORT, true), DimensionType.MAT4); var matrices = this.AsMatrix4x4Array(); for (int i = 0; i < matrices.Count; ++i) { validate.IsNullOrMatrix("Matrices", matrices[i]); } }
internal static void ValidateVertexAttributes(VALIDATIONCTX result, IReadOnlyDictionary <string, Accessor> attributes, int skinsMaxJointCount) { if (result.TryFix) { foreach (var kvp in attributes.Where(item => item.Key != "POSITION")) { // remove unnecessary bounds kvp.Value._min.Clear(); kvp.Value._max.Clear(); } } if (attributes.TryGetValue("POSITION", out Accessor positions)) { positions._ValidatePositions(result); } else { result.AddSemanticWarning("No POSITION attribute found."); } if (attributes.TryGetValue("NORMAL", out Accessor normals)) { normals._ValidateNormals(result); } if (attributes.TryGetValue("TANGENT", out Accessor tangents)) { tangents._ValidateTangents(result); } if (normals == null && tangents != null) { result.AddSemanticWarning("TANGENT", "attribute without NORMAL found."); } if (attributes.TryGetValue("JOINTS_0", out Accessor joints0)) { joints0._ValidateJoints(result, "JOINTS_0", skinsMaxJointCount); } if (attributes.TryGetValue("JOINTS_1", out Accessor joints1)) { joints0._ValidateJoints(result, "JOINTS_1", skinsMaxJointCount); } attributes.TryGetValue("WEIGHTS_0", out Accessor weights0); attributes.TryGetValue("WEIGHTS_1", out Accessor weights1); _ValidateWeights(result, weights0, weights1); }
private void _ValidatePositions(VALIDATIONCTX validate) { validate = validate.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER); if (!this.LogicalParent.MeshQuantizationAllowed) { validate.IsAnyOf(nameof(Format), Format, DimensionType.VEC3); } else { validate.IsAnyOf(nameof(Dimensions), Dimensions, DimensionType.VEC3); } validate.ArePositions("POSITION", this.AsVector3Array()); }
private void _ValidatePositions(VALIDATIONCTX result) { result = result.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(result, BufferMode.ARRAY_BUFFER); result.CheckLinkMustBeAnyOf(nameof(Dimensions), Dimensions, DimensionType.VEC3); if (!this.LogicalParent.MeshQuantizationAllowed) { result.CheckLinkMustBeAnyOf(nameof(Normalized), Normalized, false); result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.FLOAT); } var positions = this.AsVector3Array(); for (int i = 0; i < positions.Count; ++i) { result.CheckIsFinite(i, positions[i]); } }
private void _ValidateJoints(VALIDATIONCTX result, string attributeName, int skinsMaxJointCount) { result = result.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(result, BufferMode.ARRAY_BUFFER); result.CheckLinkMustBeAnyOf(nameof(Normalized), Normalized, false); result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.UNSIGNED_BYTE, EncodingType.UNSIGNED_SHORT, EncodingType.FLOAT); result.CheckLinkMustBeAnyOf(nameof(Dimensions), Dimensions, DimensionType.VEC4); var joints = this.AsVector4Array(); for (int i = 0; i < joints.Count; ++i) { var jidx = joints[i]; result.CheckIsFinite(i, jidx); result.CheckIsInRange(i, jidx, 0, skinsMaxJointCount); } }
internal static void ValidateVertexAttributes(VALIDATIONCTX validate, IReadOnlyDictionary <string, Accessor> attributes, int skinsMaxJointCount) { if (validate.TryFix) { foreach (var kvp in attributes.Where(item => item.Key != "POSITION")) { // remove unnecessary bounds kvp.Value._min.Clear(); kvp.Value._max.Clear(); } } if (attributes.TryGetValue("POSITION", out Accessor positions)) { positions._ValidatePositions(validate); } if (attributes.TryGetValue("NORMAL", out Accessor normals)) { normals._ValidateNormals(validate); } if (attributes.TryGetValue("TANGENT", out Accessor tangents)) { tangents._ValidateTangents(validate); } if (attributes.TryGetValue("JOINTS_0", out Accessor joints0)) { joints0._ValidateJoints(validate, "JOINTS_0", skinsMaxJointCount); } if (attributes.TryGetValue("JOINTS_1", out Accessor joints1)) { joints0._ValidateJoints(validate, "JOINTS_1", skinsMaxJointCount); } attributes.TryGetValue("WEIGHTS_0", out Accessor weights0); attributes.TryGetValue("WEIGHTS_1", out Accessor weights1); _ValidateWeights(validate, weights0, weights1); }
private void _ValidateTangents(VALIDATIONCTX result) { result = result.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(result, BufferMode.ARRAY_BUFFER); result.CheckLinkMustBeAnyOf(nameof(Dimensions), Dimensions, DimensionType.VEC3, DimensionType.VEC4); if (!this.LogicalParent.MeshQuantizationAllowed) { result.CheckLinkMustBeAnyOf(nameof(Normalized), Normalized, false); result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.FLOAT); } else { if (Normalized) { result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.BYTE, EncodingType.SHORT); } else { result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.FLOAT); } } // when Dimensions == VEC3, its morph target tangent deltas if (Dimensions == DimensionType.VEC4) { var tangents = this.AsVector4Array(); for (int i = 0; i < tangents.Count; ++i) { if (result.TryFixTangentOrError(i, tangents[i])) { tangents[i] = tangents[i].SanitizeTangent(); } } } }
private void _ValidateTangents(VALIDATIONCTX validate) { validate = validate.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(validate, BufferMode.ARRAY_BUFFER); if (!this.LogicalParent.MeshQuantizationAllowed) { validate.IsAnyOf(nameof(Format), Format, DimensionType.VEC3, DimensionType.VEC4); } else { validate.IsAnyOf(nameof(Dimensions), Dimensions, DimensionType.VEC3, DimensionType.VEC4); } if (validate.TryFix) { if (Dimensions == DimensionType.VEC3) { this.AsVector3Array().SanitizeNormals(); } if (Dimensions == DimensionType.VEC4) { this.AsVector4Array().SanitizeTangents(); } } if (Dimensions == DimensionType.VEC3) { validate.AreNormals("TANGENT", this.AsVector3Array()); } if (Dimensions == DimensionType.VEC4) { validate.AreTangents("TANGENT", this.AsVector4Array()); } }
internal void ValidateAnimationOutput(VALIDATIONCTX validate) { SourceBufferView.ValidateBufferUsagePlainData(validate); validate.IsAnyOf(nameof(Dimensions), Dimensions, DimensionType.SCALAR, DimensionType.VEC3, DimensionType.VEC4); }
internal void ValidateAnimationOutput(VALIDATIONCTX result) { SourceBufferView.ValidateBufferUsagePlainData(result); result.CheckLinkMustBeAnyOf(nameof(Dimensions), Dimensions, DimensionType.SCALAR, DimensionType.VEC3, DimensionType.VEC4); }