From a4b36e6d1e20b5036d1ed7cf9f61a48dbbf77812 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 27 Apr 2008 13:08:12 +0000 Subject: 3D flight --- src/client/camera.cc | 40 ++++++++++++++++---- src/client/input.cc | 101 ++++++++++++++++++++++++++++++++++++++------------- src/client/view.cc | 7 +++- src/core/entity.cc | 26 +++++++++---- src/core/entity.h | 35 +++++++++++------- src/game/game.cc | 7 +++- src/game/ship.cc | 26 ++++++++----- src/math/Makefile.am | 6 ++- src/math/axis.cc | 59 +++++++++++++++++++++++++----- src/math/axis.h | 27 ++++++++++---- src/math/color.h | 7 +++- src/math/mathlib.h | 7 ++-- src/math/matrix4f.cc | 79 ++++++++++++++++++++++++++++++++++++++++ src/math/matrix4f.h | 58 +++++++++++++++++++++++++++++ src/math/vector3f.cc | 2 +- src/math/vector3f.h | 4 ++ src/render/draw.cc | 55 ++++++++++++++++++++++++++-- src/render/gl.cc | 19 ++++++++-- src/render/gl.h | 8 ++++ 19 files changed, 474 insertions(+), 99 deletions(-) create mode 100644 src/math/matrix4f.cc create mode 100644 src/math/matrix4f.h diff --git a/src/client/camera.cc b/src/client/camera.cc index 754cbad..585aafc 100644 --- a/src/client/camera.cc +++ b/src/client/camera.cc @@ -5,6 +5,7 @@ */ #include "math/mathlib.h" +#include "math/matrix4f.h" #include "core/core.h" #include "client/client.h" #include "client/camera.h" @@ -84,7 +85,9 @@ void set_mode(Mode newmode) { case Track: // switch camera to Track mode mode = Track; - yaw_target = core::localcontrol()->direction(); + // FIXME + //yaw_target = core::localcontrol()->direction(); + yaw_target = 0; yaw_current = yaw_target; pitch_target = pitch_track; pitch_current = pitch_target; @@ -93,7 +96,9 @@ void set_mode(Mode newmode) { case Free: // switch camera to Free mode mode = Free; - yaw_target = core::localcontrol()->direction(); + // FIXME + //yaw_target = core::localcontrol()->direction(); + yaw_target = 0; yaw_current = yaw_target; pitch_target = pitch_track; pitch_current = pitch_target; @@ -150,7 +155,9 @@ void draw(float elapsed) } if (mode == Track) { - yaw_target = core::localcontrol()->direction(); + // FIXME + //yaw_target = core::localcontrol()->direction(); + yaw_target = 0; } if ((mode == Free) || (mode == Track)) { @@ -167,21 +174,40 @@ void draw(float elapsed) gl::rotate(90.0f, 0, 1.0, 0); gl::rotate(-90.0f, 1.0f , 0, 0); + math::Matrix4f matrix; + // map camera coordinates to opengl coordinates switch (mode) { case Free: case Track: if (core::localcontrol()->model()) - distance = core::localcontrol()->model()->radius(); + distance = 1+core::localcontrol()->model()->radius(); else - distance = 0.5f; - + distance = 1.5f; + + target = core::localcontrol()->location(); + matrix = core::localcontrol()->axis(); + + // apply the transpose of the axis transformation (the axis is orhtonormal) + gl::multmatrix(matrix.transpose()); + + // match the camera with the current target + gl::translate(-1.0f * target); + + // draw the local camera transformation + gl::translate(distance * core::localcontrol()->axis().forward()); + gl::translate((distance-1)/-2.0f * core::localcontrol()->axis().up()); + + /* // draw the camera transformation gl::translate(0.0f, 0.0f, -3*distance/4); gl::translate(1.2+distance, 0.0f, 0.0f); gl::rotate(-pitch_current, 0.0f, 1.0f, 0.0f); gl::rotate(-yaw_current, 0.0f, 0.0f, 1.0f); - gl::translate(-1*target); + */ + + // reposition, the engine will draw relative to 0,0,0 + //gl::translate(-1 * target); break; case Overview: diff --git a/src/client/input.cc b/src/client/input.cc index 8d80a21..994e38b 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -26,6 +26,8 @@ namespace input // local offset to make turns float local_turn = 0.0f; +// local offset to change pitch +float local_pitch = 0.0f; // local thrust setting float local_thrust = 0.0f; @@ -39,6 +41,8 @@ int mouse_y = 0; // true if the mouse is in the deadzone bool mouse_deadzone = false; +const float thruster_offset = 0.05f; + void init() { con_print << "Initializing input..." << std::endl; @@ -60,9 +64,27 @@ void shutdown() void keyreleased(const SDL_keysym &keysym) { switch (keysym.sym) { + case SDLK_SPACE: camera::next_mode(); break; + + case SDLK_KP8: // down + local_pitch = 0.0f; + break; + + case SDLK_KP2: // up + local_pitch = 0.0f; + break; + + case SDLK_KP4: // left + local_turn = 0.0f; + break; + + case SDLK_KP6: // right + local_turn = 0.0f; + break; + default: break; } @@ -86,25 +108,37 @@ void keypressed(const SDL_keysym &keysym) case SDLK_DOWN: camera::key_down(); break; + case SDLK_KP_PLUS: - local_thrust += 0.015f; - if (local_thrust > 1.0f) - local_thrust = 1.0f; + local_thrust += thruster_offset; break; + case SDLK_KP_MINUS: - // TODO set core entity params - local_thrust -= 0.020f; - if (local_thrust < 0.0f) - local_thrust = 0.0f; + local_thrust -= 2.0f * thruster_offset; break; - case SDLK_KP4: - // TODO set core entity params - local_turn += 0.05; + + case SDLK_KP8: // down + local_pitch = -1.0f; break; - case SDLK_KP6: - // TODO set core entity params - local_turn -= 0.05; + + case SDLK_KP2: // up + local_pitch = 1.0f; + break; + + case SDLK_KP4: // left + local_turn = 1.0f; break; + + case SDLK_KP6: // right + local_turn = -1.0f; + break; + + case SDLK_KP5: + local_turn = 0; + local_pitch = 0; + break; + + default: break; } @@ -118,16 +152,11 @@ void mousebuttonpressed(const SDL_MouseButtonEvent &button) { switch (button.button) { case SDL_BUTTON_WHEELUP: - local_thrust += 0.015f; - if (local_thrust > 1.0f) - local_thrust = 1.0f; - + local_thrust += thruster_offset; break; - case SDL_BUTTON_WHEELDOWN: - local_thrust -= 0.02f; - if (local_thrust < 0.0f) - local_thrust = 0.0f; + case SDL_BUTTON_WHEELDOWN: + local_thrust -= 2.0f * thruster_offset; break; } } @@ -199,19 +228,40 @@ void frame(float seconds) if (!console::visible() && core::application()->connected() && core::localcontrol()) { + if (local_thrust > 1.0f) + local_thrust = 1.0f; + else if (local_thrust < -2.0 * thruster_offset) + local_thrust = -2.0 * thruster_offset; + if (camera::mode == camera::Track && cl_mousecontrol->value()) { // mouse control when camera is in tracking mode + int deadzone_size = 24; + mouse_deadzone = true; + + // direction int l = mouse_x - (video::width >> 1); - if (abs(l) < ( CHARWIDTH >> 1 )) { + if (abs(l) < ( deadzone_size >> 1 )) { // dead zone local_turn = 0; - mouse_deadzone = true; } else { - l = (mouse_x - CHARWIDTH) - ((video::width - CHARWIDTH) >> 1); - local_turn = float (-l) / (float) ((video::width - CHARWIDTH) >> 1); + l = (mouse_x - deadzone_size) - ((video::width - deadzone_size) >> 1); + local_turn = float (-l) / (float) ((video::width - deadzone_size) >> 1); + mouse_deadzone = false; + } + + // pitch + int h = mouse_y - (video::height >> 1); + + if (abs(h) < ( deadzone_size >> 1 )) { + // dead zone + local_pitch = 0; + } else { + h = (mouse_y - deadzone_size) - ((video::height - deadzone_size) >> 1); + local_pitch = float (-h) / (float) ((video::height - deadzone_size) >> 1); mouse_deadzone = false; } + } else { if (local_turn > 1.0f) local_turn = 1.0f; @@ -222,6 +272,7 @@ void frame(float seconds) core::localcontrol()->set_thrust(local_thrust); core::localcontrol()->set_direction(local_turn); + core::localcontrol()->set_pitch(local_pitch); } } diff --git a/src/client/view.cc b/src/client/view.cc index 522526e..39cd351 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -184,8 +184,11 @@ void draw_status() // draw a basic HUD if (core::localcontrol()) { status.str(""); - status << " dir " << std::setfill('0') << std::setw(3) << roundf(core::localcontrol()->direction()) << - " speed " << std::setfill(' ') << std::setw(5) << std::fixed << std::setprecision(2) << core::localcontrol()->speed() << " - " << input::mouse_x << "+" << input::mouse_y; + status << "thrust " << std::setfill(' ') << std::setw(5) << std::fixed + << std::setprecision(2) << core::localcontrol()->thrust() << " "; + + status << "speed " << std::setfill(' ') << std::setw(5) << std::fixed + << std::setprecision(2) << core::localcontrol()->speed(); draw_text(CHARWIDTH, video::height - CHARHEIGHT -4, status); } diff --git a/src/core/entity.cc b/src/core/entity.cc index 1e90b2a..b3d58a3 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -91,7 +91,6 @@ Entity::Entity(unsigned int flags) : entity_moduletypeid = 0; entity_radius = 1.0f; - entity_direction = 0; entity_shape = Diamond; entity_created = true; @@ -118,7 +117,7 @@ Entity::Entity(std::istream & is) is >> entity_color; is >> s; // shape is >> entity_radius; - is >> entity_direction; + is >> entity_axis; entity_shape = (Shape) s ; char c; @@ -155,7 +154,7 @@ void Entity::serialize(std::ostream & os) const << entity_color << " " << entity_shape << " " << entity_radius << " " - << entity_direction << " " + << entity_axis << " " << "\"" << entity_name << "\" " << "\"" << entity_modelname << "\""; } @@ -207,9 +206,8 @@ void EntityDynamic::frame(float seconds) if (entity_speed == 0) return; - // location avoid sin/cos calculations - entity_location.x += cosf(entity_direction * M_PI / 180) * entity_speed * seconds; - entity_location.y += sinf(entity_direction * M_PI / 180) * entity_speed * seconds; + entity_location += entity_axis.forward() * entity_speed * seconds; + entity_dirty = true; } @@ -229,13 +227,13 @@ void EntityDynamic::recieve_client_update(std::istream &is) void EntityDynamic::serialize_server_update(std::ostream & os) const { - os << entity_location << " " << entity_direction << " " << entity_speed; + os << entity_location << " " << entity_axis << " " << entity_speed; } void EntityDynamic::recieve_server_update(std::istream &is) { is >> entity_location; - is >> entity_direction; + is >> entity_axis; is >> entity_speed; } @@ -335,6 +333,18 @@ void EntityControlable::set_direction(float direction) } } +void EntityControlable::set_pitch(float pitch) +{ + if ((flags() & Static) == Static) + return; + + if (target_pitch != pitch) { + target_pitch = pitch; + entity_dirty = true; + } +} + + /*----- EntityGlobe ------------------------------------------------ */ EntityGlobe::EntityGlobe(unsigned int flags) : diff --git a/src/core/entity.h b/src/core/entity.h index 20242a9..86b5ab3 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -15,6 +15,7 @@ class EntityControlable; #include "core/model.h" #include "core/player.h" +#include "math/axis.h" #include "math/mathlib.h" #include @@ -73,11 +74,11 @@ public: inline bool dirty() const { return entity_dirty; } /// entity location - inline math::Vector3f const & location() const { return entity_location; } - - /// direction the entity is facing, in degrees. - inline float direction() const { return entity_direction; } + inline math::Vector3f & location() { return entity_location; } + /// local coordinate system of the entity + inline math::Axis & axis() { return entity_axis; } + /// base color of the entity inline math::Color const & color() const { return entity_color; } @@ -129,18 +130,15 @@ public: static void list(); /* entity_ variables can be set by the module */ + math::Vector3f entity_location; + math::Axis entity_axis; + float entity_radius; std::string entity_name; std::string entity_modelname; Model *entity_model; - Shape entity_shape; - math::Vector3f entity_location; + Shape entity_shape; math::Color entity_color; - /* - * A direction of 0 degrees means the entity is looking - * along the positive X-axis. Positive angle is along the negative Z-axis. - */ - float entity_direction; unsigned int entity_moduletypeid; unsigned int entity_flags; @@ -200,7 +198,7 @@ public: /// runs one game frame for the entity /** * The default implementation will update the position() of the entity, - * determined by its speed() and direction() + * determined by its speed() and axis() */ virtual void frame(float seconds); @@ -251,10 +249,13 @@ public: virtual void recieve_server_update(std::istream &is); /// set the target thrust - void set_thrust(float t); + void set_thrust(float thrust); /// set the target direction - void set_direction(float t); + void set_direction(float direction); + + /// set the target pitch + void set_pitch(float pitch); /// runs one game frame for the entity /** @@ -273,7 +274,13 @@ public: /// target thrust as set by the client float target_thrust; /// target direction as set by the client + /** target_direction must be in the [-1, 1] range + */ float target_direction; + /// target pitch as set by the client + /** target_pitch must be in the [-1, 1] range + */ + float target_pitch; }; /// a Globe entity diff --git a/src/game/game.cc b/src/game/game.cc index 88718b4..07327d9 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -128,6 +128,8 @@ void Game::init() Star *star = 0; core::Entity *entity = 0; + float direction; + while (worldini.getline()) { if (worldini.got_key()) { if (worldini.section().compare("star") == 0) { @@ -163,9 +165,10 @@ void Game::init() continue; else if (worldini.got_key_string("model", entity->entity_modelname)) continue; - else if (worldini.got_key_angle("direction", entity->entity_direction)) + else if (worldini.got_key_angle("direction", direction)) { + entity->axis().change_direction(direction); continue; - else if (worldini.got_key_angle("radius", entity->entity_radius)) + } else if (worldini.got_key_angle("radius", entity->entity_radius)) continue; else if (worldini.got_key_vector3f("location", entity->entity_location)) continue; diff --git a/src/game/ship.cc b/src/game/ship.cc index 7c3d21d..af10525 100644 --- a/src/game/ship.cc +++ b/src/game/ship.cc @@ -37,9 +37,9 @@ void Ship::frame(float seconds) { // update thrust entity_thrust = target_thrust; - if (entity_thrust < 0) + if (entity_thrust < 0.0f) entity_thrust = 0.0f; - else if(entity_thrust > 1) + else if(entity_thrust > 1.0f) entity_thrust = 1.0f; // update direction @@ -48,9 +48,19 @@ void Ship::frame(float seconds) else if (target_direction < -1.0f) target_direction = -1.0f; - // turnspeed is rotations per second - float direction_offset = 360.0f * ship_shipmodel->turnspeed() * seconds * target_direction; - entity_direction = degrees360f(entity_direction + direction_offset); + float direction_offset = ship_shipmodel->turnspeed() * seconds * target_direction; + if (direction_offset) + entity_axis.change_direction(360.0f * direction_offset); + + // update pitch + if (target_pitch > 1.0f) + target_pitch = 1.0f; + else if (target_pitch < -1.0f) + target_pitch = -1.0f; + + float pitch_offset = ship_shipmodel->turnspeed() * seconds * target_pitch; + if (pitch_offset) + entity_axis.change_pitch(360.0f * pitch_offset); // update speed if (entity_speed < entity_thrust * ship_shipmodel->maxspeed()) { @@ -60,12 +70,10 @@ void Ship::frame(float seconds) } } else if(entity_speed > entity_thrust * ship_shipmodel->maxspeed()) { entity_speed -= ship_shipmodel->acceleration() * seconds; - if (entity_speed < 0) entity_speed = 0; + if (entity_speed < 0.0f) entity_speed = 0.0f; } - // location TODO avoid sin/cos calculations - entity_location.x += cosf(entity_direction * M_PI / 180) * entity_speed * seconds; - entity_location.y += sinf(entity_direction * M_PI / 180) * entity_speed * seconds; + entity_location += entity_axis.forward() * entity_speed * seconds; entity_dirty = true; } diff --git a/src/math/Makefile.am b/src/math/Makefile.am index 465f9b0..7ea7d66 100644 --- a/src/math/Makefile.am +++ b/src/math/Makefile.am @@ -1,9 +1,11 @@ METASOURCES = AUTO -libmath_la_SOURCES = axis.cc color.cc functions.cc plane3f.cc vector3f.cc +libmath_la_SOURCES = axis.cc color.cc functions.cc matrix4f.cc plane3f.cc \ + vector3f.cc libmath_la_LDFLAGS = -avoid-version -no-undefined -lm noinst_LTLIBRARIES = libmath.la -noinst_HEADERS = axis.h color.h functions.h mathlib.h plane3f.h vector3f.h +noinst_HEADERS = axis.h color.h functions.h mathlib.h matrix4f.h plane3f.h \ + vector3f.h INCLUDES = -I$(top_srcdir)/src diff --git a/src/math/axis.cc b/src/math/axis.cc index 7bd5262..cbca99b 100644 --- a/src/math/axis.cc +++ b/src/math/axis.cc @@ -6,6 +6,7 @@ // project headers #include "math/axis.h" +#include "math/mathlib.h" namespace math { @@ -37,18 +38,56 @@ Axis & Axis::operator=(const Axis & other) { return *this; } -// alter heading, rotate around Z-axis (positive is left) -void Axis::direction(const float angle) { - for (size_t i=0; i < 3; i++) { - //axis_vector[i].rotate(axis_vector[2], angle); - } +// change heading, rotate around Z-axis (positive is left) +void Axis::change_direction(const float angle) { + float cosa = cosf(angle * M_PI / 180.0f); + float sina = sinf(angle * M_PI / 180.0f); + + Vector3f forward = axis_vector[0] * cosa + axis_vector[1] * sina; + Vector3f left = axis_vector[1] *cosa - axis_vector[0] * sina; + + axis_vector[0].assign(forward); + axis_vector[1].assign(left); } -// alter heading, rotate around negative Y-axis (positive is up) -void Axis::pitch(const float pitch) { - for (size_t i=0; i < 3; i++) { - //axis_vector[i].rotate(axis_vector[1], -angle); - } +// change pitch, rotate around negative Y-axis (positive is up) +void Axis::change_pitch(const float angle) { + float cosa = cosf(angle * M_PI / 180.0f); + float sina = sinf(angle * M_PI / 180.0f); + + Vector3f forward = axis_vector[0] * cosa + axis_vector[2] * sina; + Vector3f up = axis_vector[2] * cosa - axis_vector[0] * sina; + + axis_vector[0].assign(forward); + axis_vector[2].assign(up); +} + +// change roll, rotate around forward vector (positive is left) +void Axis::change_roll(const float angle) { + float cosa = cosf(angle * M_PI / 180.0f); + float sina = sinf(angle * M_PI / 180.0f); + + Vector3f forward = axis_vector[2] * cosa + axis_vector[1] * sina; + Vector3f up = axis_vector[1] * cosa - axis_vector[2] * sina; + + axis_vector[2].assign(forward); + axis_vector[1].assign(up); +} + +// write an axis to a std::ostream +std::ostream &operator<<(std::ostream & os, Axis const & axis) +{ + os << axis.forward() << " " << axis.left() << " " << axis.up(); + return os; +} + +// read an axis from a std::istream +std::istream &operator>>(std::istream & is, Axis & axis) +{ + is >> axis[0]; + is >> axis[1]; + is >> axis[2]; + return is; } } diff --git a/src/math/axis.h b/src/math/axis.h index 73474ef..7e81d9a 100644 --- a/src/math/axis.h +++ b/src/math/axis.h @@ -25,28 +25,39 @@ public: void assign(const Axis & other); /// global coordinates of the X-axis in the local coordinates system - inline Vector3f const & forward() { return axis_vector[0]; } + inline Vector3f const & forward() const { return axis_vector[0]; } /// global coordinates of the Y-axis in the local coordinates system - inline Vector3f const & left() { return axis_vector[1]; } + inline Vector3f const & left() const { return axis_vector[1]; } /// global coordinates of the Z-axis in the local coordinates system - inline Vector3f const & up() { return axis_vector[2]; } + inline Vector3f const & up() const { return axis_vector[2]; } - inline Vector3f const operator[](size_t index) { return axis_vector[index]; } + inline Vector3f & operator[](size_t index) { return axis_vector[index]; } + + inline Vector3f const & operator[](size_t index) const { return axis_vector[index]; } Axis & operator=(const Axis & other); - /// alter heading, rotate around Z-axis (positive is left) - void direction(const float angle); + /// change direction, rotate around up vector (positive is left) + void change_direction(const float angle); + + /// change pitch, rotate around left vector (positive is up) + void change_pitch(const float angle); - /// alter heading, rotate around negative Y-axis (positive is up) - void pitch(const float angle); + /// change roll, rotate around forward vector (positive is left) + void change_roll(const float angle); private: Vector3f axis_vector[3]; }; +/// write an axis to a std::ostream +std::ostream &operator<<(std::ostream & os, Axis const & axis); + +/// read an axis from a std::istream +std::istream &operator>>(std::istream & is, Axis & axis); + } #endif // __INCLUDED_MATH_AXIS_H__ diff --git a/src/math/color.h b/src/math/color.h index 7fa0d68..0dd5fc8 100644 --- a/src/math/color.h +++ b/src/math/color.h @@ -46,7 +46,10 @@ public: /// multiply rgb values with scalar value. Color operator*(const float scalar) const; - /// clam color values to the 0-1 range + /// pointer to the internal data + inline float *ptr() const { return (float *) rgba_data; }; + + /// clamp color values to the 0-1 range void clamp(); float &r; @@ -54,6 +57,8 @@ public: float &b; float &a; + +private: float rgba_data[4]; }; diff --git a/src/math/mathlib.h b/src/math/mathlib.h index b76c562..77ccde5 100644 --- a/src/math/mathlib.h +++ b/src/math/mathlib.h @@ -4,8 +4,8 @@ the terms of the GNU General Public License version 2 */ -#ifndef __INCLUDED_MATH_H__ -#define __INCLUDED_MATH_H__ +#ifndef __INCLUDED_MATHLIB_H__ +#define __INCLUDED_MATHLIB_H__ /// this namespace contains mathematical classes and functions /** This is an independent library @@ -14,8 +14,9 @@ namespace math {} #include "math/vector3f.h" #include "math/plane3f.h" +#include "math/matrix4f.h" #include "math/color.h" #include "math/functions.h" -#endif // __INCLUDED_MATH_H__ +#endif // __INCLUDED_MATHLIB_H__ diff --git a/src/math/matrix4f.cc b/src/math/matrix4f.cc new file mode 100644 index 0000000..d73b12e --- /dev/null +++ b/src/math/matrix4f.cc @@ -0,0 +1,79 @@ +/* + math/matrix4f.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +// project headers +#include "math/matrix4f.h" + +// C++ headers +#include + +namespace math +{ + +Matrix4f::Matrix4f() +{ + clear(); +} + +Matrix4f::Matrix4f(const Matrix4f & other) +{ + assign(other); +} + +Matrix4f::Matrix4f(const Axis & axis) +{ + assign(axis); +} + +void Matrix4f::clear() +{ + memset(matrix, 0, sizeof(matrix)); +} + +void Matrix4f::unity() +{ + memset(matrix, 0, sizeof(matrix)); + for (int i=0; i <4; i++) + matrix[i][i] = 1; +} + +void Matrix4f::assign(const Matrix4f & other) +{ + memcpy(matrix, other.matrix, sizeof(matrix)); +} + +void Matrix4f::assign(const Axis & axis) +{ + memset(matrix, 0, sizeof(matrix)); + for (int i=0; i < 3; i++) { + memcpy(&matrix[i][0], axis[i].ptr(), sizeof(float) * 3); + } + matrix[3][3] = 1; +} + +Matrix4f & Matrix4f::operator=(const Matrix4f &other) +{ + assign(other); + return(*this); +} + +Matrix4f & Matrix4f::operator=(const Axis & axis) +{ + assign(axis); + return(*this); +} + +Matrix4f const Matrix4f::transpose() +{ + Matrix4f t; + + for (size_t i = 0; i < 4; i++) + for (size_t j = 0; j < 4; j++) + t.matrix[j][i] = matrix[i][j]; + return t; +} + +} diff --git a/src/math/matrix4f.h b/src/math/matrix4f.h new file mode 100644 index 0000000..0d7df90 --- /dev/null +++ b/src/math/matrix4f.h @@ -0,0 +1,58 @@ +/* + math/matrix4f.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_MATH_MATRIX4F_H__ +#define __INCLUDED_MATH_MATRIX4F_H__ + +// project headers +#include "math/axis.h" + +// C++ headers +#include + +namespace math +{ + +/// a transformation matrix +class Matrix4f +{ +public: + Matrix4f(); + Matrix4f(const Matrix4f & other); + Matrix4f(const Axis & axis); + + /// set all values to zero + void clear(); + + /// set the value to a 4x4 unity matrix + void unity(); + + /// assignment operator + void assign(const Matrix4f & other); + + /// assignment operator + inline Matrix4f & operator=(const Matrix4f &other); + + /// assign the matrix transformation equivalent to the coordinate system + void assign(const Axis & axis); + + /// assign the matrix transformation equivalent to the coordinate system + Matrix4f & operator=(const Axis & axis); + + /// return a pointer to the internal data + inline float * ptr() const { return (float *) matrix; } + + /// return the transpose matrix + Matrix4f const transpose(); + +private: + float matrix[4][4]; +}; + +} + +#endif // __INCLUDED_MATH_MATRIX4F_H__ + diff --git a/src/math/vector3f.cc b/src/math/vector3f.cc index 3d8e5ac..51d0385 100644 --- a/src/math/vector3f.cc +++ b/src/math/vector3f.cc @@ -1,5 +1,5 @@ /* - common/vector3f.cc + math/vector3f.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ diff --git a/src/math/vector3f.h b/src/math/vector3f.h index e94f4c7..ddb9e38 100644 --- a/src/math/vector3f.h +++ b/src/math/vector3f.h @@ -113,6 +113,9 @@ public: /// WARNING: vector must not be (0, 0, 0) void normalize(); + /// a pointer to the internal data + inline float *ptr() const { return (float *) coord; } + /* static functions */ /// Returns the unity vector on the X-axis @@ -136,6 +139,7 @@ public: float &y; float &z; +private: float coord[3]; }; diff --git a/src/render/draw.cc b/src/render/draw.cc index 4305b4d..e9976b6 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -276,7 +276,10 @@ void draw_pass_default() if (!entity->model()) { gl::push(); gl::translate(entity->location()); - gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + + // FIXME + //gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + gl::multmatrix(entity->axis()); if ((entity->flags() & core::Entity::Bright) == core::Entity::Bright) gl::disable(GL_LIGHTING); @@ -326,7 +329,9 @@ void draw_pass_model_vertex() if (test_draw_distance(entity)) { gl::push(); gl::translate(entity->location()); - gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + // FIXME + //gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + gl::multmatrix(entity->axis()); draw_model_vertex(entity); @@ -346,7 +351,9 @@ void draw_pass_model_evertex() if (test_draw_distance(entity)) { gl::push(); gl::translate(entity->location()); - gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + // FIXME + //gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + gl::multmatrix(entity->axis()); draw_model_evertex(entity); @@ -366,7 +373,9 @@ void draw_pass_model_fx() { gl::push(); gl::translate(entity->location()); - gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + // FIXME + //gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + gl::multmatrix(entity->axis()); draw_model_lights(entity); @@ -436,6 +445,42 @@ void draw_pass_spacegrid() gl::pop(); } +void draw_local_axis() +{ + if (!core::localcontrol()) + return; + + gl::push(); + gl::translate(core::localcontrol()->location()); + + gl::begin(gl::Lines); + gl::color(0.5f, 0.0f,0.0f); + gl::vertex(core::localcontrol()->axis()[0] * -1.0f); + gl::color(1.0f, 0.0f, 0.0f); + gl::vertex(core::localcontrol()->axis()[0]); + + gl::color(0.5f, 0.5f,0.0f); + gl::vertex(core::localcontrol()->axis()[1] * -1.0f); + gl::color(1.0f, 1.0f, 0.0f); + gl::vertex(0.0f, 0.0f, 0.0f); + + gl::color(0.5f, 0.5f,0.0f); + gl::vertex(core::localcontrol()->axis()[1]); + gl::color(1.0f, 1.0f, 0.0f); + gl::vertex(0.0f, 0.0f, 0.0f); + + gl::color(0.0f, 0.5f,0.0f); + gl::vertex(core::localcontrol()->axis()[2] * -1.0f); + gl::color(0.0f, 1.0f, 0.0f); + gl::vertex(0.0f, 0.0f, 0.0f); + + gl::color(0.0f, 0.5f,0.0f); + gl::vertex(core::localcontrol()->axis()[2]); + gl::color(0.0f, 1.0f, 0.0f); + gl::vertex(0.0f, 0.0f, 0.0f); + + gl::pop(); +} /* ----- Main draw routine ----------------------------------------- */ void draw(math::Vector3f const &eye, math::Vector3f const &target, float seconds) @@ -500,6 +545,8 @@ void draw(math::Vector3f const &eye, math::Vector3f const &target, float seconds gl::disable(GL_COLOR_MATERIAL); // disable color tracking gl::disable(GL_CULL_FACE); // disable culling + draw_local_axis(); + draw_pass_spacegrid(); // draw the blue spacegrid gl::disable(GL_DEPTH_TEST); // disable depth buffer writing diff --git a/src/render/gl.cc b/src/render/gl.cc index a5f2d99..37ff75f 100644 --- a/src/render/gl.cc +++ b/src/render/gl.cc @@ -7,6 +7,8 @@ #include "GL/gl.h" #include "render/gl.h" +#include "math/matrix4f.h" + using math::Vector3f; using math::Color; @@ -121,7 +123,7 @@ void scale(const float x, const float y, const float z) { } void vertex(const Vector3f& vector) { - glVertex3fv(vector.coord); + glVertex3fv(vector.ptr()); } void vertex(const float x, const float y, const float z) { @@ -129,7 +131,7 @@ void vertex(const float x, const float y, const float z) { } void normal(const Vector3f & vector) { - glNormal3fv(vector.coord); + glNormal3fv(vector.ptr()); } void normal(const float x, const float y, const float z) { @@ -144,11 +146,22 @@ void pop() { glPopMatrix(); } +void multmatrix(const math::Matrix4f & matrix) +{ + glMultMatrixf(matrix.ptr()); +} + +void multmatrix(const math::Axis & axis) +{ + math::Matrix4f matrix(axis); + glMultMatrixf(matrix.ptr()); +} + void color(const float r, const float g, const float b, const float a) { glColor4f(r,g,b,a); } void color(Color const & color) { - glColor4fv(color.rgba_data); + glColor4fv(color.ptr()); } void matrixmode(GLenum mode) { diff --git a/src/render/gl.h b/src/render/gl.h index 69eb412..4383e52 100644 --- a/src/render/gl.h +++ b/src/render/gl.h @@ -11,6 +11,8 @@ #include #include "math/vector3f.h" +#include "math/matrix4f.h" +#include "math/axis.h" #include "math/color.h" #ifdef _WIN32 @@ -146,6 +148,12 @@ namespace gl */ void scale(const float x, const float y, const float z); + /// multiply the current matrix with a coordinate system transformation + void multmatrix(const math::Axis & axis); + + /// multiply the current matrix with a 4x4 float matrix + void multmatrix(const math::Matrix4f & matrix); + /// specify the drawing color for the next GL functions /** @param color the new drawing color */ -- cgit v1.2.3