Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2011-05-05 18:08:45 +0000
committerStijn Buys <ingar@osirion.org>2011-05-05 18:08:45 +0000
commit1687737ca713cd0baeca3cf79950ef4877640c99 (patch)
treef6cfd31c850cec95da491036f1dd772397128549 /src/core/entity.cc
parent09d68d3d1d77d45343e3562c0b5e0cd6816d47d3 (diff)
Initial support for btCompoundShape and the infrastructure required to accomodate multiple meshes per collision model,
added prototype files for signals
Diffstat (limited to 'src/core/entity.cc')
-rw-r--r--src/core/entity.cc236
1 files changed, 190 insertions, 46 deletions
diff --git a/src/core/entity.cc b/src/core/entity.cc
index ec25017..64812cc 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -150,7 +150,6 @@ Entity::Entity() :
entity_body = 0;
entity_body_info = 0;
- entity_collision_shape = 0;
entity_speed = 0.0f;
@@ -189,7 +188,6 @@ Entity::Entity(std::istream & is)
entity_body = 0;
entity_body_info = 0;
- entity_collision_shape = 0;
entity_speed = 0.0f;
@@ -214,8 +212,9 @@ Entity::~Entity()
}
// delete entity menus
- for (Menus::iterator it = menus().begin(); it != menus().end(); it++) {
- delete(*it);
+ for (Menus::iterator mit = menus().begin(); mit != menus().end(); mit++) {
+ delete (*mit);
+ (*mit) = 0;
}
menus().clear();
@@ -231,8 +230,11 @@ Entity::~Entity()
}
}
- if (entity_collision_shape)
- delete entity_collision_shape;
+ for (CollisionShapes::iterator sit = entity_collision_shapes.begin(); sit != entity_collision_shapes.end(); sit++) {
+ delete (*sit);
+ (*sit) = 0;
+ }
+ entity_collision_shapes.clear();
if (entity_body)
delete entity_body;
@@ -498,33 +500,82 @@ void Entity::reset()
// construct physics body if necessary
if (!entity_body) {
+ btCollisionShape * myshape = 0;
+
// create collision shape
if (model() && model()->radius()) {
const float modelscale = radius() / model()->radius();
- if (flag_is_set(Complex) && model()->collisionmesh()) {
- // use collision mesh
- // static entities use a btBvhTriangleMeshShape
- btBvhTriangleMeshShape *meshshape = new btBvhTriangleMeshShape(model()->collisionmesh()->triangles(), true, true);
- meshshape->buildOptimizedBvh();
- meshshape->recalcLocalAabb();
+ if (flag_is_set(Complex) && model()->collisionmodel() && model()->collisionmodel()->size()) {
+ if (model()->collisionmodel()->size() == 1 ) {
+ // the collision model only has a single mesh,
+ // we can use a triangle mesh shape
+
+ model::CollisionMesh *mesh = (*model()->collisionmodel()->meshes().begin());
+
+ // static entities use a btBvhTriangleMeshShape
+ btBvhTriangleMeshShape *meshshape = new btBvhTriangleMeshShape(mesh->triangles(), true, true);
+ meshshape->buildOptimizedBvh();
+ meshshape->recalcLocalAabb();
+
+ btVector3 modelscalevec(modelscale, modelscale, modelscale);
+ meshshape->setLocalScaling(modelscalevec);
+
+ shapes().push_back(meshshape);
+ myshape = meshshape;
- btVector3 modelscalevec(modelscale, modelscale, modelscale);
- meshshape->setLocalScaling(modelscalevec);
+ } else {
+ // the collision model has multiple meshes that need to be
+ // combined into a compound shape
+ btCompoundShape *compoundshape = new btCompoundShape();
+
+ for (model::CollisionModel::CollisionMeshes::iterator it = model()->collisionmodel()->meshes().begin();
+ it != model()->collisionmodel()->meshes().end(); it++) {
+
+ model::CollisionMesh *mesh = (*it);
+ btTransform childtransform;
+ childtransform.setIdentity();
+
+ // static entities use a btBvhTriangleMeshShape
+ btBvhTriangleMeshShape *meshshape = new btBvhTriangleMeshShape(mesh->triangles(), true, true);
+ meshshape->buildOptimizedBvh();
+ meshshape->recalcLocalAabb();
+
+ // FIXME apply vertexgroup transformations
+ compoundshape->addChildShape(childtransform, meshshape);
+ shapes().push_back(meshshape);
+ }
+
+ btVector3 modelscalevec(modelscale, modelscale, modelscale);
+ compoundshape->setLocalScaling(modelscalevec);
+
+ shapes().push_back(compoundshape);
+ myshape = compoundshape;
+ }
- entity_collision_shape = meshshape;
} else {
// use bounding box
- entity_collision_shape = new btBoxShape(to_btVector3(model()->box().max() * modelscale));
+ btBoxShape *boxshape = new btBoxShape(to_btVector3(model()->box().max() * modelscale));
+ shapes().push_back(boxshape);
+ myshape = boxshape;
}
+
} else {
- entity_collision_shape = new btSphereShape(radius());
+ // use a sphere with a radius matching the entity
+ btSphereShape *sphereshape = new btSphereShape(radius());
+ shapes().push_back(sphereshape);
+ myshape = sphereshape;
+
+ }
+
+ // set margin on each mesh
+ for (CollisionShapes::iterator it = shapes().begin(); it != shapes().end(); it++) {
+ (*it)->setMargin(Cvar::sv_collisionmargin->value());
}
- entity_collision_shape->setMargin(Cvar::sv_collisionmargin->value());
- btVector3 inertia(0, 0, 0);
// create physics body
- entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(0, 0, entity_collision_shape, inertia);
+ btVector3 inertia(0, 0, 0);
+ entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(0, 0, myshape, inertia);
entity_body = new btRigidBody(*entity_body_info);
entity_body->setActivationState(ISLAND_SLEEPING);
@@ -587,38 +638,81 @@ void EntityDynamic::reset()
// construct physics body if necessary
if (!entity_body) {
+ btCollisionShape * myshape = 0;
+
// create collision shape
if (model() && model()->radius()) {
const float modelscale = radius() / model()->radius();
- if (flag_is_set(Complex) && model()->collisionmesh()) {
- // use collision mesh
- // dynamic entities use a btGImpactMeshShape
- btGImpactMeshShape *meshshape = new btGImpactMeshShape(model()->collisionmesh()->triangles());
+ if (flag_is_set(Complex) && model()->collisionmodel() && model()->collisionmodel()->size()) {
+ if (model()->collisionmodel()->size() == 1 ) {
+ // the collision model only has a single mesh,
+ // we can use a triangle mesh shape
+
+ model::CollisionMesh *mesh = (*model()->collisionmodel()->meshes().begin());
+
+ // static entities use a btBvhTriangleMeshShape
+ btGImpactMeshShape *meshshape = new btGImpactMeshShape(mesh->triangles());
+ btVector3 modelscalevec(modelscale, modelscale, modelscale);
+ meshshape->setLocalScaling(modelscalevec);
+
+ shapes().push_back(meshshape);
+ myshape = meshshape;
- btVector3 modelscalevec(modelscale, modelscale, modelscale);
- meshshape->setLocalScaling(modelscalevec);
- meshshape->updateBound();
+ } else {
+ // the collision model has multiple meshes that need to be
+ // combined into a compound shape
+ btCompoundShape *compoundshape = new btCompoundShape();
+
+ for (model::CollisionModel::CollisionMeshes::iterator it = model()->collisionmodel()->meshes().begin();
+ it != model()->collisionmodel()->meshes().end(); it++) {
+
+ model::CollisionMesh *mesh = (*it);
+ btTransform childtransform;
+
+ // dynamic entities use a btGImpactMeshShape
+ btGImpactMeshShape *meshshape = new btGImpactMeshShape(mesh->triangles());
+ // FIXME apply vertexgroup transformations
+ compoundshape->addChildShape(childtransform, meshshape);
+ shapes().push_back(meshshape);
+ }
+
+ btVector3 modelscalevec(modelscale, modelscale, modelscale);
+ compoundshape->setLocalScaling(modelscalevec);
+
+ shapes().push_back(compoundshape);
+ myshape = compoundshape;
+ }
- entity_collision_shape = meshshape;
} else {
// use bounding box
- entity_collision_shape = new btBoxShape(to_btVector3(model()->box().max() * modelscale));
+ btBoxShape *boxshape = new btBoxShape(to_btVector3(model()->box().max() * modelscale));
+ shapes().push_back(boxshape);
+ myshape = boxshape;
}
+
} else {
- entity_collision_shape = new btSphereShape(radius());
+ // use a sphere with a radius matching the entity
+ btSphereShape *sphereshape = new btSphereShape(radius());
+ shapes().push_back(sphereshape);
+ myshape = sphereshape;
+
}
- entity_collision_shape->setMargin(Cvar::sv_collisionmargin->value());
+ // set margin on each mesh
+ for (CollisionShapes::iterator it = shapes().begin(); it != shapes().end(); it++) {
+ (*it)->setMargin(Cvar::sv_collisionmargin->value());
+ }
+
btVector3 inertia(0, 0, 0);
if (entity_mass)
- entity_collision_shape->calculateLocalInertia(entity_mass, inertia);
+ myshape->calculateLocalInertia(entity_mass, inertia);
// create motion state
entity_motionstate = new btDefaultMotionState(t);
// create physics body
- entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, entity_collision_shape, inertia);
+ entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, myshape, inertia);
entity_body = new btRigidBody(*entity_body_info);
if (entity_mass) {
@@ -1009,37 +1103,87 @@ void EntityControlable::reset()
// construct physics body if necessary
if (!entity_body) {
+ btCollisionShape * myshape = 0;
+
// create collision shape
if (model() && model()->radius()) {
const float modelscale = radius() / model()->radius();
- if (flag_is_set(Complex) && model()->collisionmesh()) {
- // use collision mesh
- // dynamic entities use a btGImpactMeshShape
- btGImpactMeshShape *meshshape = new btGImpactMeshShape(model()->collisionmesh()->triangles());
+ if (flag_is_set(Complex) && model()->collisionmodel() && (model()->collisionmodel()->size() > 0) ) {
+ if (model()->collisionmodel()->size() == 1 ) {
+ // the collision model only has a single mesh,
+ // we can use a triangle mesh shape
+
+ model::CollisionMesh *mesh = (*model()->collisionmodel()->meshes().begin());
+
+ // dynamic entities use a btGImpactMeshShape
+ btGImpactMeshShape *meshshape = new btGImpactMeshShape(mesh->triangles());
+ btVector3 modelscalevec(modelscale, modelscale, modelscale);
+ meshshape->setLocalScaling(modelscalevec);
+
+ shapes().push_back(meshshape);
+ myshape = meshshape;
+ meshshape->updateBound();
- btVector3 modelscalevec(modelscale, modelscale, modelscale);
- meshshape->setLocalScaling(modelscalevec);
- meshshape->setMargin(Cvar::sv_collisionmargin->value());
- meshshape->updateBound();
+ } else {
+ // the collision model has multiple meshes that need to be
+ // combined into a compound shape
+ btCompoundShape *compoundshape = new btCompoundShape();
+ btVector3 modelscalevec(modelscale, modelscale, modelscale);
+
+ for (model::CollisionModel::CollisionMeshes::iterator it = model()->collisionmodel()->meshes().begin();
+ it != model()->collisionmodel()->meshes().end(); it++) {
+
+ model::CollisionMesh *mesh = (*it);
+ btTransform childtransform;
+ childtransform.setIdentity();
+
+ // dynamic entities use a btGImpactMeshShape
+ btGImpactMeshShape *meshshape = new btGImpactMeshShape(mesh->triangles());
+ meshshape->setLocalScaling(modelscalevec);
+ meshshape->updateBound();
+
+ // FIXME apply vertexgroup transformations
+ compoundshape->addChildShape(childtransform, meshshape);
+ shapes().push_back(meshshape);
+ }
+
+
+
+
+ shapes().push_back(compoundshape);
+ myshape = compoundshape;
+ }
- entity_collision_shape = meshshape;
} else {
// use bounding box
- entity_collision_shape = new btBoxShape(to_btVector3(model()->box().max() * modelscale));
+ btBoxShape *boxshape = new btBoxShape(to_btVector3(model()->box().max() * modelscale));
+ shapes().push_back(boxshape);
+ myshape = boxshape;
}
+
} else {
- entity_collision_shape = new btSphereShape(radius());
+ // use a sphere with a radius matching the entity
+ btSphereShape *sphereshape = new btSphereShape(radius());
+ shapes().push_back(sphereshape);
+ myshape = sphereshape;
+
}
+
+ // set margin on each mesh
+ for (CollisionShapes::iterator it = shapes().begin(); it != shapes().end(); it++) {
+ (*it)->setMargin(Cvar::sv_collisionmargin->value());
+ }
+
btVector3 inertia(0, 0, 0);
if (entity_mass)
- entity_collision_shape->calculateLocalInertia(entity_mass, inertia);
+ myshape->calculateLocalInertia(entity_mass, inertia);
// create motion state
entity_motionstate = new btDefaultMotionState(t);
// create physics body
- entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, entity_collision_shape, inertia);
+ entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, myshape, inertia);
entity_body = new btRigidBody(*entity_body_info);
entity_body->setActivationState(DISABLE_DEACTIVATION);