[DEV] add basic rigid body at the physic element

This commit is contained in:
Edouard DUPIN 2014-11-17 22:26:03 +01:00
parent 569d6c0b51
commit b980581156
7 changed files with 119 additions and 33 deletions

View File

@ -6,6 +6,7 @@
* @license BSD v3 (see license file) * @license BSD v3 (see license file)
*/ */
#include <ege/Ray.h> #include <ege/Ray.h>
#include <etk/math/Vector3D.h>
#undef __class__ #undef __class__
#define __class__ "Ray" #define __class__ "Ray"
@ -24,3 +25,14 @@ void ege::Ray::setDirection(const vec3& _direction) {
m_direction = _direction; m_direction = _direction;
m_direction.safeNormalize(); m_direction.safeNormalize();
} }
std::ostream& ege::operator <<(std::ostream& _os, const ege::Ray& _obj) {
_os << "{ori=";
_os << _obj.getOrigin();
_os << " dir=";
_os << _obj.getDirection();
_os << "}";
return _os;
}

View File

@ -62,6 +62,8 @@ namespace ege {
*/ */
void set(const vec3& _origin, const vec3& _direction); void set(const vec3& _origin, const vec3& _direction);
}; };
std::ostream& operator <<(std::ostream& _os, const ege::Ray& _obj);
} }
#endif #endif

View File

@ -69,6 +69,10 @@ vec3 ege::camera::View::getViewVector() const {
ege::Ray ege::camera::View::getRayFromScreen(const vec2& _offset) { ege::Ray ege::camera::View::getRayFromScreen(const vec2& _offset) {
ege::Ray out(m_eye, getViewVector()); ege::Ray out(m_eye, getViewVector());
EGE_WARNING("request ray from : " << _offset);
EGE_WARNING(" camera offset = " << vec2(m_angleView/2*_offset.x(), 2*_offset.y()*m_aspectRatio/m_angleView));
EGE_WARNING("return ray : " << out);
// TODO : Use offset... // TODO : Use offset...
return out; return out;
} }

View File

@ -34,13 +34,17 @@ const std::string& ege::ElementPhysic::getType() const {
} }
ege::ElementPhysic::ElementPhysic(const std::shared_ptr<ege::Environement>& _env) : ege::ElementPhysic::ElementPhysic(const std::shared_ptr<ege::Environement>& _env, bool _autoRigidBody) :
ege::Element(_env), ege::Element(_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) {
if (_autoRigidBody == true) {
createRigidBody();
} else {
EGE_TODO("add basic API to create custum rigid body");
}
} }
ege::ElementPhysic::~ElementPhysic() { ege::ElementPhysic::~ElementPhysic() {
@ -53,6 +57,28 @@ ege::ElementPhysic::~ElementPhysic() {
m_body = nullptr; m_body = nullptr;
} }
void ege::ElementPhysic::createRigidBody(float _mass) {
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
vec3 localInertia(0,0,0);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
/*
if (mass != 0.0f && getShape()!=nullptr) {
getShape()->calculateLocalInertia(mass, localInertia);
}
*/
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
m_motionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(_mass,m_motionState,getShape(),localInertia);
m_body = new btRigidBody(rbInfo);
//m_body->applyTorqueImpulse(btVector3(0,0,0.2));
//m_body->setAngularVelocity(vec3(etk::tool::frand(-1,1),etk::tool::frand(-1,1),etk::tool::frand(-1,1)));
}
bool ege::ElementPhysic::setMesh(const std::shared_ptr<ege::resource::Mesh>& _mesh) { bool ege::ElementPhysic::setMesh(const std::shared_ptr<ege::resource::Mesh>& _mesh) {
if (nullptr!=m_mesh) { if (nullptr!=m_mesh) {
removeShape(); removeShape();
@ -100,14 +126,14 @@ void ege::ElementPhysic::removeShape() {
} }
void ege::ElementPhysic::FunctionFreeShape(void* _pointer) { void ege::ElementPhysic::FunctionFreeShape(void* _pointer) {
if (nullptr == _pointer) { if (_pointer == nullptr) {
return; return;
} }
delete(static_cast<btCollisionShape*>(_pointer)); delete(static_cast<btCollisionShape*>(_pointer));
} }
void ege::ElementPhysic::setPosition(const vec3& _pos) { void ege::ElementPhysic::setPosition(const vec3& _pos) {
if (nullptr!=m_body) { if (m_body != nullptr) {
btTransform transformation = m_body->getCenterOfMassTransform(); btTransform transformation = m_body->getCenterOfMassTransform();
transformation.setOrigin(_pos); transformation.setOrigin(_pos);
m_body->setCenterOfMassTransform(transformation); m_body->setCenterOfMassTransform(transformation);
@ -115,7 +141,7 @@ void ege::ElementPhysic::setPosition(const vec3& _pos) {
} }
const vec3& ege::ElementPhysic::getPosition() { const vec3& ege::ElementPhysic::getPosition() {
if (nullptr!=m_body) { if (m_body != nullptr) {
return m_body->getCenterOfMassPosition(); return m_body->getCenterOfMassPosition();
} }
return ege::Element::getPosition(); return ege::Element::getPosition();
@ -123,14 +149,14 @@ const vec3& ege::ElementPhysic::getPosition() {
const vec3& ege::ElementPhysic::getSpeed() { const vec3& ege::ElementPhysic::getSpeed() {
static vec3 emptySpeed(0,0,0); static vec3 emptySpeed(0,0,0);
if (nullptr!=m_body) { if (m_body != nullptr) {
return m_body->getLinearVelocity(); return m_body->getLinearVelocity();
} }
return emptySpeed; return emptySpeed;
}; };
const float ege::ElementPhysic::getInvMass() { const float ege::ElementPhysic::getInvMass() {
if (nullptr!=m_body) { if (m_body != nullptr) {
return m_body->getInvMass(); return m_body->getInvMass();
} }
return 0.0000000001f; return 0.0000000001f;
@ -140,8 +166,8 @@ static void drawShape(const btCollisionShape* _shape,
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) {
if( nullptr == _draw if( _draw == nullptr
|| nullptr == _shape) { || _shape == nullptr) {
return; return;
} }
etk::Color<float> tmpColor(1.0, 0.0, 0.0, 0.3); etk::Color<float> tmpColor(1.0, 0.0, 0.0, 0.3);
@ -319,15 +345,15 @@ void ege::ElementPhysic::drawDebug(const std::shared_ptr<ewol::resource::Colored
} }
void ege::ElementPhysic::draw(int32_t _pass) { void ege::ElementPhysic::draw(int32_t _pass) {
if (false == m_elementInPhysicsSystem) { if (m_elementInPhysicsSystem == false) {
return; return;
} }
EGE_INFO("draw : " << _pass ); //EGE_INFO("draw : " << _pass );
if (_pass == 0) { if (_pass == 0) {
if( nullptr != m_body if( m_body != nullptr
&& nullptr != m_mesh && m_mesh != nullptr
&& m_body->getMotionState() ) { && m_body->getMotionState() ) {
EGE_INFO(" plop "); //EGE_INFO(" plop ");
btScalar mmm[16]; btScalar mmm[16];
btDefaultMotionState* myMotionState = (btDefaultMotionState*)m_body->getMotionState(); btDefaultMotionState* myMotionState = (btDefaultMotionState*)m_body->getMotionState();
myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(mmm); myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(mmm);
@ -340,26 +366,26 @@ void ege::ElementPhysic::draw(int32_t _pass) {
} }
void ege::ElementPhysic::dynamicEnable() { void ege::ElementPhysic::dynamicEnable() {
if (true == m_elementInPhysicsSystem) { if (m_elementInPhysicsSystem == true) {
return; return;
} }
if(nullptr!=m_body) { if(m_body != nullptr) {
m_env->getPhysicEngine().getDynamicWorld()->addRigidBody(m_body); m_env->getPhysicEngine().getDynamicWorld()->addRigidBody(m_body);
} }
if(nullptr!=m_IA) { if(m_IA != nullptr) {
m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA); m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA);
} }
m_elementInPhysicsSystem = true; m_elementInPhysicsSystem = true;
} }
void ege::ElementPhysic::dynamicDisable() { void ege::ElementPhysic::dynamicDisable() {
if (false == m_elementInPhysicsSystem) { if (m_elementInPhysicsSystem == false) {
return; return;
} }
if(nullptr!=m_IA) { if(m_IA != nullptr) {
m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA); m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA);
} }
if(nullptr!=m_body) { if(m_body != nullptr) {
// Unlink element from the engine // Unlink element from the engine
m_env->getPhysicEngine().getDynamicWorld()->removeRigidBody(m_body); m_env->getPhysicEngine().getDynamicWorld()->removeRigidBody(m_body);
m_env->getPhysicEngine().getDynamicWorld()->removeCollisionObject(m_body); m_env->getPhysicEngine().getDynamicWorld()->removeCollisionObject(m_body);
@ -368,26 +394,26 @@ void ege::ElementPhysic::dynamicDisable() {
} }
void ege::ElementPhysic::iaEnable() { void ege::ElementPhysic::iaEnable() {
if (nullptr != m_IA) { if (m_IA != nullptr) {
// IA already started ... // IA already started ...
return; return;
} }
m_IA = new localIA(*this); m_IA = new localIA(*this);
if (nullptr == m_IA) { if (m_IA == nullptr) {
EGE_ERROR("Can not start the IA == > allocation error"); EGE_ERROR("Can not start the IA == > allocation error");
return; return;
} }
if (true == m_elementInPhysicsSystem) { if (m_elementInPhysicsSystem == true) {
m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA); m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA);
} }
} }
void ege::ElementPhysic::iaDisable() { void ege::ElementPhysic::iaDisable() {
if (nullptr == m_IA) { if (m_IA == nullptr) {
// IA already stopped ... // IA already stopped ...
return; return;
} }
if (true == m_elementInPhysicsSystem) { if (m_elementInPhysicsSystem == true) {
m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA); m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA);
} }
// remove IA : // remove IA :

View File

@ -23,6 +23,7 @@
#include <ege/Environement.h> #include <ege/Environement.h>
#include <ege/elements/Element.h> #include <ege/elements/Element.h>
#include <LinearMath/btDefaultMotionState.h>
#define INDEX_RIGHT_AXIS (0) #define INDEX_RIGHT_AXIS (0)
#define INDEX_FORWARD_AXIS (1) #define INDEX_FORWARD_AXIS (1)
@ -36,13 +37,17 @@ namespace ege {
static void FunctionFreeShape(void* _pointer); static void FunctionFreeShape(void* _pointer);
protected: protected:
btRigidBody* m_body; //!< all the element have a body == > otherwise it will be not manage with this system... btRigidBody* m_body; //!< all the element have a body == > otherwise it will be not manage with this system...
private:
btDefaultMotionState* m_motionState;
public:
void createRigidBody(float _mass=400000000.0f);
public: public:
/** /**
* @brief Constructor (when constructer is called just add element that did not change. * @brief Constructor (when constructer is called just add element that did not change.
* The objest will be stored in a pool of element and keep a second time if needed == > redure memory allocation, * The objest will be stored in a pool of element and keep a second time if needed == > redure memory allocation,
* when needed, the system will call the init and un-init function... * when needed, the system will call the init and un-init function...
*/ */
ElementPhysic(const std::shared_ptr<ege::Environement>& _env); ElementPhysic(const std::shared_ptr<ege::Environement>& _env, bool _autoRigidBody=true);
/** /**
* @brief Destructor * @brief Destructor
*/ */
@ -99,11 +104,13 @@ namespace ege {
* @param[in] set the 3D position. * @param[in] set the 3D position.
*/ */
virtual void setPositionTheoric(const vec3& _pos) { }; virtual void setPositionTheoric(const vec3& _pos) { };
/** /**
* @brief get the current speed of the element * @brief get the current speed of the element
* @return the 3D speed. * @return the 3D speed.
*/ */
const vec3& getSpeed(); const vec3& getSpeed();
/** /**
* @brief get the current mass of the element * @brief get the current mass of the element
* @return the mass in kG. * @return the mass in kG.

View File

@ -96,21 +96,26 @@ void appl::Windows::init() {
if (myMesh != nullptr) { if (myMesh != nullptr) {
//std::shared_ptr<ege::ElementBase> element = std::make_shared<ege::ElementBase>(m_env); //std::shared_ptr<ege::ElementBase> element = std::make_shared<ege::ElementBase>(m_env);
std::shared_ptr<ege::ElementPhysic> element = std::make_shared<ege::ElementPhysic>(m_env); std::shared_ptr<ege::ElementPhysic> element = std::make_shared<ege::ElementPhysic>(m_env);
element->setPosition(vec3(20,10,10));
element->setMesh(myMesh); element->setMesh(myMesh);
element->setPosition(vec3(20,10,10));
// add physic interface: // add physic interface:
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(3.2,3.2,3.2)); physic->setSize(vec3(3.2,3.2,3.2));
myMesh->addPhysicElement(physic); myMesh->addPhysicElement(physic);
m_env->addElement(element); m_env->addElement(element);
/*
element = std::make_shared<ege::ElementBase>(m_env);
//std::shared_ptr<ege::ElementPhysic> element = std::make_shared<ege::ElementPhysic>(m_env); //element = std::make_shared<ege::ElementBase>(m_env);
element->setPosition(vec3(-50,0,0)); element = std::make_shared<ege::ElementPhysic>(m_env);
element->setMesh(myMesh); element->setMesh(myMesh);
element->setPosition(vec3(20,-10,10));
// add physic interface:
physic = std::make_shared<ege::PhysicsBox>();
physic->setSize(vec3(3.2,3.2,3.2));
m_env->addElement(element); m_env->addElement(element);
*/
} }
} }
@ -120,7 +125,36 @@ void appl::Windows::onCallbackPeriodicUpdateCamera(const ewol::event::Time& _eve
offset += 0.01; offset += 0.01;
static float offset2 = 0; static float offset2 = 0;
offset2 += 0.003; offset2 += 0.003;
m_camera->setEye(vec3(100*std::sin(offset),100*std::cos(offset),40*std::cos(offset2))); //m_camera->setEye(vec3(100*std::sin(offset),100*std::cos(offset),40*std::cos(offset2)));
} }
bool appl::Windows::onEventInput(const ewol::event::Input& _event) {
if (_event.getId() == 1) {
vec2 pos = relativePosition(_event.getPos());
ege::Ray ray = m_camera->getRayFromScreenPosition(pos, m_size);
APPL_INFO("pos=" << pos << " ray = " << ray);
return true;
}
return false;
}
/*
btCollisionWorld::ClosestRayResultCallback RayCallback(
btVector3(out_origin.x, out_origin.y, out_origin.z),
btVector3(out_direction.x, out_direction.y, out_direction.z)
);
dynamicsWorld->rayTest(
btVector3(out_origin.x, out_origin.y, out_origin.z),
btVector3(out_direction.x, out_direction.y, out_direction.z),
RayCallback
);
if(RayCallback.hasHit()) {
std::ostringstream oss;
oss << "mesh " << (int)RayCallback.m_collisionObject->getUserPointer();
message = oss.str();
}else{
message = "background";
}
*/

View File

@ -26,6 +26,7 @@ namespace appl {
virtual ~Windows() { }; virtual ~Windows() { };
private: private:
void onCallbackPeriodicUpdateCamera(const ewol::event::Time& _event); void onCallbackPeriodicUpdateCamera(const ewol::event::Time& _event);
bool onEventInput(const ewol::event::Input& _event);
}; };
}; };