2 // SPDX-License-Identifier: LGPL-2.1-or-later
6 #include "CSkinnedMesh.h"
7 #include "IMeshLoader.h"
11 #include "S3DVertex.h"
13 #include "tiniergltf.hpp"
26 class CGLTFMeshFileLoader
: public IMeshLoader
29 CGLTFMeshFileLoader() noexcept
{};
31 bool isALoadableFileExtension(const io::path
&filename
) const override
;
33 IAnimatedMesh
*createMesh(io::IReadFile
*file
) override
;
37 static T
rawget(const char *ptr
);
45 std::size_t byteStride
;
47 using Source
= std::variant
<BufferSource
, std::vector
<T
>, std::tuple
<>>;
50 static Accessor
sparseIndices(
51 const tiniergltf::GlTF
&model
,
52 const tiniergltf::AccessorSparseIndices
&indices
,
53 const std::size_t count
);
54 static Accessor
sparseValues(
55 const tiniergltf::GlTF
&model
,
56 const tiniergltf::AccessorSparseValues
&values
,
57 const std::size_t count
,
58 const std::size_t defaultByteStride
);
60 const tiniergltf::GlTF
&model
,
61 std::size_t accessorIdx
);
62 static Accessor
make(const tiniergltf::GlTF
&model
, std::size_t accessorIdx
);
63 static constexpr tiniergltf::Accessor::Type
getType();
64 static constexpr tiniergltf::Accessor::ComponentType
getComponentType();
65 std::size_t getCount() const { return count
; }
66 T
get(std::size_t i
) const;
69 Accessor(const char *ptr
, std::size_t byteStride
, std::size_t count
) :
70 source(BufferSource
{ptr
, byteStride
}), count(count
) {}
71 Accessor(std::vector
<T
> vec
, std::size_t count
) :
72 source(vec
), count(count
) {}
73 Accessor(std::size_t count
) :
74 source(std::make_tuple()), count(count
) {}
75 // Directly from buffer, sparse, or default-initialized
77 const std::size_t count
;
80 template <typename
... Ts
>
81 using AccessorVariant
= std::variant
<Accessor
<Ts
>...>;
83 template <std::size_t N
, typename
... Ts
>
84 using ArrayAccessorVariant
= std::variant
<Accessor
<std::array
<Ts
, N
>>...>;
86 template <std::size_t N
>
87 using NormalizedValuesAccessor
= ArrayAccessorVariant
<N
, u8
, u16
, f32
>;
89 template <std::size_t N
>
90 static NormalizedValuesAccessor
<N
> createNormalizedValuesAccessor(
91 const tiniergltf::GlTF
&model
,
92 const std::size_t accessorIdx
);
94 template <std::size_t N
>
95 static std::array
<f32
, N
> getNormalizedValues(
96 const NormalizedValuesAccessor
<N
> &accessor
,
102 MeshExtractor(tiniergltf::GlTF
&&model
,
103 CSkinnedMesh
*mesh
) noexcept
104 : m_gltf_model(std::move(model
)), m_irr_model(mesh
) {};
106 /* Gets indices for the given mesh/primitive.
108 * Values are return in Irrlicht winding order.
110 std::optional
<std::vector
<u16
>> getIndices(
111 const tiniergltf::MeshPrimitive
&primitive
) const;
113 std::optional
<std::vector
<video::S3DVertex
>> getVertices(
114 const tiniergltf::MeshPrimitive
&primitive
) const;
116 std::size_t getMeshCount() const;
118 std::size_t getPrimitiveCount(const std::size_t meshIdx
) const;
121 const std::vector
<std::string
> &getWarnings() {
126 const tiniergltf::GlTF m_gltf_model
;
127 CSkinnedMesh
*m_irr_model
;
129 std::vector
<std::function
<void()>> m_mesh_loaders
;
130 std::vector
<CSkinnedMesh::SJoint
*> m_loaded_nodes
;
132 std::vector
<std::string
> warnings
;
133 void warn(const std::string
&warning
) {
134 warnings
.push_back(warning
);
137 void copyPositions(const std::size_t accessorIdx
,
138 std::vector
<video::S3DVertex
>& vertices
) const;
140 void copyNormals(const std::size_t accessorIdx
,
141 std::vector
<video::S3DVertex
>& vertices
) const;
143 void copyTCoords(const std::size_t accessorIdx
,
144 std::vector
<video::S3DVertex
>& vertices
) const;
146 void addPrimitive(const tiniergltf::MeshPrimitive
&primitive
,
147 const std::optional
<std::size_t> skinIdx
,
148 CSkinnedMesh::SJoint
*parent
);
150 void deferAddMesh(const std::size_t meshIdx
,
151 const std::optional
<std::size_t> skinIdx
,
152 CSkinnedMesh::SJoint
*parentJoint
);
154 void loadNode(const std::size_t nodeIdx
, CSkinnedMesh::SJoint
*parentJoint
);
160 void loadAnimation(const std::size_t animIdx
);
163 tiniergltf::GlTF
parseGLTF(io::IReadFile
*file
);