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>2010-10-18 23:41:41 +0000
committerStijn Buys <ingar@osirion.org>2010-10-18 23:41:41 +0000
commit7a373c3f1fb8ea9dbef7690154bbe332fc386eca (patch)
treee56652c9b6197017d7eb8e86e5cd431bf9861d57
parent4c5b00221c9405c5af06143974fbc6296ebe46b5 (diff)
bullet ActionInterface for controlable entities, KeepAlive flag and g_keepalive
-rw-r--r--src/core/entity.cc92
-rw-r--r--src/core/entity.h53
-rw-r--r--src/core/gameserver.cc45
-rw-r--r--src/core/physics.h2
-rw-r--r--src/game/base/cargopod.cc3
-rw-r--r--src/game/base/game.cc5
-rw-r--r--src/game/base/game.h3
-rw-r--r--src/game/base/ship.cc80
8 files changed, 196 insertions, 87 deletions
diff --git a/src/core/entity.cc b/src/core/entity.cc
index a1db040..1438466 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -520,7 +520,7 @@ void Entity::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(ISLAND_SLEEPING);
+ entity_body->setActivationState(ISLAND_SLEEPING);
if (zone())
zone()->physics()->addRigidBody(entity_body);
@@ -540,12 +540,16 @@ EntityDynamic::EntityDynamic() : Entity()
{
entity_state = Normal;
entity_timer = 0;
+ entity_keepalive_time = 0.0f;
+ entity_keepalive_timeout = 0.0f;
}
EntityDynamic::EntityDynamic(std::istream & is) : Entity(is)
{
entity_state = Normal;
entity_timer = 0;
+ entity_keepalive_time = 0.0f;
+ entity_keepalive_timeout = 0.0f;
}
EntityDynamic::~EntityDynamic()
@@ -560,6 +564,16 @@ void EntityDynamic::set_state(int state)
}
}
+void EntityDynamic::set_keepalive_time(float time)
+{
+ entity_keepalive_time = time;
+}
+
+void EntityDynamic::set_keepalive_timeout(float timeout)
+{
+ entity_keepalive_timeout = timeout;
+}
+
void EntityDynamic::reset()
{
Entity::reset();
@@ -577,7 +591,6 @@ void EntityDynamic::frame(float seconds)
return;
// transfer bullet state to entity state
- // FIXME disable physics when docked
if (entity_body) {
// this makes sure an update is sent if speed goes to 0 in the next step
if (entity_speed > 0) {
@@ -672,6 +685,27 @@ void EntityDynamic::receive_server_update(std::istream &is)
}
}
+/*----- EntityControlable::ActionInterface ------------------------- */
+
+EntityControlable::ActionInterface::ActionInterface(EntityControlable *entity)
+{
+ actioninterface_entity = entity;
+}
+
+EntityControlable::ActionInterface::~ActionInterface()
+{
+ actioninterface_entity = 0;
+}
+
+void EntityControlable::ActionInterface::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep)
+{
+ actioninterface_entity->action(deltaTimeStep);
+}
+
+void EntityControlable::ActionInterface::debugDraw(btIDebugDraw* debugDrawer)
+{
+}
+
/*----- EntityControlable ------------------------------------------ */
EntityControlable::EntityControlable() : EntityDynamic()
@@ -688,7 +722,7 @@ EntityControlable::EntityControlable() : EntityDynamic()
entity_owner = 0;
- entity_vehicle = 0;
+ entity_actioninterface = 0;
}
EntityControlable::EntityControlable(std::istream & is) :
@@ -706,7 +740,7 @@ EntityControlable::EntityControlable(std::istream & is) :
entity_owner = 0;
- entity_vehicle = 0;
+ entity_actioninterface = 0;
}
@@ -800,14 +834,6 @@ void EntityControlable::receive_server_update(std::istream &is)
entity_movement /= 100.0f;
}
-void EntityControlable::frame(float seconds)
-{
- //entity_direction = target_direction;
- //entity_thrust = target_thrust;
- //entity_dirty = true;
- EntityDynamic::frame(seconds);
-}
-
void EntityControlable::set_thrust(float thrust)
{
if ((flags() & Static) == Static)
@@ -892,11 +918,9 @@ void EntityControlable::set_zone(Zone *zone)
if (entity_zone) {
entity_zone->remove(this);
- if (vehicle() && entity_zone->physics()) {
- entity_zone->physics()->removeAction(entity_vehicle);
+ if (body() && entity_zone->physics()) {
+ entity_zone->physics()->removeAction(entity_actioninterface);
entity_zone->physics()->removeRigidBody(body());
- delete entity_vehicle;
- entity_vehicle = 0;
}
}
@@ -909,10 +933,9 @@ void EntityControlable::set_zone(Zone *zone)
if (entity_zone) {
entity_zone->add(this);
- if (body() && entity_zone->physics()) {
- entity_vehicle = new btRaycastVehicle(entity_vehicletuning, body(), entity_zone->raycaster());
+ if (body() && entity_zone->physics()) {
entity_zone->physics()->addRigidBody(body());
- entity_zone->physics()->addAction(entity_vehicle);
+ entity_zone->physics()->addAction(entity_actioninterface);
reset();
}
}
@@ -945,20 +968,19 @@ 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->setWorldTransform(t);
- if (zone()) {
- if (!entity_vehicle) {
- entity_vehicle = new btRaycastVehicle(entity_vehicletuning, body(), entity_zone->raycaster());
+
+ entity_actioninterface = new ActionInterface(this);
+
+ if (zone()) {
entity_zone->physics()->addRigidBody(body());
- entity_zone->physics()->addAction(entity_vehicle);
- }
+ entity_zone->physics()->addAction(entity_actioninterface);
- // transfer entity location to motion state
- zone()->physics()->synchronizeSingleMotionState(entity_body);
+ // transfer entity location to motion state
+ zone()->physics()->synchronizeSingleMotionState(entity_body);
+ }
}
+ entity_body->setWorldTransform(t);
if ((entity_state == Docked) || (entity_state == Destroyed) || (!visible())){
entity_body->activate(false);
} else {
@@ -968,6 +990,18 @@ void EntityControlable::reset()
set_dirty();
}
+// bullet physics frame (runs at bullet framerate)
+void EntityControlable::action(btScalar seconds)
+{
+}
+
+// osirion game frame (runs at osirion server framerate)
+void EntityControlable::frame(float seconds)
+{
+ EntityDynamic::frame(seconds);
+}
+
+
/*----- EntityGlobe ------------------------------------------------ */
EntityGlobe::EntityGlobe() : Entity()
diff --git a/src/core/entity.h b/src/core/entity.h
index 057ffb2..f6ee1d7 100644
--- a/src/core/entity.h
+++ b/src/core/entity.h
@@ -41,8 +41,10 @@ class Entity : public Label
friend class Extension;
public:
- /// Entity flags
- enum Flags {Static = 1, Solid = 2, Bright = 4, Dockable = 8, ShowOnMap = 16};
+ /**
+ * @brief entity flags
+ */
+ enum Flags {Static = 1, Solid = 2, Bright = 4, Dockable = 8, ShowOnMap = 16, KeepAlive = 32};
/// Entity type constants
enum Type {Default = 0, Dynamic = 1, Controlable = 2, Globe = 3};
@@ -492,7 +494,17 @@ public:
return entity_timer;
}
-/*----- mutators -------------------------------------------------- */
+ /// time when the entity was last alive
+ inline const float keepalive_time() const {
+ return entity_keepalive_time;
+ }
+
+ /// keepalive timeout
+ inline const float keepalive_timeout() const {
+ return entity_keepalive_timeout;
+ }
+
+ /*----- mutators -------------------------------------------------- */
/// mass of the entity
inline void set_mass(const float mass) {
@@ -528,6 +540,12 @@ public:
/// set event state
virtual void set_state(int state);
+
+ /// set the time when the entity was last alive, in game time seconds
+ void set_keepalive_time(float time);
+
+ /// set the timeout after which the entitie is deleted, in seconds
+ void set_keepalive_timeout(float timeout);
/// runs one game frame for the entity
/**
@@ -542,6 +560,8 @@ public:
virtual void reset();
protected:
+ float entity_keepalive_time;
+ float entity_keepalive_timeout;
float entity_timer;
int entity_state;
};
@@ -551,6 +571,20 @@ class EntityControlable : public EntityDynamic
{
friend class Player;
public:
+ /// bullet action interface class
+ class ActionInterface: public btActionInterface {
+ public:
+ ActionInterface(EntityControlable *entity);
+ virtual ~ActionInterface();
+
+ virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
+
+ virtual void debugDraw(btIDebugDraw* debugDrawer);
+
+ private:
+ EntityControlable *actioninterface_entity;
+ };
+
/// server-side constructor, create a controlable entity
EntityControlable();
@@ -581,9 +615,9 @@ public:
return entity_movement;
}
- /// physics vehicle container
- inline btRaycastVehicle *vehicle() {
- return entity_vehicle;
+ /// physics action
+ inline ActionInterface *actioninterface() {
+ return entity_actioninterface;
}
/*----- serializers ----------------------------------------------- */
@@ -655,6 +689,10 @@ public:
float entity_thrust;
protected:
+
+ /// physics action interface callback
+ virtual void action (btScalar seconds);
+
/* target_ variables can be set by the client */
/**
@@ -688,8 +726,7 @@ protected:
float entity_movement;
- btRaycastVehicle::btVehicleTuning entity_vehicletuning;
- btRaycastVehicle *entity_vehicle;
+ ActionInterface *entity_actioninterface;
private:
// owner of the entity
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index 597de33..e6c44d0 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -15,6 +15,7 @@
#include "core/loader.h"
#include "core/parser.h"
#include "core/physics.h"
+#include "core/range.h"
#include "core/netserver.h"
#include "filesystem/filesystem.h"
#include "sys/sys.h"
@@ -564,8 +565,7 @@ void GameServer::frame(unsigned long timestamp)
}
// view is to be deleted
- if (view->destroyed())
- {
+ if (view->destroyed()) {
if (control) {
// player is docked at deleted entity
if (control->state() == Entity::Docked) {
@@ -590,15 +590,42 @@ void GameServer::frame(unsigned long timestamp)
}
// mark all entities as updated
+ const float keepalive_distance_squared = range::fxdistance * range::fxdistance;
+
for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end();) {
- Entity *entity = (*it).second;
+
+ // perform a keep-alive pass
+ if ((*it).second->flag_is_set(Entity::KeepAlive) && ((*it).second->type() == Entity::Dynamic) && (*it).second->zone()) {
+
+ bool keepalive = false;
+ EntityDynamic *entity = static_cast<EntityDynamic *>((*it).second);
+
+ for (Zone::Content::const_iterator zit = entity->zone()->content().begin(); zit != entity->zone()->content().end(); zit++) {
+
+ if (( (*zit)->type() == Entity::Controlable) && ( (*zit) != entity)) {
+
+ const EntityControlable *other = static_cast<const EntityControlable *>(*zit);
+ if (other->owner() && (other->state() != Entity::Docked) && (math::distancesquared(entity->location(), other->location()) < keepalive_distance_squared)) {
+ keepalive = true;
+ }
+ }
+
+ }
+
+ if (keepalive) {
+ entity->set_keepalive_time(time() + entity->keepalive_timeout());
+ } else if ((entity->keepalive_time() > 0.0f) && (entity->keepalive_time() < time())) {
+ entity->die();
+ }
+ }
- if (entity->entity_destroyed) {
- delete entity;
- (*it).second = entity = 0;
+ // delete the entity if necessary
+ if ((*it).second->entity_destroyed) {
+ delete (*it).second;
+ (*it).second = 0;
Entity::registry().erase(it++);
} else {
- entity->clear_updates();
+ (*it).second->clear_updates();
++it;
}
}
@@ -607,10 +634,6 @@ void GameServer::frame(unsigned long timestamp)
application()->notify_zonechange();
localplayer()->set_zonechange(false);
}
-
- /*if (!Cvar::sv_dedicated->value()) {
- update_clientstate();
- }*/
}
void GameServer::save_config()
diff --git a/src/core/physics.h b/src/core/physics.h
index 071ad33..ecceb67 100644
--- a/src/core/physics.h
+++ b/src/core/physics.h
@@ -15,7 +15,7 @@
#include "BulletCollision/CollisionShapes/btTriangleMesh.h"
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/Gimpact/btGImpactShape.h"
-#include "BulletDynamics/Vehicle/btRaycastVehicle.h"
+#include "BulletDynamics/Dynamics/btActionInterface.h"
namespace core
{
diff --git a/src/game/base/cargopod.cc b/src/game/base/cargopod.cc
index efdfe33..6581b75 100644
--- a/src/game/base/cargopod.cc
+++ b/src/game/base/cargopod.cc
@@ -15,6 +15,9 @@ CargoPod::CargoPod() : EntityDynamic()
entity_moduletypeid = cargopod_enttype;
set_name("Cargo pod");
set_label("cargopod");
+
+ set_flag(core::Entity::KeepAlive);
+ set_keepalive_timeout(Game::g_keepalive ? Game::g_keepalive->value() : 0);
// FIXME hardcoded modelname
set_modelname("maps/cargo/pod");
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index 346208b..ebf09ce 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -55,6 +55,7 @@ core::Cvar *Game::g_impulseacceleration = 0;
core::Cvar *Game::g_jumppointrange = 0;
core::Cvar *Game::g_devel = 0;
core::Cvar *Game::g_damping = 0;
+core::Cvar *Game::g_keepalive;
core::Module *factory()
{
@@ -802,6 +803,9 @@ Game::Game() : core::Module("Project::OSiRiON", true)
g_damping = core::Cvar::get("g_damping", "0.1", core::Cvar::Archive);
g_damping->set_info("[float] physics damping factor (0-1)");
+
+ g_keepalive = core::Cvar::get("g_keepalive", "300", core::Cvar::Archive);
+ g_keepalive->set_info("[float] amount of time dynamic objects are kept alive, in seconds");
}
Game::~Game()
@@ -1372,7 +1376,6 @@ bool Game::load_defaults()
void Game::frame(float seconds)
{
-
if (!running())
return;
}
diff --git a/src/game/base/game.h b/src/game/base/game.h
index c229a18..07df62d 100644
--- a/src/game/base/game.h
+++ b/src/game/base/game.h
@@ -83,6 +83,9 @@ public:
/// physics variable: default damping factor of space
static core::Cvar *g_damping;
+
+ /// game variable: amount of time dynamic objects are kept alive when there are no players
+ static core::Cvar *g_keepalive;
private:
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc
index 44676c4..9f04e43 100644
--- a/src/game/base/ship.cc
+++ b/src/game/base/ship.cc
@@ -519,10 +519,7 @@ void Ship::frame(float seconds)
entity_thrust = target_thrust;
}
math::clamp(entity_thrust, 0.0f, 1.0f);
- actual_thrust = entity_thrust + current_target_afterburner * 0.15f;
- if ((entity_state == core::Entity::ImpulseInitiate) || (entity_state == core::Entity::Impulse)) {
- actual_thrust = 1.0f;
- }
+
// update strafe control target
if (current_target_strafe < target_strafe) {
@@ -546,25 +543,6 @@ void Ship::frame(float seconds)
current_target_vstrafe = target_vstrafe;
}
- // update roll control target
- if (current_target_roll < target_roll) {
- current_target_roll += direction_reaction * seconds;
- if (current_target_roll > target_roll)
- current_target_roll = target_roll;
- } else if (current_target_roll > target_roll) {
- current_target_roll -= direction_reaction * seconds;
- if (current_target_roll < target_roll)
- current_target_roll = target_roll;
- }
- math::clamp(current_target_roll, -1.0f, 1.0f);
-
- if (fabs(current_target_roll) > MIN_DELTA) {
- float roll_offset = seconds * current_target_roll;
- get_axis().change_roll(actual_turnspeed * roll_offset);
- } else {
- current_target_roll = 0.0f;
- }
-
// update direction control target
if (current_target_direction < target_direction) {
current_target_direction += direction_reaction * seconds;
@@ -578,13 +556,6 @@ void Ship::frame(float seconds)
}
}
- if (fabs(current_target_direction) > MIN_DELTA) {
- math::clamp(current_target_direction, -1.0f, 1.0f);
- target_axis.change_direction(actual_turnspeed * current_target_direction);
- } else {
- current_target_direction = 0.0f;
- }
-
// update pitch control target
if (current_target_pitch < target_pitch) {
current_target_pitch += direction_reaction * seconds;
@@ -596,13 +567,17 @@ void Ship::frame(float seconds)
current_target_pitch = target_pitch;
}
- if (fabs(current_target_pitch) > MIN_DELTA) {
- math::clamp(current_target_pitch, -1.0f, 1.0f);
- target_axis.change_pitch(actual_turnspeed * current_target_pitch);
- } else {
- current_target_pitch = 0.0f;
+ // update roll control target
+ if (current_target_roll < target_roll) {
+ current_target_roll += direction_reaction * seconds;
+ if (current_target_roll > target_roll)
+ current_target_roll = target_roll;
+ } else if (current_target_roll > target_roll) {
+ current_target_roll -= direction_reaction * seconds;
+ if (current_target_roll < target_roll)
+ current_target_roll = target_roll;
}
-
+
/*
// -- BULLET
@@ -628,10 +603,35 @@ void Ship::frame(float seconds)
EntityDynamic::frame(seconds);
*/
+
+ // apply direction rotation to target axis
+ if (fabs(current_target_direction) > MIN_DELTA) {
+ math::clamp(current_target_direction, -1.0f, 1.0f);
+ target_axis.change_direction(actual_turnspeed * current_target_direction);
+ } else {
+ current_target_direction = 0.0f;
+ }
+
+ // apply pitch rotation to target axis
+ if (fabs(current_target_pitch) > MIN_DELTA) {
+ math::clamp(current_target_pitch, -1.0f, 1.0f);
+ target_axis.change_pitch(actual_turnspeed * current_target_pitch);
+ } else {
+ current_target_pitch = 0.0f;
+ }
+
+ // apply roll rotation to axis
+ if (fabs(current_target_roll) > MIN_DELTA) {
+ math::clamp(current_target_roll, -1.0f, 1.0f);
+ get_axis().change_roll(actual_turnspeed * current_target_roll * seconds);
+ } else {
+ current_target_roll = 0.0f;
+ }
+
+ // update axis
float cosangle; // cosine of an angle
float angle; // angle in radians
- // update axis
n.assign(math::crossproduct(axis().forward(), target_axis.forward()));
if (!(n.length() < MIN_DELTA)) {
n.normalize();
@@ -642,6 +642,12 @@ void Ship::frame(float seconds)
}
// update speed
+ if ((entity_state == core::Entity::ImpulseInitiate) || (entity_state == core::Entity::Impulse)) {
+ actual_thrust = 1.0f;
+ } else {
+ actual_thrust = entity_thrust + current_target_afterburner * 0.15f;
+ }
+
const float max = actual_thrust * actual_maxspeed;
if (entity_speed < max) {
entity_speed += actual_acceleration * seconds;