feat: implement contact listeners

This commit is contained in:
2026-09-02 21:42:49 +02:00
parent 287e5c6885
commit d515a36403
20 changed files with 595 additions and 95 deletions
@@ -59,6 +59,16 @@ public:
virtual void ResolveReferences(const ObjectMap&) {
}
// Trigger callbacks called when this component's owner overlaps a sensor.
// Only called when the owner has a Collider set as a trigger (or overlaps one).
virtual void OnTriggerEnter(GameObject* other) {
(void)other;
}
virtual void OnTriggerExit(GameObject* other) {
(void)other;
}
bool HasStarted{false};
protected:
@@ -55,6 +55,8 @@ public:
float maxDistance,
PhysicsRaycastHit& hit) const override;
std::vector<TriggerEvent> ConsumeTriggerEvents() override;
private:
class Impl;
std::unique_ptr<Impl> m_Impl;
@@ -21,6 +21,7 @@ class PhysicsSceneBridge final {
public:
explicit PhysicsSceneBridge(std::unique_ptr<PhysicsWorld> world);
[[nodiscard]] bool IsValid() const { return m_World != nullptr; }
[[nodiscard]] PhysicsWorld& GetWorld() { return *m_World; }
[[nodiscard]] const PhysicsWorld& GetWorld() const { return *m_World; }
@@ -116,3 +116,9 @@ struct PhysicsBodyDesc {
bool useGravity{true};
bool allowSleep{true};
};
struct TriggerEvent {
GameObject* owner{nullptr};
GameObject* other{nullptr};
bool entered{true};
};
@@ -1,5 +1,7 @@
#pragma once
#include <vector>
#include <glm/glm.hpp>
#include <unordered_set>
@@ -49,6 +51,9 @@ public:
float maxDistance,
PhysicsRaycastHit& hit) const = 0;
// Trigger events accumulated during the last Step().
virtual std::vector<TriggerEvent> ConsumeTriggerEvents() { return {}; }
private:
std::unordered_set<Rigidbody*> m_RegisteredRigidbodies;
};
+4
View File
@@ -3,6 +3,8 @@
#include <functional>
#include <memory>
#include <destrum/Event.h>
#include <destrum/ObjectModel/ObjectId.h>
#include <destrum/Scene/SceneManager.h>
@@ -12,6 +14,7 @@
class GameObject;
class SceneSerializer;
class PhysicsWorld;
class Scene final {
friend Scene& SceneManager::CreateScene(const std::string& name);
@@ -104,6 +107,7 @@ public:
PhysicsSceneBridge& GetPhysics() { return m_Physics; }
private:
explicit Scene(const std::string& name);
explicit Scene(const std::string& name, std::unique_ptr<PhysicsWorld> physicsWorld);
PhysicsSceneBridge m_Physics{std::make_unique<JoltPhysicsWorld>()};
+5 -3
View File
@@ -16,6 +16,7 @@ public:
Scene& CreateScene(const std::string& name);
Scene& GetCurrentScene() const;
const std::vector<std::shared_ptr<Scene>>& GetActiveScenes() const { return m_activeScenes; }
void Update(float dt);
void FixedUpdate(float dt);
@@ -34,7 +35,9 @@ public:
void Destroy();
void SwitchScene(int index);
int GetActiveSceneId() const { return m_scenes.empty() ? -1 : m_ActiveSceneIndex; }
void AddActiveScene(int index);
void RemoveActiveScene(int index);
int GetActiveSceneId() const;
[[nodiscard]] const std::vector<std::shared_ptr<Scene>>& GetScenes() const { return m_scenes; }
@@ -47,8 +50,7 @@ private:
SceneManager() = default;
int m_ActiveSceneIndex{0};
std::vector<std::shared_ptr<Scene>> m_activeScenes;
std::vector<std::shared_ptr<Scene>> m_scenes;
};
@@ -2,13 +2,37 @@
#define DESTRUM_SCENESERIALIZER_H
#include <filesystem>
#include <functional>
#include <future>
#include <nlohmann/json.hpp>
class Scene;
class SceneSerializer final {
public:
struct LoadResult {
bool success{false};
std::string errorMessage;
nlohmann::json root;
};
static bool Save(Scene& scene, const std::filesystem::path& path);
static bool Load(Scene& scene, const std::filesystem::path& path);
static bool Load(Scene& scene, const std::filesystem::path& path,
std::function<void(float)> progressCallback = nullptr);
// Thread-safe: parse and validate a scene file on any thread.
// No engine state is touched during parsing.
static LoadResult LoadSceneFile(const std::filesystem::path& path);
// Main-thread-only: construct a scene from pre-validated JSON.
static bool ConstructScene(Scene& scene, LoadResult& result,
std::function<void(float)> progressCallback = nullptr);
// Parse the scene file on a background thread. Call LoadFromJson on the
// main thread once the future is ready.
static std::future<LoadResult> LoadSceneFileAsync(const std::filesystem::path& path);
};
#endif //DESTRUM_SCENESERIALIZER_H