diff options
author | Stijn Buys <ingar@osirion.org> | 2010-10-17 17:19:03 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2010-10-17 17:19:03 +0000 |
commit | d6e4c4e7c2b1e28961f1dfe2f25ef96ced60b21b (patch) | |
tree | 63744dff093a8b23f65d9c68b922b678805647d9 /src | |
parent | ea6e6bb769d713ac55114c1940626f13e384ebed (diff) |
core bullet physics support,
initial vstrafe support
Diffstat (limited to 'src')
-rw-r--r-- | src/client/action.h | 1 | ||||
-rw-r--r-- | src/client/input.cc | 22 | ||||
-rw-r--r-- | src/client/keyboard.cc | 16 | ||||
-rw-r--r-- | src/core/Makefile.am | 73 | ||||
-rw-r--r-- | src/core/entity.cc | 127 | ||||
-rw-r--r-- | src/core/entity.h | 78 | ||||
-rw-r--r-- | src/core/gameserver.cc | 9 | ||||
-rw-r--r-- | src/core/physics.cc | 54 | ||||
-rw-r--r-- | src/core/physics.h | 53 | ||||
-rw-r--r-- | src/core/zone.cc | 36 | ||||
-rw-r--r-- | src/core/zone.h | 9 | ||||
-rw-r--r-- | src/game/base/cargo.cc | 1 | ||||
-rw-r--r-- | src/game/base/cargopod.cc | 5 | ||||
-rw-r--r-- | src/game/base/game.cc | 5 | ||||
-rw-r--r-- | src/game/base/ship.cc | 15 | ||||
-rw-r--r-- | src/game/base/ship.h | 3 | ||||
-rw-r--r-- | src/math/axis.cc | 9 | ||||
-rw-r--r-- | src/math/axis.h | 12 | ||||
-rw-r--r-- | src/math/vector3f.cc | 7 | ||||
-rw-r--r-- | src/math/vector3f.h | 11 | ||||
-rw-r--r-- | src/render/Makefile.am | 45 | ||||
-rw-r--r-- | src/render/debugdrawer.cc | 127 | ||||
-rw-r--r-- | src/render/debugdrawer.h | 54 | ||||
-rw-r--r-- | src/render/draw.cc | 37 | ||||
-rw-r--r-- | src/render/render.cc | 10 | ||||
-rw-r--r-- | src/render/render.h | 4 | ||||
-rw-r--r-- | src/sys/sys.h | 5 |
27 files changed, 749 insertions, 79 deletions
diff --git a/src/client/action.h b/src/client/action.h index 5d56bb9..6cb710b 100644 --- a/src/client/action.h +++ b/src/client/action.h @@ -25,6 +25,7 @@ public: Console, Left, Right, Up, Down, RollLeft, RollRight, + StrafeUp, StrafeDown, StrafeLeft, StrafeRight, ThrustUp, ThrustDown, Afterburner, Reverse, diff --git a/src/client/input.cc b/src/client/input.cc index 16ba048..d483f5d 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -52,6 +52,7 @@ float local_pitch = 0.0f; float local_thrust = 0.0f; float local_roll = 0.0f; float local_strafe = 0.0f; +float local_vstrafe = 0.0f; float local_afterburner = 0.0f; // last controlled entity @@ -375,7 +376,13 @@ void action_press(Key *key) case Action::StrafeRight: local_strafe = -1.0f; break; - + case Action::StrafeUp: + local_vstrafe = -1.0f; + break; + case Action::StrafeDown: + local_vstrafe = -1.0f; + break; + /* -- thruster ------------------------------------ */ case Action::ThrustUp: local_thrust += thruster_offset; @@ -456,6 +463,12 @@ void action_release(Key *key) case Action::StrafeRight: local_strafe = 0.0f; break; + case Action::StrafeUp: + local_vstrafe = 0.0f; + break; + case Action::StrafeDown: + local_vstrafe = 0.0f; + break; /* -- thruster ------------------------------------ */ case Action::ThrustUp: @@ -483,6 +496,8 @@ void action_release(Key *key) local_direction = 0.0f; local_pitch = 0.0f; local_roll = 0.0f; + local_vstrafe = 0.0f; + local_strafe = 0.0f; render::Camera::set_direction(0.0f); render::Camera::set_pitch(0.0f); @@ -660,6 +675,7 @@ void reset() local_direction = 0.0f; local_pitch = 0.0f; local_roll = 0.0f; + local_vstrafe = 0.0f; local_strafe = 0.0f; local_afterburner = 0.0f; @@ -897,6 +913,7 @@ void frame() core::localcontrol()->set_pitch(local_pitch / render::State::aspect()); core::localcontrol()->set_roll(local_roll); core::localcontrol()->set_strafe(local_strafe); + core::localcontrol()->set_vstrafe(local_vstrafe); core::localcontrol()->set_afterburner(local_afterburner); } else { @@ -904,6 +921,9 @@ void frame() local_direction = 0.0f; local_pitch = 0.0f; local_roll = 0.0f; + local_vstrafe = 0.0f; + local_strafe = 0.0f; + local_afterburner = 0.0f; render::Camera::set_direction(0.0f); render::Camera::set_pitch(0.0f); diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc index e617c59..176e310 100644 --- a/src/client/keyboard.cc +++ b/src/client/keyboard.cc @@ -54,6 +54,8 @@ Keyboard::Keyboard() add_action("+strafeleft", Action::StrafeLeft, "strafe left"); add_action("+straferight", Action::StrafeRight, "strafe right"); + add_action("+strafeup", Action::StrafeUp, "strafe up"); + add_action("+strafedown", Action::StrafeDown, "strafe down"); add_action("+afterburner", Action::Afterburner, "afterburner"); add_action("+reverse", Action::Reverse, "reverse engine"); @@ -112,11 +114,11 @@ Keyboard::Keyboard() add_key("`", SDLK_BACKQUOTE, '`', "+console"); add_key("a", SDLK_a, 'a', "+strafeleft"); - add_key("b", SDLK_b, 'b'); + add_key("b", SDLK_b, 'b', "beam"); add_key("c", SDLK_c, 'c'); add_key("d", SDLK_d, 'd', "+straferight"); add_key("e", SDLK_e, 'e', "+rollright"); - add_key("f", SDLK_f, 'f'); + add_key("f", SDLK_f, 'f', "+strafedown"); add_key("g", SDLK_g, 'g'); add_key("h", SDLK_h, 'h'); add_key("i", SDLK_i, 'i'); @@ -130,7 +132,7 @@ Keyboard::Keyboard() add_key("o", SDLK_o, 'o'); add_key("p", SDLK_p, 'p'); add_key("q", SDLK_q, 'q', "+rollleft"); - add_key("r", SDLK_r, 'r'); + add_key("r", SDLK_r, 'r', "+strafeup"); add_key("s", SDLK_s, 's', "+reverse"); add_key("t", SDLK_t, 't', "ui_chatbar"); add_key("u", SDLK_u, 'u'); @@ -280,16 +282,16 @@ void Keyboard::save_binds() for (it = begin(); it != end(); it++) { Key *key = (*it).second; if (key->bind(Key::None).size()) { - ofs << "bind " << key->name() << " " << key->bind(Key::None) << std::endl; + ofs << "bind " << key->name() << " \"" << key->bind(Key::None) << '\"' << std::endl; } if (key->bind(Key::Shift).size()) { - ofs << "bind shift+" << key->name() << " " << key->bind(Key::Shift) << std::endl; + ofs << "bind shift+" << key->name() << " \"" << key->bind(Key::Shift) << '\"' << std::endl; } if (key->bind(Key::Ctrl).size()) { - ofs << "bind ctrl+" << key->name() << " " << key->bind(Key::Ctrl) << std::endl; + ofs << "bind ctrl+" << key->name() << " \"" << key->bind(Key::Ctrl) << '\"' << std::endl; } if (key->bind(Key::Alt).size()) { - ofs << "bind alt+" << key->name() << " " << key->bind(Key::Alt) << std::endl; + ofs << "bind alt+" << key->name() << " \"" << key->bind(Key::Alt) << '\"' << std::endl; } /* } else { diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 6085085..7155f86 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -1,17 +1,72 @@ METASOURCES = AUTO INCLUDES = -I$(top_srcdir)/src -libcore_la_SOURCES = application.cc commandbuffer.cc core.cc cvar.cc \ - descriptions.cc entity.cc extension.cc func.cc gameconnection.cc gameinterface.cc \ - gameserver.cc info.cc item.cc inventory.cc label.cc loader.cc module.cc netclient.cc \ - netconnection.cc netplayer.cc netserver.cc parser.cc player.cc stats.cc timer.cc zone.cc +noinst_LTLIBRARIES = libcore.la + libcore_la_LDFLAGS = -avoid-version -no-undefined + libcore_la_LIBADD = $(top_builddir)/src/model/libmodel.la \ $(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/math/libmath.la $(top_builddir)/src/sys/libsys.la \ $(top_builddir)/src/auxiliary/libauxiliary.la -noinst_LTLIBRARIES = libcore.la -noinst_HEADERS = application.h commandbuffer.h core.h cvar.h entity.h func.h \ - gameconnection.h gameinterface.h gameserver.h label.h message.h module.h net.h netclient.h \ - netconnection.h netserver.h player.h range.h stats.h timer.h parser.h descriptions.h \ - extension.h loader.h info.h item.h inventory.h zone.h + +libcore_la_SOURCES = \ + application.cc \ + commandbuffer.cc \ + core.cc \ + cvar.cc \ + descriptions.cc \ + entity.cc \ + extension.cc \ + func.cc \ + gameconnection.cc \ + gameinterface.cc \ + gameserver.cc \ + info.cc \ + inventory.cc \ + item.cc \ + label.cc \ + loader.cc \ + module.cc \ + netclient.cc \ + netconnection.cc \ + netplayer.cc \ + netserver.cc \ + parser.cc \ + physics.cc \ + player.cc \ + stats.cc \ + timer.cc \ + zone.cc + +noinst_HEADERS = \ + application.h \ + commandbuffer.h \ + core.h \ + cvar.h \ + descriptions.h \ + entity.h \ + extension.h \ + func.h \ + gameconnection.h \ + gameinterface.h \ + gameserver.h \ + info.h \ + inventory.h \ + item.h \ + label.h \ + loader.h \ + message.h \ + module.h \ + netclient.h \ + netconnection.h \ + net.h \ + netplayer.h \ + netserver.h \ + parser.h \ + physics.h \ + player.h \ + range.h \ + stats.h \ + timer.h \ + zone.h 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) diff --git a/src/core/entity.h b/src/core/entity.h index 3ba2b0c..2719040 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -28,6 +28,7 @@ class EntityControlable; #include "core/descriptions.h" #include "core/inventory.h" #include "core/label.h" +#include "core/physics.h" #include "core/player.h" #include "core/zone.h" @@ -146,11 +147,30 @@ public: return entity_radius; } - /// current speed of the entity in game units per second + /** + * @brief current speed of the entity in game units per second + * For a normal entity, speed is always 0. Use the EntityDynamic + * and EntityControlable classes to create moving entities + */ inline const float speed() const { return entity_speed; } + /// mass of the entity + inline const float mass() const { + return entity_mass; + } + + /// physics body + inline btRigidBody *body() { + return entity_body; + } + + /// collision shape + inline btCollisionShape *collision_shape() { + return entity_collision_shape; + } + /// indicates a server-side entity inline const bool serverside() const { return entity_serverside; @@ -234,11 +254,6 @@ public: */ virtual void set_zone(Zone *zone); - /// current speed of the entity in game units per second - inline void set_speed(const float speed) { - entity_speed = speed; - } - /// set visibility inline void set_visible(const bool visible = true) { entity_visible = visible; @@ -259,10 +274,11 @@ public: inline void set_radius(const float radius) { entity_radius = radius; } - -/* ---- actors ---------------------------------------------------- */ + + /* ---- actors ---------------------------------------------------- */ /// called when the entity received a docking request + // FIXME move docking functions to game virtual void dock(Entity *entity); /// set flags @@ -275,6 +291,11 @@ public: entity_flags &= ~flag; } + /** + * @brief reset the physics state + */ + virtual void reset(); + /// add an entity menu void add_menu(MenuDescription *menu); @@ -318,7 +339,6 @@ public: /** * @brief mutable reference to the secondary color */ - inline math::Color& get_color_second() { return entity_color_second; } @@ -387,7 +407,7 @@ public: /* entity_ variables can be set by the module */ - /// speed of the entity + float entity_mass; float entity_speed; Shape entity_shape; unsigned int entity_moduletypeid; @@ -398,8 +418,11 @@ public: /// timestamp when entity data was received from the server float entity_servertimestamp; -private: +protected: + btRigidBody *entity_body; + btCollisionShape *entity_collision_shape; +private: unsigned int entity_id; unsigned int entity_flags; @@ -430,7 +453,7 @@ private: Info* entity_info; Extension* entity_extension[4]; - + static Registry entity_registry; static size_t entity_nextid; @@ -466,6 +489,27 @@ public: return entity_timer; } + inline btMotionState *motionstate() { + return entity_motionstate; + } + + /*----- mutators -------------------------------------------------- */ + + /// mass of the entity + inline void set_mass(const float mass) { + entity_mass = mass; + } + + /// current speed of the entity in game units per second + inline void set_speed(const float speed) { + entity_speed = speed; + } + + /** + * @brief reset the physics state + */ + virtual void reset(); + /*----- serializers ----------------------------------------------- */ /// serialize the entity to a stream @@ -501,6 +545,9 @@ public: protected: float entity_timer; int entity_state; + + btMotionState *entity_motionstate; + }; @@ -577,7 +624,10 @@ public: void set_roll(float roll); /// set target strafe - void set_strafe(float strage); + void set_strafe(float strafe); + + /// set target vertical strafe + void set_vstrafe(float vstrafe); /// set afterburner/reverse void set_afterburner(float afterburner); @@ -621,6 +671,8 @@ protected: float target_afterburner; float target_strafe; + + float target_vstrafe; float entity_movement; diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 31c6d42..597de33 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -14,6 +14,7 @@ #include "core/gameserver.h" #include "core/loader.h" #include "core/parser.h" +#include "core/physics.h" #include "core/netserver.h" #include "filesystem/filesystem.h" #include "sys/sys.h" @@ -130,6 +131,8 @@ GameServer::GameServer() : GameInterface() Parser::init(); + Physics::init(); + server_module = Loader::init(); if (!server_module) { @@ -228,8 +231,10 @@ GameServer::~GameServer() Func::remove("time"); Func::remove("who"); + Physics::done(); + Parser::done(); - + server_instance = 0; } @@ -490,6 +495,8 @@ void GameServer::frame(unsigned long timestamp) update_clientstate(); }*/ + Physics::frame(timestamp); + if ((Cvar::sv_dedicated->value() || Cvar::sv_private->value())) { if (core::Cvar::sv_framerate->value()) { float f = 1000.0f / core::Cvar::sv_framerate->value(); diff --git a/src/core/physics.cc b/src/core/physics.cc new file mode 100644 index 0000000..a8577b3 --- /dev/null +++ b/src/core/physics.cc @@ -0,0 +1,54 @@ +/* + core/physics.cc + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#include "core/physics.h" +#include "core/zone.h" + +namespace core { + +btDefaultCollisionConfiguration *Physics::physics_configuration; +btCollisionDispatcher *Physics::physics_dispatcher; +btSequentialImpulseConstraintSolver *Physics::physics_solver; +unsigned long Physics::physics_timestamp; + +void Physics::init() +{ + con_print << "^BInitializing physics engine..." << std::endl; + + physics_configuration = new btDefaultCollisionConfiguration(); + physics_dispatcher = new btCollisionDispatcher(physics_configuration); + physics_solver = new btSequentialImpulseConstraintSolver; + + physics_timestamp = 0; +} + +void Physics::done() +{ + con_print << "^Bshutting down physics engine..." << std::endl; + delete physics_solver; + delete physics_dispatcher; + delete physics_configuration; + + physics_configuration = 0; + physics_dispatcher = 0; + physics_solver = 0; +} + +void Physics::frame(const unsigned long timestamp) +{ + if (!timestamp) + return; + + const float seconds = (float) (timestamp - physics_timestamp) / 1000.0f; + + for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { + (*it).second->physics()->stepSimulation(seconds); + } + + physics_timestamp = timestamp; +} + +} // namespace core
\ No newline at end of file diff --git a/src/core/physics.h b/src/core/physics.h new file mode 100644 index 0000000..e565403 --- /dev/null +++ b/src/core/physics.h @@ -0,0 +1,53 @@ +/* + core/physics.h + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CORE_PHYSICS_H__ +#define __INCLUDED_CORE_PHYSICS_H__ + +#include "sys/sys.h" +#include "math/vector3f.h" +#include "math/axis.h" + +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionShapes/btTriangleMesh.h" +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/Gimpact/btGImpactShape.h" + +namespace core +{ + +class Physics { +public: + static void init(); + + static void done(); + + static void frame(const unsigned long timestamp); + + inline static btDefaultCollisionConfiguration *configuration() { + return physics_configuration; + } + + inline static btCollisionDispatcher *dispatcher() { + return physics_dispatcher; + } + + inline static btSequentialImpulseConstraintSolver *solver() { + return physics_solver; + } + +private: + static btDefaultCollisionConfiguration *physics_configuration; + static btCollisionDispatcher *physics_dispatcher; + static btSequentialImpulseConstraintSolver *physics_solver; + + static unsigned long physics_timestamp; +}; + +} // namespace core + +#endif // __INCLUDED_CORE_PHYSICS_H__ + diff --git a/src/core/zone.cc b/src/core/zone.cc index 3791b93..8a8c056 100644 --- a/src/core/zone.cc +++ b/src/core/zone.cc @@ -116,27 +116,46 @@ void Zone ::clear() } /* ---- class Zone ------------------------------------------------- */ -Zone::Zone(std::string const & label) +Zone::Zone(std::string const & label) : Label(label) { - zone_id = 0; - zone_sky.clear(); + zone_id = 0; zone_defaultview = 0; - set_label(label); + btVector3 worldAabbMin(-10000, -10000, -10000); + btVector3 worldAabbMax(10000, 10000, 10000); + const int maxProxies = 1024; + + zone_bullet_cache = new btAxisSweep3(worldAabbMin, worldAabbMax, maxProxies); + zone_bullet_world = new btDiscreteDynamicsWorld(Physics::dispatcher(), zone_bullet_cache, Physics::solver(), Physics::configuration()); + + // disable gravity + zone_bullet_world->setGravity(btVector3(0.0f, 0.0f, 0.0f)); + } -Zone::Zone(std::istream & is) +Zone::Zone(std::istream & is) : Label() { zone_id = 0; + zone_defaultview = 0; + // client side does not setup a bullet physics environment + zone_bullet_cache = 0; + zone_bullet_world = 0; receive_server_update(is); } Zone::~Zone() { for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) { + (*it) = 0; } zone_content.clear(); + + if (zone_bullet_world) + delete zone_bullet_world; + + if (zone_bullet_cache) + delete zone_bullet_cache; } void Zone::print() @@ -153,12 +172,19 @@ 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 38a9298..f040939 100644 --- a/src/core/zone.h +++ b/src/core/zone.h @@ -19,6 +19,7 @@ class Zone; } #include "core/entity.h" +#include "core/physics.h" namespace core { @@ -140,6 +141,11 @@ public: /// remove an entity from this zone void remove(Entity *entity); + /// physics world for this zone + inline btDiscreteDynamicsWorld *physics() { + return zone_bullet_world; + } + private: unsigned int zone_id; @@ -149,6 +155,9 @@ private: static Registry zone_registry; Entity *zone_defaultview; + + btAxisSweep3 *zone_bullet_cache; + btDiscreteDynamicsWorld *zone_bullet_world; }; } diff --git a/src/game/base/cargo.cc b/src/game/base/cargo.cc index 1a933e8..daf4ac2 100644 --- a/src/game/base/cargo.cc +++ b/src/game/base/cargo.cc @@ -374,6 +374,7 @@ void Cargo::eject(core::EntityControlable *ejector, const int amount) ejector->owner()->send(msgstr.str()); ejector->owner()->sound("game/eject"); } + pod->reset(); } void Cargo::list() diff --git a/src/game/base/cargopod.cc b/src/game/base/cargopod.cc index a3b44bf..b6d2123 100644 --- a/src/game/base/cargopod.cc +++ b/src/game/base/cargopod.cc @@ -18,6 +18,11 @@ CargoPod::CargoPod() : EntityDynamic() // FIXME hardcoded modelname set_modelname("maps/cargo/pod"); + + set_mass(radius()); + + // activate physics + reset(); } CargoPod::~CargoPod() diff --git a/src/game/base/game.cc b/src/game/base/game.cc index 3c84d58..c0ef4ce 100644 --- a/src/game/base/game.cc +++ b/src/game/base/game.cc @@ -604,7 +604,7 @@ void Game::func_launch(core::Player *player, std::string const &args) ship->get_axis().assign(dock->axis()); ship->set_state(core::Entity::Normal); - ship->set_state(core::Entity::Jump); + ship->reset(); player->set_view(0); player->send("^BLaunching from " + dock->name()); @@ -671,8 +671,7 @@ void Game::func_goto(core::Player *player, const std::string &args) ship->get_axis().assign(dock->axis()); ship->get_axis().change_direction(180.0f); ship->set_state(core::Entity::Normal); - - ship->set_state(core::Entity::Jump); + ship->reset(); player->set_view(0); player->send("Going to " + dock->name()); diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index a588122..d7d6b59 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -76,6 +76,8 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) : core::EntityControlable( set_flag(core::Entity::Dockable); } + + set_mass(radius()); reset(); } @@ -89,7 +91,10 @@ void Ship::reset() current_target_pitch = 0.0f;; current_target_roll = 0.0f; current_target_strafe = 0.0f; + current_target_vstrafe = 0.0f; current_target_afterburner = 0.0f; + + EntityControlable::reset(); } // this is called if another shuo wants to dock this ship @@ -617,6 +622,16 @@ void Ship::frame(float seconds) if ((entity_movement > 0) || (entity_speed > 0)) { set_dirty(); } + + // transfer entity location to motion state + btTransform t; + t.setIdentity(); + t.setOrigin(math::to_btVector3(location())); + t.setBasis(math::to_btMatrix3x3(axis())); + entity_body->setWorldTransform(t); + + if (zone()) + zone()->physics()->synchronizeSingleMotionState(entity_body); } } // namespace game diff --git a/src/game/base/ship.h b/src/game/base/ship.h index 1114df2..1f4f743 100644 --- a/src/game/base/ship.h +++ b/src/game/base/ship.h @@ -40,7 +40,7 @@ public: void initiate_jump(JumpPoint *depart); /// void reset drive controls - void reset(); + virtual void reset(); /// explode the ship void explode(); @@ -62,6 +62,7 @@ private: float current_target_pitch; float current_target_roll; float current_target_strafe; + float current_target_vstrafe; float current_target_afterburner; bool ship_jumpdrive; diff --git a/src/math/axis.cc b/src/math/axis.cc index 8273469..7281047 100644 --- a/src/math/axis.cc +++ b/src/math/axis.cc @@ -35,6 +35,15 @@ void Axis::assign(const Axis & other) } } +void Axis::assign(const btMatrix3x3 & other) +{ + for (size_t i = 0; i < 3; i++) { + for (size_t j = 0; j < 3; j++) { + axis_vector[i][j] = other[i][j]; + } + } +} + Axis & Axis::operator=(const Axis & other) { assign(other); diff --git a/src/math/axis.h b/src/math/axis.h index c22568c..d3a5ec6 100644 --- a/src/math/axis.h +++ b/src/math/axis.h @@ -10,7 +10,7 @@ #include <iostream> #include "math/vector3f.h" - +#include "LinearMath/btMatrix3x3.h" namespace math { @@ -24,6 +24,8 @@ public: void clear(); void assign(const Axis & other); + + void assign(const btMatrix3x3 & other); /// global coordinates of the X-axis in the local coordinates system inline const Vector3f & forward() const { @@ -86,6 +88,14 @@ private: Vector3f axis_vector[3]; }; +/// helper function to conver math::Axis to btMatrix3x3 +inline btMatrix3x3 to_btMatrix3x3(const math::Axis &a) +{ + return btMatrix3x3(a[0][0], a[0][1], a[0][2], + a[1][0], a[1][1], a[1][2], + a[2][0], a[2][1], a[2][2]); +} + /// write an axis to a std::ostream std::ostream &operator<<(std::ostream & os, const Axis & axis); diff --git a/src/math/vector3f.cc b/src/math/vector3f.cc index 4594665..421d84e 100644 --- a/src/math/vector3f.cc +++ b/src/math/vector3f.cc @@ -48,6 +48,13 @@ void Vector3f::assign(const Vector3f & other) memcpy(coord, other.coord, sizeof(coord)); } +void Vector3f::assign(const btVector3 & other) +{ + for (size_t i = 0; i < 3; i++) { + coord[i] = other[i]; + } +} + Vector3f & Vector3f::operator=(const Vector3f & other) { assign(other); diff --git a/src/math/vector3f.h b/src/math/vector3f.h index 09e6e84..a7437aa 100644 --- a/src/math/vector3f.h +++ b/src/math/vector3f.h @@ -10,6 +10,8 @@ #include <iostream> #include "math/vector3f.h" +#include "LinearMath/btVector3.h" + namespace math { @@ -49,6 +51,9 @@ public: /// assignment void assign(const Vector3f & other); + + /// assign bullet btVector3 value + void assign(const btVector3 & other); /// assignment operator Vector3f& operator=(const Vector3f &other); @@ -214,6 +219,12 @@ float distance(const Vector3f& first, const Vector3f& second); /// distance between two vectors squared float distancesquared(const Vector3f& first, const Vector3f& second); +/// helper function to convert Vector3f to btVector3 +inline btVector3 to_btVector3(const math::Vector3f & v) +{ + return btVector3(v[0], v[1], v[2]); +} + } // namespace math #endif // __INCLUDED_MATH_VECTOR3F_H__ diff --git a/src/render/Makefile.am b/src/render/Makefile.am index 4636250..4389805 100644 --- a/src/render/Makefile.am +++ b/src/render/Makefile.am @@ -8,10 +8,43 @@ noinst_LTLIBRARIES = librender.la endif librender_la_LDFLAGS = -avoid-version -no-undefined @GL_LIBS@ + librender_la_LIBADD = $(top_builddir)/src/math/libmath.la -librender_la_SOURCES = camera.cc draw.cc dust.cc gl.cc image.cc jpgfile.cc \ - particles.cc pngfile.cc render.cc renderext.cc screenshot.cc sky.cc \ - state.cc text.cc textures.cc tgafile.cc -noinst_HEADERS = camera.h draw.h dust.h gl.h image.h jpgfile.h \ - particles.h pngfile.h render.h renderext.h screenshot.h sky.h \ - state.h text.h textures.h tgafile.h + +librender_la_SOURCES = \ + camera.cc \ + debugdrawer.cc \ + draw.cc \ + dust.cc \ + gl.cc \ + image.cc \ + jpgfile.cc \ + particles.cc \ + pngfile.cc \ + render.cc \ + renderext.cc \ + screenshot.cc \ + sky.cc \ + state.cc \ + text.cc \ + textures.cc \ + tgafile.cc + +noinst_HEADERS = \ + camera.h \ + debugdrawer.h \ + draw.h \ + dust.h \ + gl.h \ + image.h \ + jpgfile.h \ + particles.h \ + pngfile.h \ + render.h \ + renderext.h \ + screenshot.h \ + sky.h \ + state.h \ + text.h \ + textures.h \ + tgafile.h diff --git a/src/render/debugdrawer.cc b/src/render/debugdrawer.cc new file mode 100644 index 0000000..03d5746 --- /dev/null +++ b/src/render/debugdrawer.cc @@ -0,0 +1,127 @@ +/* + render/debugdrawer.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "render/debugdrawer.h" +#include "render/gl.h" +#include "sys/sys.h" + +namespace render { + +DebugDrawer bullet_debugdrawer; + +DebugDrawer::DebugDrawer() +{ + debugdrawer_debugmode = btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawConstraints; +} + +DebugDrawer::~DebugDrawer() +{ +} + +void DebugDrawer::drawLine(const btVector3& from, const btVector3& to,const btVector3& color) +{ + gl::vertex(from[0], from[1], from[2]); + gl::vertex(to[0], to[1], to[2]); +} + +void DebugDrawer::drawLine(const btVector3& from, const btVector3 & to, const btVector3 & fromColor, const btVector3 & toColor) +{ + gl::vertex(from[0], from[1], from[2]); + gl::vertex(to[0], to[1], to[2]); +} + +void DebugDrawer::drawContactPoint(const btVector3 & point, const btVector3 & normal, btScalar distance , int lifetime, const btVector3 & color) +{ + +} + +void DebugDrawer::drawSphere(btScalar radius, const btTransform & transform, const btVector3 & color) +{ + btVector3 start = transform.getOrigin(); + + const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0); + const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0); + const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius); + + // XY + drawLine(start-xoffs, start+yoffs, color); + drawLine(start+yoffs, start+xoffs, color); + drawLine(start+xoffs, start-yoffs, color); + drawLine(start-yoffs, start-xoffs, color); + + // XZ + drawLine(start-xoffs, start+zoffs, color); + drawLine(start+zoffs, start+xoffs, color); + drawLine(start+xoffs, start-zoffs, color); + drawLine(start-zoffs, start-xoffs, color); + + // YZ + drawLine(start-yoffs, start+zoffs, color); + drawLine(start+zoffs, start+yoffs, color); + drawLine(start+yoffs, start-zoffs, color); + drawLine(start-zoffs, start-yoffs, color); +} + +void DebugDrawer::drawSphere(const btVector3 & p, btScalar radius, const btVector3 & color) +{ + btTransform tr; + tr.setIdentity(); + tr.setOrigin(p); + drawSphere(radius,tr,color); +} + +void DebugDrawer::drawBox(const btVector3 & bbMin, const btVector3 & bbMax, const btVector3 & color) +{ + drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color); + drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMin[2]), color); + drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMin[2]), color); + drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMin[2]), color); + drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color); + drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color); + drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color); + drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color); + drawLine(btVector3(bbMin[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color); + drawLine(btVector3(bbMax[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color); + drawLine(btVector3(bbMax[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color); + drawLine(btVector3(bbMin[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color); +} + +void DebugDrawer::drawBox(const btVector3 & bbMin, const btVector3 & bbMax, const btTransform & trans, const btVector3 & color) +{ + drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color); + drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color); +} +void DebugDrawer::reportErrorWarning(const char *warningString) +{ + con_warn << warningString << std::endl; +} + +void DebugDrawer::draw3dText(const btVector3 &location, const char *textString) +{ +} + +void DebugDrawer::setDebugMode(int debugMode) +{ + debugdrawer_debugmode = debugMode; +} + +int DebugDrawer::getDebugMode() const +{ + return debugdrawer_debugmode; +} + + +} // namespace render
\ No newline at end of file diff --git a/src/render/debugdrawer.h b/src/render/debugdrawer.h new file mode 100644 index 0000000..a23cecc --- /dev/null +++ b/src/render/debugdrawer.h @@ -0,0 +1,54 @@ +/* + render/debugdrawer.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_RENDER_DEBUGDRAWER_H__ +#define __INCLUDED_RENDER_DEBUGDRAWER_H__ + +#include "LinearMath/btIDebugDraw.h" + +namespace render { + +/** + * @brief implementation for the bullet debug draw interface + * This class implements the bullet btIDebugDraw interface to + * render the world as seen by the bullet physics library + */ +class DebugDrawer: public btIDebugDraw +{ +public: + DebugDrawer(); + virtual ~DebugDrawer(); + + virtual void drawLine(const btVector3 & from, const btVector3 & to, const btVector3 & color); + + virtual void drawLine(const btVector3& from, const btVector3 & to, const btVector3 & fromColor, const btVector3 & toColor); + + virtual void drawContactPoint(const btVector3 & point, const btVector3 & normal, btScalar distance, int lifetime, const btVector3 & color); + + virtual void drawSphere(btScalar radius, const btTransform & transform, const btVector3 & color); + + virtual void drawSphere(const btVector3 & p, btScalar radius, const btVector3 & color); + + virtual void drawBox(const btVector3 & bbMin, const btVector3 & bbMax, const btVector3 & color); + + virtual void drawBox(const btVector3 & bbMin, const btVector3 & bbMax, const btTransform & trans, const btVector3 & color); + + virtual void reportErrorWarning(const char *warningString); + + virtual void draw3dText(const btVector3 &location, const char *textString); + + virtual void setDebugMode(int debugMode); + + virtual int getDebugMode() const; + +private: + int debugdrawer_debugmode; +}; + +extern DebugDrawer bullet_debugdrawer; +} // namespace render + +#endif // __INCLUDED_RENDER_DEBUGDRAWER_H__ diff --git a/src/render/draw.cc b/src/render/draw.cc index d54387a..656653b 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -15,6 +15,7 @@ #include "model/model.h" #include "render/render.h" #include "render/textures.h" +#include "render/debugdrawer.h" #include "render/draw.h" #include "render/dust.h" #include "render/gl.h" @@ -1206,12 +1207,17 @@ void draw(float seconds) glPolygonMode(GL_FRONT, GL_FILL); draw_pass_sky(); // draw the skybox + + gl::depthmask(GL_TRUE); // enable writing to the depth buffer + gl::enable(GL_DEPTH_TEST); + gl::enable(GL_CULL_FACE); // enable culling + gl::enable(GL_COLOR_MATERIAL); // enable color tracking // enable wireframe mode if requested if (r_wireframe && r_wireframe->value()) { glPolygonMode(GL_FRONT, GL_LINE); } - + // set vertex array pointers glInterleavedArrays(GL_T2F_N3F_V3F, 0, core::game()->vertexarray()->ptr()); @@ -1220,12 +1226,6 @@ void draw(float seconds) glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); - gl::depthmask(GL_TRUE); // enable writing to the depth buffer - gl::enable(GL_DEPTH_TEST); - - gl::enable(GL_CULL_FACE); // enable culling - gl::enable(GL_COLOR_MATERIAL); // enable color tracking - if (r_normalize && r_normalize->value()) { // enable full normalization gl::enable(GL_NORMALIZE); @@ -1248,7 +1248,7 @@ void draw(float seconds) // disable full normalization gl::disable(GL_NORMALIZE); } else { - // disable resaling of normals + // disable rescaling of normals gl::disable(GL_RESCALE_NORMAL); } @@ -1294,12 +1294,27 @@ void draw(float seconds) glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); - + gl::depthmask(GL_TRUE); // enable depth buffer writing + gl::disable(GL_DEPTH_TEST); // disable depth buffer testing + + // draw physics + if (r_physics && r_physics->value()) { + if (zone->physics()) { + if (!zone->physics()->getDebugDrawer()) + zone->physics()->setDebugDrawer(&bullet_debugdrawer); + + // draw physics bodies in red + gl::color(1.0f, 0.0f, 0.0f, 1.0f); + gl::begin(gl::Lines); + zone->physics()->debugDrawWorld(); + gl::end(); + } + } + gl::disable(GL_COLOR_MATERIAL); // disable color tracking gl::disable(GL_CULL_FACE); // disable culling - gl::depthmask(GL_TRUE); // enable depth buffer writing - gl::disable(GL_DEPTH_TEST); // disable depth buffer testing + // GL_BLEND must be enabled for the GUI } diff --git a/src/render/render.cc b/src/render/render.cc index acc9c86..398cb6b 100644 --- a/src/render/render.cc +++ b/src/render/render.cc @@ -36,7 +36,7 @@ core::Cvar *r_radius = 0; core::Cvar *r_sky = 0; core::Cvar *r_wireframe = 0; core::Cvar *r_mipmap = 0; -core::Cvar *r_collision = 0; +core::Cvar *r_physics = 0; core::Cvar *r_normals = 0; core::Cvar *r_normalize = 0; @@ -106,10 +106,10 @@ void init(int width, int height) r_specular = core::Cvar::get("r_specular", "0.2", core::Cvar::Archive); r_specular->set_info("[float] specular light intensity"); - /* - r_collision = core::Cvar::get("r_collision", "1", core::Cvar::Archive); - r_collision->set_info("[bool] render collision (server side only)"); - */ + + r_physics = core::Cvar::get("r_physics", "0", core::Cvar::Archive); + r_physics->set_info("[bool] render physics (local game only)"); + Screenshot::screenshotformat = core::Cvar::get("screenshotformat", "jpg", core::Cvar::Archive); Screenshot::screenshotformat->set_info("[string] screenshot format: jpg png tga"); diff --git a/src/render/render.h b/src/render/render.h index 190cdb5..5e5f3d1 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -56,8 +56,8 @@ extern core::Cvar *r_sky; extern core::Cvar *r_wireframe; /// render vertex normals extern core::Cvar *r_normals; -/// render collision -extern core::Cvar *r_collision; +/// render physics +extern core::Cvar *r_physics; /// use hardware generated mipmaps (requires OpenGL 1.4, does not work on all cards) extern core::Cvar *r_mipmap; /// use GL_NORMALIZE instead of GL_RESCALE_NORMAL diff --git a/src/sys/sys.h b/src/sys/sys.h index eb9d099..3d94bcb 100644 --- a/src/sys/sys.h +++ b/src/sys/sys.h @@ -9,11 +9,6 @@ #include "config.h" -// disable bullet for now -#ifdef HAVE_BULLET -#undef HAVE_BULLET -#endif - #include <string> /// maximum line size throught the game |