90 lines
2.9 KiB
C++
90 lines
2.9 KiB
C++
#pragma once
|
|
|
|
#include <vector>
|
|
#include <optional>
|
|
|
|
#include <destrum/Physics/PhysicsWorld.h>
|
|
|
|
class Rigidbody;
|
|
|
|
// Simple CPU placeholder backend.
|
|
//
|
|
// This is NOT a replacement for Jolt/PhysX/Bullet.
|
|
// It exists so your component/scene/render sync can be implemented and tested
|
|
// before the real backend is added.
|
|
//
|
|
// It supports:
|
|
// - static, dynamic, kinematic bodies
|
|
// - gravity
|
|
// - force/impulse integration
|
|
// - very simple sphere/box/capsule raycasts using bounding spheres
|
|
//
|
|
// It does NOT support:
|
|
// - collision response
|
|
// - contacts
|
|
// - friction
|
|
// - constraints
|
|
// - real character controllers
|
|
class SimplePhysicsWorld final : public PhysicsWorld {
|
|
public:
|
|
explicit SimplePhysicsWorld(const glm::vec3& gravity = glm::vec3{0.0f, -9.81f, 0.0f});
|
|
|
|
void Step(float fixedDt) override;
|
|
|
|
PhysicsBodyHandle CreateBody(const PhysicsBodyDesc& desc) override;
|
|
void DestroyBody(PhysicsBodyHandle body) override;
|
|
|
|
void SetBodyTransform(PhysicsBodyHandle body, const PhysicsTransform& transform) override;
|
|
PhysicsTransform GetBodyTransform(PhysicsBodyHandle body) const override;
|
|
|
|
void SetLinearVelocity(PhysicsBodyHandle body, const glm::vec3& velocity) override;
|
|
glm::vec3 GetLinearVelocity(PhysicsBodyHandle body) const override;
|
|
|
|
void AddForce(PhysicsBodyHandle body, const glm::vec3& force) override;
|
|
void AddImpulse(PhysicsBodyHandle body, const glm::vec3& impulse) override;
|
|
|
|
bool Raycast(const glm::vec3& origin,
|
|
const glm::vec3& direction,
|
|
float maxDistance,
|
|
PhysicsRaycastHit& hit,
|
|
PhysicsBodyHandle ignoreBody = {}) const override;
|
|
|
|
void SyncKinematicBodiesToPhysics(float fixedDt) override;
|
|
void SyncDynamicBodiesToTransforms();
|
|
|
|
[[nodiscard]] const glm::vec3& GetGravity() const { return m_Gravity; }
|
|
void SetGravity(const glm::vec3& gravity) { m_Gravity = gravity; }
|
|
|
|
private:
|
|
struct BodyRecord {
|
|
bool alive{false};
|
|
|
|
PhysicsBodyHandle handle{};
|
|
PhysicsBodyDesc desc{};
|
|
|
|
PhysicsTransform previousTransform{};
|
|
PhysicsTransform currentTransform{};
|
|
|
|
glm::vec3 linearVelocity{0.0f};
|
|
glm::vec3 accumulatedForce{0.0f};
|
|
|
|
Rigidbody* rigidbody{nullptr};
|
|
};
|
|
|
|
[[nodiscard]] BodyRecord* FindBody(PhysicsBodyHandle body);
|
|
[[nodiscard]] const BodyRecord* FindBody(PhysicsBodyHandle body) const;
|
|
|
|
[[nodiscard]] float GetApproxBoundingRadius(const BodyRecord& body) const;
|
|
[[nodiscard]] static bool RaySphere(const glm::vec3& origin,
|
|
const glm::vec3& dirNormalized,
|
|
const glm::vec3& center,
|
|
float radius,
|
|
float maxDistance,
|
|
float& outDistance);
|
|
|
|
glm::vec3 m_Gravity{0.0f, -9.81f, 0.0f};
|
|
|
|
std::vector<BodyRecord> m_Bodies;
|
|
std::uint32_t m_NextId{0};
|
|
};
|