internal void OnValidateBinaryChunk(Validation.ValidationContext result, Byte[] binaryChunk) { if (_uri == null) { if (binaryChunk == null) { result.GetContext(this).AddSchemaError("Binary chunk not found"); return; } if (_byteLength > binaryChunk.Length) { result.GetContext(this).AddSchemaError("Buffer length larger than Binary chunk"); } } }
internal void ValidateNormals(Validation.ValidationContext 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(); } } }
internal void ValidateIndices(Validation.ValidationContext 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 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}"); } } }
protected override void OnValidateContent(Validation.ValidationContext validate) { if (_weights.Count > 0) { foreach (var p in this.Primitives) { validate.GetContext(p).AreEqual("MorphTargetsCount", p.MorphTargetsCount, _weights.Count); } } base.OnValidateContent(validate); }
internal void ValidateMatrices(Validation.ValidationContext result) { result = result.GetContext(this); SourceBufferView.ValidateBufferUsageData(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 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}'."); }
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 OnValidateBinaryChunk(Validation.ValidationContext validate, Byte[] binaryChunk) { validate = validate.GetContext(this); if (_uri == null) { validate .NotNull(nameof(binaryChunk), binaryChunk) .IsLessOrEqual("ByteLength", _byteLength, binaryChunk.Length); } else { validate .IsValidURI(nameof(_uri), _uri, EMBEDDEDGLTFBUFFER, EMBEDDEDOCTETSTREAM); } }
internal void ValidateJoints(Validation.ValidationContext result, string attributeName) { 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) { result.CheckIsFinite(i, joints[i]); } }
internal void ValidateTangents(Validation.ValidationContext result) { result = result.GetContext(this); SourceBufferView.ValidateBufferUsageGPU(result, BufferMode.ARRAY_BUFFER); result.CheckLinkMustBeAnyOf(nameof(Normalized), Normalized, false); result.CheckLinkMustBeAnyOf(nameof(Encoding), Encoding, EncodingType.FLOAT); result.CheckLinkMustBeAnyOf(nameof(Dimensions), Dimensions, DimensionType.VEC3, DimensionType.VEC4); var tangents = this.AsVector4Array(); for (int i = 0; i < tangents.Count; ++i) { result.CheckIsTangent(i, tangents[i]); } }
internal void ValidateWeights(Validation.ValidationContext result, int jwset) { 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); var weights = this.AsVector4Array(); for (int i = 0; i < weights.Count; ++i) { result.CheckIsInRange(i, weights[i], 0, 1); // theoretically, the sum of all the weights should give 1, ASSUMING there's only one weight set. // but in practice, that seems not to be true. } }
internal void ValidatePositions(Validation.ValidationContext 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]); } }
protected override void OnValidateReferences(Validation.ValidationContext validate) { base.OnValidateReferences(validate); // check out of range indices foreach (var idx in this._nodes) { validate.IsNullOrIndex(nameof(VisualChildren), idx, this.LogicalParent.LogicalNodes); } // checks if a root node is being used as a child. foreach (var node in this.LogicalParent.LogicalNodes) { if (this._nodes.Any(ridx => node._HasVisualChild(ridx))) { validate.GetContext(node)._LinkThrow("Children", "Root nodes cannot be children."); } } // check duplicated indices // if (this._nodes.Distinct().Count() != this._nodes.Count) result.AddError(this, "has duplicated node references"); }
internal void ValidateBufferUsagePlainData(Validation.ValidationContext result) { if (this._byteStride.HasValue) { if (result.TryFixLinkOrError("BufferView", "Unexpected ByteStride found. Expected null")) { this._byteStride = null; } } result = result.GetContext(this); if (!this._target.HasValue) { return; } if (result.TryFixLinkOrError("Device Buffer Target", $"is set as {this._target.Value}. But an accessor wants to use it as a plain data buffer.")) { this._target = null; } }
internal void ValidateTangents(Validation.ValidationContext 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(); } } } }
internal void ValidateContent(Validation.ValidationContext validate) { validate = validate.GetContext(this); OnValidateContent(validate); }
internal void ValidateReferences(Validation.ValidationContext validate) { validate = validate.GetContext(this); OnValidateReferences(validate); }