mirror of
https://github.com/minetest/minetest.git
synced 2024-07-04 15:05:27 +02:00
Fix/improve reading from accessors
- Alignment issues - Use os::Byteswap::byteswap - Directly write into matrices
This commit is contained in:
parent
be375cdfb6
commit
8c35461af2
@ -12,6 +12,7 @@
|
|||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "quaternion.h"
|
#include "quaternion.h"
|
||||||
#include "vector3d.h"
|
#include "vector3d.h"
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
#include "tiniergltf.hpp"
|
#include "tiniergltf.hpp"
|
||||||
|
|
||||||
@ -163,24 +164,23 @@ SelfType::Accessor<T>::make(const tiniergltf::GlTF &model, std::size_t accessorI
|
|||||||
return tiniergltf::Accessor::ComponentType::V; \
|
return tiniergltf::Accessor::ComponentType::V; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VEC_ACCESSOR_TYPES(T, U, n) \
|
#define VEC_ACCESSOR_TYPES(T, U, N) \
|
||||||
template <> \
|
template <> \
|
||||||
constexpr tiniergltf::Accessor::Type SelfType::Accessor<std::array<T, n>>::getType() \
|
constexpr tiniergltf::Accessor::Type SelfType::Accessor<std::array<T, N>>::getType() \
|
||||||
{ \
|
{ \
|
||||||
return tiniergltf::Accessor::Type::VEC##n; \
|
return tiniergltf::Accessor::Type::VEC##N; \
|
||||||
} \
|
} \
|
||||||
template <> \
|
template <> \
|
||||||
constexpr tiniergltf::Accessor::ComponentType SelfType::Accessor<std::array<T, n>>::getComponentType() \
|
constexpr tiniergltf::Accessor::ComponentType SelfType::Accessor<std::array<T, N>>::getComponentType() \
|
||||||
{ \
|
{ \
|
||||||
return tiniergltf::Accessor::ComponentType::U; \
|
return tiniergltf::Accessor::ComponentType::U; \
|
||||||
} \
|
} \
|
||||||
template <> \
|
template <> \
|
||||||
std::array<T, n> SelfType::rawget(const void *ptr) \
|
std::array<T, N> SelfType::rawget(const u8 *ptr) \
|
||||||
{ \
|
{ \
|
||||||
const T *tptr = reinterpret_cast<const T *>(ptr); \
|
std::array<T, N> res; \
|
||||||
std::array<T, n> res; \
|
for (u8 i = 0; i < N; ++i) \
|
||||||
for (u8 i = 0; i < n; ++i) \
|
res[i] = rawget<T>(ptr + sizeof(T) * i); \
|
||||||
res[i] = rawget<T>(tptr + i); \
|
|
||||||
return res; \
|
return res; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,66 +217,47 @@ T SelfType::Accessor<T>::get(std::size_t i) const
|
|||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: clang and gcc should both optimize this out.
|
|
||||||
static inline bool is_big_endian()
|
|
||||||
{
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T SelfType::rawget(const void *ptr)
|
T SelfType::rawget(const u8 *ptr)
|
||||||
{
|
{
|
||||||
if (!is_big_endian())
|
T dest;
|
||||||
return *reinterpret_cast<const T *>(ptr);
|
std::memcpy(&dest, ptr, sizeof(dest));
|
||||||
// glTF uses little endian.
|
#ifdef __BIG_ENDIAN__
|
||||||
// On big-endian systems, we have to swap the byte order.
|
return os::Byteswap::byteswap(dest);
|
||||||
// TODO test this on a big endian system
|
#else
|
||||||
const u8 *bptr = reinterpret_cast<const u8 *>(ptr);
|
return dest;
|
||||||
u8 bytes[sizeof(T)];
|
#endif
|
||||||
for (std::size_t i = 0; i < sizeof(T); ++i) {
|
|
||||||
bytes[sizeof(T) - i - 1] = bptr[i];
|
|
||||||
}
|
|
||||||
return *reinterpret_cast<const T *>(bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that these "more specialized templates" should win.
|
// Note that these "more specialized templates" should win.
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
core::matrix4 SelfType::rawget(const void *ptr)
|
core::matrix4 SelfType::rawget(const u8 *ptr)
|
||||||
{
|
{
|
||||||
const f32 *fptr = reinterpret_cast<const f32 *>(ptr);
|
|
||||||
f32 M[16];
|
|
||||||
for (u8 i = 0; i < 16; ++i) {
|
|
||||||
M[i] = rawget<f32>(fptr + i);
|
|
||||||
}
|
|
||||||
core::matrix4 mat;
|
core::matrix4 mat;
|
||||||
mat.setM(M);
|
for (u8 i = 0; i < 16; ++i) {
|
||||||
|
mat[i] = rawget<f32>(ptr + i * sizeof(f32));
|
||||||
|
}
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
core::vector3df SelfType::rawget(const void *ptr)
|
core::vector3df SelfType::rawget(const u8 *ptr)
|
||||||
{
|
{
|
||||||
const f32 *fptr = reinterpret_cast<const f32 *>(ptr);
|
|
||||||
return core::vector3df(
|
return core::vector3df(
|
||||||
rawget<f32>(fptr),
|
rawget<f32>(ptr),
|
||||||
rawget<f32>(fptr + 1),
|
rawget<f32>(ptr + sizeof(f32)),
|
||||||
rawget<f32>(fptr + 2));
|
rawget<f32>(ptr + 2 * sizeof(f32)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
core::quaternion SelfType::rawget(const void *ptr)
|
core::quaternion SelfType::rawget(const u8 *ptr)
|
||||||
{
|
{
|
||||||
const f32 *fptr = reinterpret_cast<const f32 *>(ptr);
|
|
||||||
return core::quaternion(
|
return core::quaternion(
|
||||||
rawget<f32>(fptr),
|
rawget<f32>(ptr),
|
||||||
rawget<f32>(fptr + 1),
|
rawget<f32>(ptr + sizeof(f32)),
|
||||||
rawget<f32>(fptr + 2),
|
rawget<f32>(ptr + 2 * sizeof(f32)),
|
||||||
rawget<f32>(fptr + 3));
|
rawget<f32>(ptr + 3 * sizeof(f32)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
|
@ -32,7 +32,7 @@ class CGLTFMeshFileLoader : public IMeshLoader
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static T rawget(const void *ptr);
|
static T rawget(const u8 *ptr);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class Accessor
|
class Accessor
|
||||||
|
Loading…
Reference in New Issue
Block a user