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-02-08 16:55:23 +0000
committerStijn Buys <ingar@osirion.org>2011-02-08 16:55:23 +0000
commit38eb51c26ab0d9dbebc974c7a21f96a429ce3098 (patch)
tree8563fdcf4de0d19ad20e660ae30b4b333825e4d4
parent84dd93a63305bd3b1ff3c5c897a6f3e729bfefed (diff)
Corrected triangle loading of collision model, added 'complex' flag to ships.ini
to enable collision models on player ships.
-rw-r--r--src/core/entity.cc95
-rw-r--r--src/core/entity.h12
-rw-r--r--src/game/base/ship.cc4
-rw-r--r--src/game/base/shipmodel.cc7
-rw-r--r--src/game/base/shipmodel.h14
-rw-r--r--src/model/collisionmesh.cc3
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)
@@ -967,17 +1017,31 @@ 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;
}