[DEV] continue integration of react physics

This commit is contained in:
Edouard DUPIN 2017-05-19 00:25:46 +00:00
parent 4ed894376d
commit d72cefd665
11 changed files with 342 additions and 28 deletions

View File

@ -78,6 +78,19 @@ void ege::Environement::rmEngine(const std::string& _type) {
return;
}
ememory::SharedPtr<ege::Engine> ege::Environement::getEngine(const std::string& _type) {
// check if not exist
for (auto &it: m_engine) {
if (it == nullptr) {
continue;
}
if (it->getType() == _type) {
return it;
}
}
EGE_ERROR("try to get an unexisting engine type : '" << _type << "'");
return nullptr;
}
void ege::Environement::engineComponentRemove(const ememory::SharedPtr<ege::Component>& _ref) {
for (auto &it: m_engine) {

View File

@ -87,8 +87,10 @@ namespace ege {
void addEngine(const ememory::SharedPtr<ege::Engine>& _ref);
void rmEngine(const ememory::SharedPtr<ege::Engine>& _ref);
void rmEngine(const std::string& _type);
ememory::SharedPtr<ege::Engine> getEngine(const std::string& _type);
void engineComponentRemove(const ememory::SharedPtr<ege::Component>& _ref);
void engineComponentAdd(const ememory::SharedPtr<ege::Component>& _ref);
private:
std::vector<ememory::SharedPtr<ege::Element>> m_listElement; //!< List of all element added in the Game
protected:

View File

@ -83,8 +83,19 @@ void ege::Element::addComponent(const ememory::SharedPtr<ege::Component>& _ref)
m_env->engineComponentAdd(_ref);
m_component[iii]->addFriendComponent(_ref);
}
// notify new component of all previously added component:
componentRemoved = _ref;
for (int32_t iii=0; iii<m_component.size(); ++iii) {
if (m_component[iii] == nullptr) {
continue;
}
if (m_component[iii] == _ref) {
continue;
}
componentRemoved->addFriendComponent(m_component[iii]);
}
}
void ege::Element::rmComponent(const ememory::SharedPtr<ege::Component>& _ref) {
if (_ref == nullptr) {
EGE_ERROR("try to remove an empty component");

View File

@ -4,27 +4,238 @@
* @license MPL v2.0 (see license file)
*/
#include <ege/physics/Component.hpp>
#include <ege/physics/Engine.hpp>
#include <ege/Environement.hpp>
#include <ege/physicsShape/PhysicsShape.hpp>
#include <ege/physicsShape/PhysicsBox.hpp>
#include <ege/physicsShape/PhysicsCapsule.hpp>
#include <ege/physicsShape/PhysicsCone.hpp>
#include <ege/physicsShape/PhysicsConvexHull.hpp>
#include <ege/physicsShape/PhysicsCylinder.hpp>
#include <ege/physicsShape/PhysicsSphere.hpp>
const std::string& ege::physics::Component::getType() const {
static std::string tmp("physics");
return tmp;
}
ege::physics::Component::Component(ememory::SharedPtr<ege::Environement> _env) {
m_engine = ememory::dynamicPointerCast<ege::physics::Engine>(_env->getEngine(getType()));
// Initial position and orientation of the rigid body
rp3d::Vector3 initPosition(0.0f, 0.0f, 0.0f);
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
rp3d::Transform transform(initPosition, initOrientation);
m_rigidBody = m_engine->getDynamicWorld()->createRigidBody(transform);
}
void ege::physics::Component::setTransform(const etk::Transform3D& _transform) {
/*
if (_transform == m_transform) {
ege::physics::Component::Component(ememory::SharedPtr<ege::Environement> _env, const etk::Transform3D& _transform) {
m_engine = ememory::dynamicPointerCast<ege::physics::Engine>(_env->getEngine(getType()));
rp3d::Vector3 initPosition(_transform.getPosition().x(),
_transform.getPosition().y(),
_transform.getPosition().z());
rp3d::Quaternion initOrientation(_transform.getOrientation().x(),
_transform.getOrientation().y(),
_transform.getOrientation().z(),
_transform.getOrientation().w());
rp3d::Transform transform(initPosition, initOrientation);
// Create a rigid body in the world
m_rigidBody = m_engine->getDynamicWorld()->createRigidBody(transform);
}
ege::physics::Component::~Component() {
if (m_rigidBody == nullptr) {
return;
}
m_transform = _transform;
signalPosition.emit(m_transform);
*/
m_engine->getDynamicWorld()->destroyRigidBody(m_rigidBody);
m_rigidBody = nullptr;
}
const etk::Transform3D& ege::physics::Component::getTransform() const {
/*
return m_transform;
*/
return etk::Transform3D::identity();
void ege::physics::Component::generate() {
if (m_shape.size() == 0) {
EGE_WARNING("No Shape Availlable ...");
return;
}
for (auto &it: m_shape) {
if (it == nullptr) {
continue;
}
switch (it->getType()) {
case ege::PhysicsShape::box : {
EGE_ERROR(" Box");
const ege::PhysicsBox* tmpElement = it->toBox();
if (tmpElement == nullptr) {
EGE_ERROR(" Box ==> can not cast in BOX");
continue;
}
// Half extents of the box in the x, y and z directions
const rp3d::Vector3 halfExtents(tmpElement->getSize().x(),
tmpElement->getSize().y(),
tmpElement->getSize().z());
// Create the box shape
rp3d::BoxShape shape(halfExtents);
rp3d::Vector3 position(tmpElement->getOrigin().x(),
tmpElement->getOrigin().y(),
tmpElement->getOrigin().z());
rp3d::Quaternion orientation(tmpElement->getQuaternion().x(),
tmpElement->getQuaternion().y(),
tmpElement->getQuaternion().z(),
tmpElement->getQuaternion().w());
rp3d::Transform transform(position, orientation);
m_rigidBody->addCollisionShape(&shape, transform, 4.0f /* mass */);
break;
}
case ege::PhysicsShape::cylinder : {
EGE_DEBUG(" Cylinder");
const ege::PhysicsCylinder* tmpElement = it->toCylinder();
if (tmpElement == nullptr) {
EGE_ERROR(" Cylinder ==> can not cast in Cylinder");
continue;
}
// Create the box shape
rp3d::CylinderShape shape(tmpElement->getSize().x(), tmpElement->getSize().y());
rp3d::Vector3 position(tmpElement->getOrigin().x(),
tmpElement->getOrigin().y(),
tmpElement->getOrigin().z());
rp3d::Quaternion orientation(tmpElement->getQuaternion().x(),
tmpElement->getQuaternion().y(),
tmpElement->getQuaternion().z(),
tmpElement->getQuaternion().w());
rp3d::Transform transform(position, orientation);
m_rigidBody->addCollisionShape(&shape, transform, 4.0f /* mass */);
break;
}
case ege::PhysicsShape::capsule : {
EGE_DEBUG(" Capsule");
const ege::PhysicsCapsule* tmpElement = it->toCapsule();
if (tmpElement == nullptr) {
EGE_ERROR(" Capsule ==> can not cast in Capsule");
continue;
}
/*
btCollisionShape* tmpShape = new btCapsuleShape(tmpElement->getRadius(), tmpElement->getHeight());
if (tmpShape != nullptr) {
if (outputShape == nullptr) {
return tmpShape;
} else {
vec4 qqq = tmpElement->getQuaternion();
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
outputShape->addChildShape(localTransform, tmpShape);
}
}
*/
break;
}
case ege::PhysicsShape::cone : {
EGE_DEBUG(" Cone");
const ege::PhysicsCone* tmpElement = it->toCone();
if (tmpElement == nullptr) {
EGE_ERROR(" Cone ==> can not cast in Cone");
continue;
}
/*
btCollisionShape* tmpShape = new btConeShape(tmpElement->getRadius(), tmpElement->getHeight());
if (tmpShape != nullptr) {
if (outputShape == nullptr) {
return tmpShape;
} else {
vec4 qqq = tmpElement->getQuaternion();
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
outputShape->addChildShape(localTransform, tmpShape);
}
}
*/
break;
}
case ege::PhysicsShape::sphere : {
EGE_DEBUG(" Sphere");
const ege::PhysicsSphere* tmpElement = it->toSphere();
if (tmpElement == nullptr) {
EGE_ERROR(" Sphere ==> can not cast in Sphere");
continue;
}
/*
btCollisionShape* tmpShape = new btSphereShape(tmpElement->getRadius());
if (tmpShape != nullptr) {
if (outputShape == nullptr) {
return tmpShape;
} else {
vec4 qqq = tmpElement->getQuaternion();
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
outputShape->addChildShape(localTransform, tmpShape);
}
}
*/
break;
}
case ege::PhysicsShape::convexHull : {
EGE_DEBUG(" convexHull");
const ege::PhysicsConvexHull* tmpElement = it->toConvexHull();
if (tmpElement == nullptr) {
EGE_ERROR(" convexHull ==> can not cast in convexHull");
continue;
}
/*
btConvexHullShape* tmpShape = new btConvexHullShape(&(tmpElement->getPointList()[0].x()), tmpElement->getPointList().size());
if (tmpShape != nullptr) {
if (outputShape == nullptr) {
return tmpShape;
} else {
vec4 qqq = tmpElement->getQuaternion();
const btTransform localTransform(btQuaternion(qqq.x(),qqq.y(),qqq.z(),qqq.w()), tmpElement->getOrigin());
outputShape->addChildShape(localTransform, tmpShape);
}
}
*/
break;
}
default :
EGE_DEBUG(" ???");
// TODO : UNKNOW type ...
break;
}
}
}
const std::vector<ememory::SharedPtr<ege::PhysicsShape>>& ege::physics::Component::getShape() const {
return m_shape;
}
void ege::physics::Component::setShape(const std::vector<ememory::SharedPtr<ege::PhysicsShape>>& _prop) {
m_shape = _prop;
}
void ege::physics::Component::addShape(const ememory::SharedPtr<ege::PhysicsShape>& _shape) {
m_shape.push_back(_shape);
}
void ege::physics::Component::setTransform(const etk::Transform3D& _transform) {
if (m_rigidBody == nullptr) {
return;
}
rp3d::Vector3 position(_transform.getPosition().x(),
_transform.getPosition().y(),
_transform.getPosition().z());
rp3d::Quaternion orientation(_transform.getOrientation().x(),
_transform.getOrientation().y(),
_transform.getOrientation().z(),
_transform.getOrientation().w());
rp3d::Transform transform(position, orientation);
m_rigidBody->setTransform(transform);
}
etk::Transform3D ege::physics::Component::getTransform() const {
if (m_rigidBody == nullptr) {
return etk::Transform3D::identity();
}
rp3d::Transform transform = m_rigidBody->getTransform();
vec3 position(transform.getPosition().x,
transform.getPosition().y,
transform.getPosition().z);
etk::Quaternion orientation(transform.getOrientation().x,
transform.getOrientation().y,
transform.getOrientation().z,
transform.getOrientation().w);
return etk::Transform3D(position, orientation);
}

View File

@ -10,14 +10,30 @@
#include <ege/Component.hpp>
#include <etk/math/Transform3D.hpp>
#include <esignal/Signal.hpp>
#include <ephysics/reactphysics3d.h>
#include <ege/resource/Mesh.hpp>
namespace ege {
class Environement;
namespace physics {
class Engine;
class Component : public ege::Component {
public:
esignal::Signal<etk::Transform3D> signalPosition;
protected:
ememory::SharedPtr<ege::physics::Engine> m_engine;
rp3d::RigidBody* m_rigidBody;
public:
/**
* @brief Create a basic position component (no orientation and position (0,0,0))
*/
Component(ememory::SharedPtr<ege::Environement> _env);
/**
* @brief Create a basic position component
* @param[in] _transform transformation of the position
*/
Component(ememory::SharedPtr<ege::Environement> _env, const etk::Transform3D& _transform);
~Component();
public:
virtual const std::string& getType() const;
/**
@ -29,7 +45,14 @@ namespace ege {
* @brief set a new transformation
* @return Transformation of the position
*/
const etk::Transform3D& getTransform() const;
etk::Transform3D getTransform() const;
protected:
std::vector<ememory::SharedPtr<ege::PhysicsShape>> m_shape; //!< collision shape module ... (independent of bullet lib)
public:
const std::vector<ememory::SharedPtr<ege::PhysicsShape>>& getShape() const;
void setShape(const std::vector<ememory::SharedPtr<ege::PhysicsShape>>& _prop);
void addShape(const ememory::SharedPtr<ege::PhysicsShape>& _shape);
void generate();
};
}
}

View File

@ -99,7 +99,7 @@ void ege::physics::Engine::update(const echrono::Duration& _delta) {
m_accumulator -= timeStep;
}
}
#if 0
std::vector<ege::physics::Engine::collisionPoints> ege::physics::Engine::getListOfCollision() {
std::vector<collisionPoints> out;
/*
@ -130,4 +130,6 @@ std::vector<ege::physics::Engine::collisionPoints> ege::physics::Engine::getList
}
*/
return out;
}
}
#endif

View File

@ -37,6 +37,7 @@ namespace ege {
public:
// Define a collision point ==> for debug only ...
//! @not_in_doc
#if 0
class collisionPoints {
public:
ememory::SharedPtr<ege::Element> elem1;
@ -60,6 +61,7 @@ namespace ege {
* @return the requested list of points
*/
std::vector<ege::physics::Engine::collisionPoints> getListOfCollision();
#endif
/**
* @brief Set the gravity axis of the physic engine
* @param[in] _axePower energy of this gravity
@ -69,6 +71,9 @@ namespace ege {
void debugDrawWorld() {
// TODO: later ...
}
rp3d::DynamicsWorld* getDynamicWorld() {
return m_dynamicsWorld;
}
public:
const std::string& getType() const override;
void componentRemove(const ememory::SharedPtr<ege::Component>& _ref) override;

View File

@ -66,4 +66,22 @@ bool ege::render::Component::setMesh(ememory::SharedPtr<ege::resource::Mesh> _me
return true;
}
return true;
}
void ege::render::Component::draw(int32_t _pass) {
//EGE_INFO("draw : " << _pass );
if (_pass == 0) {
if(m_mesh != nullptr) {
//EGE_INFO("element pos = " << getPosition());
float mmm[16];
// Get the OpenGL matrix array of the transform
m_transform.getOpenGLMatrix(mmm);
//EGE_INFO(" mat = " << mat4(mmm));
mat4 transformationMatrix(mmm);
//mat4 transformationMatrix = mat4(mmm) * etk::matScale(vec3(20,20,20));
// TODO: check this : transformationMatrix.transpose();
m_mesh->draw(transformationMatrix);
}
}
}

View File

@ -59,6 +59,12 @@ namespace ege {
const etk::Transform3D& getTransform() {
return m_transform;
}
/**
* @brief draw the curent element (can have multiple display)
* @param[in] pass Id of the current pass : [0..?]
*/
virtual void draw(int32_t _pass=0);
public:
const std::string& getType() const override;
void addFriendComponent(const ememory::SharedPtr<ege::Component>& _component) override;

View File

@ -92,7 +92,7 @@ void ege::render::Engine::getOrderedElementForDisplay(std::vector<ege::render::E
}
}
}
#define NUMBER_OF_SUB_PASS (5)
void ege::render::Engine::render(const echrono::Duration& _delta, const ememory::SharedPtr<ege::Camera>& _camera) {
for (auto &it : m_component) {
@ -107,10 +107,6 @@ void ege::render::Engine::render(const echrono::Duration& _delta, const ememory:
getOrderedElementForDisplay(m_displayElementOrdered, _camera->getEye(), _camera->getViewVector());
EGE_VERBOSE("DRAW : " << m_displayElementOrdered.size() << "/" << m_component.size() << " elements");
// TODO : remove this == > no more needed ==> checked in the generate the list of the element ordered
for (auto &it: m_displayElementOrdered) {
it.element->preCalculationDraw(*_camera);
}
// note : the first pass is done at the reverse way to prevent multiple display od the same point in the screen
// (and we remember that the first pass is to display all the non transparent elements)
for (int32_t iii=m_displayElementOrdered.size()-1; iii >= 0; iii--) {

View File

@ -21,6 +21,7 @@
#include <ege/physicsShape/PhysicsSphere.hpp>
#include <ege/position/Component.hpp>
#include <ege/render/Component.hpp>
#include <ege/physics/Component.hpp>
appl::Windows::Windows() {
addObjectType("appl::Windows");
@ -91,29 +92,53 @@ void appl::Windows::init() {
}
ememory::SharedPtr<ege::resource::Mesh> myMesh;
// Create an external box :
// Create an external box:
myMesh = createViewBoxStar();
if (myMesh != nullptr) {
m_env->addStaticMeshToDraw(myMesh);
ememory::SharedPtr<ege::Element> element = ememory::makeShared<ege::Element>(m_env);
// 1st Position component:
etk::Transform3D transform(vec3(0,0,0), etk::Quaternion::identity());
ememory::SharedPtr<ege::position::Component> componentPosition = ememory::makeShared<ege::position::Component>(transform);
element->addComponent(componentPosition);
// 2nd something to diplay:
ememory::SharedPtr<ege::render::Component> componentRender = ememory::makeShared<ege::render::Component>(myMesh);
element->addComponent(componentRender);
// add it ..
m_env->addElement(element);
}
// create basic gird:
myMesh = ege::resource::Mesh::createGrid(10, vec3(0,0,0), 5);
if (myMesh != nullptr) {
m_env->addStaticMeshToDraw(myMesh);
ememory::SharedPtr<ege::Element> element = ememory::makeShared<ege::Element>(m_env);
// 1st Position component:
etk::Transform3D transform(vec3(0,0,0), etk::Quaternion::identity());
ememory::SharedPtr<ege::position::Component> componentPosition = ememory::makeShared<ege::position::Component>(transform);
element->addComponent(componentPosition);
// 2nd something to diplay:
ememory::SharedPtr<ege::render::Component> componentRender = ememory::makeShared<ege::render::Component>(myMesh);
element->addComponent(componentRender);
// add it ..
m_env->addElement(element);
}
// create cubes ...
myMesh = ege::resource::Mesh::createCube(3);
if (myMesh != nullptr) {
ememory::SharedPtr<ege::Element> element = ememory::makeShared<ege::Element>(m_env);
// add all component:
// 1st Position component:
etk::Transform3D transform(vec3(0,0,2), etk::Quaternion::identity());
ememory::SharedPtr<ege::position::Component> componentPosition = ememory::makeShared<ege::position::Component>(transform);
element->addComponent(componentPosition);
//ememory::SharedPtr<ege::position::Component> componentPosition = ememory::makeShared<ege::position::Component>(transform);
//element->addComponent(componentPosition);
// 2nd something to diplay:
ememory::SharedPtr<ege::render::Component> componentRender = ememory::makeShared<ege::render::Component>(myMesh);
element->addComponent(componentRender);
// 3rd some physic:
ememory::SharedPtr<ege::physics::Component> componentPhysics = ememory::makeShared<ege::physics::Component>(m_env, transform);
ememory::SharedPtr<ege::PhysicsBox> physic = ememory::makeShared<ege::PhysicsBox>();
physic->setSize(vec3(3.2,3.2,3.2));
componentPhysics->addShape(physic);
componentPhysics->generate();
element->addComponent(componentPhysics);
// add it ..
m_env->addElement(element);
@ -175,6 +200,7 @@ bool appl::Windows::onEventInput(const ewol::event::Input& _event) {
if (_event.getId() == 1) {
if (_event.getStatus() == gale::key::status::down) {
vec2 pos = relativePosition(_event.getPos());
/*
ege::Ray ray = m_camera->getRayFromScreenPosition(pos, m_size);
ememory::SharedPtr<ege::resource::Mesh> myMesh;
@ -192,6 +218,7 @@ bool appl::Windows::onEventInput(const ewol::event::Input& _event) {
m_env->addElement(element);
APPL_INFO("Create cube at position " << ray.getOrigin() << " velocity: " << ray.getDirection()*100);
}
*/
return true;
}
} else if (_event.getId() == 4) {