Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/entity.cc')
-rw-r--r--src/core/entity.cc127
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)