diff options
Diffstat (limited to 'src/core/entity.cc')
-rw-r--r-- | src/core/entity.cc | 127 |
1 files changed, 118 insertions, 9 deletions
diff --git a/src/core/entity.cc b/src/core/entity.cc index ba79424..8a7976f 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -15,6 +15,8 @@ #include "core/application.h" #include "core/gameinterface.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" + namespace core { @@ -141,7 +143,12 @@ Entity::Entity() : entity_flags = 0; entity_moduletypeid = 0; + entity_model = 0; + entity_body = 0; + entity_collision_shape = 0; + entity_speed = 0.0f; + entity_mass = 0.0f; entity_radius = 0.5f; entity_shape = Diamond; @@ -150,8 +157,6 @@ Entity::Entity() : entity_destroyed = false; entity_dirty = false; - entity_model = 0; - entity_zone = 0; entity_oldzone = 0; entity_visible = true; @@ -175,7 +180,11 @@ Entity::Entity(std::istream & is) entity_visible = true; entity_model = 0; + entity_body = 0; + entity_collision_shape = 0; + entity_speed = 0.0f; + entity_mass = 0.0f; entity_created = true; entity_destroyed = false; @@ -209,6 +218,12 @@ Entity::~Entity() if (entity_zone) entity_zone->remove(this); + + if (entity_collision_shape) + delete entity_collision_shape; + + if (entity_body) + delete entity_body; } void Entity::die() @@ -229,6 +244,34 @@ void Entity::clear_updates() } } +// reset physics state +void Entity::reset() +{ + if (!entity_body) { + if (entity_collision_shape ) { + delete entity_collision_shape ; + entity_collision_shape = 0; + } + + if (model()) { + entity_collision_shape = new btBoxShape(to_btVector3(model()->maxbbox())); + } else { + entity_collision_shape = new btSphereShape(radius()); + } + + btVector3 inertia(0, 0, 0); + entity_body = new btRigidBody(0.0f, 0, entity_collision_shape, inertia); + } + + btTransform t; + t.setIdentity(); + t.setOrigin(to_btVector3(location())); + t.setBasis(to_btMatrix3x3(axis())); + + entity_body->setWorldTransform(t); + set_dirty(); +} + void Entity::set_info(Info *info) { entity_info = info; @@ -260,8 +303,9 @@ void Entity::set_zone(Zone *zone) entity_zone = zone; entity_dirty = true; - if (entity_zone) + if (entity_zone) { entity_zone->add(this); + } } void Entity::set_model(model::Model *model) @@ -460,16 +504,21 @@ EntityDynamic::EntityDynamic() : Entity() { entity_state = Normal; entity_timer = 0; + + entity_motionstate = new btDefaultMotionState(); } 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) @@ -480,17 +529,66 @@ void EntityDynamic::set_state(int state) } } +// reset physics state +void EntityDynamic::reset() +{ + assert(entity_motionstate); + + // construct physics body if necessary + if (!entity_body) { + if (entity_collision_shape ) { + delete entity_collision_shape ; + entity_collision_shape = 0; + } + + if (model()) { + entity_collision_shape = new btBoxShape(to_btVector3(model()->maxbbox())); + } else { + entity_collision_shape = new btSphereShape(radius()); + } + + btVector3 inertia(0, 0, 0); + entity_collision_shape->calculateLocalInertia(entity_mass, inertia); + entity_body = new btRigidBody(entity_mass, entity_motionstate, entity_collision_shape, inertia); + } + + // transfer entity location to motion state + btTransform t; + t.setIdentity(); + t.setOrigin(to_btVector3(location())); + t.setBasis(to_btMatrix3x3(axis())); + entity_body->setWorldTransform(t); + if (zone()) + zone()->physics()->synchronizeSingleMotionState(entity_body); + + set_dirty(); +} + void EntityDynamic::frame(float seconds) { if ((flags() & Static) == Static) return; - if (entity_speed == 0) - return; - - get_location() += axis().forward() * entity_speed * seconds; - - set_dirty(); + // transfer bullet state to entity state + // FIXME disable physics when docked + if (entity_body && entity_motionstate) { + + // this makes sure an update is sent if speed goes to 0 in the next step + if (entity_speed > 0) { + set_dirty(); + } + + btTransform t; + entity_motionstate->getWorldTransform(t); + get_location().assign(t.getOrigin()); + get_axis().assign(t.getBasis()); + + entity_speed = (float) entity_body->getLinearVelocity().length(); + + if (entity_speed > 0) { + set_dirty(); + } + } } void EntityDynamic::serialize_server_create(std::ostream & os) const @@ -755,6 +853,17 @@ void EntityControlable::set_strafe(float strafe) } } +void EntityControlable::set_vstrafe(float vstrafe) +{ + if ((flags() & Static) == Static) + return; + + if (target_vstrafe != vstrafe) { + target_vstrafe = vstrafe; + set_dirty(); + } +} + void EntityControlable::set_afterburner(float afterburner) { if ((flags() & Static) == Static) |