From 38eb51c26ab0d9dbebc974c7a21f96a429ce3098 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 8 Feb 2011 16:55:23 +0000 Subject: Corrected triangle loading of collision model, added 'complex' flag to ships.ini to enable collision models on player ships. --- src/core/entity.cc | 95 ++++++++++++++++++++++++++++++++++++++-------- src/core/entity.h | 12 +++--- src/game/base/ship.cc | 4 +- src/game/base/shipmodel.cc | 7 ++++ src/game/base/shipmodel.h | 14 +++++++ src/model/collisionmesh.cc | 3 +- 6 files changed, 112 insertions(+), 23 deletions(-) diff --git a/src/core/entity.cc b/src/core/entity.cc index 6aef6e5..7aa72fa 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_motionstate = 0; entity_collision_shape = 0; entity_speed = 0.0f; @@ -191,7 +190,6 @@ Entity::Entity(std::istream & is) entity_body = 0; entity_body_info = 0; - entity_motionstate = 0; entity_collision_shape = 0; entity_speed = 0.0f; @@ -235,9 +233,6 @@ Entity::~Entity() } } - if (entity_motionstate) - delete entity_motionstate; - if (entity_collision_shape) delete entity_collision_shape; @@ -511,6 +506,7 @@ void Entity::reset() 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(); @@ -519,7 +515,7 @@ void Entity::reset() btVector3 modelscalevec(modelscale, modelscale, modelscale); meshshape->setLocalScaling(modelscalevec); - meshshape->setMargin(0.0f); + //meshshape->setMargin(0.0f); //meshshape->updateBound(); entity_collision_shape = meshshape; @@ -536,14 +532,12 @@ void Entity::reset() if (entity_mass) entity_collision_shape->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, 0, entity_collision_shape, inertia); entity_body = new btRigidBody(*entity_body_info); entity_body->setActivationState(ISLAND_SLEEPING); + entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); if (zone()) zone()->physics()->addRigidBody(entity_body); @@ -553,7 +547,6 @@ void Entity::reset() body()->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); body()->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); body()->setWorldTransform(t); - motionstate()->setWorldTransform(t); //if (zone()) // zone()->physics()->synchronizeSingleMotionState(entity_body); @@ -567,16 +560,20 @@ EntityDynamic::EntityDynamic() : Entity() { entity_state = Normal; entity_timer = 0; + entity_motionstate = 0; } EntityDynamic::EntityDynamic(std::istream & is) : Entity(is) { entity_state = Normal; entity_timer = 0; + entity_motionstate = 0; } EntityDynamic::~EntityDynamic() { + if (entity_motionstate) + delete entity_motionstate; } void EntityDynamic::set_state(int state) @@ -593,7 +590,58 @@ void EntityDynamic::reset() return; } - Entity::reset(); + // location and orientation + btTransform t; + t.setIdentity(); + t.setOrigin(to_btVector3(location())); + t.setBasis(to_btMatrix3x3(axis())); + + // construct physics body if necessary + if (!entity_body) { + // 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()); + + btVector3 modelscalevec(modelscale, modelscale, modelscale); + meshshape->setLocalScaling(modelscalevec); + //meshshape->setMargin(0.0f); + meshshape->updateBound(); + + entity_collision_shape = meshshape; + } else { + // use bounding box + entity_collision_shape = new btBoxShape(to_btVector3(model()->box().max() * modelscale)); + } + } else { + entity_collision_shape = new btSphereShape(radius()); + } + btVector3 inertia(0, 0, 0); + if (entity_mass) + entity_collision_shape->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 = new btRigidBody(*entity_body_info); + entity_body->setActivationState(ISLAND_SLEEPING); + entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + + if (zone()) + zone()->physics()->addRigidBody(entity_body); + } + + // transfer entity location to motion state + body()->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); + body()->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); + body()->setWorldTransform(t); if (entity_state == Docked) { body()->setLinearFactor(btVector3(0.0f, 0.0f, 0.0f)); @@ -602,6 +650,8 @@ void EntityDynamic::reset() body()->setLinearFactor(btVector3(1.0f, 1.0f, 1.0f)); body()->setAngularFactor(btVector3(1.0f, 1.0f, 1.0f)); } + + set_dirty(); } void EntityDynamic::frame(float seconds) @@ -966,18 +1016,32 @@ void EntityControlable::reset() // construct physics body if necessary if (!entity_body) { - // create collision shape // create collision shape if (model() && model()->radius()) { const float modelscale = radius() / model()->radius(); - entity_collision_shape = new btBoxShape(to_btVector3(model()->box().max() * modelscale)); + + if (flag_is_set(Complex) && model()->collisionmesh()) { + // use collision mesh + // dynamic entities use a btGImpactMeshShape + btGImpactMeshShape *meshshape = new btGImpactMeshShape(model()->collisionmesh()->triangles()); + + btVector3 modelscalevec(modelscale, modelscale, modelscale); + meshshape->setLocalScaling(modelscalevec); + //meshshape->setMargin(0.0f); + meshshape->updateBound(); + + entity_collision_shape = meshshape; + } else { + // use bounding box + entity_collision_shape = new btBoxShape(to_btVector3(model()->box().max() * modelscale)); + } } else { entity_collision_shape = new btSphereShape(radius()); } btVector3 inertia(0, 0, 0); if (entity_mass) entity_collision_shape->calculateLocalInertia(entity_mass, inertia); - + // create motion state entity_motionstate = new btDefaultMotionState(t); @@ -985,6 +1049,7 @@ void EntityControlable::reset() entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, entity_collision_shape, inertia); entity_body = new btRigidBody(*entity_body_info); entity_body->setActivationState(DISABLE_DEACTIVATION); + //entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); entity_actioninterface = new ActionInterface(this); diff --git a/src/core/entity.h b/src/core/entity.h index 378a71a..e12123e 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -173,11 +173,6 @@ public: return entity_collision_shape; } - /// physics motion info - inline btMotionState *motionstate() { - return entity_motionstate; - } - /// indicates a server-side entity inline const bool serverside() const { return entity_serverside; @@ -456,7 +451,6 @@ protected: btRigidBody *entity_body; btRigidBody::btRigidBodyConstructionInfo *entity_body_info; btCollisionShape *entity_collision_shape; - btMotionState *entity_motionstate; // the zone the entity belongs to Zone* entity_zone; @@ -536,6 +530,11 @@ public: return entity_timer; } + /// physics motion info + inline btMotionState *motionstate() { + return entity_motionstate; + } + /*----- mutators -------------------------------------------------- */ /// mass of the entity @@ -588,6 +587,7 @@ public: protected: float entity_timer; int entity_state; + btMotionState *entity_motionstate; }; /// an entity that can be controlled by a player diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index ef60e97..84b4e0a 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -374,8 +374,9 @@ void Ship::frame(float seconds) /* -- update state ----------------------------------------- */ // speed might be set to 0 on this update - if (entity_speed != 0.0f) + if (entity_speed != 0.0f) { set_dirty(); + } if (entity_state == core::Entity::Docked) { @@ -642,6 +643,7 @@ void Ship::frame(float seconds) */ EntityControlable::frame(seconds); + } } // namespace game diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc index 126557c..ec712ac 100644 --- a/src/game/base/shipmodel.cc +++ b/src/game/base/shipmodel.cc @@ -92,6 +92,9 @@ bool ShipModel::init() } else if (inifile.got_key_bool("dock", b)) { shipmodel->set_dockable(b); continue; + } else if (inifile.got_key_bool("complex", b)) { + shipmodel->set_complex_collision(b); + continue; } else if (inifile.got_key_float("maxspeed", f)) { shipmodel->set_maxspeed(f * 0.01f); continue; @@ -212,6 +215,7 @@ ShipModel::ShipModel() : core::Info(shipmodel_infotype) shipmodel_jumpdrive = false; // no jumpdrive capability shipmodel_dockable = false; // not dockable shipmodel_template = 0; + shipmodel_complex_collision = false; } @@ -374,6 +378,9 @@ void ShipModel::apply(core::Entity *entity) const if (radius()) entity->set_radius(radius()); + + if (complex_collision()) + entity->set_flag(core::Entity::Complex); } void ShipModel::apply(Ship *ship) const diff --git a/src/game/base/shipmodel.h b/src/game/base/shipmodel.h index f790bcd..a576c1d 100644 --- a/src/game/base/shipmodel.h +++ b/src/game/base/shipmodel.h @@ -80,6 +80,11 @@ public: return shipmodel_angular_damping; } + /// complex collision + inline const bool complex_collision() const { + return shipmodel_complex_collision; + } + /// maximum thrust speed inline const float maxspeed() const { return shipmodel_maxspeed; @@ -191,6 +196,13 @@ protected: shipmodel_angular_damping = angular_damping; } + /** + * @brief enable collision mesh + */ + inline void set_complex_collision(const float complex_collision) { + shipmodel_complex_collision = complex_collision; + } + public: void generate_info(); @@ -232,6 +244,8 @@ private: bool shipmodel_jumpdrive; bool shipmodel_dockable; + bool shipmodel_complex_collision; + const Template *shipmodel_template; /* --- static ----------------------------------------------------- */ diff --git a/src/model/collisionmesh.cc b/src/model/collisionmesh.cc index 90aafc3..5d4505a 100644 --- a/src/model/collisionmesh.cc +++ b/src/model/collisionmesh.cc @@ -69,7 +69,8 @@ void CollisionMesh::add_triangle(const math::Vector3f & v0, const math::Vector3f collisionmesh_triangles->addTriangle( to_btVector3(v0), to_btVector3(v1), - to_btVector3(v1) + to_btVector3(v2), + true ); collisionmesh_size += 1; } -- cgit v1.2.3