Monad Engine da02fba2
> Undercity Codex_
Loading...
Searching...
No Matches
GameObject.h
Go to the documentation of this file.
1/**
2 * @file GameObject.h
3 * @ingroup mnd_scene
4 * @brief Scene node with a 3D transform and an attachable component list.
5 *
6 * ## Scene graph overview
7 * GameObjects form a tree. Each node stores a local transform (position,
8 * rotation, scale) relative to its parent. World-space values are computed
9 * by concatenating transforms up to the root.
10 *
11 * ```
12 * Scene
13 * └── PlayerObject (has PlayerControllerComponent, CameraComponent)
14 * └── GunObject (has MeshComponent, AnimationComponent)
15 * ```
16 *
17 * ## Component lookup
18 * Components are stored by pointer inside the object. Use GetComponent<T>()
19 * for typed access:
20 * @code
21 * auto *cam = player->GetComponent<CameraComponent>();
22 * if (cam) cam->DoSomething();
23 * @endcode
24 *
25 * ## GLTF loading
26 * LoadGLTF() creates a GameObject hierarchy that mirrors the node tree of a
27 * .glb/.gltf file, attaching MeshComponent and AnimationComponent as needed.
28 *
29 * @see Component, Scene, MeshComponent, CameraComponent
30 */
31
32#pragma once
33#include <memory>
34#include <vector>
35
36#include "Types.h"
37#include "scene/Component.h"
38
39namespace mnd
40{
41class Scene;
42
44{
45 virtual ~ObjectCreatorBase() = default;
47};
48
49template<typename T>
51{
52 GameObject *CreateGameObject() override { return new T(); }
53};
54
56{
57public:
59 {
60 static GameObjectFactory instance;
61 return instance;
62 }
63
64 template<typename T>
65 void RegisterObject(const std::string &name)
66 {
67 m_creators.emplace(name, std::make_unique<ObjectCreator<T>>());
68 }
69
70 GameObject *CreateGameObject(const std::string &typeName)
71 {
72 auto iter = m_creators.find(typeName);
73 if (iter == m_creators.end())
74 {
75 return nullptr;
76 }
77 return iter->second->CreateGameObject();
78 }
79
80private:
81 std::unordered_map<std::string, std::unique_ptr<ObjectCreatorBase>> m_creators;
82};
83
84/**
85 * @brief Node in the scene graph: a named transform that owns components and children.
86 *
87 * GameObjects are created and owned exclusively by Scene (via Scene::CreateObject).
88 * They are never constructed directly to ensure the scene always holds ownership.
89 */
91{
92public:
93 virtual ~GameObject() = default;
94
95 virtual void LoadProperties(const nlohmann::json &json) {}
96
97 virtual void Init() {}
98
99 /**
100 * @brief Update this object and all its components and children recursively.
101 * @param deltaTime Seconds since the previous frame.
102 */
103 virtual void Update(f32 deltaTime);
104
105 const str &GetName() const; ///< Returns the object's display name.
106 void SetName(const str &name); ///< Sets the display name (used by FindChildByName).
107
108 GameObject *GetParent(); ///< Returns the parent node, or nullptr for root objects.
109
110 bool IsAlive() const; ///< Returns false after MarkForDestroy() is called.
111 void MarkForDestroy(); ///< Flag this object for removal at end of frame.
112
113 /**
114 * @brief Attach a component to this object (takes ownership).
115 * @param component Heap-allocated Component subclass. The GameObject owns it.
116 */
117 void AddComponent(Component *component);
118
119 /**
120 * @brief Find and return the first component of type T attached to this object.
121 * @tparam T A Component subclass decorated with the COMPONENT macro.
122 * @return Raw pointer to the component, or nullptr if none is attached.
123 */
124 template<typename T, typename = typename std::enable_if_t<std::is_base_of_v<Component, T>>>
126 {
127 usize typeId = Component::StaticTypeId<T>();
128
129 for (auto &component : m_components)
130 {
131 if (component->GetTypeId() == typeId)
132 {
133 return static_cast<T *>(component.get());
134 }
135 }
136
137 return nullptr;
138 }
139
140 /**
141 * @brief Re-parent this object in the scene hierarchy.
142 * @param parent New parent node, or nullptr to make this a root object.
143 * @return true on success.
144 */
145 bool SetParent(GameObject *parent);
146
147 /// Returns the Scene that owns this object.
148 Scene *GetScene();
149
150 void SetActive(bool active); ///< Show/hide this object (and stop Update calls).
151 bool IsActive() const; ///< Returns false if the object is hidden.
152
153 /// @name Local Transform
154 /// Position, rotation, and scale are all relative to the parent object.
155 /// @{
156 const vec3 &GetPosition() const;
157 void SetPosition(const vec3 &pos);
158
159 void SetRotation(const quat &rot);
160 const quat &GetRotation() const;
161
162 const vec3 &GetScale() const;
163 void SetScale(const vec3 &scale);
164 /// @}
165
166 /// @name World-Space Queries
167 /// @{
168 /**
169 * @brief Compute the local transform matrix (TRS order).
170 * @return A 4×4 matrix combining local position, rotation, and scale.
171 */
172 mat4 GetLocalTransform() const;
173
174 /**
175 * @brief Compute the world transform by walking up the parent chain.
176 * @return Product of all ancestor local transforms × this local transform.
177 */
178 mat4 GetWorldTransform() const;
179
180 /**
181 * @brief Extract the world-space position from GetWorldTransform().
182 * @return The translation column of the world matrix.
183 */
184 vec3 GetWorldPosition() const;
185 /// @}
186
187 void SetWorldPosition(const vec3 &pos);
189 void SetWorldRotation(const quat &rot);
190
191 /**
192 * @brief Load a GLTF / GLB file and build a matching GameObject hierarchy.
193 *
194 * Each GLTF node becomes a child GameObject. Meshes get a MeshComponent,
195 * animations get an AnimationComponent attached to the root.
196 *
197 * @param path Filesystem path to the .gltf or .glb file.
198 * @return Root of the loaded hierarchy (heap-allocated, caller takes ownership).
199 */
200 static GameObject *LoadGLTF(const std::string &path, Scene *scene);
201
202 /**
203 * @brief Depth-first search for a child with the given name.
204 * @param name Exact name to search for (case-sensitive).
205 * @return Pointer to the first matching descendant, or nullptr.
206 */
207 GameObject *FindChildByName(const std::string &name);
208
209 /// Editor access: iterate immediate children (non-owning).
210 const std::vector<std::unique_ptr<GameObject>> &GetChildren() const { return m_children; }
211
212 /// Editor access: iterate attached components (non-owning).
213 const std::vector<std::unique_ptr<Component>> &GetComponents() const { return m_components; }
214
215protected:
216 GameObject() = default;
217
218private:
219 std::vector<std::unique_ptr<GameObject>> m_children; ///< Owned child nodes.
220 std::vector<std::unique_ptr<Component>> m_components; ///< Owned component list.
221
222 str m_name; ///< Display name (used for lookup and logging).
223 GameObject *m_parent = nullptr; ///< Non-owning back-pointer to parent node.
224 Scene *m_scene = nullptr; ///< Non-owning back-pointer to owning Scene.
225 bool m_isAlive = true; ///< Cleared by MarkForDestroy(); Scene prunes dead objects.
226
227 vec3 m_position = vec3(0.0f); ///< Local position relative to parent.
228 quat m_rotation = quat(1.0f, 0.0f, 0.0f, 0.0f); ///< Local rotation as a unit quaternion.
229 vec3 m_scale = vec3(1.0f); ///< Local scale per axis.
230 bool m_active = true; ///< When false, Update() and rendering are skipped.
231
232 friend class Scene;
233};
234
235#define GAMEOBJECT(ObjectClass) \
236public: \
237 static void Register() \
238 { \
239 mnd::GameObjectFactory::GetInstance().RegisterObject<ObjectClass>(std::string(#ObjectClass)); \
240 }
241
242} // namespace mnd
Engine-wide primitive type aliases and GLM math imports.
GameObject * CreateGameObject(const std::string &typeName)
Definition GameObject.h:70
void RegisterObject(const std::string &name)
Definition GameObject.h:65
static GameObjectFactory & GetInstance()
Definition GameObject.h:58
Node in the scene graph: a named transform that owns components and children.
Definition GameObject.h:91
const vec3 & GetScale() const
void SetName(const str &name)
Sets the display name (used by FindChildByName).
bool IsAlive() const
Returns false after MarkForDestroy() is called.
const std::vector< std::unique_ptr< Component > > & GetComponents() const
Editor access: iterate attached components (non-owning).
Definition GameObject.h:213
virtual void Update(f32 deltaTime)
Update this object and all its components and children recursively.
const vec3 & GetPosition() const
void SetActive(bool active)
Show/hide this object (and stop Update calls).
vec3 GetWorldPosition() const
Extract the world-space position from GetWorldTransform().
quat GetWorldRotation()
void SetPosition(const vec3 &pos)
GameObject()=default
static GameObject * LoadGLTF(const std::string &path, Scene *scene)
Load a GLTF / GLB file and build a matching GameObject hierarchy.
const str & GetName() const
Returns the object's display name.
void MarkForDestroy()
Flag this object for removal at end of frame.
mat4 GetLocalTransform() const
Compute the local transform matrix (TRS order).
void SetWorldRotation(const quat &rot)
void SetRotation(const quat &rot)
virtual ~GameObject()=default
void AddComponent(Component *component)
Attach a component to this object (takes ownership).
void SetScale(const vec3 &scale)
bool SetParent(GameObject *parent)
Re-parent this object in the scene hierarchy.
virtual void Init()
Definition GameObject.h:97
const quat & GetRotation() const
GameObject * GetParent()
Returns the parent node, or nullptr for root objects.
bool IsActive() const
Returns false if the object is hidden.
GameObject * FindChildByName(const std::string &name)
Depth-first search for a child with the given name.
Scene * GetScene()
Returns the Scene that owns this object.
const std::vector< std::unique_ptr< GameObject > > & GetChildren() const
Editor access: iterate immediate children (non-owning).
Definition GameObject.h:210
T * GetComponent()
Find and return the first component of type T attached to this object.
Definition GameObject.h:125
mat4 GetWorldTransform() const
Compute the world transform by walking up the parent chain.
void SetWorldPosition(const vec3 &pos)
virtual void LoadProperties(const nlohmann::json &json)
Definition GameObject.h:95
Container for the entire game object graph.
Definition Scene.h:59
glm::mat4 mat4
4×4 column-major float matrix (model/view/projection).
Definition Types.h:63
glm::vec3 vec3
3-component float vector (e.g. world position, RGB colour, normals).
Definition Types.h:51
glm::quat quat
Unit quaternion for rotation (avoids gimbal lock).
Definition Types.h:65
std::string str
Convenience alias for std::string.
Definition Types.h:45
float f32
32-bit IEEE float — the standard GL scalar type.
Definition Types.h:40
size_t usize
Platform-native unsigned size type.
Definition Types.h:43
virtual ~ObjectCreatorBase()=default
virtual GameObject * CreateGameObject()=0
GameObject * CreateGameObject() override
Definition GameObject.h:52