diff --git a/ege/Environement.cpp b/ege/Environement.cpp index 30a7bb6..1a10250 100644 --- a/ege/Environement.cpp +++ b/ege/Environement.cpp @@ -78,6 +78,19 @@ void ege::Environement::rmEngine(const std::string& _type) { return; } +ememory::SharedPtr 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& _ref) { for (auto &it: m_engine) { diff --git a/ege/Environement.hpp b/ege/Environement.hpp index f424339..2d3740c 100644 --- a/ege/Environement.hpp +++ b/ege/Environement.hpp @@ -87,8 +87,10 @@ namespace ege { void addEngine(const ememory::SharedPtr& _ref); void rmEngine(const ememory::SharedPtr& _ref); void rmEngine(const std::string& _type); + ememory::SharedPtr getEngine(const std::string& _type); void engineComponentRemove(const ememory::SharedPtr& _ref); void engineComponentAdd(const ememory::SharedPtr& _ref); + private: std::vector> m_listElement; //!< List of all element added in the Game protected: diff --git a/ege/elements/Element.cpp b/ege/elements/Element.cpp index 9f2baab..48f67ec 100644 --- a/ege/elements/Element.cpp +++ b/ege/elements/Element.cpp @@ -83,8 +83,19 @@ void ege::Element::addComponent(const ememory::SharedPtr& _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; iiiaddFriendComponent(m_component[iii]); + } } + void ege::Element::rmComponent(const ememory::SharedPtr& _ref) { if (_ref == nullptr) { EGE_ERROR("try to remove an empty component"); diff --git a/ege/physics/Component.cpp b/ege/physics/Component.cpp index 902c34a..0beb62a 100644 --- a/ege/physics/Component.cpp +++ b/ege/physics/Component.cpp @@ -4,27 +4,238 @@ * @license MPL v2.0 (see license file) */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include const std::string& ege::physics::Component::getType() const { static std::string tmp("physics"); return tmp; } +ege::physics::Component::Component(ememory::SharedPtr _env) { + m_engine = ememory::dynamicPointerCast(_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 _env, const etk::Transform3D& _transform) { + m_engine = ememory::dynamicPointerCast(_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>& ege::physics::Component::getShape() const { + return m_shape; +} + +void ege::physics::Component::setShape(const std::vector>& _prop) { + m_shape = _prop; +} + +void ege::physics::Component::addShape(const ememory::SharedPtr& _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); } diff --git a/ege/physics/Component.hpp b/ege/physics/Component.hpp index 8683ceb..1d8a75e 100644 --- a/ege/physics/Component.hpp +++ b/ege/physics/Component.hpp @@ -10,14 +10,30 @@ #include #include #include +#include +#include namespace ege { + class Environement; namespace physics { + class Engine; class Component : public ege::Component { public: esignal::Signal signalPosition; protected: - + ememory::SharedPtr m_engine; + rp3d::RigidBody* m_rigidBody; + public: + /** + * @brief Create a basic position component (no orientation and position (0,0,0)) + */ + Component(ememory::SharedPtr _env); + /** + * @brief Create a basic position component + * @param[in] _transform transformation of the position + */ + Component(ememory::SharedPtr _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> m_shape; //!< collision shape module ... (independent of bullet lib) + public: + const std::vector>& getShape() const; + void setShape(const std::vector>& _prop); + void addShape(const ememory::SharedPtr& _shape); + void generate(); }; } } \ No newline at end of file diff --git a/ege/physics/Engine.cpp b/ege/physics/Engine.cpp index 368a343..fa015b7 100644 --- a/ege/physics/Engine.cpp +++ b/ege/physics/Engine.cpp @@ -99,7 +99,7 @@ void ege::physics::Engine::update(const echrono::Duration& _delta) { m_accumulator -= timeStep; } } - +#if 0 std::vector ege::physics::Engine::getListOfCollision() { std::vector out; /* @@ -130,4 +130,6 @@ std::vector ege::physics::Engine::getList } */ return out; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/ege/physics/Engine.hpp b/ege/physics/Engine.hpp index 7ed98a0..7bc89ba 100644 --- a/ege/physics/Engine.hpp +++ b/ege/physics/Engine.hpp @@ -37,6 +37,7 @@ namespace ege { public: // Define a collision point ==> for debug only ... //! @not_in_doc +#if 0 class collisionPoints { public: ememory::SharedPtr elem1; @@ -60,6 +61,7 @@ namespace ege { * @return the requested list of points */ std::vector 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& _ref) override; diff --git a/ege/render/Component.cpp b/ege/render/Component.cpp index de3c730..2477fa9 100644 --- a/ege/render/Component.cpp +++ b/ege/render/Component.cpp @@ -66,4 +66,22 @@ bool ege::render::Component::setMesh(ememory::SharedPtr _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); + } + } } \ No newline at end of file diff --git a/ege/render/Component.hpp b/ege/render/Component.hpp index b3bf31d..a5d7f79 100644 --- a/ege/render/Component.hpp +++ b/ege/render/Component.hpp @@ -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& _component) override; diff --git a/ege/render/Engine.cpp b/ege/render/Engine.cpp index 4ae7d43..5c6ca40 100644 --- a/ege/render/Engine.cpp +++ b/ege/render/Engine.cpp @@ -92,7 +92,7 @@ void ege::render::Engine::getOrderedElementForDisplay(std::vector& _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--) { diff --git a/sample/Collision/appl/Windows.cpp b/sample/Collision/appl/Windows.cpp index 9baaaa3..ccb2ae2 100644 --- a/sample/Collision/appl/Windows.cpp +++ b/sample/Collision/appl/Windows.cpp @@ -21,6 +21,7 @@ #include #include #include +#include appl::Windows::Windows() { addObjectType("appl::Windows"); @@ -91,29 +92,53 @@ void appl::Windows::init() { } ememory::SharedPtr myMesh; - // Create an external box : + // Create an external box: myMesh = createViewBoxStar(); if (myMesh != nullptr) { - m_env->addStaticMeshToDraw(myMesh); + ememory::SharedPtr element = ememory::makeShared(m_env); + // 1st Position component: + etk::Transform3D transform(vec3(0,0,0), etk::Quaternion::identity()); + ememory::SharedPtr componentPosition = ememory::makeShared(transform); + element->addComponent(componentPosition); + // 2nd something to diplay: + ememory::SharedPtr componentRender = ememory::makeShared(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 element = ememory::makeShared(m_env); + // 1st Position component: + etk::Transform3D transform(vec3(0,0,0), etk::Quaternion::identity()); + ememory::SharedPtr componentPosition = ememory::makeShared(transform); + element->addComponent(componentPosition); + // 2nd something to diplay: + ememory::SharedPtr componentRender = ememory::makeShared(myMesh); + element->addComponent(componentRender); + // add it .. + m_env->addElement(element); } + // create cubes ... myMesh = ege::resource::Mesh::createCube(3); if (myMesh != nullptr) { ememory::SharedPtr element = ememory::makeShared(m_env); // add all component: // 1st Position component: etk::Transform3D transform(vec3(0,0,2), etk::Quaternion::identity()); - ememory::SharedPtr componentPosition = ememory::makeShared(transform); - element->addComponent(componentPosition); - + //ememory::SharedPtr componentPosition = ememory::makeShared(transform); + //element->addComponent(componentPosition); // 2nd something to diplay: ememory::SharedPtr componentRender = ememory::makeShared(myMesh); element->addComponent(componentRender); - + // 3rd some physic: + ememory::SharedPtr componentPhysics = ememory::makeShared(m_env, transform); + ememory::SharedPtr physic = ememory::makeShared(); + 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 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) {