Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2010-10-18 19:13:58 +0000
committerStijn Buys <ingar@osirion.org>2010-10-18 19:13:58 +0000
commit4c5b00221c9405c5af06143974fbc6296ebe46b5 (patch)
tree3bbe7fbc47f6238a086260c56964d2d654cf6124 /src
parent85e3fd447aa3f45ba1dfe063b29a3e13f3416f11 (diff)
local vstrafe support, initial ship collision, g_damping factor
Diffstat (limited to 'src')
-rw-r--r--src/client/input.cc2
-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
-rw-r--r--src/game/base/cargopod.cc3
-rw-r--r--src/game/base/game.cc14
-rw-r--r--src/game/base/game.h8
-rw-r--r--src/game/base/ship.cc96
10 files changed, 237 insertions, 40 deletions
diff --git a/src/client/input.cc b/src/client/input.cc
index f9acce0..0412093 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -382,7 +382,7 @@ void action_press(Key *key)
local_strafe = -1.0f;
break;
case Action::StrafeUp:
- local_vstrafe = -1.0f;
+ local_vstrafe = 1.0f;
break;
case Action::StrafeDown:
local_vstrafe = -1.0f;
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;
};
}
diff --git a/src/game/base/cargopod.cc b/src/game/base/cargopod.cc
index 3e61cff..efdfe33 100644
--- a/src/game/base/cargopod.cc
+++ b/src/game/base/cargopod.cc
@@ -23,6 +23,9 @@ CargoPod::CargoPod() : EntityDynamic()
// activate physics
reset();
+
+ const float damp = Game::g_damping->value();
+ body()->setDamping(damp, damp);
}
CargoPod::~CargoPod()
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index a075574..346208b 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -54,6 +54,7 @@ core::Cvar *Game::g_impulsespeed = 0;
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::Module *factory()
{
@@ -729,12 +730,14 @@ Game::Game() : core::Module("Project::OSiRiON", true)
return;
}
+ // load world.ini and the zones it refers to
if (!load_world()) {
abort();
return;
}
- if (!load_player()) {
+ // load game default settings
+ if (!load_defaults()) {
abort();
return;
}
@@ -796,6 +799,9 @@ Game::Game() : core::Module("Project::OSiRiON", true)
g_devel = core::Cvar::get("g_devel", "0", core::Cvar::Archive);
g_devel->set_info("[bool] enable or disable developer mode");
+
+ g_damping = core::Cvar::get("g_damping", "0.1", core::Cvar::Archive);
+ g_damping->set_info("[float] physics damping factor (0-1)");
}
Game::~Game()
@@ -1301,13 +1307,13 @@ bool Game::generate_entity_menus(core::Entity *entity)
return true;
}
-// load default player settings
-bool Game::load_player()
+// load game defaults settings
+bool Game::load_defaults()
{
Default::clear();
filesystem::IniFile inifile;
- inifile.open("player");
+ inifile.open("game");
if (!inifile.is_open()) {
con_error << "Could not open " << inifile.name() << "!" << std::endl;
return false;
diff --git a/src/game/base/game.h b/src/game/base/game.h
index 3f67a25..c229a18 100644
--- a/src/game/base/game.h
+++ b/src/game/base/game.h
@@ -78,8 +78,12 @@ public:
/// game variable: jumppoint range
static core::Cvar *g_jumppointrange;
- /// game variable: enable or disable development mode
+ /// game variable: enable or disable development mode (cheat mode)
static core::Cvar *g_devel;
+
+ /// physics variable: default damping factor of space
+ static core::Cvar *g_damping;
+
private:
bool load_world();
@@ -94,7 +98,7 @@ private:
bool load_ships();
- bool load_player();
+ bool load_defaults();
/* ---- engine functions ----------------------------------- */
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc
index 88aefbe..44676c4 100644
--- a/src/game/base/ship.cc
+++ b/src/game/base/ship.cc
@@ -77,9 +77,11 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) : core::EntityControlable(
set_flag(core::Entity::Dockable);
}
- //set_mass(radius());
- set_mass(0);
+ set_mass(radius());
reset();
+
+ const float damp = Game::g_damping->value();
+ body()->setDamping(damp, damp);
}
Ship::~Ship()
@@ -271,14 +273,17 @@ void Ship::explode()
{
set_state(core::Entity::Destroyed);
- target_thrust = 0;
+ target_direction = 0;
target_pitch = 0;
target_roll = 0;
- target_direction = 0;
+ target_strafe = 0.0f;
+ target_vstrafe = 0.0f;
+
target_afterburner = 0.0f;
target_thrust = 0;
- entity_thrust = 0;
+ entity_thrust = 0;
+
if (owner()) {
if (owner()->control() == this)
owner()->set_view(this);
@@ -305,8 +310,6 @@ void Ship::frame(float seconds)
float actual_acceleration = ship_shipmodel->acceleration();
float actual_thrust = 0;
- float cosangle; // cosine of an angle
- float angle; // angle in radians
math::Vector3f n; // normal of a plane
math::Axis target_axis(axis()); // target axis
@@ -321,15 +324,17 @@ void Ship::frame(float seconds)
if (entity_state == core::Entity::Docked) {
- target_thrust = 0;
+ target_direction = 0;
target_pitch = 0;
target_roll = 0;
- target_direction = 0;
+ target_strafe = 0.0f;
+ target_vstrafe = 0.0f;
+
target_afterburner = 0.0f;
target_thrust = 0;
- entity_speed = 0;
entity_thrust = 0;
+ entity_speed = 0.0f;
} else if (entity_state == core::Entity::JumpInitiate) {
@@ -369,22 +374,26 @@ void Ship::frame(float seconds)
}
// control is disabled while the jumpdrive is activated
- target_thrust = 0;
+ target_direction = 0;
target_pitch = 0;
target_roll = 0;
- target_direction = 0;
+ target_strafe = 0.0f;
+ target_vstrafe = 0.0f;
+
target_afterburner = 0.0f;
- target_thrust = 0.1;
+ target_thrust = 0.1f;
} else if (entity_state == core::Entity::Jump) {
// control is disabled while the jumpdrive is activated
- target_thrust = 0;
+ target_direction = 0;
target_pitch = 0;
target_roll = 0;
- target_direction = 0;
+ target_strafe = 0.0f;
+ target_vstrafe = 0.0f;
+
target_afterburner = 0.0f;
- target_thrust = 0;
+ target_thrust = 0.0f;
// FIXME 5 second cooldown
entity_state = core::Entity::Normal;
@@ -469,11 +478,13 @@ void Ship::frame(float seconds)
}
} else if (entity_state == core::Entity::Destroyed) {
-
- target_thrust = 0;
+
+ target_direction = 0;
target_pitch = 0;
target_roll = 0;
- target_direction = 0;
+ target_strafe = 0.0f;
+ target_vstrafe = 0.0f;
+
target_afterburner = 0.0f;
target_thrust = 0;
@@ -523,6 +534,17 @@ void Ship::frame(float seconds)
if (current_target_strafe < target_strafe)
current_target_strafe = target_strafe;
}
+
+ // update vstrafe control target
+ if (current_target_vstrafe < target_vstrafe) {
+ current_target_vstrafe += strafe_reaction * seconds;
+ if (current_target_vstrafe > target_vstrafe)
+ current_target_vstrafe = target_vstrafe;
+ } else if (current_target_vstrafe > target_vstrafe) {
+ current_target_vstrafe -= strafe_reaction * seconds;
+ if (current_target_vstrafe < target_vstrafe)
+ current_target_vstrafe = target_vstrafe;
+ }
// update roll control target
if (current_target_roll < target_roll) {
@@ -581,6 +603,34 @@ void Ship::frame(float seconds)
current_target_pitch = 0.0f;
}
+ /*
+ // -- BULLET
+
+ // apply thrust
+ body()->applyCentralForce(math::to_btVector3(axis().forward() * (actual_thrust * actual_acceleration)));
+
+ // apply strafe
+ body()->applyCentralForce(math::to_btVector3(axis().left() * (current_target_strafe * 0.15f * actual_acceleration)));
+ body()->applyCentralForce(math::to_btVector3(axis().up() * (current_target_vstrafe * 0.15f * actual_acceleration)));
+
+ // FIXME get movement state from linear/angular velocity
+ entity_movement = target_thrust;
+ entity_movement = math::max(entity_movement, fabs(current_target_pitch));
+ entity_movement = math::max(entity_movement, fabs(current_target_direction));
+ entity_movement = math::max(entity_movement, fabs(current_target_roll));
+ entity_movement = math::max(entity_movement, fabs(current_target_afterburner));
+ entity_movement = math::max(entity_movement, fabs(current_target_strafe));
+ entity_movement = math::max(entity_movement, fabs(current_target_vstrafe));
+
+ if (entity_movement > 0) {
+ set_dirty();
+ }
+
+ EntityDynamic::frame(seconds);
+ */
+ 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)) {
@@ -605,10 +655,17 @@ void Ship::frame(float seconds)
}
}
+ // apply strafe to location
if (fabs(current_target_strafe) > MIN_DELTA) {
get_location() += axis().left() * (current_target_strafe * 0.15f * actual_maxspeed) * seconds;
}
+
+ // apply vstrafe to location
+ if (fabs(current_target_vstrafe) > MIN_DELTA) {
+ get_location() += axis().up() * (current_target_vstrafe * 0.15f * actual_maxspeed) * seconds;
+ }
+ // apply speed to location
if (fabs(speed()) > MIN_DELTA) {
get_location() += axis().forward() * speed() * seconds;
}
@@ -619,6 +676,7 @@ void Ship::frame(float seconds)
entity_movement = math::max(entity_movement, fabs(current_target_roll));
entity_movement = math::max(entity_movement, fabs(current_target_afterburner));
entity_movement = math::max(entity_movement, fabs(current_target_strafe));
+ entity_movement = math::max(entity_movement, fabs(current_target_vstrafe));
if ((entity_movement > 0) || (entity_speed > 0)) {
set_dirty();