[DEV] add dynamic shape at mesh
This commit is contained in:
parent
43bbec9af3
commit
efca3ae4ba
171
ege/CollisionShapeCreator.cpp
Normal file
171
ege/CollisionShapeCreator.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD v3 (see license file)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ege/CollisionShapeCreator.h>
|
||||
|
||||
#include <btBulletCollisionCommon.h>
|
||||
#include <BulletCollision/CollisionShapes/btConvexPolyhedron.h>
|
||||
#include <BulletCollision/CollisionShapes/btShapeHull.h>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||
#include <ewol/renderer/resources/physicsShape/PhysicsShape.h>
|
||||
#include <ewol/renderer/resources/physicsShape/PhysicsBox.h>
|
||||
#include <ewol/renderer/resources/physicsShape/PhysicsCapsule.h>
|
||||
#include <ewol/renderer/resources/physicsShape/PhysicsCone.h>
|
||||
#include <ewol/renderer/resources/physicsShape/PhysicsConvexHull.h>
|
||||
#include <ewol/renderer/resources/physicsShape/PhysicsCylinder.h>
|
||||
#include <ewol/renderer/resources/physicsShape/PhysicsSphere.h>
|
||||
|
||||
// Documentetion of bullet library :
|
||||
// http://bulletphysics.org/mediawiki-1.5.8/index.php/Collision_Shapes
|
||||
|
||||
btCollisionShape* ege::collision::CreateShape(const ewol::Mesh* _mesh)
|
||||
{
|
||||
if (NULL == _mesh) {
|
||||
return new btEmptyShape();;
|
||||
}
|
||||
const etk::Vector<ewol::PhysicsShape*>& physiqueProperty = _mesh->GetPhysicalProperties();
|
||||
if (physiqueProperty.Size()==0) {
|
||||
return new btEmptyShape();;
|
||||
}
|
||||
int32_t count = 0;
|
||||
for (int32_t iii=0; iii<physiqueProperty.Size(); iii++) {
|
||||
if (NULL==physiqueProperty[iii]) {
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
btCompoundShape* outputShape = NULL;
|
||||
if (count>1) {
|
||||
outputShape = new btCompoundShape();
|
||||
}
|
||||
for (int32_t iii=0; iii<physiqueProperty.Size(); iii++) {
|
||||
if (NULL==physiqueProperty[iii]) {
|
||||
continue;
|
||||
}
|
||||
switch (physiqueProperty[iii]->GetType()) {
|
||||
case ewol::PhysicsShape::box : {
|
||||
const ewol::PhysicsBox* tmpElement = physiqueProperty[iii]->ToBox();
|
||||
if (NULL ==tmpElement) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btBoxShape(tmpElement->GetSize());
|
||||
if (NULL != tmpShape) {
|
||||
if (outputShape == NULL) {
|
||||
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 ewol::PhysicsShape::cylinder : {
|
||||
const ewol::PhysicsCylinder* tmpElement = physiqueProperty[iii]->ToCylinder();
|
||||
if (NULL ==tmpElement) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btCylinderShape(tmpElement->GetSize());
|
||||
if (NULL != tmpShape) {
|
||||
if (outputShape == NULL) {
|
||||
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 ewol::PhysicsShape::capsule : {
|
||||
const ewol::PhysicsCapsule* tmpElement = physiqueProperty[iii]->ToCapsule();
|
||||
if (NULL ==tmpElement) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btCapsuleShape(tmpElement->GetRadius(), tmpElement->GetHeight());
|
||||
if (NULL != tmpShape) {
|
||||
if (outputShape == NULL) {
|
||||
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 ewol::PhysicsShape::cone : {
|
||||
const ewol::PhysicsCone* tmpElement = physiqueProperty[iii]->ToCone();
|
||||
if (NULL ==tmpElement) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btConeShape(tmpElement->GetRadius(), tmpElement->GetHeight());
|
||||
if (NULL != tmpShape) {
|
||||
if (outputShape == NULL) {
|
||||
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 ewol::PhysicsShape::sphere : {
|
||||
const ewol::PhysicsSphere* tmpElement = physiqueProperty[iii]->ToSphere();
|
||||
if (NULL ==tmpElement) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btCollisionShape* tmpShape = new btSphereShape(tmpElement->GetRadius());
|
||||
if (NULL != tmpShape) {
|
||||
if (outputShape == NULL) {
|
||||
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 ewol::PhysicsShape::convexHull : {
|
||||
const ewol::PhysicsConvexHull* tmpElement = physiqueProperty[iii]->ToConvexHull();
|
||||
if (NULL ==tmpElement) {
|
||||
// ERROR ...
|
||||
continue;
|
||||
}
|
||||
btConvexHullShape* tmpShape = new btConvexHullShape(&(tmpElement->GetPointList()[0].x()), tmpElement->GetPointList().Size());
|
||||
if (NULL != tmpShape) {
|
||||
if (outputShape == NULL) {
|
||||
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 :
|
||||
// TODO : UNKNOW type ...
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL==outputShape) {
|
||||
return new btEmptyShape();
|
||||
}
|
||||
return outputShape;
|
||||
}
|
||||
|
||||
|
23
ege/CollisionShapeCreator.h
Normal file
23
ege/CollisionShapeCreator.h
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD v3 (see license file)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __EGE_COLLISION_SHAPE_CREATOR_H__
|
||||
#define __EGE_COLLISION_SHAPE_CREATOR_H__
|
||||
|
||||
#include <etk/types.h>
|
||||
#include <ewol/renderer/resources/Mesh.h>
|
||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||
|
||||
namespace ege {
|
||||
namespace collision {
|
||||
btCollisionShape* CreateShape(const ewol::Mesh* _mesh);
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||
|
||||
#include <ege/CollisionShapeCreator.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "ElementGame"
|
||||
|
||||
@ -37,6 +39,8 @@ const etk::UString& ege::ElementGame::GetType(void) const
|
||||
ege::ElementGame::ElementGame(ege::Environement& _env) :
|
||||
m_env(_env),
|
||||
m_body(NULL),
|
||||
m_uID(0),
|
||||
m_mesh(NULL),
|
||||
m_shape(NULL),
|
||||
m_life(100),
|
||||
m_lifeMax(100),
|
||||
@ -58,6 +62,7 @@ ege::ElementGame::~ElementGame(void)
|
||||
IADisable();
|
||||
// same ...
|
||||
DynamicDisable();
|
||||
RemoveShape();
|
||||
if (NULL != m_mesh) {
|
||||
// release the mesh
|
||||
ewol::resource::Release(m_mesh);
|
||||
@ -66,11 +71,75 @@ ege::ElementGame::~ElementGame(void)
|
||||
delete(m_body);
|
||||
m_body = NULL;
|
||||
}
|
||||
if (NULL != m_shape) {
|
||||
EGE_DEBUG("Destroy element : uId=" << m_uID);
|
||||
}
|
||||
|
||||
void ege::ElementGame::RemoveShape(void)
|
||||
{
|
||||
// no shape
|
||||
if (NULL == m_shape) {
|
||||
return;
|
||||
}
|
||||
// need to chek if the shape is the same as the mesh shape ...
|
||||
if (m_mesh == NULL) {
|
||||
// no mesh ==> standalone shape
|
||||
delete(m_shape);
|
||||
m_shape=NULL;
|
||||
return;
|
||||
}
|
||||
EGE_DEBUG("Destroy element : uId=" << m_uID);
|
||||
if (m_shape != m_mesh->GetShape()) {
|
||||
delete(m_shape);
|
||||
m_shape=NULL;
|
||||
return;
|
||||
}
|
||||
// otherwise : the shape is auto remove by the resources when no more needed ...
|
||||
}
|
||||
|
||||
void ege::ElementGame::FunctionFreeShape(void* _pointer)
|
||||
{
|
||||
if (NULL==_pointer) {
|
||||
return;
|
||||
}
|
||||
delete(static_cast<btCollisionShape*>(_pointer));
|
||||
}
|
||||
|
||||
bool ege::ElementGame::LoadMesh(const etk::UString& _meshFileName)
|
||||
{
|
||||
ewol::Mesh* tmpMesh=NULL;
|
||||
ewol::resource::Keep(_meshFileName, tmpMesh);
|
||||
if(NULL==tmpMesh) {
|
||||
EGE_ERROR("can not load the resources : " << _meshFileName);
|
||||
return false;
|
||||
}
|
||||
return SetMesh(tmpMesh);
|
||||
}
|
||||
|
||||
bool ege::ElementGame::SetMesh(ewol::Mesh* _mesh)
|
||||
{
|
||||
if (NULL!=m_mesh) {
|
||||
RemoveShape();
|
||||
ewol::resource::Release(m_mesh);
|
||||
}
|
||||
m_mesh = _mesh;
|
||||
// auto load the shape :
|
||||
if (NULL==m_mesh) {
|
||||
return true;
|
||||
}
|
||||
if (NULL != m_mesh->GetShape()) {
|
||||
m_shape = static_cast<btCollisionShape*>(m_mesh->GetShape());
|
||||
return true;
|
||||
}
|
||||
m_mesh->SetShape(ege::collision::CreateShape(m_mesh));
|
||||
m_mesh->SetFreeShapeFunction(&FunctionFreeShape);
|
||||
m_shape = static_cast<btCollisionShape*>(m_mesh->GetShape());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ege::ElementGame::SetShape(btCollisionShape* _shape)
|
||||
{
|
||||
RemoveShape();
|
||||
m_shape = _shape;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,6 +32,8 @@ namespace ege
|
||||
{
|
||||
class ElementGame
|
||||
{
|
||||
private:
|
||||
static void FunctionFreeShape(void* _pointer);
|
||||
protected:
|
||||
ege::Environement& m_env;
|
||||
protected:
|
||||
@ -58,15 +60,46 @@ namespace ege
|
||||
* @return The requested Unique ID.
|
||||
*/
|
||||
inline uint32_t GetUID(void) const { return m_uID; };
|
||||
protected:
|
||||
private:
|
||||
ewol::Mesh* m_mesh; //!< Mesh of the Element (can be NULL)
|
||||
btCollisionShape* m_shape; //!< shape of the element (set a copy here to have the debug display of it)
|
||||
public:
|
||||
/**
|
||||
* @brief Select a mesh with a specific name.
|
||||
* @param[in] _meshFileName Filename of the Mesh.
|
||||
* @note Automaticly load the shape if it is specify in the mesh file
|
||||
* @return true if no error occured
|
||||
*/
|
||||
void LoadMesh(const etk::UString& _meshFileName);
|
||||
bool LoadMesh(const etk::UString& _meshFileName);
|
||||
/**
|
||||
* @brief Set the the Mesh properties.
|
||||
* @param[in] _mesh The mesh pointer. (NULL to force the mesh remove ...)
|
||||
* @note : this remove the shape and the mesh properties.
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool SetMesh(ewol::Mesh* _mesh);
|
||||
/**
|
||||
* @brief Set the shape properties.
|
||||
* @param[in] _shape The shape pointer.
|
||||
* @note : this remove the shape properties.
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool SetShape(btCollisionShape* _shape);
|
||||
/**
|
||||
* @brief Get a pointer on the Mesh file.
|
||||
* @return the mesh pointer.
|
||||
*/
|
||||
inline ewol::Mesh* GetMesh(void) { return m_mesh; };
|
||||
/**
|
||||
* @brief Get a pointer on the bullet collision shape.
|
||||
* @return the collision pointer.
|
||||
*/
|
||||
inline btCollisionShape* GetShape(void) { return m_shape; };
|
||||
private:
|
||||
/**
|
||||
* @brief Remove the curent selected shape.
|
||||
*/
|
||||
void RemoveShape(void);
|
||||
protected:
|
||||
float m_life; //!< Current life of the object
|
||||
float m_lifeMax; //!< Maximum possible life of the element
|
||||
|
@ -175,8 +175,8 @@ void ege::Environement::AddCreator(const etk::UString& _type, ege::createElement
|
||||
ege::ElementGame* ege::Environement::CreateElement(
|
||||
const etk::UString& _type,
|
||||
const etk::UString* _description,
|
||||
const ejson::Value* _value,
|
||||
const exml::Node* _node,
|
||||
ejson::Value* _value,
|
||||
exml::Node* _node,
|
||||
bool _autoAddElement)
|
||||
{
|
||||
if (false==GetHachTableCreating().Exist(_type)) {
|
||||
@ -237,12 +237,12 @@ ege::ElementGame* ege::Environement::CreateElement(const etk::UString& _type, co
|
||||
return CreateElement(_type, &_description, NULL, NULL, _autoAddElement);
|
||||
}
|
||||
|
||||
ege::ElementGame* ege::Environement::CreateElement(const etk::UString& _type, const ejson::Value* _value, bool _autoAddElement)
|
||||
ege::ElementGame* ege::Environement::CreateElement(const etk::UString& _type, ejson::Value* _value, bool _autoAddElement)
|
||||
{
|
||||
return CreateElement(_type, NULL, _value, NULL, _autoAddElement);
|
||||
}
|
||||
|
||||
ege::ElementGame* ege::Environement::CreateElement(const etk::UString& _type, const exml::Node* _node, bool _autoAddElement)
|
||||
ege::ElementGame* ege::Environement::CreateElement(const etk::UString& _type, exml::Node* _node, bool _autoAddElement)
|
||||
{
|
||||
return CreateElement(_type, NULL, NULL, _node, _autoAddElement);
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ namespace ege {
|
||||
class ElementGame;
|
||||
class Environement;
|
||||
typedef ege::ElementGame* (*createElement_string_tf)(ege::Environement& _env, const etk::UString& _description);
|
||||
typedef ege::ElementGame* (*createElement_ejson_tf)(ege::Environement& _env, const ejson::Value* _value);
|
||||
typedef ege::ElementGame* (*createElement_exml_tf)(ege::Environement& _env, const exml::Node* _node);
|
||||
typedef ege::ElementGame* (*createElement_ejson_tf)(ege::Environement& _env, ejson::Value* _value);
|
||||
typedef ege::ElementGame* (*createElement_exml_tf)(ege::Environement& _env, exml::Node* _node);
|
||||
|
||||
class ElementInteraction
|
||||
{
|
||||
@ -81,10 +81,10 @@ namespace ege {
|
||||
*/
|
||||
ege::ElementGame* CreateElement(const etk::UString& _type, bool _autoAddElement=true);
|
||||
ege::ElementGame* CreateElement(const etk::UString& _type, const etk::UString& _description, bool _autoAddElement=true);
|
||||
ege::ElementGame* CreateElement(const etk::UString& _type, const ejson::Value* _value, bool _autoAddElement=true);
|
||||
ege::ElementGame* CreateElement(const etk::UString& _type, const exml::Node* _node, bool _autoAddElement=true);
|
||||
ege::ElementGame* CreateElement(const etk::UString& _type, ejson::Value* _value, bool _autoAddElement=true);
|
||||
ege::ElementGame* CreateElement(const etk::UString& _type, exml::Node* _node, bool _autoAddElement=true);
|
||||
protected:
|
||||
ege::ElementGame* CreateElement(const etk::UString& _type, const etk::UString* _description, const ejson::Value* _value, const exml::Node* _node, bool _autoAddElement);
|
||||
ege::ElementGame* CreateElement(const etk::UString& _type, const etk::UString* _description, ejson::Value* _value, exml::Node* _node, bool _autoAddElement);
|
||||
public:
|
||||
class ResultNearestElement
|
||||
{
|
||||
|
@ -12,6 +12,7 @@ def Create(target):
|
||||
'ege/AudioElement.cpp',
|
||||
'ege/AudioEngine.cpp',
|
||||
'ege/Camera.cpp',
|
||||
'ege/CollisionShapeCreator.cpp',
|
||||
'ege/ElementGame.cpp',
|
||||
'ege/Particule.cpp',
|
||||
'ege/ParticuleEngine.cpp',
|
||||
|
Loading…
x
Reference in New Issue
Block a user