11#include <btBulletDynamicsCommon.h>
12#include <glm/gtc/type_ptr.hpp>
19 std::shared_ptr<SceneNode> sceneNode)
45 if (collision->getBodyComponent() ==
nullptr) {
63 collision->bodyComponent_ =
nullptr;
74 entt::entity nodeEntity = sceneNode->getEntity();
78 physicsComp.collisionShape =
nullptr;
102 btVector3 localInertia(0, 0, 0);
132 flags |= btCollisionObject::CF_KINEMATIC_OBJECT;
133 rigidBody_->setActivationState(DISABLE_DEACTIVATION);
135 flags &= ~btCollisionObject::CF_KINEMATIC_OBJECT;
148 btVector3 localInertia(0, 0, 0);
151 flags |= btCollisionObject::CF_STATIC_OBJECT;
162 if (!sceneNode)
return;
165 glm::mat4 worldMat = sceneNode->getWorldMatrix();
166 glm::quat currentRotation = glm::quat_cast(glm::mat3(worldMat));
167 teleport(position, currentRotation);
172 if (!sceneNode)
return;
175 sceneNode->setWorldPosition(position);
176 sceneNode->setWorldRotation(rotation);
180 btTransform newTransform;
181 newTransform.setIdentity();
186 rigidBody_->getMotionState()->setWorldTransform(newTransform);
189 rigidBody_->setLinearVelocity(btVector3(0, 0, 0));
190 rigidBody_->setAngularVelocity(btVector3(0, 0, 0));
214 return glm::vec3(0.0f);
228 return glm::vec3(0.0f);
236 if (!collision)
return;
265 if (!collision)
return;
312 if (!physics)
return;
315 btDispatcher* dispatcher = world->getDispatcher();
316 int numManifolds = dispatcher->getNumManifolds();
318 std::set<CollisionComponent*> currentCollisions;
320 for (
int i = 0; i < numManifolds; i++) {
321 btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
322 if (manifold->getNumContacts() == 0)
continue;
324 const btCollisionObject* objA = manifold->getBody0();
325 const btCollisionObject* objB = manifold->getBody1();
330 if (!isBodyA && !isBodyB)
continue;
333 const btCollisionObject* otherObj = isBodyA ? objB : objA;
336 void* userPtr = otherObj->getUserPointer();
341 currentCollisions.insert(otherCollision);
353 myCollision->onCollisionStay(other);
358 myCollision->onCollisionBegin(other);
365 if (!currentCollisions.contains(prev)) {
368 myCollision->onCollisionEnd(prev);
393 btCollisionShape* shape = collision->getShape();
396 shape = collision->createShape();
397 collision->shape_ = shape;
402 glm::mat4 localTransform = collision->getLocalTransform();
404 btLocal.setFromOpenGLMatrix(glm::value_ptr(localTransform));
414 PLOGI <<
"PhysicsBodyComponent::createRigidBody() starting";
416 PLOGI <<
"PhysicsBodyComponent::createRigidBody() early return - rigidBody_=" << (
rigidBody_ ?
"set" :
"null") <<
" compoundShape_=" << (
compoundShape_ ?
"set" :
"null");
422 PLOGI <<
"PhysicsBodyComponent::createRigidBody() - no physics engine";
428 PLOGI <<
"PhysicsBodyComponent::createRigidBody() - sceneNode expired";
433 glm::mat4 worldMatrix = sceneNode->getWorldMatrix();
450 flags |= btCollisionObject::CF_KINEMATIC_OBJECT;
452 rigidBody_->setActivationState(DISABLE_DEACTIVATION);
456 bool hasTrigger =
false;
458 if (collision->isTrigger()) {
465 flags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
472 PLOGI <<
"PhysicsBodyComponent::createRigidBody() completed - rigidBody created with mass=" << info.
mass;
495 if (!sceneNode)
return;
497 entt::entity nodeEntity = sceneNode->getEntity();
498 if (!registry.valid(nodeEntity))
return;
static entt::registry & get()
Gets the registry for all components.
Base class for collision shape components.
PhysicsBodyComponent * bodyComponent_
EngineCore::Engine * getEngineModule()
gets the pointer to the engine object
static EngineManager & getInstance()
gets a reference to the engine manager
PhysicsEngine * getPhysicsEngine() const
Getter for the pointer to the physics engine.
std::vector< T * > getComponents() const
Returns all components of type T.
virtual void endPlay()
Called when the component is removed or the game ends.
virtual void beginPlay()
Called when the component is added to the scene or the game starts.
LogicComponent(Scene *owningScene)
Entity * getOwningEntity() const
Gets the entity this component belongs to.
void unregisterCollision(CollisionComponent *collision)
Unregisters a collision component from this body. Called by CollisionComponent::endPlay().
void registerCollision(CollisionComponent *collision)
Registers a collision component with this body. Called by CollisionComponent::beginPlay().
void beginPlay() override
Called when the component is added to the scene or the game starts.
void endPlay() override
Called when the component is removed or the game ends.
void setRestitution(float restitution)
Sets the restitution (bounciness).
void setFriction(float friction)
Sets the friction coefficient.
void rebuildCollisionShape()
void setStatic(bool isStatic)
Sets whether the body is static (immovable).
glm::vec3 getAngularVelocity() const
Gets the angular velocity.
void markShapeDirty()
Marks the collision shape as needing rebuild. Called when a collision component's shape changes.
PhysicsEngine * getPhysicsEngine() const
std::weak_ptr< SceneNode > sceneNode_
std::set< CollisionComponent * > previousCollisions_
bool isStatic() const
Checks if the body is static.
~PhysicsBodyComponent() override
void setKinematic(bool kinematic)
Sets whether the body is kinematic. Kinematic bodies are moved by code, not physics.
void setAngularVelocity(const glm::vec3 &velocity)
Sets the angular velocity.
glm::vec3 getLinearVelocity() const
Gets the linear velocity.
void updateEcsComponent()
btCompoundShape * compoundShape_
void setMass(float mass)
Sets the mass of the rigid body.
void processCollisions()
Processes collision events and dispatches callbacks. Called after physics step.
void setLinearVelocity(const glm::vec3 &velocity)
Sets the linear velocity.
void rebuildIfDirty()
Rebuilds the collision shape if dirty.
void teleport(const glm::vec3 &position)
Teleports the body to a new position.
std::vector< CollisionComponent * > collisions_
PhysicsBodyComponent(Scene *scene, entt::entity entity, std::shared_ptr< SceneNode > sceneNode)
Constructs a PhysicsBodyComponent.
The physics engine manages creating and destroying physics objects for the physics simulation.
btRigidBody * createRigidBody(const RigidBodyCreateInfo &info) const
Creates a rigid body for the physics simulation.
btDiscreteDynamicsWorld * getDynamicsWorld() const
Gets the world where the physics simulation is performed inside.
void removeRigidBody(btRigidBody *body) const
Removes a rigid body from the physics simulation.
A scene is the overarching structure which can spawn actors.
Log category system implementation.
btQuaternion getQuat(glm::quat quaternion)
btVector3 getVec3(glm::vec3 v)
vec3 getVec3(btVector3 v)
Tag for EnTT which tags entities which should simulate physics.
Rigid body create info is used to create a rigid body. It delivers all informations like the initial ...
glm::mat4 transform
initial location for the rigid body
float restitution
energy absorption 0.0f means full absorption on impact, 0.5f half of the energy is maintained after i...
float friction
friction 0.0f - 1.0f. 0 is ice 0.3f - 0.5f wood or plastic. 0.7f - 1.0f High friction
btCollisionShape * shape
pointer to the collision shape
float mass
mass in Kilograms. Mass of 0 is a static object --> immovable