[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)
*/
#include <ege/Ray.h>
#include <etk/math/Vector3D.h>
#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;
}

View File

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

View File

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

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),
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<ege::resource::Mesh>& _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<btCollisionShape*>(_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<ewol::resource::Colored3DObject>& _draw,
mat4 _transformationMatrix,
std::vector<vec3> _tmpVertices) {
if( nullptr == _draw
|| nullptr == _shape) {
if( _draw == nullptr
|| _shape == nullptr) {
return;
}
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) {
if (false == m_elementInPhysicsSystem) {
if (m_elementInPhysicsSystem == false) {
return;
}
EGE_INFO("draw : " << _pass );
//EGE_INFO("draw : " << _pass );
if (_pass == 0) {
if( nullptr != m_body
&& nullptr != m_mesh
if( m_body != nullptr
&& m_mesh != nullptr
&& m_body->getMotionState() ) {
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 :

View File

@ -23,6 +23,7 @@
#include <ege/Environement.h>
#include <ege/elements/Element.h>
#include <LinearMath/btDefaultMotionState.h>
#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<ege::Environement>& _env);
ElementPhysic(const std::shared_ptr<ege::Environement>& _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.

View File

@ -96,21 +96,26 @@ void appl::Windows::init() {
if (myMesh != nullptr) {
//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);
element->setPosition(vec3(20,10,10));
element->setMesh(myMesh);
element->setPosition(vec3(20,10,10));
// add physic interface:
std::shared_ptr<ege::PhysicsBox> physic = std::make_shared<ege::PhysicsBox>();
physic->setSize(vec3(3.2,3.2,3.2));
myMesh->addPhysicElement(physic);
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->setPosition(vec3(-50,0,0));
//element = std::make_shared<ege::ElementBase>(m_env);
element = std::make_shared<ege::ElementPhysic>(m_env);
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);
*/
}
}
@ -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";
}
*/

View File

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