internal void ValidateIndices(ValidationContext validate, int count) { validate = validate.GetContext(this); var bv = validate.Root.LogicalBufferViews[_bufferView]; BufferView.VerifyAccess(validate, bv, _byteOffset ?? _byteOffsetDefault, (DimensionType.SCALAR, _componentType.ToComponent()), count); }
internal AccessorSparseValues(BufferView bv, int byteOffset) { Guard.NotNull(bv, nameof(bv)); Guard.MustBeGreaterThanOrEqualTo(byteOffset, _byteOffsetMinimum, nameof(byteOffset)); this._bufferView = bv.LogicalIndex; this._byteOffset = byteOffset.AsNullable(_byteOffsetDefault); }
/// <summary> /// Associates this <see cref="Accessor"/> with a <see cref="BufferView"/> /// </summary> /// <param name="buffer">The <see cref="BufferView"/> source.</param> /// <param name="bufferByteOffset">The start byte offset within <paramref name="buffer"/>.</param> /// <param name="itemCount">The number of items in the accessor.</param> /// <param name="encoding">The <see cref="IndexEncodingType"/> item encoding.</param> public void SetIndexData(BufferView buffer, int bufferByteOffset, int itemCount, IndexEncodingType encoding) { Guard.NotNull(buffer, nameof(buffer)); Guard.MustShareLogicalParent(this, buffer, nameof(buffer)); Guard.IsFalse(buffer.IsVertexBuffer, nameof(buffer)); SetData(buffer, bufferByteOffset, itemCount, DimensionType.SCALAR, encoding.ToComponent(), false); }
internal void Validate(ValidationContext result, int count) { result = result.GetContext(this); var bv = result.Root.LogicalBufferViews[_bufferView]; BufferView.CheckAccess(result, bv, _byteOffset ?? _byteOffsetDefault, DimensionType.SCALAR, _componentType.ToComponent(), false, count); }
/// <summary> /// Associates this <see cref="Accessor"/> with a <see cref="BufferView"/> /// </summary> /// <param name="buffer">The <see cref="BufferView"/> source.</param> /// <param name="bufferByteOffset">The start byte offset within <paramref name="buffer"/>.</param> /// <param name="itemCount">The number of items in the accessor.</param> /// <param name="dimensions">The <see cref="DimensionType"/> item type.</param> /// <param name="encoding">The <see cref="EncodingType"/> item encoding.</param> /// <param name="normalized">The item normalization mode.</param> public void SetVertexData(BufferView buffer, int bufferByteOffset, int itemCount, DimensionType dimensions = DimensionType.VEC3, EncodingType encoding = EncodingType.FLOAT, Boolean normalized = false) { Guard.NotNull(buffer, nameof(buffer)); Guard.MustShareLogicalParent(this, buffer, nameof(buffer)); Guard.MustBePositiveAndMultipleOf(dimensions.DimCount() * encoding.ByteLength(), 4, nameof(encoding)); Guard.IsFalse(buffer.IsIndexBuffer, nameof(buffer)); SetData(buffer, bufferByteOffset, itemCount, dimensions, encoding, normalized); }
internal AccessorSparseIndices(BufferView bv, int byteOffset, IndexEncodingType encoding) { Guard.NotNull(bv, nameof(bv)); Guard.MustBeGreaterThanOrEqualTo(byteOffset, _byteOffsetMinimum, nameof(byteOffset)); this._bufferView = bv.LogicalIndex; this._byteOffset = byteOffset.AsNullable(_byteOffsetDefault); this._componentType = encoding; }
internal AccessorSparse(BufferView indices, int indicesOffset, IndexEncodingType indicesEncoding, BufferView values, int valuesOffset, int count) { Guard.NotNull(indices, nameof(indices)); Guard.NotNull(values, nameof(values)); Guard.MustBeGreaterThanOrEqualTo(count, _countMinimum, nameof(count)); this._count = count; this._indices = new AccessorSparseIndices(indices, indicesOffset, indicesEncoding); this._values = new AccessorSparseValues(values, valuesOffset); }
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. }
/// <summary> /// Associates this <see cref="Accessor"/> with a <see cref="BufferView"/> /// </summary> /// <param name="buffer">The <see cref="BufferView"/> source.</param> /// <param name="bufferByteOffset">The start byte offset within <paramref name="buffer"/>.</param> /// <param name="itemCount">The number of items in the accessor.</param> /// <param name="encoding">The <see cref="IndexEncodingType"/> item encoding.</param> public void SetIndexData(BufferView buffer, int bufferByteOffset, int itemCount, IndexEncodingType encoding) { Guard.NotNull(buffer, nameof(buffer)); Guard.MustShareLogicalParent(this, buffer, nameof(buffer)); if (buffer.DeviceBufferTarget.HasValue) { Guard.IsTrue(buffer.DeviceBufferTarget.Value == BufferMode.ELEMENT_ARRAY_BUFFER, nameof(buffer)); } SetData(buffer, bufferByteOffset, itemCount, DimensionType.SCALAR, encoding.ToComponent(), false); }
protected override void OnValidate(Validation.ValidationContext 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. }
/// <summary> /// Associates this <see cref="Accessor"/> with a <see cref="BufferView"/> /// </summary> /// <param name="buffer">The <see cref="BufferView"/> source.</param> /// <param name="bufferByteOffset">The start byte offset within <paramref name="buffer"/>.</param> /// <param name="itemCount">The number of items in the accessor.</param> /// <param name="dimensions">The <see cref="DimensionType"/> item type.</param> /// <param name="encoding">The <see cref="EncodingType"/> item encoding.</param> /// <param name="normalized">The item normalization mode.</param> public void SetVertexData(BufferView buffer, int bufferByteOffset, int itemCount, DimensionType dimensions = DimensionType.VEC3, EncodingType encoding = EncodingType.FLOAT, Boolean normalized = false) { Guard.NotNull(buffer, nameof(buffer)); Guard.MustShareLogicalParent(this, buffer, nameof(buffer)); Guard.MustBePositiveAndMultipleOf(dimensions.DimCount() * encoding.ByteLength(), 4, nameof(encoding)); if (buffer.DeviceBufferTarget.HasValue) { Guard.IsTrue(buffer.DeviceBufferTarget.Value == BufferMode.ARRAY_BUFFER, nameof(buffer)); } SetData(buffer, bufferByteOffset, itemCount, dimensions, encoding, normalized); }
/// <summary> /// Associates this <see cref="Accessor"/> with a <see cref="BufferView"/> /// </summary> /// <param name="buffer">The <see cref="BufferView"/> source.</param> /// <param name="bufferByteOffset">The start byte offset within <paramref name="buffer"/>.</param> /// <param name="itemCount">The number of items in the accessor.</param> /// <param name="dimensions">The <see cref="DimensionType"/> item type.</param> /// <param name="encoding">The <see cref="EncodingType"/> item encoding.</param> /// <param name="normalized">The item normalization mode.</param> public void SetData(BufferView buffer, int bufferByteOffset, int itemCount, DimensionType dimensions, EncodingType encoding, Boolean normalized) { Guard.MustShareLogicalParent(this, buffer, nameof(buffer)); Guard.MustBeGreaterThanOrEqualTo(bufferByteOffset, _byteOffsetMinimum, nameof(bufferByteOffset)); Guard.MustBeGreaterThanOrEqualTo(itemCount, _countMinimum, nameof(itemCount)); this._bufferView = buffer.LogicalIndex; this._byteOffset = bufferByteOffset.AsNullable(_byteOffsetDefault, _byteOffsetMinimum, int.MaxValue); this._count = itemCount; this._type = dimensions; this._componentType = encoding; this._normalized = normalized.AsNullable(_normalizedDefault); UpdateBounds(); }
protected override void OnValidateContent(VALIDATIONCTX validate) { base.OnValidateContent(validate); // if Accessor.Type uses a custom dimension, // 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); 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. }
/// <summary> /// Creates or reuses a <see cref="BufferView"/> instance /// at <see cref="ModelRoot.LogicalBufferViews"/>. /// </summary> /// <param name="buffer">The buffer to wrap.</param> /// <param name="byteOffset">The zero-based index of the first Byte in <paramref name="buffer"/></param> /// <param name="byteLength">The number of elements in <paramref name="buffer"/></param> /// <param name="byteStride">For strided vertex buffers, it must be a value multiple of 4, 0 otherwise</param> /// <param name="target">The type hardware device buffer, or null</param> /// <returns>A <see cref="BufferView"/> instance.</returns> public BufferView UseBufferView(Buffer buffer, int byteOffset = 0, int?byteLength = null, int byteStride = 0, BufferMode?target = null) { Guard.NotNull(buffer, nameof(buffer)); Guard.MustShareLogicalParent(this, "this", buffer, nameof(buffer)); var content = new BYTES(buffer.Content, byteOffset, byteLength.AsValue(buffer.Content.Length - byteOffset)); foreach (var bv in this.LogicalBufferViews) { if (BufferView.AreEqual(bv, content, byteStride, target)) { return(bv); } } var newbv = new BufferView(buffer, byteOffset, byteLength, byteStride, target); this._bufferViews.Add(newbv); return(newbv); }
/// <summary> /// Creates or reuses a <see cref="BufferView"/> instance /// at <see cref="ModelRoot.LogicalBufferViews"/>. /// </summary> /// <param name="buffer">The buffer to wrap.</param> /// <param name="byteOffset">The zero-based index of the first Byte in <paramref name="buffer"/></param> /// <param name="byteLength">The number of elements in <paramref name="buffer"/></param> /// <param name="byteStride">For strided vertex buffers, it must be a value multiple of 4, 0 otherwise</param> /// <param name="target">The type hardware device buffer, or null</param> /// <returns>A <see cref="BufferView"/> instance.</returns> public BufferView UseBufferView(Buffer buffer, int byteOffset = 0, int?byteLength = null, int byteStride = 0, BufferMode?target = null) { Guard.NotNull(buffer, nameof(buffer)); Guard.MustShareLogicalParent(this, "this", buffer, nameof(buffer)); byteLength = byteLength.AsValue(buffer.Content.Length - byteOffset); foreach (var bv in this.LogicalBufferViews) { if (bv.Content.Array != buffer.Content) { continue; } if (bv.Content.Offset != byteOffset) { continue; } if (bv.Content.Count != byteLength.Value) { continue; } if (bv.ByteStride != byteStride) { continue; } if (bv.DeviceBufferTarget != target) { continue; } return(bv); } var newbv = new BufferView(buffer, byteOffset, byteLength, byteStride, target); this._bufferViews.Add(newbv); return(newbv); }
internal static bool AreEqual(BufferView bv, BYTES content, int byteStride, BufferMode?target) { if (bv.Content.Array != content.Array) { return(false); } if (bv.Content.Offset != content.Offset) { return(false); } if (bv.Content.Count != content.Count) { return(false); } if (bv.ByteStride != byteStride) { return(false); } if (bv._target != target) { return(false); } return(true); }
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); }