[DEV] collision implementation done
This commit is contained in:
parent
2b1c2619c7
commit
bc20095852
@ -39,7 +39,8 @@ ege::ElementPhysic::ElementPhysic(const std::shared_ptr<ege::Environement>& _env
|
|||||||
m_body(nullptr),
|
m_body(nullptr),
|
||||||
m_shape(nullptr),
|
m_shape(nullptr),
|
||||||
m_elementInPhysicsSystem(false),
|
m_elementInPhysicsSystem(false),
|
||||||
m_IA(nullptr) {
|
m_IA(nullptr),
|
||||||
|
m_detectCollisionEnable(false) {
|
||||||
if (_autoRigidBody == true) {
|
if (_autoRigidBody == true) {
|
||||||
createRigidBody();
|
createRigidBody();
|
||||||
} else {
|
} else {
|
||||||
@ -447,3 +448,22 @@ void ege::ElementPhysic::setAngularVelocity(const vec3& _value) {
|
|||||||
m_body->setAngularVelocity(_value);
|
m_body->setAngularVelocity(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ege::ElementPhysic::setCollisionDetectionStatus(bool _status) {
|
||||||
|
if (m_body == nullptr) {
|
||||||
|
EGE_WARNING("no body");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_detectCollisionEnable == _status) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_detectCollisionEnable = _status;
|
||||||
|
if (m_detectCollisionEnable == true) {
|
||||||
|
m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
||||||
|
} else {
|
||||||
|
if ((m_body->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) != 0) {
|
||||||
|
m_body->setCollisionFlags(m_body->getCollisionFlags() - btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -180,6 +180,28 @@ namespace ege {
|
|||||||
const std::shared_ptr<ewol::resource::Colored3DObject>& _draw,
|
const std::shared_ptr<ewol::resource::Colored3DObject>& _draw,
|
||||||
mat4 _transformationMatrix,
|
mat4 _transformationMatrix,
|
||||||
std::vector<vec3> _tmpVertices);
|
std::vector<vec3> _tmpVertices);
|
||||||
|
protected:
|
||||||
|
bool m_detectCollisionEnable; //!< physic collision detect enable.
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief get collision status of the object.
|
||||||
|
* @return the collision status.
|
||||||
|
*/
|
||||||
|
bool getCollisionDetectionStatus() {
|
||||||
|
return m_detectCollisionEnable;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Change enable status of the object.
|
||||||
|
* @param[in] _status new requested status.
|
||||||
|
*/
|
||||||
|
void setCollisionDetectionStatus(bool _status=true);
|
||||||
|
/**
|
||||||
|
* @brief when a collision is detected with an other object (just after calculate data update
|
||||||
|
* @param[in] _obj the Other object
|
||||||
|
* @param[in] _point Position of the impact in the global world
|
||||||
|
* @param[in] _normal Normal of the impact
|
||||||
|
*/
|
||||||
|
virtual void onCollisionDetected(const std::shared_ptr<ege::Element>& _obj, const vec3& _point, const vec3& _normal) {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <ege/physics/Engine.h>
|
#include <ege/physics/Engine.h>
|
||||||
|
|
||||||
|
#include <ege/debug.h>
|
||||||
|
|
||||||
#include <ewol/openGL/openGL.h>
|
#include <ewol/openGL/openGL.h>
|
||||||
#include <etk/math/Matrix4.h>
|
#include <etk/math/Matrix4.h>
|
||||||
@ -24,9 +25,36 @@
|
|||||||
#include <btBulletDynamicsCommon.h>
|
#include <btBulletDynamicsCommon.h>
|
||||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||||
|
|
||||||
|
#include <ege/elements/ElementPhysic.h>
|
||||||
|
|
||||||
|
|
||||||
|
// unique callback function :
|
||||||
|
extern ContactProcessedCallback gContactProcessedCallback;
|
||||||
|
|
||||||
|
// TODO : remove double collision call ...
|
||||||
|
static bool handleContactsProcess(btManifoldPoint& _point, btCollisionObject* _body0, btCollisionObject* _body1) {
|
||||||
|
ege::ElementPhysic* elem0 = static_cast<ege::ElementPhysic*>(_body0->getUserPointer());
|
||||||
|
ege::ElementPhysic* elem1 = static_cast<ege::ElementPhysic*>(_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->shared_from_this(), _point.getPositionWorldOnA(), -_point.m_normalWorldOnB);
|
||||||
|
}
|
||||||
|
if (elem1->getCollisionDetectionStatus() == true) {
|
||||||
|
elem1->onCollisionDetected(elem0->shared_from_this(), _point.getPositionWorldOnA(), _point.m_normalWorldOnB);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ege::physics::Engine::Engine() {
|
ege::physics::Engine::Engine() {
|
||||||
setBulletConfig();
|
setBulletConfig();
|
||||||
|
// set callback for collisions ...
|
||||||
|
gContactProcessedCallback = (ContactProcessedCallback)handleContactsProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
ege::physics::Engine::~Engine() {
|
ege::physics::Engine::~Engine() {
|
||||||
@ -75,7 +103,36 @@ void ege::physics::Engine::setBulletConfig(std::shared_ptr<btDefaultCollisionCon
|
|||||||
// By default we set no gravity
|
// By default we set no gravity
|
||||||
m_dynamicsWorld->setGravity(btVector3(0,0,0));
|
m_dynamicsWorld->setGravity(btVector3(0,0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_env.setDynamicWorld(m_dynamicsWorld);
|
//m_env.setDynamicWorld(m_dynamicsWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
// some doccumantation : http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Collision_Callbacks_and_Triggers
|
||||||
|
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) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ege::ElementPhysic* elem0 = static_cast<ege::ElementPhysic*>(obA->getUserPointer());
|
||||||
|
ege::ElementPhysic* elem1 = static_cast<ege::ElementPhysic*>(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->shared_from_this(), elem1->shared_from_this(), pt.getPositionWorldOnA(), pt.getPositionWorldOnB(), pt.m_normalWorldOnB));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
}
|
}
|
@ -25,6 +25,7 @@ namespace ege {
|
|||||||
#include <ewol/resource/Manager.h>
|
#include <ewol/resource/Manager.h>
|
||||||
#include <ewol/Dimension.h>
|
#include <ewol/Dimension.h>
|
||||||
|
|
||||||
|
|
||||||
class btBroadphaseInterface;
|
class btBroadphaseInterface;
|
||||||
class btCollisionShape;
|
class btCollisionShape;
|
||||||
class btOverlappingPairCache;
|
class btOverlappingPairCache;
|
||||||
@ -36,6 +37,7 @@ class btDynamicsWorld;
|
|||||||
#include <LinearMath/btScalar.h>
|
#include <LinearMath/btScalar.h>
|
||||||
class btVector3;
|
class btVector3;
|
||||||
|
|
||||||
|
|
||||||
//#include <ege/elements/Element.h>
|
//#include <ege/elements/Element.h>
|
||||||
|
|
||||||
namespace ege {
|
namespace ege {
|
||||||
@ -70,6 +72,32 @@ namespace ege {
|
|||||||
std::shared_ptr<btDynamicsWorld> getDynamicWorld() {
|
std::shared_ptr<btDynamicsWorld> getDynamicWorld() {
|
||||||
return m_dynamicsWorld;
|
return m_dynamicsWorld;
|
||||||
};
|
};
|
||||||
|
public:
|
||||||
|
// Define a collision point ==> for debug only ...
|
||||||
|
//! @not-in-doc
|
||||||
|
class collisionPoints {
|
||||||
|
public:
|
||||||
|
std::shared_ptr<ege::Element> elem1;
|
||||||
|
std::shared_ptr<ege::Element> elem2;
|
||||||
|
vec3 positionElem1;
|
||||||
|
vec3 positionElem2;
|
||||||
|
vec3 normalElem2;
|
||||||
|
collisionPoints(const std::shared_ptr<ege::Element>& _elem1,
|
||||||
|
const std::shared_ptr<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();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -20,12 +20,6 @@
|
|||||||
#include <ege/physicsShape/PhysicsBox.h>
|
#include <ege/physicsShape/PhysicsBox.h>
|
||||||
#include <ege/physicsShape/PhysicsSphere.h>
|
#include <ege/physicsShape/PhysicsSphere.h>
|
||||||
|
|
||||||
#include <BulletDynamics/Dynamics/btRigidBody.h>
|
|
||||||
#include <LinearMath/btDefaultMotionState.h>
|
|
||||||
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
|
|
||||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
|
||||||
|
|
||||||
|
|
||||||
#undef __class__
|
#undef __class__
|
||||||
#define __class__ "Windows"
|
#define __class__ "Windows"
|
||||||
|
|
||||||
@ -145,6 +139,20 @@ void appl::Windows::init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace appl {
|
||||||
|
class ElementHerit : public ege::ElementPhysic {
|
||||||
|
public:
|
||||||
|
ElementHerit(const std::shared_ptr<ege::Environement>& _env, bool _autoRigidBody=true) :
|
||||||
|
ege::ElementPhysic(_env, _autoRigidBody) {
|
||||||
|
setCollisionDetectionStatus(true);
|
||||||
|
}
|
||||||
|
virtual void onCollisionDetected(const std::shared_ptr<ege::Element>& _obj, const vec3& _point, const vec3& _normal) {
|
||||||
|
APPL_WARNING("[" << getUID() << "] collision : pos=" << _point << " norm=" <<_normal);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool appl::Windows::onEventInput(const ewol::event::Input& _event) {
|
bool appl::Windows::onEventInput(const ewol::event::Input& _event) {
|
||||||
static float ploppp=1;
|
static float ploppp=1;
|
||||||
if (_event.getId() == 1) {
|
if (_event.getId() == 1) {
|
||||||
@ -155,7 +163,7 @@ bool appl::Windows::onEventInput(const ewol::event::Input& _event) {
|
|||||||
std::shared_ptr<ege::resource::Mesh> myMesh;
|
std::shared_ptr<ege::resource::Mesh> myMesh;
|
||||||
myMesh = ege::resource::Mesh::createCube(1, "basics", etk::color::green);
|
myMesh = ege::resource::Mesh::createCube(1, "basics", etk::color::green);
|
||||||
if (myMesh != nullptr) {
|
if (myMesh != nullptr) {
|
||||||
std::shared_ptr<ege::ElementPhysic> element = std::make_shared<ege::ElementPhysic>(m_env);
|
std::shared_ptr<appl::ElementHerit> element = std::make_shared<appl::ElementHerit>(m_env);
|
||||||
std::shared_ptr<ege::PhysicsBox> physic = std::make_shared<ege::PhysicsBox>();
|
std::shared_ptr<ege::PhysicsBox> physic = std::make_shared<ege::PhysicsBox>();
|
||||||
physic->setSize(vec3(1.01,1.01,1.01));
|
physic->setSize(vec3(1.01,1.01,1.01));
|
||||||
myMesh->addPhysicElement(physic);
|
myMesh->addPhysicElement(physic);
|
||||||
@ -216,30 +224,14 @@ bool appl::Windows::onEventInput(const ewol::event::Input& _event) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Collision_Callbacks_and_Triggers
|
|
||||||
// manually detect collision : (loop to detect cillisions ...
|
|
||||||
void appl::Windows::onCallbackPeriodicCheckCollision(const ewol::event::Time& _event) {
|
void appl::Windows::onCallbackPeriodicCheckCollision(const ewol::event::Time& _event) {
|
||||||
int32_t numManifolds = m_env->getPhysicEngine().getDynamicWorld()->getDispatcher()->getNumManifolds();
|
std::vector<ege::physics::Engine::collisionPoints> list = m_env->getPhysicEngine().getListOfCollision();
|
||||||
if (numManifolds != 0) {
|
|
||||||
APPL_ERROR("numManifolds=" << numManifolds);
|
if (list.size() != 0) {
|
||||||
|
APPL_INFO("num contact =" << list.size());
|
||||||
}
|
}
|
||||||
for (int i=0;i<numManifolds;i++) {
|
for (size_t iii=0;iii<list.size();++iii) {
|
||||||
btPersistentManifold* contactManifold = m_env->getPhysicEngine().getDynamicWorld()->getDispatcher()->getManifoldByIndexInternal(i);
|
APPL_ERROR(" [" << list[iii].elem1->getUID() << "]:point1=" << list[iii].positionElem1 << " [" << list[iii].elem1->getUID() << "]:point2=" << list[iii].positionElem2 << " normal=" << list[iii].normalElem2);
|
||||||
const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
|
|
||||||
const btCollisionObject* obB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
|
|
||||||
int numContacts = contactManifold->getNumContacts();
|
|
||||||
if (numContacts != 0) {
|
|
||||||
APPL_ERROR(" numContacts=" << numContacts);
|
|
||||||
}
|
|
||||||
for (int j=0;j<numContacts;j++) {
|
|
||||||
btManifoldPoint& pt = contactManifold->getContactPoint(j);
|
|
||||||
if (pt.getDistance()<0.f) {
|
|
||||||
const vec3& ptA = pt.getPositionWorldOnA();
|
|
||||||
const vec3& ptB = pt.getPositionWorldOnB();
|
|
||||||
const vec3& normalOnB = pt.m_normalWorldOnB;
|
|
||||||
APPL_ERROR(" point1=" << ptA << " point2=" << ptB << " normal=" << normalOnB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user