diff --git a/src/ObjLoading/XModel/Gltf/GltfLoader.cpp b/src/ObjLoading/XModel/Gltf/GltfLoader.cpp index d7eb4d4c..b7610a46 100644 --- a/src/ObjLoading/XModel/Gltf/GltfLoader.cpp +++ b/src/ObjLoading/XModel/Gltf/GltfLoader.cpp @@ -636,12 +636,13 @@ namespace throw GltfLoadException("Accessor references invalid buffer view"); const auto* bufferView = m_buffer_views[*jAccessor.bufferView].get(); + const auto byteOffset = jAccessor.byteOffset.value_or(0u); if (jAccessor.componentType == JsonAccessorComponentType::FLOAT) - m_accessors.emplace_back(std::make_unique(bufferView, jAccessor.type, jAccessor.count)); + m_accessors.emplace_back(std::make_unique(bufferView, jAccessor.type, byteOffset, jAccessor.count)); else if (jAccessor.componentType == JsonAccessorComponentType::UNSIGNED_BYTE) - m_accessors.emplace_back(std::make_unique(bufferView, jAccessor.type, jAccessor.count)); + m_accessors.emplace_back(std::make_unique(bufferView, jAccessor.type, byteOffset, jAccessor.count)); else if (jAccessor.componentType == JsonAccessorComponentType::UNSIGNED_SHORT) - m_accessors.emplace_back(std::make_unique(bufferView, jAccessor.type, jAccessor.count)); + m_accessors.emplace_back(std::make_unique(bufferView, jAccessor.type, byteOffset, jAccessor.count)); else throw GltfLoadException(std::format("Accessor has unsupported component type {}", static_cast(jAccessor.componentType))); } diff --git a/src/ObjLoading/XModel/Gltf/Internal/GltfAccessor.cpp b/src/ObjLoading/XModel/Gltf/Internal/GltfAccessor.cpp index f33ff546..3ded1bb8 100644 --- a/src/ObjLoading/XModel/Gltf/Internal/GltfAccessor.cpp +++ b/src/ObjLoading/XModel/Gltf/Internal/GltfAccessor.cpp @@ -81,9 +81,10 @@ size_t NullAccessor::GetCount() const return m_count; } -FloatAccessor::FloatAccessor(const BufferView* bufferView, const JsonAccessorType type, const size_t count) +FloatAccessor::FloatAccessor(const BufferView* bufferView, const JsonAccessorType type, size_t byteOffset, const size_t count) : m_buffer_view(bufferView), m_type(type), + m_byte_offset(byteOffset), m_count(count) { } @@ -109,7 +110,7 @@ bool FloatAccessor::GetFloatVec2(const size_t index, float (&out)[2]) const if (index >= m_count) return false; - return m_buffer_view->ReadElement(&out, index, sizeof(float[2])); + return m_buffer_view->ReadElement(&out, index, sizeof(float[2]), m_byte_offset); } bool FloatAccessor::GetFloatVec3(const size_t index, float (&out)[3]) const @@ -118,7 +119,7 @@ bool FloatAccessor::GetFloatVec3(const size_t index, float (&out)[3]) const if (index >= m_count) return false; - return m_buffer_view->ReadElement(&out, index, sizeof(float[3])); + return m_buffer_view->ReadElement(&out, index, sizeof(float[3]), m_byte_offset); } bool FloatAccessor::GetFloatVec4(const size_t index, float (&out)[4]) const @@ -127,7 +128,7 @@ bool FloatAccessor::GetFloatVec4(const size_t index, float (&out)[4]) const if (index >= m_count) return false; - return m_buffer_view->ReadElement(&out, index, sizeof(float[4])); + return m_buffer_view->ReadElement(&out, index, sizeof(float[4]), m_byte_offset); } bool FloatAccessor::GetUnsigned(size_t index, unsigned& out) const @@ -140,9 +141,10 @@ bool FloatAccessor::GetUnsignedVec4(size_t index, unsigned (&out)[4]) const return false; } -UnsignedByteAccessor::UnsignedByteAccessor(const BufferView* bufferView, const JsonAccessorType type, const size_t count) +UnsignedByteAccessor::UnsignedByteAccessor(const BufferView* bufferView, const JsonAccessorType type, size_t byteOffset, const size_t count) : m_buffer_view(bufferView), m_type(type), + m_byte_offset(byteOffset), m_count(count) { } @@ -169,7 +171,7 @@ bool UnsignedByteAccessor::GetFloatVec2(const size_t index, float (&out)[2]) con return false; uint8_t temp[2]; - if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[2]))) + if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[2]), m_byte_offset)) return false; // Return as normalized value between 0 and 1 @@ -186,7 +188,7 @@ bool UnsignedByteAccessor::GetFloatVec3(const size_t index, float (&out)[3]) con return false; uint8_t temp[3]; - if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[3]))) + if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[3]), m_byte_offset)) return false; // Return as normalized value between 0 and 1 @@ -204,7 +206,7 @@ bool UnsignedByteAccessor::GetFloatVec4(const size_t index, float (&out)[4]) con return false; uint8_t temp[4]; - if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[4]))) + if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[4]), m_byte_offset)) return false; // Return as normalized value between 0 and 1 @@ -222,7 +224,7 @@ bool UnsignedByteAccessor::GetUnsigned(const size_t index, unsigned& out) const return false; uint8_t temp; - if (!m_buffer_view->ReadElement(&temp, index, sizeof(uint8_t))) + if (!m_buffer_view->ReadElement(&temp, index, sizeof(uint8_t), m_byte_offset)) return false; out = temp; @@ -236,7 +238,7 @@ bool UnsignedByteAccessor::GetUnsignedVec4(const size_t index, unsigned (&out)[4 return false; uint8_t temp[4]; - if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[4]))) + if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[4]), m_byte_offset)) return false; out[0] = static_cast(temp[0]); @@ -247,9 +249,10 @@ bool UnsignedByteAccessor::GetUnsignedVec4(const size_t index, unsigned (&out)[4 return true; } -UnsignedShortAccessor::UnsignedShortAccessor(const BufferView* bufferView, const JsonAccessorType type, const size_t count) +UnsignedShortAccessor::UnsignedShortAccessor(const BufferView* bufferView, const JsonAccessorType type, size_t byteOffset, const size_t count) : m_buffer_view(bufferView), m_type(type), + m_byte_offset(byteOffset), m_count(count) { } @@ -276,7 +279,7 @@ bool UnsignedShortAccessor::GetFloatVec2(const size_t index, float (&out)[2]) co return false; uint16_t temp[2]; - if (!m_buffer_view->ReadElement(temp, index, sizeof(uint16_t[2]))) + if (!m_buffer_view->ReadElement(temp, index, sizeof(uint16_t[2]), m_byte_offset)) return false; // Return as normalized value between 0 and 1 @@ -293,7 +296,7 @@ bool UnsignedShortAccessor::GetFloatVec3(const size_t index, float (&out)[3]) co return false; uint16_t temp[3]; - if (!m_buffer_view->ReadElement(temp, index, sizeof(uint16_t[3]))) + if (!m_buffer_view->ReadElement(temp, index, sizeof(uint16_t[3]), m_byte_offset)) return false; // Return as normalized value between 0 and 1 @@ -311,7 +314,7 @@ bool UnsignedShortAccessor::GetFloatVec4(const size_t index, float (&out)[4]) co return false; uint16_t temp[4]; - if (!m_buffer_view->ReadElement(temp, index, sizeof(uint16_t[4]))) + if (!m_buffer_view->ReadElement(temp, index, sizeof(uint16_t[4]), m_byte_offset)) return false; // Return as normalized value between 0 and 1 @@ -329,7 +332,7 @@ bool UnsignedShortAccessor::GetUnsigned(const size_t index, unsigned& out) const return false; uint16_t temp; - if (!m_buffer_view->ReadElement(&temp, index, sizeof(uint16_t))) + if (!m_buffer_view->ReadElement(&temp, index, sizeof(uint16_t), m_byte_offset)) return false; out = temp; @@ -343,7 +346,7 @@ bool UnsignedShortAccessor::GetUnsignedVec4(const size_t index, unsigned (&out)[ return false; uint16_t temp[4]; - if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[4]))) + if (!m_buffer_view->ReadElement(temp, index, sizeof(uint8_t[4]), m_byte_offset)) return false; out[0] = static_cast(temp[0]); diff --git a/src/ObjLoading/XModel/Gltf/Internal/GltfAccessor.h b/src/ObjLoading/XModel/Gltf/Internal/GltfAccessor.h index c2aeaaa7..12b442c3 100644 --- a/src/ObjLoading/XModel/Gltf/Internal/GltfAccessor.h +++ b/src/ObjLoading/XModel/Gltf/Internal/GltfAccessor.h @@ -49,7 +49,7 @@ namespace gltf class FloatAccessor final : public Accessor { public: - FloatAccessor(const BufferView* bufferView, JsonAccessorType type, size_t count); + FloatAccessor(const BufferView* bufferView, JsonAccessorType type, size_t byteOffset, size_t count); [[nodiscard]] std::optional GetType() const override; [[nodiscard]] std::optional GetComponentType() const override; @@ -64,13 +64,14 @@ namespace gltf private: const BufferView* m_buffer_view; JsonAccessorType m_type; + size_t m_byte_offset; size_t m_count; }; class UnsignedByteAccessor final : public Accessor { public: - UnsignedByteAccessor(const BufferView* bufferView, JsonAccessorType type, size_t count); + UnsignedByteAccessor(const BufferView* bufferView, JsonAccessorType type, size_t byteOffset, size_t count); [[nodiscard]] std::optional GetType() const override; [[nodiscard]] std::optional GetComponentType() const override; @@ -85,13 +86,14 @@ namespace gltf private: const BufferView* m_buffer_view; JsonAccessorType m_type; + size_t m_byte_offset; size_t m_count; }; class UnsignedShortAccessor final : public Accessor { public: - UnsignedShortAccessor(const BufferView* bufferView, JsonAccessorType type, size_t count); + UnsignedShortAccessor(const BufferView* bufferView, JsonAccessorType type, size_t byteOffset, size_t count); [[nodiscard]] std::optional GetType() const override; [[nodiscard]] std::optional GetComponentType() const override; @@ -106,6 +108,7 @@ namespace gltf private: const BufferView* m_buffer_view; JsonAccessorType m_type; + size_t m_byte_offset; size_t m_count; }; } // namespace gltf diff --git a/src/ObjLoading/XModel/Gltf/Internal/GltfBufferView.cpp b/src/ObjLoading/XModel/Gltf/Internal/GltfBufferView.cpp index cf071987..0b87fecb 100644 --- a/src/ObjLoading/XModel/Gltf/Internal/GltfBufferView.cpp +++ b/src/ObjLoading/XModel/Gltf/Internal/GltfBufferView.cpp @@ -10,10 +10,10 @@ BufferView::BufferView(const Buffer* buffer, const size_t offset, const size_t l { } -bool BufferView::ReadElement(void* dest, const size_t elementIndex, const size_t elementSize) const +bool BufferView::ReadElement(void* dest, const size_t elementIndex, const size_t elementSize, const size_t elementOffset) const { - const auto stride = std::max(elementSize, m_stride); - const auto bufferViewOffset = elementIndex * stride; + const auto stride = std::max(elementOffset + elementSize, m_stride); + const auto bufferViewOffset = elementOffset + elementIndex * stride; if (bufferViewOffset + elementSize > m_length) return false; diff --git a/src/ObjLoading/XModel/Gltf/Internal/GltfBufferView.h b/src/ObjLoading/XModel/Gltf/Internal/GltfBufferView.h index fc0e442c..2a69d77d 100644 --- a/src/ObjLoading/XModel/Gltf/Internal/GltfBufferView.h +++ b/src/ObjLoading/XModel/Gltf/Internal/GltfBufferView.h @@ -8,7 +8,7 @@ namespace gltf public: BufferView(const Buffer* buffer, size_t offset, size_t length, size_t stride); - bool ReadElement(void* dest, size_t elementIndex, size_t elementSize) const; + bool ReadElement(void* dest, size_t elementIndex, size_t elementSize, size_t elementOffset) const; private: const Buffer* m_buffer;