Vulkan Schnee 0.0.1 (22840dc8)
High-performance rendering engine
Loading...
Searching...
No Matches
PhysicsEngine.h
1#pragma once
2
3#include <btBulletDynamicsCommon.h>
4#include "Engine/Physics/CollisionProfile.h"
5#include <glm/mat4x4.hpp>
6#include <glm/vec3.hpp>
7#include <map>
8#include <set>
9#include <unordered_map>
10
11namespace Engine
12{
13 namespace Components
14 {
15 class PhysicsBody;
16 }
17
18 namespace Physics
19 {
21 struct CollisionEvent;
22 struct PhysicsQueryFilter;
23
31 {
32 glm::vec3 point{ 0.0f };
33
34 glm::vec3 normal{ 0.0f };
35
36 float fraction = 0.0f;
37
38 float distance = 0.0f;
39
41 const btCollisionObject* collisionObject = nullptr;
42
48 };
49
57 {
59 glm::mat4 transform {1.0f};
60
62 float mass = 1.0f;
63
65 btCollisionShape* shape = nullptr;
66
68 float friction = 0.5f;
69
71 float restitution = 0.0f;
72 };
73 }
74
75 namespace Core
76 {
86 {
87 public:
92
97 explicit PhysicsEngine( Physics::CollisionProfileRegistry * collisionProfileRegistry );
98
103
109
115
121 void onPhysicsComponentDestroyed( entt::registry & registry, entt::entity entity );
122
132 void update(double deltaTimeSeconds);
133
141
148
156
163
170
178
185
190 [[nodiscard]] btDiscreteDynamicsWorld * getDynamicsWorld() const;
191
203 [[nodiscard]] bool raycastClosest(
204 const glm::vec3& origin,
205 const glm::vec3& direction,
206 float maxDistance,
207 Physics::RaycastHit& outHit
208 ) const;
209
224 [[nodiscard]] bool raycastClosest(
225 const glm::vec3& origin,
226 const glm::vec3& direction,
227 float maxDistance,
228 const Physics::PhysicsQueryFilter& filter,
229 Physics::RaycastHit& outHit
230 ) const;
231
244 [[nodiscard]] bool sphereSweepClosest(
245 const glm::vec3& from,
246 const glm::vec3& to,
247 float radius,
248 Physics::RaycastHit& outHit,
249 const btCollisionObject* ignoredObject = nullptr
250 ) const;
251
267 [[nodiscard]] bool sphereSweepClosest(
268 const glm::vec3& from,
269 const glm::vec3& to,
270 float radius,
271 const Physics::PhysicsQueryFilter& filter,
272 Physics::RaycastHit& outHit,
273 const btCollisionObject* ignoredObject = nullptr
274 ) const;
275
288 [[nodiscard]] bool sphereClosest(
289 const glm::vec3& position,
290 float radius,
291 Physics::RaycastHit& outHit,
292 const btCollisionObject* ignoredObject = nullptr
293 ) const;
294
309 [[nodiscard]] bool sphereClosest(
310 const glm::vec3& position,
311 float radius,
312 const Physics::PhysicsQueryFilter& filter,
313 Physics::RaycastHit& outHit,
314 const btCollisionObject* ignoredObject = nullptr
315 ) const;
316
322 static btCollisionShape * createBoxShape(const glm::vec3& halfExtents);
323
329 static btCollisionShape * createSphereShape(float radius);
330
337 static btCollisionShape * createCapsuleShape(float radius, float height);
338
345 static btCollisionShape * createPlaneShape(const glm::vec3& surfaceNormal, float distanceFromOrigin);
346
352 static btCollisionShape * createConvexHullShape(const std::vector<glm::vec3>& vertices);
353
365 static btCollisionShape * createTriangleMeshShape(
366 const std::vector<glm::vec3>& vertices,
367 const std::vector<uint32_t>& indices,
368 btTriangleMesh*& triangleMeshOut);
369
374 static btCompoundShape * createCompoundShape();
375
386 [[nodiscard]] btRigidBody * createRigidBody( const Physics::RigidBodyCreateInfo & info ) const;
387
400 [[nodiscard]] btRigidBody * createRigidBody(
401 const Physics::RigidBodyCreateInfo & info,
402 std::uint16_t collisionGroup,
403 std::uint16_t collisionMask
404 ) const;
405
414 void removeRigidBody(btRigidBody* body ) const;
415
422 void debugDrawAll() const;
423
424 private:
426 {
428 std::uint32_t generation = 0;
429 };
430
432 {
434 std::uint32_t generation = 0;
435 };
436
448
458
467
472 Physics::CollisionHandle collisionHandle
473 );
475 [[nodiscard]] bool bodyMatchesQueryFilter(
476 const Components::PhysicsBody * body,
477 const Physics::PhysicsQueryFilter & filter
478 ) const;
479
481 std::vector<RuntimeBodySlot> bodySlots_;
482 std::vector<RuntimeCollisionSlot> collisionSlots_;
483 std::uint32_t nextBodyId_ = 1;
484 std::uint32_t nextCollisionId_ = 1;
485 std::set<ComponentPairKey> previousComponentPairs_;
486 std::vector<PendingComponentEvent> pendingLifetimeComponentEvents_;
487 std::vector<PendingComponentEvent> pendingComponentEvents_;
488 std::vector<PendingActorEvent> pendingActorEvents_;
489
490 btBroadphaseInterface* broadphase;
491 btCollisionConfiguration* collisionConfiguration;
492 btCollisionDispatcher* dispatcher;
493 btConstraintSolver* solver;
494 btDiscreteDynamicsWorld* dynamicsWorld;
495 };
496 }
497}
Base class for collision shape components.
Component that manages a physics rigid body for an entity.
PhysicsEngine(Physics::CollisionProfileRegistry *collisionProfileRegistry)
Creates a physics engine with an explicit collision profile registry.
Components::PhysicsBody * resolve(Physics::PhysicsBodyHandle handle) const
Resolves a runtime body handle to a physics body component.
bool raycastClosest(const glm::vec3 &origin, const glm::vec3 &direction, float maxDistance, Physics::RaycastHit &outHit) const
Casts a ray through the physics world and returns the closest hit, if any.
PhysicsEngine()
Creates a physics engine using the active collision profile registry.
btCollisionDispatcher * dispatcher
void unregisterCollision(Physics::CollisionHandle handle)
Unregisters a collision handle and queues End events for active pairs that reference it.
void dispatchQueuedCollisionEvents()
Dispatches collision events queued by the last PhysicsEngine::update() call.
Physics::CollisionHandle registerCollision(Components::Collision *collision)
Registers a collision component for handle-based lookup.
std::vector< RuntimeCollisionSlot > collisionSlots_
std::vector< PendingActorEvent > pendingActorEvents_
void debugDrawAll() const
Draws debug visualization of all collision shapes in the world.
btConstraintSolver * solver
btRigidBody * createRigidBody(const Physics::RigidBodyCreateInfo &info) const
Creates and adds a rigid body to the physics world with default Bullet collision filters.
static btCollisionShape * createConvexHullShape(const std::vector< glm::vec3 > &vertices)
Creates a convex hull collision shape from vertex positions.
btDiscreteDynamicsWorld * getDynamicsWorld() const
Gets the Bullet dynamics world used by this physics engine.
void queueDirectedEvents(const ComponentPairKey &pair, Physics::CollisionEventType eventType)
bool sphereClosest(const glm::vec3 &position, float radius, Physics::RaycastHit &outHit, const btCollisionObject *ignoredObject=nullptr) const
Tests a sphere at one position and returns the closest overlapping collision object,...
static btCollisionShape * createCapsuleShape(float radius, float height)
Creates a capsule collision shape aligned to Bullet's Y axis.
static btCollisionShape * createPlaneShape(const glm::vec3 &surfaceNormal, float distanceFromOrigin)
Creates an infinite static plane collision shape.
btCollisionConfiguration * collisionConfiguration
Physics::CollisionProfileRegistry * getCollisionProfileRegistry() const
Gets the collision profile registry assigned to this physics engine.
std::vector< RuntimeBodySlot > bodySlots_
bool raycastClosest(const glm::vec3 &origin, const glm::vec3 &direction, float maxDistance, const Physics::PhysicsQueryFilter &filter, Physics::RaycastHit &outHit) const
Casts a filtered ray through the physics world and returns the closest hit, if any.
std::vector< PendingComponentEvent > pendingLifetimeComponentEvents_
bool sphereSweepClosest(const glm::vec3 &from, const glm::vec3 &to, float radius, const Physics::PhysicsQueryFilter &filter, Physics::RaycastHit &outHit, const btCollisionObject *ignoredObject=nullptr) const
Sweeps a filtered sphere through the physics world and returns the closest hit, if any.
btBroadphaseInterface * broadphase
bool sphereClosest(const glm::vec3 &position, float radius, const Physics::PhysicsQueryFilter &filter, Physics::RaycastHit &outHit, const btCollisionObject *ignoredObject=nullptr) const
Tests a filtered sphere and returns the closest overlapping collision object, if any.
void update(double deltaTimeSeconds)
Steps the physics simulation and queues collision events.
void removeRigidBody(btRigidBody *body) const
Removes a rigid body from the physics world and deletes it.
Physics::PhysicsBodyHandle registerBody(Components::PhysicsBody *body)
Registers a physics body component for handle-based lookup.
Physics::CollisionProfileRegistry * collisionProfileRegistry_
void unregisterBody(Physics::PhysicsBodyHandle handle)
Unregisters a physics body handle and queues End events for active pairs that reference it.
static btCollisionShape * createBoxShape(const glm::vec3 &halfExtents)
Creates a box collision shape.
void onPhysicsComponentDestroyed(entt::registry &registry, entt::entity entity)
Cleans up legacy ECS physics data when a SimulatesPhysics component is destroyed.
btRigidBody * createRigidBody(const Physics::RigidBodyCreateInfo &info, std::uint16_t collisionGroup, std::uint16_t collisionMask) const
Creates and adds a rigid body to the physics world with explicit Bullet collision filters.
static btCompoundShape * createCompoundShape()
Creates an empty compound collision shape.
std::set< ComponentPairKey > previousComponentPairs_
~PhysicsEngine()
Removes remaining Bullet objects and destroys the Bullet world infrastructure.
std::vector< PendingComponentEvent > pendingComponentEvents_
void setCollisionProfileRegistry(Physics::CollisionProfileRegistry *collisionProfileRegistry)
Sets the collision profile registry used by collision events and filtered queries.
bool bodyMatchesQueryFilter(const Components::PhysicsBody *body, const Physics::PhysicsQueryFilter &filter) const
bool sphereSweepClosest(const glm::vec3 &from, const glm::vec3 &to, float radius, Physics::RaycastHit &outHit, const btCollisionObject *ignoredObject=nullptr) const
Sweeps a sphere through the physics world and returns the closest overlap hit, if any.
void queueInvalidationEndEvents(Physics::PhysicsBodyHandle bodyHandle, Physics::CollisionHandle collisionHandle)
static btCollisionShape * createSphereShape(float radius)
Creates a sphere collision shape.
static btCollisionShape * createTriangleMeshShape(const std::vector< glm::vec3 > &vertices, const std::vector< uint32_t > &indices, btTriangleMesh *&triangleMeshOut)
Creates a static triangle mesh collision shape from vertices and triangle indices.
btDiscreteDynamicsWorld * dynamicsWorld
Components::Collision * resolve(Physics::CollisionHandle handle) const
Resolves a runtime collision handle to a collision component.
Registers collision profile names, enum mappings, and pair responses.
CollisionEventType
Lifetime state for a collision or overlap pair.
@ Begin
Pair was absent on the previous physics step and is present now.
CollisionResponse
Collision response selected for a pair of collision profiles.
@ Ignore
No contact callback and no physical collision response.
friend bool operator==(const ComponentPairKey &, const ComponentPairKey &)=default
friend auto operator<=>(const ComponentPairKey &, const ComponentPairKey &)=default
std::vector< PendingComponentEvent > componentEvents
Actor-level collision or overlap event generated by PhysicsEngine.
Runtime handle for a registered collision component.
Runtime handle for a registered physics body component.
Collision profile filter used by PhysicsEngine scene queries.
Result data for physics raycasts and sweep tests.
glm::vec3 normal
World-space surface normal at the impact point.
float distance
Distance from query origin to impact point in meters.
Components::PhysicsBody * getPhysicsBody() const
Gets the engine physics body attached to collisionObject.
const btCollisionObject * collisionObject
Bullet collision object hit by the query.
float fraction
Normalized hit fraction along the query segment.
glm::vec3 point
World-space impact point.
Parameters used by Engine::Core::PhysicsEngine::createRigidBody().
btCollisionShape * shape
Collision shape used by the body. Must not be nullptr.
float friction
Surface friction. 0.0 is low friction, 1.0 is high friction.
float restitution
Restitution. 0.0 absorbs impact energy, 1.0 preserves impact energy.
glm::mat4 transform
Initial world transform for the rigid body.
float mass
Mass in kilograms. A value of 0 creates an immovable static body.