[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_shape(nullptr),
|
||||
m_elementInPhysicsSystem(false),
|
||||
m_IA(nullptr) {
|
||||
m_IA(nullptr),
|
||||
m_detectCollisionEnable(false) {
|
||||
if (_autoRigidBody == true) {
|
||||
createRigidBody();
|
||||
} else {
|
||||
@ -447,3 +448,22 @@ void ege::ElementPhysic::setAngularVelocity(const vec3& _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,
|
||||
mat4 _transformationMatrix,
|
||||
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/debug.h>
|
||||
|
||||
#include <ewol/openGL/openGL.h>
|
||||
#include <etk/math/Matrix4.h>
|
||||
@ -24,9 +25,36 @@
|
||||
#include <btBulletDynamicsCommon.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() {
|
||||
setBulletConfig();
|
||||
// set callback for collisions ...
|
||||
gContactProcessedCallback = (ContactProcessedCallback)handleContactsProcess;
|
||||
}
|
||||
|
||||
ege::physics::Engine::~Engine() {
|
||||
@ -75,7 +103,36 @@ void ege::physics::Engine::setBulletConfig(std::shared_ptr<btDefaultCollisionCon
|
||||
// By default we set no gravity
|
||||
m_dynamicsWorld->setGravity(btVector3(0,0,0));
|
||||
}
|
||||
|
||||
//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/Dimension.h>
|
||||
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionShape;
|
||||
class btOverlappingPairCache;
|
||||
@ -36,6 +37,7 @@ class btDynamicsWorld;
|
||||
#include <LinearMath/btScalar.h>
|
||||
class btVector3;
|
||||
|
||||
|
||||
//#include <ege/elements/Element.h>
|
||||
|
||||
namespace ege {
|
||||
@ -70,6 +72,32 @@ namespace ege {
|
||||
std::shared_ptr<btDynamicsWorld> getDynamicWorld() {
|
||||
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/PhysicsSphere.h>
|
||||
|
||||
#include <BulletDynamics/Dynamics/btRigidBody.h>
|
||||
#include <LinearMath/btDefaultMotionState.h>
|
||||
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
|
||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||
|
||||
|
||||
#undef __class__
|
||||
#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) {
|
||||
static float ploppp=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;
|
||||
myMesh = ege::resource::Mesh::createCube(1, "basics", etk::color::green);
|
||||
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>();
|
||||
physic->setSize(vec3(1.01,1.01,1.01));
|
||||
myMesh->addPhysicElement(physic);
|
||||
@ -216,30 +224,14 @@ bool appl::Windows::onEventInput(const ewol::event::Input& _event) {
|
||||
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) {
|
||||
int32_t numManifolds = m_env->getPhysicEngine().getDynamicWorld()->getDispatcher()->getNumManifolds();
|
||||
if (numManifolds != 0) {
|
||||
APPL_ERROR("numManifolds=" << numManifolds);
|
||||
std::vector<ege::physics::Engine::collisionPoints> list = m_env->getPhysicEngine().getListOfCollision();
|
||||
|
||||
if (list.size() != 0) {
|
||||
APPL_INFO("num contact =" << list.size());
|
||||
}
|
||||
for (int i=0;i<numManifolds;i++) {
|
||||
btPersistentManifold* contactManifold = m_env->getPhysicEngine().getDynamicWorld()->getDispatcher()->getManifoldByIndexInternal(i);
|
||||
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);
|
||||
}
|
||||
}
|
||||
for (size_t iii=0;iii<list.size();++iii) {
|
||||
APPL_ERROR(" [" << list[iii].elem1->getUID() << "]:point1=" << list[iii].positionElem1 << " [" << list[iii].elem1->getUID() << "]:point2=" << list[iii].positionElem2 << " normal=" << list[iii].normalElem2);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user