Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/entity.cc106
-rw-r--r--src/core/entity.h30
-rw-r--r--src/core/physics.h1
-rw-r--r--src/core/zone.cc11
-rw-r--r--src/core/zone.h6
5 files changed, 140 insertions, 14 deletions
diff --git a/src/core/entity.cc b/src/core/entity.cc
index 7ff9d7b..a1db040 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -222,9 +222,14 @@ Entity::~Entity()
if (entity_inventory)
delete entity_inventory;
- if (entity_zone)
+ if (entity_zone) {
entity_zone->remove(this);
+ if (body() && entity_zone->physics()) {
+ entity_zone->physics()->removeRigidBody(body());
+ }
+ }
+
if (entity_motionstate)
delete entity_motionstate;
@@ -278,9 +283,14 @@ void Entity::set_zone(Zone *zone)
if (entity_zone == zone)
return;
- if (entity_zone)
+ if (entity_zone) {
entity_zone->remove(this);
+ if (body() && entity_zone->physics()) {
+ entity_zone->physics()->removeRigidBody(body());
+ }
+ }
+ // oldzone is cleared after every game frame
if (!entity_oldzone)
entity_oldzone = entity_zone;
@@ -289,6 +299,10 @@ void Entity::set_zone(Zone *zone)
if (entity_zone) {
entity_zone->add(this);
+ if (body() && entity_zone->physics()) {
+ entity_zone->physics()->addRigidBody(body());
+ reset();
+ }
}
}
@@ -432,6 +446,7 @@ void Entity::receive_server_create(std::istream &is)
if (inventory()) {
inventory()->receive_server_update(is);
}
+
entity_dirty = false;
}
@@ -672,6 +687,8 @@ EntityControlable::EntityControlable() : EntityDynamic()
target_afterburner = 0.0f;
entity_owner = 0;
+
+ entity_vehicle = 0;
}
EntityControlable::EntityControlable(std::istream & is) :
@@ -688,6 +705,8 @@ EntityControlable::EntityControlable(std::istream & is) :
target_afterburner = 0.0f;
entity_owner = 0;
+
+ entity_vehicle = 0;
}
@@ -866,6 +885,89 @@ void EntityControlable::set_afterburner(float afterburner)
}
}
+void EntityControlable::set_zone(Zone *zone)
+{
+ if (entity_zone == zone)
+ return;
+
+ if (entity_zone) {
+ entity_zone->remove(this);
+ if (vehicle() && entity_zone->physics()) {
+ entity_zone->physics()->removeAction(entity_vehicle);
+ entity_zone->physics()->removeRigidBody(body());
+ delete entity_vehicle;
+ entity_vehicle = 0;
+ }
+ }
+
+ // oldzone is cleared after every game frame
+ if (!entity_oldzone)
+ entity_oldzone = entity_zone;
+
+ entity_zone = zone;
+ set_dirty();
+
+ if (entity_zone) {
+ entity_zone->add(this);
+ if (body() && entity_zone->physics()) {
+ entity_vehicle = new btRaycastVehicle(entity_vehicletuning, body(), entity_zone->raycaster());
+ entity_zone->physics()->addRigidBody(body());
+ entity_zone->physics()->addAction(entity_vehicle);
+ reset();
+ }
+ }
+}
+
+void EntityControlable::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()) {
+ entity_collision_shape = new btBoxShape(to_btVector3(model()->maxbbox()));
+ } 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(DISABLE_DEACTIVATION);
+ }
+
+ entity_body->setWorldTransform(t);
+ if (zone()) {
+ if (!entity_vehicle) {
+ entity_vehicle = new btRaycastVehicle(entity_vehicletuning, body(), entity_zone->raycaster());
+ entity_zone->physics()->addRigidBody(body());
+ entity_zone->physics()->addAction(entity_vehicle);
+ }
+
+ // transfer entity location to motion state
+ zone()->physics()->synchronizeSingleMotionState(entity_body);
+ }
+
+ if ((entity_state == Docked) || (entity_state == Destroyed) || (!visible())){
+ entity_body->activate(false);
+ } else {
+ entity_body->activate(true);
+ }
+
+ set_dirty();
+}
+
/*----- EntityGlobe ------------------------------------------------ */
EntityGlobe::EntityGlobe() : Entity()
diff --git a/src/core/entity.h b/src/core/entity.h
index e51dac3..057ffb2 100644
--- a/src/core/entity.h
+++ b/src/core/entity.h
@@ -425,6 +425,11 @@ protected:
btCollisionShape *entity_collision_shape;
btMotionState *entity_motionstate;
+ // the zone the entity belongs to
+ Zone* entity_zone;
+ // the previous zone the entity belonged too
+ Zone* entity_oldzone;
+
private:
unsigned int entity_id;
unsigned int entity_flags;
@@ -445,11 +450,6 @@ private:
model::Model* entity_model;
- // the zone the entity belongs to
- Zone* entity_zone;
- // the previous zone the entity belonged too
- Zone* entity_oldzone;
-
Menus entity_menus;
Inventory* entity_inventory;
@@ -581,6 +581,11 @@ public:
return entity_movement;
}
+ /// physics vehicle container
+ inline btRaycastVehicle *vehicle() {
+ return entity_vehicle;
+ }
+
/*----- serializers ----------------------------------------------- */
/// serialize the entity to a stream
@@ -594,6 +599,18 @@ public:
/*----- mutators -------------------------------------------------- */
+ /**
+ * @brief set the zone the entity is currently in
+ * this fuction removes the entity from its previous zone
+ * and removes it to the new one, if it is not 0
+ */
+ virtual void set_zone(Zone *zone);
+
+ /**
+ * @brief reset the physics state
+ */
+ virtual void reset();
+
/// receive a client-to-server update from a stream
virtual void receive_client_update(std::istream &is);
@@ -671,6 +688,9 @@ protected:
float entity_movement;
+ btRaycastVehicle::btVehicleTuning entity_vehicletuning;
+ btRaycastVehicle *entity_vehicle;
+
private:
// owner of the entity
Player *entity_owner;
diff --git a/src/core/physics.h b/src/core/physics.h
index e565403..071ad33 100644
--- a/src/core/physics.h
+++ b/src/core/physics.h
@@ -15,6 +15,7 @@
#include "BulletCollision/CollisionShapes/btTriangleMesh.h"
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/Gimpact/btGImpactShape.h"
+#include "BulletDynamics/Vehicle/btRaycastVehicle.h"
namespace core
{
diff --git a/src/core/zone.cc b/src/core/zone.cc
index 8a8c056..a38959f 100644
--- a/src/core/zone.cc
+++ b/src/core/zone.cc
@@ -127,6 +127,7 @@ Zone::Zone(std::string const & label) : Label(label)
zone_bullet_cache = new btAxisSweep3(worldAabbMin, worldAabbMax, maxProxies);
zone_bullet_world = new btDiscreteDynamicsWorld(Physics::dispatcher(), zone_bullet_cache, Physics::solver(), Physics::configuration());
+ zone_bullet_raycaster = new btDefaultVehicleRaycaster(zone_bullet_world);
// disable gravity
zone_bullet_world->setGravity(btVector3(0.0f, 0.0f, 0.0f));
@@ -151,6 +152,9 @@ Zone::~Zone()
zone_content.clear();
+ if (zone_bullet_raycaster)
+ delete zone_bullet_raycaster;
+
if (zone_bullet_world)
delete zone_bullet_world;
@@ -172,19 +176,12 @@ void Zone::print()
void Zone::add(Entity *entity)
{
zone_content.push_back(entity);
- if (physics() && entity->body()) {
- physics()->addRigidBody(entity->body());
- entity->reset();
- }
}
void Zone::remove(Entity *entity)
{
for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) {
if ((*it) == entity) {
- if (physics() && entity->body()) {
- physics()->removeRigidBody(entity->body());
- }
zone_content.erase(it);
return;
}
diff --git a/src/core/zone.h b/src/core/zone.h
index f040939..d4b08bf 100644
--- a/src/core/zone.h
+++ b/src/core/zone.h
@@ -145,6 +145,11 @@ public:
inline btDiscreteDynamicsWorld *physics() {
return zone_bullet_world;
}
+
+ /// physics vehicle raycaster
+ inline btVehicleRaycaster *raycaster() {
+ return zone_bullet_raycaster;
+ }
private:
unsigned int zone_id;
@@ -158,6 +163,7 @@ private:
btAxisSweep3 *zone_bullet_cache;
btDiscreteDynamicsWorld *zone_bullet_world;
+ btVehicleRaycaster *zone_bullet_raycaster;
};
}