Skip to content

Commit

Permalink
Fix: Don't allow direct accessor memcpy for matrices
Browse files Browse the repository at this point in the history
Matrices sometimes need special padding between rows, so we can't just perform a memcpy in those cases.
  • Loading branch information
spnda committed Jun 22, 2024
1 parent 235bafd commit 9068102
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 8 deletions.
1 change: 1 addition & 0 deletions docs/tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ For example, if you had a custom vector type like ``MyVec3``, you'd just need to
**fastgltf** includes these definitions for types from other math libraries. Currently, **fastgltf** supports
DirectXMath with ``fastgltf/dxmath_element_traits.hpp`` and glm with ``fastgltf/glm_element_traits.hpp``.
Simply including these headers will allow the tools to convert to your preferred types directly.
These headers could also be used as a reference on how to add support for other types.

.. note::

Expand Down
12 changes: 4 additions & 8 deletions include/fastgltf/tools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ void iterateAccessorWithIndex(const Asset& asset, const Accessor& accessor, Func
}

FASTGLTF_EXPORT template <typename ElementType, std::size_t TargetStride = sizeof(ElementType),
typename BufferDataAdapter = DefaultBufferDataAdapter>
typename BufferDataAdapter = DefaultBufferDataAdapter>
#if FASTGLTF_HAS_CONCEPTS
requires Element<ElementType>
#endif
Expand Down Expand Up @@ -780,13 +780,12 @@ void copyFromAccessor(const Asset& asset, const Accessor& accessor, void* dest,
}

auto& view = asset.bufferViews[*accessor.bufferViewIndex];
auto srcStride = view.byteStride ? *view.byteStride
: getElementByteSize(accessor.type, accessor.componentType);
auto srcStride = view.byteStride.value_or(elemSize);

auto srcBytes = adapter(asset, *accessor.bufferViewIndex).subspan(accessor.byteOffset);

// If the data is normalized or the component/accessor type is different, we have to convert each element and can't memcpy.
if (std::is_trivially_copyable_v<ElementType> && !accessor.normalized && accessor.componentType == Traits::enum_component_type) {
if (std::is_trivially_copyable_v<ElementType> && !accessor.normalized && accessor.componentType == Traits::enum_component_type && !isMatrix(accessor.type)) {
if (srcStride == elemSize && srcStride == TargetStride) {
std::memcpy(dest, srcBytes.data(), elemSize * accessor.count);
} else {
Expand All @@ -812,10 +811,7 @@ FASTGLTF_EXPORT inline auto getTransformMatrix(const Node& node, const math::fma
return base * matrix;
},
[&](const TRS& trs) {
return base
* translate(math::fmat4x4(), trs.translation)
* math::fmat4x4(asMatrix(trs.rotation))
* scale(math::fmat4x4(), trs.scale);
return scale(rotate(translate(base, trs.translation), trs.rotation), trs.scale);
}
}, node.transform);
}
Expand Down

0 comments on commit 9068102

Please sign in to comment.