[DEV] add a bacic callback of the collision detection (need to do better) and debug AABB elements

This commit is contained in:
Edouard DUPIN 2017-06-23 00:11:30 +00:00
parent e7351e8a0f
commit 71a5e41f5a
6 changed files with 57 additions and 93 deletions

View File

@ -15,7 +15,7 @@ namespace ege {
protected:
public:
virtual const std::string& getType() const;
virtual const std::string& getType() const override;
};
}
}

View File

@ -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;

View File

@ -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<ege::Environement> _env) {
m_engine = ememory::dynamicPointerCast<ege::physics::Engine>(_env->getEngine(getType()));
// Initial position and orientation of the rigid body
@ -27,6 +31,8 @@ ege::physics::Component::Component(ememory::SharedPtr<ege::Environement> _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<ege::Environement> _env, const etk::Transform3D& _transform) {
@ -42,6 +48,8 @@ ege::physics::Component::Component(ememory::SharedPtr<ege::Environement> _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<ewol::resource::Color
break;
}
}
}
}
void ege::physics::Component::drawAABB(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera) {
if (m_rigidBody == nullptr) {
return;
}
mat4 transformationMatrix;
etk::Color<float> 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);
}

View File

@ -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<etk::Transform3D> signalPosition;
protected:
@ -40,7 +42,7 @@ namespace ege {
Component(ememory::SharedPtr<ege::Environement> _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<ege::physics::Shape>& _shape);
void generate();
void drawShape(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _camera);
void drawAABB(ememory::SharedPtr<ewol::resource::Colored3DObject> _draw, ememory::SharedPtr<ege::Camera> _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;
};
}
}

View File

@ -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<ege::Component>& _ref) {
ememory::SharedPtr<ege::physics::Component> ref = ememory::dynamicPointerCast<ege::physics::Component>(_ref);
for (auto it=m_component.begin();
@ -42,30 +52,6 @@ void ege::physics::Engine::componentAdd(const ememory::SharedPtr<ege::Component>
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<ege::EntityPhysic*>(_body0->getUserPointer());
ege::EntityPhysic* elem1 = static_cast<ege::EntityPhysic*>(_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<ege::Camera>& _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::collisionPoints> ege::physics::Engine::getListOfCollision() {
std::vector<collisionPoints> out;
/*
if (m_dynamicsWorld != nullptr) {
int32_t numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
for (int i=0;i<numManifolds;i++) {
btPersistentManifold* contactManifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
const btCollisionObject* obB = static_cast<const btCollisionObject*>(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<ege::EntityPhysic*>(obA->getUserPointer());
ege::EntityPhysic* elem1 = static_cast<ege::EntityPhysic*>(obB->getUserPointer());
if ( elem0 == nullptr
|| elem1 == nullptr) {
continue;
}
int numContacts = contactManifold->getNumContacts();
for (int j=0;j<numContacts;j++) {
btManifoldPoint& pt = contactManifold->getContactPoint(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

View File

@ -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<bool> propertyDebugAABB;
eproperty::Value<bool> 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<ege::Element> elem1;
ememory::SharedPtr<ege::Element> elem2;
vec3 positionElem1;
vec3 positionElem2;
vec3 normalElem2;
collisionPoints(const ememory::SharedPtr<ege::Element>& _elem1,
const ememory::SharedPtr<ege::Element>& _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<ege::physics::Engine::collisionPoints> 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<ege::Component>& _ref) override;
void update(const echrono::Duration& _delta) override;
void renderDebug(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera) override;
private:
// herited from rp3D::EventListener
void beginContact(const rp3d::ContactPointInfo& _contact) override;
void newContact(const rp3d::ContactPointInfo& _contact) override;
};
}
}