18 if (!obj || !world)
return;
23 for (
size_t i = 0; i < obj->
GetChildren().GetSize(); ++i) {
30 if (!obj || !world)
return;
35 for (
size_t i = 0; i < obj->
GetChildren().GetSize(); ++i) {
43 "Scene '{0}' destroyed without Unload(); "
44 "OnDeactivate/OnUnload did not run.",
126 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
137 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
146 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
161 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
178 const auto& shape = collider->
GetShape();
180 if (
auto* aabb = std::get_if<Physics::AABB>(&shape)) {
182 aabb->min * worldScale + worldPos,
183 aabb->max * worldScale + worldPos);
185 }
else if (
auto* sphere = std::get_if<Physics::BoundingSphere>(&shape)) {
187 float maxScale = std::max({worldScale.GetX(), worldScale.GetY(), worldScale.GetZ()});
189 }
else if (
auto* capsule = std::get_if<Physics::BoundingCapsule>(&shape)) {
191 worldCapsule.
center = capsule->center * worldScale + worldPos;
192 float maxScale = std::max({worldScale.GetX(), worldScale.GetY(), worldScale.GetZ()});
193 worldCapsule.
radius = capsule->radius * maxScale;
194 worldCapsule.
halfHeight = capsule->halfHeight * maxScale;
199 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
202 if (!collider)
continue;
207 pos = transform->GetWorldPosition() + collider->
GetOffset();
208 scale = transform->GetWorldScale();
210 pos = cam->GetPosition() + collider->
GetOffset();
212 drawColliderShape(collider, pos, scale);
225 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
227 Objects[i]->FixedUpdate(fixedDeltaTime);
235 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
237 Objects[i]->LateUpdate(deltaTime);
244 if (
Objects.indexOf(
object) != -1)
return;
250 static_cast<Light*
>(
object));
258 object->Initialize();
259 if (
bActive)
object->SetActive(
true);
265 int index =
Objects.indexOf(
object);
266 if (index == -1)
return;
291 const auto& children =
object->GetChildren();
292 for (
size_t i = 0; i < children.GetSize(); ++i) {
293 if (children[i] && !children[i]->IsPendingDestroy()) {
300 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
309 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
319 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
336 static_cast<Light*
>(obj));
343 int index =
Objects.indexOf(obj);
357 for (
size_t i = 0; i <
Objects.GetSize(); ++i) {
const Physics::ColliderShape & GetShape() const
Math::Vector3D GetOffset() const
static void Flush(Camera *camera)
Uploads all queued lines and draws them in one pass, then clears the queue.
static void DrawSphere(const Math::Vector3D ¢er, float radius, float r, float g, float b, float a=1.0f, int segments=16)
Queues a wireframe sphere approximated with segments latitude/longitude rings.
static void DrawAABB(const Physics::AABB &aabb, float r, float g, float b, float a=1.0f)
Queues a wireframe box outline.
static void DrawCapsule(const Physics::BoundingCapsule &capsule, float r, float g, float b, float a=1.0f, int segments=16)
Queues a wireframe capsule outline.
const List< GameObject * > & GetChildren() const
void MarkForDestroy()
Flags the object for deferred destruction on the next scene pass.
bool IsPendingDestroy() const
virtual bool IsLight() const
T * GetComponent()
Finds the first attached component of type T, or nullptr.
void RegisterLight(Light *light)
void Initialize()
Allocates the GPU light buffer; call once before the first UpdateAndBind.
void UpdateAndBind()
Packs every registered light and the fog/ambient parameters into the light buffer and binds it.
void UnregisterLight(Light *light)
Implements a dynamic array-like list for storing and managing a collection of elements.
void RegisterCollider(ColliderComponent *collider)
void UnregisterCollider(ColliderComponent *collider)
static RenderCommandQueue * GetInstance()
Lazily creates and returns the process-wide singleton instance.
List< GameObject * > FindObjectsByTag(const std::string &tag)
Collects every object whose tag matches.
void Unload()
Deactivates if active, calls OnUnload(), and destroys all owned objects.
void Deactivate()
Marks the scene inactive and calls OnDeactivate().
List< GameObject * > Objects
virtual void Update(float deltaTime)=0
Advances all active, root-level objects by deltaTime, then steps lighting and physics.
virtual void FixedUpdate(float fixedDeltaTime)
Advances all active, root-level objects on the fixed timestep.
void Resume()
Reactivates a paused scene without re-running OnActivate().
void SetSkybox(Skybox *skybox)
Replaces the scene's skybox, deleting the previous one.
void ProcessPendingDestroy()
Actually deletes objects queued by DestroyObject().
GameObject * FindObjectByName(const std::string &name)
Linear search for the first object with a matching name.
virtual void OnLoad()
Override to load scene-specific assets; called once from Load().
void DestroyObject(GameObject *object)
Queues an object for destruction; actually freed on the next ProcessPendingDestroy().
virtual void RemoveObject(GameObject *object)
virtual void OnUnload()
Override to release scene-specific assets; called from Unload().
void DestroyAllObjects()
Destroys every object still owned by the scene, e.g. during Unload().
List< GameObject * > m_pendingDestroy
void Activate()
Marks the scene active and calls OnActivate().
virtual void OnActivate()
Override for logic that should run when the scene becomes active.
LightManager * m_lightManager
GameObject * FindObjectByID(uint64_t id)
Linear search for the object with a matching unique ID.
void Load()
Moves Unloaded -> Loading -> Active, calling OnLoad() and Initialize().
virtual void OnDeactivate()
Override for logic that should run when the scene stops being active.
const std::string & GetName() const
void Pause()
Freezes the scene without tearing it down; leaves it in the Paused state.
virtual void AddObject(GameObject *object)
Takes ownership of object, registering it with lighting and physics as needed.
virtual bool Initialize()
Runs once before the scene's first Begin()/Update().
Physics::PhysicsWorld * m_physicsWorld
virtual void Begin()=0
Activates every owned object; runs once after Initialize().
virtual void LateUpdate(float deltaTime)
Advances all active, root-level objects after the main Update pass.
void Render()
Submit render commands for this frame.
bool IsInitialized() const
void Initialize()
Create GPU resources (shader, buffers, cubemap texture).
Root namespace for everything the engine exposes.
static void RegisterCollidersRecursive(GameObject *obj, Physics::PhysicsWorld *world)
Walks obj and its children, registering any ColliderComponent found with world.
static void UnregisterCollidersRecursive(GameObject *obj, Physics::PhysicsWorld *world)
Walks obj and its children, unregistering any ColliderComponent found from world.