SleakEngine
0.1.0
C++23 multi-backend game engine
Toggle main menu visibility
Loading...
Searching...
No Matches
ModelLoader.hpp
Go to the documentation of this file.
1
#ifndef _MODELLOADER_HPP_
2
#define _MODELLOADER_HPP_
3
4
#include <
Core/OSDef.hpp
>
5
#include <
Math/Matrix.hpp
>
6
#include <
Math/Quaternion.hpp
>
7
#include <
Math/Vector.hpp
>
8
#include <cstdint>
9
#include <string>
10
#include <unordered_map>
11
#include <vector>
12
13
struct
aiNode;
14
struct
aiScene;
15
struct
aiMesh;
16
struct
aiMaterial;
17
struct
aiAnimation;
18
19
namespace
Sleak
{
20
21
class
GameObject
;
22
class
Material
;
23
class
Texture
;
24
class
Skeleton
;
25
class
AnimationClip
;
26
struct
MeshData
;
27
template
<
typename
T>
class
RefPtr
;
28
29
/// Import-time adjustments applied while loading a model file.
30
/// @ingroup rendering
31
struct
ModelLoadOptions
{
32
float
scaleFactor
= 1.0f;
33
bool
flipUVs
=
true
;
34
bool
flipNormals
=
false
;
35
bool
flipWinding
=
false
;
36
Math::Vector3D
position
=
Math::Vector3D
(0.0f, 0.0f, 0.0f);
37
Math::Quaternion
rotation
=
Math::Quaternion
();
38
};
39
40
/// Per-load texture cache to avoid loading the same texture file multiple times.
41
using
TextureCache
=
42
std::unordered_map<std::string, RefPtr<::Sleak::Texture>>;
43
44
/// Per-load cache so meshes sharing an Assimp material share one Material.
45
using
MaterialCache
= std::unordered_map<uint64_t, RefPtr<Material>>;
46
47
/// Assimp-backed importer that builds a GameObject hierarchy (meshes, materials, optionally a skeleton) from a model file.
48
///
49
/// Load() reads any format Assimp supports (FBX, glTF, OBJ, and the
50
/// rest) and returns the root of a ready-to-use GameObject tree with
51
/// meshes, materials, and textures attached. Rigged files also get a
52
/// Skeleton and an AnimatorComponent. The caller owns the returned
53
/// root: hand it to SceneBase::AddObject() and the scene takes over.
54
/// Load() returns nullptr on failure, so always check.
55
///
56
/// ModelLoadOptions covers the adjustments every import pipeline
57
/// eventually needs. `scaleFactor` converts source units to meters
58
/// (0.01 for a centimeter-based rig). `flipUVs` defaults to true
59
/// because most exporters disagree with the engine's texture origin.
60
/// `flipNormals` and `flipWinding` fix models that import inside out or
61
/// with black faces, which is nearly always an exporter handedness
62
/// mismatch rather than a shading problem.
63
///
64
/// When your mesh and your animations ship as separate files, load the
65
/// mesh once and pull the clips in with LoadAnimationsOnly(), passing
66
/// the skeleton the mesh import produced. Textures are cached for the
67
/// duration of a single Load(), so a model reusing one texture across
68
/// many materials reads it from disk once.
69
///
70
/// @code{.cpp}
71
/// Sleak::ModelLoadOptions opts;
72
/// opts.scaleFactor = 0.01f; // source is in centimeters
73
/// opts.flipUVs = true;
74
/// opts.position = Sleak::Math::Vector3D(0.0f, 0.0f, 0.0f);
75
///
76
/// Sleak::GameObject* model =
77
/// Sleak::ModelLoader::Load("assets/models/Mannequin.fbx", opts);
78
/// if (!model) {
79
/// SLEAK_ERROR("Failed to load mannequin");
80
/// return;
81
/// }
82
/// AddObject(model);
83
///
84
/// // Attach clips from separate files to the imported skeleton
85
/// if (auto* anim = model->GetComponent<Sleak::AnimatorComponent>()) {
86
/// for (auto* clip : Sleak::ModelLoader::LoadAnimationsOnly(
87
/// "assets/animations/Walking.fbx", anim->GetSkeleton())) {
88
/// if (!clip) continue;
89
/// clip->name = "Walking";
90
/// anim->AddClip(clip);
91
/// }
92
/// anim->Play("Walking", true);
93
/// }
94
/// @endcode
95
///
96
/// @see ModelLoadOptions, GameObject, AnimatorComponent, Skeleton,
97
/// AnimationClip, Material
98
/// @ingroup rendering
99
class
ENGINE_API
ModelLoader
{
100
public
:
101
/// Imports a model file and returns the root of the resulting GameObject hierarchy.
102
static
GameObject
*
Load
(
const
std::string& filePath,
103
const
ModelLoadOptions
& options = {});
104
105
/// Load only animations from an FBX, reusing an existing skeleton.
106
static
std::vector<AnimationClip*>
LoadAnimationsOnly
(
107
const
std::string& filePath,
Skeleton
* skeleton);
108
109
private
:
110
/// Static mesh path (with PreTransformVertices).
111
static
void
ProcessNode(aiNode* node,
const
aiScene* scene,
112
GameObject
* parent,
const
std::string& directory,
113
const
ModelLoadOptions
& options,
114
TextureCache
& textureCache,
115
MaterialCache
& materialCache);
116
117
/// Animated mesh path (without PreTransformVertices).
118
static
void
ProcessNodeAnimated(
119
aiNode* node,
const
aiScene* scene,
GameObject
* parent,
120
const
std::string& directory,
const
ModelLoadOptions
& options,
121
TextureCache
& textureCache,
MaterialCache
& materialCache,
122
Skeleton
* skeleton, std::vector<AnimationClip*>& clips);
123
124
/// Converts one Assimp mesh into engine MeshData, wiring up bone weights
125
/// when a skeleton is given.
126
static
MeshData
ProcessMesh(aiMesh* mesh,
const
ModelLoadOptions
& options,
127
Skeleton
* skeleton =
nullptr
);
128
129
/// Converts one Assimp material into an engine Material, loading its
130
/// textures through textureCache.
131
static
RefPtr<Material>
ProcessMaterial(aiMaterial* mat,
132
const
aiScene* scene,
133
const
std::string& directory,
134
TextureCache
& textureCache,
135
bool
skinned =
false
);
136
137
/// Resolves and loads a single texture slot off an Assimp material,
138
/// reusing textureCache when possible.
139
static
RefPtr<::Sleak::Texture>
LoadMaterialTexture(
140
aiMaterial* mat,
int
type,
const
aiScene* scene,
141
const
std::string& directory,
TextureCache
& textureCache);
142
143
/// Builds a Skeleton from the scene's bone hierarchy.
144
static
Skeleton
* ExtractSkeleton(
const
aiScene* scene);
145
/// Converts every Assimp animation in the scene into engine AnimationClips
146
/// bound to skeleton.
147
static
std::vector<AnimationClip*> ExtractAnimations(
const
aiScene* scene,
148
Skeleton
* skeleton);
149
/// Recursively registers each Assimp node as a skeleton bone under
150
/// parentId.
151
static
void
BuildBoneHierarchy(
const
aiNode* node,
Skeleton
* skeleton,
152
int
parentId);
153
/// Recursively mirrors the Assimp node tree into the skeleton's bone tree,
154
/// returning the created bone's id.
155
static
int
BuildNodeTree(
const
aiNode* node,
Skeleton
* skeleton);
156
157
/// Assimp matrix to engine matrix conversion.
158
static
Math::Matrix4
ConvertMatrix(
const
void
* aiMat);
159
};
160
161
}
// namespace Sleak
162
163
#endif
// _MODELLOADER_HPP_
Matrix.hpp
OSDef.hpp
Quaternion.hpp
Vector.hpp
Sleak::AnimationClip
Definition
AnimationClip.hpp:33
Sleak::GameObject
Definition
GameObject.hpp:62
Sleak::Material
Definition
Material.hpp:90
Sleak::Math::Quaternion
Represents a quaternion for 3D rotations.
Definition
Quaternion.hpp:26
Sleak::Math::Vector3D
Definition
Vector.hpp:354
Sleak::ModelLoader
Definition
ModelLoader.hpp:99
Sleak::ModelLoader::Load
static GameObject * Load(const std::string &filePath, const ModelLoadOptions &options={})
Imports a model file and returns the root of the resulting GameObject hierarchy.
Definition
ModelLoader.cpp:44
Sleak::ModelLoader::LoadAnimationsOnly
static std::vector< AnimationClip * > LoadAnimationsOnly(const std::string &filePath, Skeleton *skeleton)
Load only animations from an FBX, reusing an existing skeleton.
Definition
ModelLoader.cpp:592
Sleak::RefPtr
Definition
RefPtr.hpp:62
Sleak::Skeleton
Definition
Skeleton.hpp:36
Sleak::Texture
Definition
Texture.hpp:78
Sleak::Math::Matrix4
Matrix< float, 4, 4 > Matrix4
Definition
Matrix.hpp:413
Sleak
Root namespace for everything the engine exposes.
Definition
Camera.hpp:10
Sleak::TextureCache
std::unordered_map< std::string, RefPtr<::Sleak::Texture > > TextureCache
Per-load texture cache to avoid loading the same texture file multiple times.
Definition
ModelLoader.hpp:41
Sleak::MaterialCache
std::unordered_map< uint64_t, RefPtr< Material > > MaterialCache
Per-load cache so meshes sharing an Assimp material share one Material.
Definition
ModelLoader.hpp:45
Sleak::MeshData
Definition
MeshData.hpp:103
Sleak::ModelLoadOptions
Definition
ModelLoader.hpp:31
Sleak::ModelLoadOptions::flipUVs
bool flipUVs
Definition
ModelLoader.hpp:33
Sleak::ModelLoadOptions::scaleFactor
float scaleFactor
Definition
ModelLoader.hpp:32
Sleak::ModelLoadOptions::position
Math::Vector3D position
Definition
ModelLoader.hpp:36
Sleak::ModelLoadOptions::flipWinding
bool flipWinding
Definition
ModelLoader.hpp:35
Sleak::ModelLoadOptions::rotation
Math::Quaternion rotation
Definition
ModelLoader.hpp:37
Sleak::ModelLoadOptions::flipNormals
bool flipNormals
Definition
ModelLoader.hpp:34
include
public
Runtime
ModelLoader.hpp
Generated on
for SleakEngine by
1.18.0