diff options
author | Stijn Buys <ingar@osirion.org> | 2010-10-18 19:13:58 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2010-10-18 19:13:58 +0000 |
commit | 4c5b00221c9405c5af06143974fbc6296ebe46b5 (patch) | |
tree | 3bbe7fbc47f6238a086260c56964d2d654cf6124 /src | |
parent | 85e3fd447aa3f45ba1dfe063b29a3e13f3416f11 (diff) |
local vstrafe support, initial ship collision, g_damping factor
Diffstat (limited to 'src')
-rw-r--r-- | src/client/input.cc | 2 | ||||
-rw-r--r-- | src/core/entity.cc | 106 | ||||
-rw-r--r-- | src/core/entity.h | 30 | ||||
-rw-r--r-- | src/core/physics.h | 1 | ||||
-rw-r--r-- | src/core/zone.cc | 11 | ||||
-rw-r--r-- | src/core/zone.h | 6 | ||||
-rw-r--r-- | src/game/base/cargopod.cc | 3 | ||||
-rw-r--r-- | src/game/base/game.cc | 14 | ||||
-rw-r--r-- | src/game/base/game.h | 8 | ||||
-rw-r--r-- | src/game/base/ship.cc | 96 |
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(); |