diff --git a/ege/ia/Component.hpp b/ege/ia/Component.hpp index b7ca2ca..4e1f284 100644 --- a/ege/ia/Component.hpp +++ b/ege/ia/Component.hpp @@ -15,7 +15,7 @@ namespace ege { protected: public: - virtual const std::string& getType() const; + virtual const std::string& getType() const override; }; } } \ No newline at end of file diff --git a/ege/particule/Component.hpp b/ege/particule/Component.hpp index d1761cd..c087284 100644 --- a/ege/particule/Component.hpp +++ b/ege/particule/Component.hpp @@ -16,7 +16,7 @@ namespace ege { class Engine; class Component : public ege::Component { public: - virtual const std::string& getType() const; + virtual const std::string& getType() const override; protected: ege::particule::Engine* m_particuleEngine; const char* m_particuleType; diff --git a/ege/physics/Component.cpp b/ege/physics/Component.cpp index ad3a6b1..d9e70ec 100644 --- a/ege/physics/Component.cpp +++ b/ege/physics/Component.cpp @@ -19,6 +19,10 @@ const std::string& ege::physics::Component::getType() const { return tmp; } +void ege::physics::Component::notifyContact(const rp3d::ContactPointInfo& _contactPointInfo) { + EGE_INFO("collision detection " << vec3(_contactPointInfo.normal.x, _contactPointInfo.normal.y, _contactPointInfo.normal.z) << " depth=" << _contactPointInfo.penetrationDepth); +} + ege::physics::Component::Component(ememory::SharedPtr _env) { m_engine = ememory::dynamicPointerCast(_env->getEngine(getType())); // Initial position and orientation of the rigid body @@ -27,6 +31,8 @@ ege::physics::Component::Component(ememory::SharedPtr _env) { rp3d::Transform transform(initPosition, initOrientation); m_lastTransformEmit = etk::Transform3D(vec3(0,0,0), etk::Quaternion::identity()); m_rigidBody = m_engine->getDynamicWorld()->createRigidBody(transform); + // set collision callback: + m_engine->getDynamicWorld()->testCollision(m_rigidBody, this); } ege::physics::Component::Component(ememory::SharedPtr _env, const etk::Transform3D& _transform) { @@ -42,6 +48,8 @@ ege::physics::Component::Component(ememory::SharedPtr _env, c // Create a rigid body in the world m_rigidBody = m_engine->getDynamicWorld()->createRigidBody(transform); m_lastTransformEmit = _transform; + // set collision callback: + m_engine->getDynamicWorld()->testCollision(m_rigidBody, this); } void ege::physics::Component::setType(enum ege::physics::Component::type _type) { @@ -65,6 +73,8 @@ ege::physics::Component::~Component() { if (m_rigidBody == nullptr) { return; } + // disable callback + m_engine->getDynamicWorld()->testCollision(m_rigidBody, nullptr); m_engine->getDynamicWorld()->destroyRigidBody(m_rigidBody); m_rigidBody = nullptr; } @@ -427,4 +437,17 @@ void ege::physics::Component::drawShape(ememory::SharedPtr _draw, ememory::SharedPtr _camera) { + if (m_rigidBody == nullptr) { + return; + } + mat4 transformationMatrix; + etk::Color tmpColor(0.0, 1.0, 0.0, 0.8); + rp3d::AABB value = m_rigidBody->getAABB(); + vec3 minimum(value.getMin().x, value.getMin().y, value.getMin().z); + vec3 maximum(value.getMax().x, value.getMax().y, value.getMax().z); + _draw->drawCubeLine(minimum, maximum, tmpColor, transformationMatrix); + +} diff --git a/ege/physics/Component.hpp b/ege/physics/Component.hpp index a36f030..c2665cf 100644 --- a/ege/physics/Component.hpp +++ b/ege/physics/Component.hpp @@ -18,7 +18,9 @@ namespace ege { class Environement; namespace physics { class Engine; - class Component : public ege::Component { + class Component : + public ege::Component, + public rp3d::CollisionCallback { public: esignal::Signal signalPosition; protected: @@ -40,7 +42,7 @@ namespace ege { Component(ememory::SharedPtr _env, const etk::Transform3D& _transform); ~Component(); public: - virtual const std::string& getType() const; + virtual const std::string& getType() const override; enum class type { bodyDynamic, @@ -86,9 +88,13 @@ namespace ege { void addShape(const ememory::SharedPtr& _shape); void generate(); void drawShape(ememory::SharedPtr _draw, ememory::SharedPtr _camera); + void drawAABB(ememory::SharedPtr _draw, ememory::SharedPtr _camera); private: void emitAll(); friend class ege::physics::Engine; + private: + // herited from rp3d::CollisionCallback to notify the contact on the current rigid body + void notifyContact(const rp3d::ContactPointInfo& _contactPointInfo) override; }; } } \ No newline at end of file diff --git a/ege/physics/Engine.cpp b/ege/physics/Engine.cpp index 6db26bd..6fe6505 100644 --- a/ege/physics/Engine.cpp +++ b/ege/physics/Engine.cpp @@ -17,6 +17,16 @@ const std::string& ege::physics::Engine::getType() const { return tmp; } +void ege::physics::Engine::beginContact(const rp3d::ContactPointInfo& _contact) { + // Called when a new contact point is found between two bodies that were separated before. + EGE_WARNING("collision detection [BEGIN] " << vec3(_contact.normal.x, _contact.normal.y, _contact.normal.z) << " depth=" << _contact.penetrationDepth); +} + +void ege::physics::Engine::newContact(const rp3d::ContactPointInfo& _contact) { + //Called when a new contact point is found between two bodies. + EGE_WARNING("collision detection [ NEW ] " << vec3(_contact.normal.x, _contact.normal.y, _contact.normal.z) << " depth=" << _contact.penetrationDepth); +} + void ege::physics::Engine::componentRemove(const ememory::SharedPtr& _ref) { ememory::SharedPtr ref = ememory::dynamicPointerCast(_ref); for (auto it=m_component.begin(); @@ -42,30 +52,6 @@ void ege::physics::Engine::componentAdd(const ememory::SharedPtr m_component.push_back(ref); } -// unique callback function : -/* -extern ContactProcessedCallback gContactProcessedCallback; - -// TODO : remove double collision call ... -static bool handleContactsProcess(btManifoldPoint& _point, btCollisionObject* _body0, btCollisionObject* _body1) { - ege::Entityhysic* elem0 = static_cast(_body0->getUserPointer()); - ege::EntityPhysic* elem1 = static_cast(_body1->getUserPointer()); - if ( elem0 == nullptr - || elem1 == nullptr) { - EGE_WARNING("callback of collision error"); - return false; - } - EGE_VERBOSE("collision process between " << elem0->getUID() << " && " << elem1->getUID() << " pos=" << _point.getPositionWorldOnA() << " norm=" << _point.m_normalWorldOnB); - if (elem0->getCollisionDetectionStatus() == true) { - elem0->onCollisionDetected(elem1->sharedFromThis(), _point.getPositionWorldOnA(), -_point.m_normalWorldOnB); - } - if (elem1->getCollisionDetectionStatus() == true) { - elem1->onCollisionDetected(elem0->sharedFromThis(), _point.getPositionWorldOnA(), _point.m_normalWorldOnB); - } - return true; -} -*/ - ege::physics::Engine::Engine(ege::Environement* _env) : ege::Engine(_env), propertyDebugAABB(this, "debug-AABB", false, "display the global AABB box of every shape"), @@ -81,11 +67,13 @@ ege::physics::Engine::Engine(ege::Environement* _env) : if (m_dynamicsWorld != nullptr) { // Set the number of iterations of the constraint solver m_dynamicsWorld->setNbIterationsVelocitySolver(15); + m_dynamicsWorld->setEventListener(this); } } ege::physics::Engine::~Engine() { if (m_dynamicsWorld != nullptr) { + m_dynamicsWorld->setEventListener(nullptr); delete m_dynamicsWorld; m_dynamicsWorld = nullptr; } @@ -125,7 +113,6 @@ void ege::physics::Engine::update(const echrono::Duration& _delta) { } } - void ege::physics::Engine::renderDebug(const echrono::Duration& _delta, const ememory::SharedPtr& _camera) { if (propertyDebugShape.get() == true) { for (auto &it : m_component) { @@ -135,40 +122,13 @@ void ege::physics::Engine::renderDebug(const echrono::Duration& _delta, const em it->drawShape(m_debugDrawProperty, _camera); } } -} - -#if 0 -std::vector ege::physics::Engine::getListOfCollision() { - std::vector out; - /* - if (m_dynamicsWorld != nullptr) { - int32_t numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds(); - for (int i=0;igetDispatcher()->getManifoldByIndexInternal(i); - const btCollisionObject* obA = static_cast(contactManifold->getBody0()); - const btCollisionObject* obB = static_cast(contactManifold->getBody1()); - if ( obA == nullptr - || obB == nullptr) { + if (propertyDebugAABB.get() == true) { + for (auto &it : m_component) { + if (it == nullptr) { continue; } - ege::EntityPhysic* elem0 = static_cast(obA->getUserPointer()); - ege::EntityPhysic* elem1 = static_cast(obB->getUserPointer()); - if ( elem0 == nullptr - || elem1 == nullptr) { - continue; - } - int numContacts = contactManifold->getNumContacts(); - for (int j=0;jgetContactPoint(j); - if (pt.getDistance()<0.f) { - out.push_back(collisionPoints(elem0->sharedFromThis(), elem1->sharedFromThis(), pt.getPositionWorldOnA(), pt.getPositionWorldOnB(), pt.m_normalWorldOnB)); - } - } + it->drawAABB(m_debugDrawProperty, _camera); } } - */ - return out; } -#endif - diff --git a/ege/physics/Engine.hpp b/ege/physics/Engine.hpp index c605240..deb1567 100644 --- a/ege/physics/Engine.hpp +++ b/ege/physics/Engine.hpp @@ -29,7 +29,9 @@ namespace ege { namespace ege { namespace physics { - class Engine : public ege::Engine { + class Engine: + public ege::Engine, + public rp3d::EventListener { public: eproperty::Value propertyDebugAABB; eproperty::Value propertyDebugShape; @@ -40,42 +42,11 @@ namespace ege { Engine(ege::Environement* _env); ~Engine(); public: - // Define a collision point ==> for debug only ... - //! @not_in_doc -#if 0 - class collisionPoints { - public: - ememory::SharedPtr elem1; - ememory::SharedPtr elem2; - vec3 positionElem1; - vec3 positionElem2; - vec3 normalElem2; - collisionPoints(const ememory::SharedPtr& _elem1, - const ememory::SharedPtr& _elem2, - const vec3& _pos1, - const vec3& _pos2, - const vec3& _normal) : - elem1(_elem1), - elem2(_elem2), - positionElem1(_pos1), - positionElem2(_pos2), - normalElem2(_normal) { } - }; - /** - * @brief Get the list of all collision point actually availlable ... - * @return the requested list of points - */ - std::vector getListOfCollision(); -#endif /** * @brief Set the gravity axis of the physic engine * @param[in] _axePower energy of this gravity */ void setGravity(const vec3& _axePower); - - void debugDrawWorld() { - // TODO: later ... - } rp3d::DynamicsWorld* getDynamicWorld() { return m_dynamicsWorld; } @@ -89,6 +60,10 @@ namespace ege { void componentAdd(const ememory::SharedPtr& _ref) override; void update(const echrono::Duration& _delta) override; void renderDebug(const echrono::Duration& _delta, const ememory::SharedPtr& _camera) override; + private: + // herited from rp3D::EventListener + void beginContact(const rp3d::ContactPointInfo& _contact) override; + void newContact(const rp3d::ContactPointInfo& _contact) override; }; } }