diff options
author | Stijn Buys <ingar@osirion.org> | 2011-05-05 18:08:45 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2011-05-05 18:08:45 +0000 |
commit | 1687737ca713cd0baeca3cf79950ef4877640c99 (patch) | |
tree | f6cfd31c850cec95da491036f1dd772397128549 /src/core | |
parent | 09d68d3d1d77d45343e3562c0b5e0cd6816d47d3 (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')
-rw-r--r-- | src/core/Makefile.am | 2 | ||||
-rw-r--r-- | src/core/entity.cc | 236 | ||||
-rw-r--r-- | src/core/entity.h | 16 | ||||
-rw-r--r-- | src/core/physics.cc | 4 | ||||
-rw-r--r-- | src/core/signals.cc | 16 | ||||
-rw-r--r-- | src/core/signals.h | 51 |
6 files changed, 273 insertions, 52 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am index ce76303..e6b98e5 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -31,6 +31,7 @@ noinst_HEADERS = \ physics.h \ player.h \ range.h \ + signals.h \ stats.h \ timer.h \ zone.h @@ -60,6 +61,7 @@ libcore_la_SOURCES = \ parser.cc \ physics.cc \ player.cc \ + signals.cc \ stats.cc \ timer.cc \ zone.cc 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); diff --git a/src/core/entity.h b/src/core/entity.h index 54849b7..a356525 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -57,6 +57,9 @@ public: /// entity menus collection typedef typedef std::list<MenuDescription *> Menus; + + /// type definition for entity bullet shapes collection + typedef std::list<btCollisionShape *> CollisionShapes; /// create a new entity and add it to the registry Entity(); @@ -164,8 +167,8 @@ public: } /// physics collision shape - inline btCollisionShape *collision_shape() { - return entity_collision_shape; + inline CollisionShapes collision_shapes() { + return entity_collision_shapes; } /// indicates a server-side entity @@ -192,6 +195,11 @@ public: inline Menus &menus() { return entity_menus; } + + /// entity collision shapes + inline CollisionShapes & shapes() { + return entity_collision_shapes; + } /// extensions inline Extension *extension(size_t type) const { @@ -445,9 +453,9 @@ public: protected: btRigidBody *entity_body; btRigidBody::btRigidBodyConstructionInfo *entity_body_info; - btCollisionShape *entity_collision_shape; + CollisionShapes entity_collision_shapes; - // the zone the entity belongs to + // the zone the entity belongs to Zone* entity_zone; // the previous zone the entity belonged too Zone* entity_oldzone; diff --git a/src/core/physics.cc b/src/core/physics.cc index 5504c50..90fb184 100644 --- a/src/core/physics.cc +++ b/src/core/physics.cc @@ -21,7 +21,7 @@ void Physics::init() { con_print << "^BInitializing physics engine..." << std::endl; - model::CollisionMesh::init(); + model::CollisionModel::init(); physics_configuration = new btDefaultCollisionConfiguration(); physics_dispatcher = new btCollisionDispatcher(physics_configuration); @@ -35,7 +35,7 @@ void Physics::done() { con_print << "^BShutting down physics engine..." << std::endl; - model::CollisionMesh::shutdown(); + model::CollisionModel::shutdown(); delete physics_solver; delete physics_dispatcher; diff --git a/src/core/signals.cc b/src/core/signals.cc new file mode 100644 index 0000000..f05b328 --- /dev/null +++ b/src/core/signals.cc @@ -0,0 +1,16 @@ +/* + core/signals.cc + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#include "core/signals.h" + +namespace core { + +void Signal::send(Player *sender, Player *reciever, Signals signal) +{ + +} + +} // namespace core
\ No newline at end of file diff --git a/src/core/signals.h b/src/core/signals.h new file mode 100644 index 0000000..88841ea --- /dev/null +++ b/src/core/signals.h @@ -0,0 +1,51 @@ +/* + core/signals.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CORE_SIGNALS_H__ +#define __INCLUDED_CORE_SIGNALS_H__ + +#include <list> + +#include "core/player.h" + +namespace core +{ + +/** + * @brief a signal is a confirmation request from one player to another. + */ +class Signal { +public: + /// signal types + enum Signals {Trade = 1, Dock = 2, Chat = 3}; + + /// current state of a signal + enum State {Rejected = 0, Accepted = 1, Pending = 2}; + + + /// type definition for the signal registry + typedef std::list<Signal*> Registry; + + static void send(Player *sender, Player *receiver, Signals signal); + + static void init(); + + static void done(); + + static void clear(); + +private: + Signals signal_type; + State signal_state; + unsigned long signal_timestamp; + + static Registry signal_registry; +}; + +} + +#endif // __INCLUDED_CORE_SIGNALS_H__ + |