Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-04-27 13:08:12 +0000
committerStijn Buys <ingar@osirion.org>2008-04-27 13:08:12 +0000
commita4b36e6d1e20b5036d1ed7cf9f61a48dbbf77812 (patch)
tree7efd0048fd8c10b1f04d427c78e3ac8da402f059
parentfe95954f9d17c9dade1827fe5d4cf8cffffddbce (diff)
3D flight
-rw-r--r--src/client/camera.cc40
-rw-r--r--src/client/input.cc101
-rw-r--r--src/client/view.cc7
-rw-r--r--src/core/entity.cc26
-rw-r--r--src/core/entity.h35
-rw-r--r--src/game/game.cc7
-rw-r--r--src/game/ship.cc26
-rw-r--r--src/math/Makefile.am6
-rw-r--r--src/math/axis.cc59
-rw-r--r--src/math/axis.h27
-rw-r--r--src/math/color.h7
-rw-r--r--src/math/mathlib.h7
-rw-r--r--src/math/matrix4f.cc79
-rw-r--r--src/math/matrix4f.h58
-rw-r--r--src/math/vector3f.cc2
-rw-r--r--src/math/vector3f.h4
-rw-r--r--src/render/draw.cc55
-rw-r--r--src/render/gl.cc19
-rw-r--r--src/render/gl.h8
19 files changed, 474 insertions, 99 deletions
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 <iostream>
@@ -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 <cmath>
+
+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 <iostream>
+
+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 <GL/glu.h>
#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
*/