From b98058115619ed7f8c96726f4b3f2e8b65c2a872 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Mon, 17 Nov 2014 22:26:03 +0100 Subject: [PATCH] [DEV] add basic rigid body at the physic element --- ege/Ray.cpp | 12 ++++++ ege/Ray.h | 2 + ege/camera/View.cpp | 4 ++ ege/elements/ElementPhysic.cpp | 76 ++++++++++++++++++++++----------- ege/elements/ElementPhysic.h | 9 +++- sample/RayTest/appl/Windows.cpp | 48 ++++++++++++++++++--- sample/RayTest/appl/Windows.h | 1 + 7 files changed, 119 insertions(+), 33 deletions(-) diff --git a/ege/Ray.cpp b/ege/Ray.cpp index 6d6e996..c322827 100644 --- a/ege/Ray.cpp +++ b/ege/Ray.cpp @@ -6,6 +6,7 @@ * @license BSD v3 (see license file) */ #include +#include #undef __class__ #define __class__ "Ray" @@ -24,3 +25,14 @@ void ege::Ray::setDirection(const vec3& _direction) { m_direction = _direction; 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; +} \ No newline at end of file diff --git a/ege/Ray.h b/ege/Ray.h index d52e1a4..026aedb 100644 --- a/ege/Ray.h +++ b/ege/Ray.h @@ -62,6 +62,8 @@ namespace ege { */ void set(const vec3& _origin, const vec3& _direction); }; + + std::ostream& operator <<(std::ostream& _os, const ege::Ray& _obj); } #endif diff --git a/ege/camera/View.cpp b/ege/camera/View.cpp index 308d998..b49b600 100644 --- a/ege/camera/View.cpp +++ b/ege/camera/View.cpp @@ -69,6 +69,10 @@ vec3 ege::camera::View::getViewVector() const { ege::Ray ege::camera::View::getRayFromScreen(const vec2& _offset) { 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... return out; } diff --git a/ege/elements/ElementPhysic.cpp b/ege/elements/ElementPhysic.cpp index 4b5d2d5..f974baf 100644 --- a/ege/elements/ElementPhysic.cpp +++ b/ege/elements/ElementPhysic.cpp @@ -34,13 +34,17 @@ const std::string& ege::ElementPhysic::getType() const { } -ege::ElementPhysic::ElementPhysic(const std::shared_ptr& _env) : +ege::ElementPhysic::ElementPhysic(const std::shared_ptr& _env, bool _autoRigidBody) : ege::Element(_env), m_body(nullptr), m_shape(nullptr), m_elementInPhysicsSystem(false), m_IA(nullptr) { - + if (_autoRigidBody == true) { + createRigidBody(); + } else { + EGE_TODO("add basic API to create custum rigid body"); + } } ege::ElementPhysic::~ElementPhysic() { @@ -53,6 +57,28 @@ ege::ElementPhysic::~ElementPhysic() { 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& _mesh) { if (nullptr!=m_mesh) { removeShape(); @@ -100,14 +126,14 @@ void ege::ElementPhysic::removeShape() { } void ege::ElementPhysic::FunctionFreeShape(void* _pointer) { - if (nullptr == _pointer) { + if (_pointer == nullptr) { return; } delete(static_cast(_pointer)); } void ege::ElementPhysic::setPosition(const vec3& _pos) { - if (nullptr!=m_body) { + if (m_body != nullptr) { btTransform transformation = m_body->getCenterOfMassTransform(); transformation.setOrigin(_pos); m_body->setCenterOfMassTransform(transformation); @@ -115,7 +141,7 @@ void ege::ElementPhysic::setPosition(const vec3& _pos) { } const vec3& ege::ElementPhysic::getPosition() { - if (nullptr!=m_body) { + if (m_body != nullptr) { return m_body->getCenterOfMassPosition(); } return ege::Element::getPosition(); @@ -123,14 +149,14 @@ const vec3& ege::ElementPhysic::getPosition() { const vec3& ege::ElementPhysic::getSpeed() { static vec3 emptySpeed(0,0,0); - if (nullptr!=m_body) { + if (m_body != nullptr) { return m_body->getLinearVelocity(); } return emptySpeed; }; const float ege::ElementPhysic::getInvMass() { - if (nullptr!=m_body) { + if (m_body != nullptr) { return m_body->getInvMass(); } return 0.0000000001f; @@ -140,8 +166,8 @@ static void drawShape(const btCollisionShape* _shape, const std::shared_ptr& _draw, mat4 _transformationMatrix, std::vector _tmpVertices) { - if( nullptr == _draw - || nullptr == _shape) { + if( _draw == nullptr + || _shape == nullptr) { return; } etk::Color tmpColor(1.0, 0.0, 0.0, 0.3); @@ -319,15 +345,15 @@ void ege::ElementPhysic::drawDebug(const std::shared_ptrgetMotionState() ) { - EGE_INFO(" plop "); + //EGE_INFO(" plop "); btScalar mmm[16]; btDefaultMotionState* myMotionState = (btDefaultMotionState*)m_body->getMotionState(); myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(mmm); @@ -340,26 +366,26 @@ void ege::ElementPhysic::draw(int32_t _pass) { } void ege::ElementPhysic::dynamicEnable() { - if (true == m_elementInPhysicsSystem) { + if (m_elementInPhysicsSystem == true) { return; } - if(nullptr!=m_body) { + if(m_body != nullptr) { m_env->getPhysicEngine().getDynamicWorld()->addRigidBody(m_body); } - if(nullptr!=m_IA) { + if(m_IA != nullptr) { m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA); } m_elementInPhysicsSystem = true; } void ege::ElementPhysic::dynamicDisable() { - if (false == m_elementInPhysicsSystem) { + if (m_elementInPhysicsSystem == false) { return; } - if(nullptr!=m_IA) { + if(m_IA != nullptr) { m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA); } - if(nullptr!=m_body) { + if(m_body != nullptr) { // Unlink element from the engine m_env->getPhysicEngine().getDynamicWorld()->removeRigidBody(m_body); m_env->getPhysicEngine().getDynamicWorld()->removeCollisionObject(m_body); @@ -368,26 +394,26 @@ void ege::ElementPhysic::dynamicDisable() { } void ege::ElementPhysic::iaEnable() { - if (nullptr != m_IA) { + if (m_IA != nullptr) { // IA already started ... return; } m_IA = new localIA(*this); - if (nullptr == m_IA) { + if (m_IA == nullptr) { EGE_ERROR("Can not start the IA == > allocation error"); return; } - if (true == m_elementInPhysicsSystem) { + if (m_elementInPhysicsSystem == true) { m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA); } } void ege::ElementPhysic::iaDisable() { - if (nullptr == m_IA) { + if (m_IA == nullptr) { // IA already stopped ... return; } - if (true == m_elementInPhysicsSystem) { + if (m_elementInPhysicsSystem == true) { m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA); } // remove IA : diff --git a/ege/elements/ElementPhysic.h b/ege/elements/ElementPhysic.h index b0c6d29..b4c90b3 100644 --- a/ege/elements/ElementPhysic.h +++ b/ege/elements/ElementPhysic.h @@ -23,6 +23,7 @@ #include #include +#include #define INDEX_RIGHT_AXIS (0) #define INDEX_FORWARD_AXIS (1) @@ -36,13 +37,17 @@ namespace ege { static void FunctionFreeShape(void* _pointer); protected: 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: /** * @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, * when needed, the system will call the init and un-init function... */ - ElementPhysic(const std::shared_ptr& _env); + ElementPhysic(const std::shared_ptr& _env, bool _autoRigidBody=true); /** * @brief Destructor */ @@ -99,11 +104,13 @@ namespace ege { * @param[in] set the 3D position. */ virtual void setPositionTheoric(const vec3& _pos) { }; + /** * @brief get the current speed of the element * @return the 3D speed. */ const vec3& getSpeed(); + /** * @brief get the current mass of the element * @return the mass in kG. diff --git a/sample/RayTest/appl/Windows.cpp b/sample/RayTest/appl/Windows.cpp index 95b4acc..ec1fa60 100644 --- a/sample/RayTest/appl/Windows.cpp +++ b/sample/RayTest/appl/Windows.cpp @@ -96,21 +96,26 @@ void appl::Windows::init() { if (myMesh != nullptr) { //std::shared_ptr element = std::make_shared(m_env); std::shared_ptr element = std::make_shared(m_env); - element->setPosition(vec3(20,10,10)); element->setMesh(myMesh); + element->setPosition(vec3(20,10,10)); // add physic interface: std::shared_ptr physic = std::make_shared(); physic->setSize(vec3(3.2,3.2,3.2)); myMesh->addPhysicElement(physic); m_env->addElement(element); - /* - element = std::make_shared(m_env); - //std::shared_ptr element = std::make_shared(m_env); - element->setPosition(vec3(-50,0,0)); + + + //element = std::make_shared(m_env); + element = std::make_shared(m_env); element->setMesh(myMesh); + element->setPosition(vec3(20,-10,10)); + + // add physic interface: + physic = std::make_shared(); + physic->setSize(vec3(3.2,3.2,3.2)); m_env->addElement(element); - */ + } } @@ -120,7 +125,36 @@ void appl::Windows::onCallbackPeriodicUpdateCamera(const ewol::event::Time& _eve offset += 0.01; static float offset2 = 0; 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"; +} +*/ \ No newline at end of file diff --git a/sample/RayTest/appl/Windows.h b/sample/RayTest/appl/Windows.h index 2e1c631..5f85db7 100644 --- a/sample/RayTest/appl/Windows.h +++ b/sample/RayTest/appl/Windows.h @@ -26,6 +26,7 @@ namespace appl { virtual ~Windows() { }; private: void onCallbackPeriodicUpdateCamera(const ewol::event::Time& _event); + bool onEventInput(const ewol::event::Input& _event); }; };