Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/camera.cc39
-rw-r--r--src/client/camera.h3
-rw-r--r--src/client/draw.cc4
-rw-r--r--src/client/input.cc9
-rw-r--r--src/game/game.cc29
-rw-r--r--src/game/ship.cc13
-rw-r--r--src/game/ship.h2
-rw-r--r--src/math/plane3f.h4
-rw-r--r--src/render/face.cc13
-rw-r--r--src/render/face.h6
-rw-r--r--src/render/model.cc280
-rw-r--r--src/render/model.h56
-rw-r--r--src/render/render.cc8
13 files changed, 314 insertions, 152 deletions
diff --git a/src/client/camera.cc b/src/client/camera.cc
index e8a6625..dd49aa6 100644
--- a/src/client/camera.cc
+++ b/src/client/camera.cc
@@ -25,6 +25,8 @@ namespace camera
// gameworld coordinates of the camera target
math::Vector3f target;
+// gameworld coordinates of the camera eye
+math::Vector3f eye;
// target yaw, angle in XZ plane, positive is looking left
float yaw_target;
@@ -168,18 +170,55 @@ void draw(float elapsed)
// map camera coordinates to opengl coordinates
switch (mode) {
case Free:
+ // calculate the position of the eye
+ eye.x = -distance-1;
+ eye.y = 0;
+ eye.z = distance/2;
+
+ eye.x = eye.z * sin(-pitch_current * M_1_PI * 0.5f) + eye.x * cos(-pitch_current * M_1_PI * 0.5f);
+ eye.y = eye.y;
+ eye.z = eye.z * sin(-pitch_current * M_1_PI * 0.5f) - eye.x * cos(-pitch_current * M_1_PI * 0.5f);
+
+ eye.x = eye.x * cos(-yaw_current * M_1_PI * 0.5f) - eye.y * sin(-yaw_current * M_1_PI * 0.5f);
+ eye.y = eye.x * sin(-yaw_current * M_1_PI * 0.5f) + eye.y * cos(-yaw_current * M_1_PI * 0.5f);
+ eye.z = eye.z;
+
+ eye = eye + target;
+
+ // draw the camera transformation
gl::translate(1.0f+distance, 0.0f, -distance/2);
gl::rotate(-pitch_current, 0, 1.0f, 0 );
gl::rotate(-yaw_current, 0, 0, 1.0f);
gl::translate(-1*target);
break;
+
case Track:
+ // calculate the position of the eye
+ eye.x = -distance-1;
+ eye.y = 0;
+ eye.z = distance;
+
+ eye.x = eye.z * sin(-pitch_current * M_1_PI * 0.5f) + eye.x * cos(-pitch_current * M_1_PI * 0.5f);
+ eye.y = eye.y;
+ eye.z = eye.z * sin(-pitch_current * M_1_PI * 0.5f) - eye.x * cos(-pitch_current * M_1_PI * 0.5f);
+
+ eye.x = eye.x * cos(-yaw_current * M_1_PI * 0.5f) - eye.y * sin(-yaw_current * M_1_PI * 0.5f);
+ eye.y = eye.x * sin(-yaw_current * M_1_PI * 0.5f) + eye.y * cos(-yaw_current * M_1_PI * 0.5f);
+ eye.z = eye.z;
+
+ eye = eye + target;
+
+ // draw the camera transformation
gl::translate(1.0f+distance, 0.0f, -distance);
gl::rotate(-pitch_current, 0, 1.0f, 0);
gl::rotate(-yaw_current, 0, 0, 1.0f);
gl::translate(-1*target);
break;
+
case Overview:
+ eye = target;
+ eye.z = eye.z + distance;
+
gl::rotate(-75.0f, 0.0f, 1.0f, 0.0f);
gl::translate(0.0f, 0.0f, -distance);
//gl::translate(x_offset, 0.0f, z_offset);
diff --git a/src/client/camera.h b/src/client/camera.h
index 93b44d1..08adfaa 100644
--- a/src/client/camera.h
+++ b/src/client/camera.h
@@ -44,6 +44,9 @@ namespace camera
/// gameworld coordinates of the camera target
extern math::Vector3f target;
+ /// gameworld coordinates of the camera eye
+ extern math::Vector3f eye;
+
} // namespace camera
} // namespace client
diff --git a/src/client/draw.cc b/src/client/draw.cc
index 91032a8..1ea315b 100644
--- a/src/client/draw.cc
+++ b/src/client/draw.cc
@@ -148,7 +148,7 @@ void draw_entity_default(core::Entity *entity)
render::gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f );
if (model) {
- model->draw(entity);
+ model->draw(entity, camera::eye);
} else {
switch(entity->shape()) {
case core::Entity::Sphere:
@@ -182,7 +182,7 @@ void draw_entity_controlable(core::EntityControlable *entity)
render::gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f );
if (model) {
- model->draw(entity);
+ model->draw(entity, camera::eye);
} else {
draw_ship(entity);
}
diff --git a/src/client/input.cc b/src/client/input.cc
index eda13fd..3b2db09 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -24,6 +24,8 @@ namespace input
float local_turn;
// local thrust setting
float local_thrust;
+// last controlled entity
+unsigned int last_control = 0;
void init()
{
@@ -103,6 +105,12 @@ void keypressed(const SDL_keysym &keysym)
void frame(float seconds)
{
+ if (core::localcontrol() && (last_control != core::localcontrol()->id())) {
+ local_turn = core::localcontrol()->direction();
+ local_thrust = core::localcontrol()->thrust();
+ last_control = core::localcontrol()->id();
+ }
+
SDL_Event event;
while (SDL_PollEvent(&event)) {
@@ -117,6 +125,7 @@ void frame(float seconds)
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == '`' || event.key.keysym.sym == '~') {
+ last_control = 0;
console::toggle();
setkeyboardmode(console::visible());
if (console::visible() && chat::visible())
diff --git a/src/game/game.cc b/src/game/game.cc
index 4aa505d..7dc342a 100644
--- a/src/game/game.cc
+++ b/src/game/game.cc
@@ -25,7 +25,7 @@ void func_join(core::Player *player, std::string const &args)
if (player->control())
return;
- player->player_control = new Ship(player);
+ player->player_control = new Ship(player, "micron_vector");
player->control()->entity_color = player->color();
std::string message(player->name());
@@ -54,6 +54,30 @@ void func_spectate(core::Player *player, std::string const &args)
player->player_dirty = true;
}
+/// a player buys a ship
+void func_buy(core::Player *player, std::string const &args)
+{
+ if (!player->control()) {
+ return;
+ }
+
+ std::string shipname;
+ std::istringstream is(args);
+ is >> shipname;
+ if ((shipname == "micron_vector") || (shipname == "canasta")) {
+ // player has only ship for now
+ player->player_control->die();
+ player->player_control = 0;
+
+ player->player_control = new Ship(player, shipname);
+ player->control()->entity_color = player->color();
+
+ core::server()->broadcast(player->name() + " purchased a " + shipname);
+ }
+ if (!shipname.size()) {
+ core::server()->send(player, "Usage: buy <micron_vector|canasta>");
+ }
+}
/*----- Game ------------------------------------------------------ */
Game::Game() : core::Module("Project::OSiRiON")
@@ -127,9 +151,10 @@ void Game::init()
axis->entity_name = "axis: Origin";
// add engine game functions
+ core::Func::add("buy", (core::GameFuncPtr) func_buy);
core::Func::add("join", (core::GameFuncPtr) func_join);
core::Func::add("spectate", (core::GameFuncPtr) func_spectate);
-
+
// add engine game variables
core::Cvar::set("g_borgcubes", "2", core::Cvar::Game);
core::Cvar::set("g_name", name().c_str(), core::Cvar::Game | core::Cvar::ReadOnly);
diff --git a/src/game/ship.cc b/src/game/ship.cc
index 37c8cd8..19cccbe 100644
--- a/src/game/ship.cc
+++ b/src/game/ship.cc
@@ -17,13 +17,20 @@ using math::degrees180f;
namespace game {
-Ship::Ship(core::Player *owner) :
+Ship::Ship(core::Player *owner, std::string const & model) :
core::EntityControlable(owner, ship_enttype)
{
// entity properties
- entity_name = "ship: <" + owner->name() + "> Micron Vector";
entity_owner = owner;
- entity_modelname = "ships/micron_vector";
+
+ // ship model
+ if (model.size()) {
+ entity_modelname = "ships/" + model;
+ entity_name = model + ": <" + owner->name() + ">";
+ } else {
+ entity_modelname = "ships/micron_vector";
+ entity_name = "micron_vector: <" + owner->name() + ">";
+ }
// ship specs
acceleration = 1.5f;
diff --git a/src/game/ship.h b/src/game/ship.h
index 1d0fdd4..88f42e5 100644
--- a/src/game/ship.h
+++ b/src/game/ship.h
@@ -17,7 +17,7 @@ namespace game {
class Ship : public core::EntityControlable
{
public:
- Ship(core::Player *owner);
+ Ship(core::Player *owner, std::string const & model);
~Ship();
/// update the ship state
diff --git a/src/math/plane3f.h b/src/math/plane3f.h
index ddaef16..02037d2 100644
--- a/src/math/plane3f.h
+++ b/src/math/plane3f.h
@@ -29,7 +29,8 @@ public:
/// the points defining the plane.
/// @param i 0 <= i < 3
inline Vector3f const & point(size_t i) const { return plane_point[i]; }
-
+ /// plane texture
+ inline std::string & texture() { return plane_texture; }
/// first parameter of the general equation
inline float a() const { return plane_normal[0]; }
/// second parameter of the general equation
@@ -42,6 +43,7 @@ public:
private:
Vector3f plane_point[3];
Vector3f plane_normal;
+ std::string plane_texture;
float pd;
};
diff --git a/src/render/face.cc b/src/render/face.cc
index cd69b4e..764c452 100644
--- a/src/render/face.cc
+++ b/src/render/face.cc
@@ -9,10 +9,15 @@
namespace render {
-Face::Face(math::Vector3f const & normal) :
+Face::Face(math::Vector3f const & normal, math::Color const *color) :
face_normal(normal)
{
face_normal.normalize();
+
+ if (color)
+ face_color = new math::Color(*color);
+ else
+ face_color = 0;
}
Face::~Face()
@@ -22,6 +27,9 @@ Face::~Face()
}
face_vertex.clear();
+
+ if (face_color)
+ delete face_color;
}
void Face::add_vertex(math::Vector3f const & vertex)
@@ -33,7 +41,8 @@ void Face::add_vertex(math::Vector3f const & vertex)
void Face::draw()
{
- gl::begin(gl::LineLoop);
+ //gl::begin(gl::LineLoop);
+ gl::begin(gl::Polygon);
for (std::vector<math::Vector3f *>::iterator it = face_vertex.begin(); it != face_vertex.end(); it++) {
gl::vertex(*(*it));
}
diff --git a/src/render/face.h b/src/render/face.h
index d44b1d0..a0a4d5a 100644
--- a/src/render/face.h
+++ b/src/render/face.h
@@ -16,12 +16,15 @@ namespace render {
/// one face (polygon) of a model
class Face {
public:
- Face(math::Vector3f const & normal);
+ Face(math::Vector3f const & normal, math::Color const *color=0);
~Face();
/// the normal of this face
inline math::Vector3f const & normal() const { return face_normal; };
+ /// the color of this face
+ inline math::Color const *color() const { return face_color; };
+
/// add a vertex to the face
void add_vertex(math::Vector3f const &vertex);
@@ -30,6 +33,7 @@ public:
private:
math::Vector3f face_normal;
+ math::Color *face_color;
std::vector<math::Vector3f *> face_vertex;
};
diff --git a/src/render/model.cc b/src/render/model.cc
index 907958a..70b5f18 100644
--- a/src/render/model.cc
+++ b/src/render/model.cc
@@ -1,7 +1,7 @@
/*
render/model.h
- This file is part of the Osirion project and is distributed under
- the terms of the GNU General Public License version 2
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
*/
#include <iostream>
@@ -23,57 +23,55 @@ const float MAX_BOUNDS = 8192;
const float delta = 10e-10;
Engine::Engine(math::Vector3f const & location) :
- engine_location(location)
-{
-}
+ engine_location(location)
+{}
Engine::~Engine()
-{
-}
+{}
std::map<std::string, Model*> Model::registry;
Model::Model(std::string const & name) :
- model_name(name)
+ model_name(name)
{
model_scale = 1.0f / 1024.0f;
-
+
std::string fn("maps/");
fn.append(name);
fn.append(".map");
filesystem::File *f = filesystem::open(fn.c_str());
-
+
if (!f) {
return;
}
-
+
fn = f->path();
fn.append(f->name());
filesystem::close(f);
-
+
std::ifstream ifs(fn.c_str());
if (!ifs.is_open()) {
con_warn << "Could not stream " << fn << "!\n";
return;
}
-
+
// --------- the actual reading
using math::Vector3f;
using math::Plane3f;
-
+
std::vector<Plane3f *> planes;
unsigned int level = 0;
char data[1024];
-
+
std::string class_name;
math::Vector3f class_origin;
float class_angle;
-
+
while (ifs) {
ifs.getline(data, 1023);
std::istringstream linestream(data);
std::string firstword;
-
+
if (linestream >> firstword) {
if (firstword == "//") {
//cout << " COMMENT!" << std::endl;
@@ -85,24 +83,24 @@ Model::Model(std::string const & name) :
//cout << " LEVEL -" << level << std::endl;
if ((level == 2) && (class_name == "worldspawn")) {
//cout << "brush with " << planes.size() << " faces" << std::endl;
-
+
// for every face
std::vector<Vector3f *>points;
for (std::vector<Plane3f *>::iterator face = planes.begin(); face != planes.end(); face++) {
make_face((*face), planes);
}
-
+
// clean planes
for (std::vector<Plane3f *>::iterator it = planes.begin(); it != planes.end(); it++) {
- delete (*it);
+ delete(*it);
}
planes.clear();
-
+
} else if ((level == 1) && (class_name == "target_engine")) {
//con_debug << " engine at " << class_origin << "\n";
add_engine(new Engine(class_origin * model_scale));
}
-
+
if (level == 1) {
class_angle = 0;
class_name.clear();
@@ -110,7 +108,7 @@ Model::Model(std::string const & name) :
}
level--;
-
+
} else if (firstword == "\"classname\"") {
class_name.clear();
if (linestream >> class_name) {
@@ -128,20 +126,20 @@ Model::Model(std::string const & name) :
} else if (firstword == "\"origin\"") {
std::string tmp;
char c;
- while ( (linestream.get(c)) && (c != '"'));
- while ( (linestream.get(c)) && (c != '"'))
+ while ((linestream.get(c)) && (c != '"'));
+ while ((linestream.get(c)) && (c != '"'))
tmp += c;
std::istringstream is(tmp);
is >> class_origin.x;
is >> class_origin.y;
is >> class_origin.z;
//con_debug << " origin '" << class_origin << "'" << std::endl;
-
+
} else if (firstword == "\"angle\"") {
std::string tmp;
char c;
- while ( (linestream.get(c)) && (c != '"'));
- while ( (linestream.get(c)) && (c != '"'))
+ while ((linestream.get(c)) && (c != '"'));
+ while ((linestream.get(c)) && (c != '"'))
tmp += c;
std::istringstream is(tmp);
is >> class_angle;
@@ -164,22 +162,23 @@ Model::Model(std::string const & name) :
linestream >> p3;
linestream >> tmp; // )
linestream >> texture;
-
+
//cout << data << std::endl;
//cout << "(" << p1 << ") (" << p2 << ") (" << p3 << ") " << texture << std::endl;
-
+
Plane3f *plane = new Plane3f(p1, p2, p3);
+ plane->texture() = texture;
planes.push_back(plane);
//cout << "normal " << plane->normal() << std::endl;
} else {
//cout << " UNKNOWN line for '" << classname << "' level " << level << std::endl;
}
- }
+ }
}
}
-
+
ifs.close();
-
+
con_debug << " maps/" << name << ".map " << model_face.size() << " polygons\n";
}
@@ -187,13 +186,13 @@ Model::~Model()
{
// delete all faces
for (std::list<Face *>::iterator fit = model_face.begin(); fit != model_face.end(); fit++) {
- delete (*fit);
+ delete(*fit);
}
model_face.clear();
-
+
// delete all engines
- for(std::list<Engine *>::iterator eit = model_engine.begin(); eit != model_engine.end(); eit++) {
- delete (*eit);
+ for (std::list<Engine *>::iterator eit = model_engine.begin(); eit != model_engine.end(); eit++) {
+ delete(*eit);
}
model_engine.clear();
}
@@ -202,16 +201,24 @@ void Model::make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes
{
using math::Vector3f;
using math::Plane3f;
-
+
+ // ignore caulk
+ if (face->texture() == "common/caulk") {
+ return;
+ }
+
+ // using suggestions from
+ // http://www.flipcode.com/archives/Level_Editing.shtml
+
//cout << "Face with normal " << face->normal() << endl;
std::vector<math::Vector3f *> vl;
// inital vertexes
-
- // check if the face is x-axis oriented
- if ( (fabsf(face->normal().x) >= fabsf(face->normal().y) ) && (fabsf(face->normal().x) >= fabsf(face->normal().z)) ) {
+
+ // check if the face is x-axis oriented
+ if ((fabsf(face->normal().x) >= fabsf(face->normal().y)) && (fabsf(face->normal().x) >= fabsf(face->normal().z))) {
//cout << " x oriented" << std::endl;
-
+
if (face->normal().x >= 0) {
vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, -MAX_BOUNDS));
vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, MAX_BOUNDS));
@@ -225,38 +232,38 @@ void Model::make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes
}
// calculate the x coordinate of each face vertex
for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- (*it)->x = ( -face->d() -
- face->normal().z * (*it)->z -
- face->normal().y * (*it)->y ) /
- face->normal().x;
+ (*it)->x = (-face->d() -
+ face->normal().z * (*it)->z -
+ face->normal().y * (*it)->y) /
+ face->normal().x;
}
}
-
- // check if the face is y-axis oriented
- else if ( (fabsf(face->normal().y) >= fabsf(face->normal().x) ) && (fabsf(face->normal().y) >= fabsf(face->normal().z)) ) {
+
+ // check if the face is y-axis oriented
+ else if ((fabsf(face->normal().y) >= fabsf(face->normal().x)) && (fabsf(face->normal().y) >= fabsf(face->normal().z))) {
//cout << " y oriented" << std::endl;
-
+
if (face->normal().y >= 0) {
- vl.push_back(new Vector3f(-MAX_BOUNDS, 0, -MAX_BOUNDS));
- vl.push_back(new Vector3f(-MAX_BOUNDS, 0, MAX_BOUNDS));
- vl.push_back(new Vector3f(MAX_BOUNDS, 0, MAX_BOUNDS));
- vl.push_back(new Vector3f(MAX_BOUNDS, 0, -MAX_BOUNDS));
- } else {
vl.push_back(new Vector3f(MAX_BOUNDS, 0, -MAX_BOUNDS));
vl.push_back(new Vector3f(MAX_BOUNDS, 0, MAX_BOUNDS));
vl.push_back(new Vector3f(-MAX_BOUNDS, 0, MAX_BOUNDS));
vl.push_back(new Vector3f(-MAX_BOUNDS, 0, -MAX_BOUNDS));
+ } else {
+ vl.push_back(new Vector3f(-MAX_BOUNDS, 0, -MAX_BOUNDS));
+ vl.push_back(new Vector3f(-MAX_BOUNDS, 0, MAX_BOUNDS));
+ vl.push_back(new Vector3f(MAX_BOUNDS, 0, MAX_BOUNDS));
+ vl.push_back(new Vector3f(MAX_BOUNDS, 0, -MAX_BOUNDS));
}
-
+
// calculate the x coordinate of each face vertex
for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- (*it)->y = ( -face->d() -
- face->normal().z * (*it)->z -
- face->normal().x * (*it)->x ) /
- face->normal().y;
+ (*it)->y = (-face->d() -
+ face->normal().z * (*it)->z -
+ face->normal().x * (*it)->x) /
+ face->normal().y;
}
}
-
+
// face must be z-axis oriented
else {
//cout << " z oriented" << std::endl;
@@ -271,42 +278,40 @@ void Model::make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes
vl.push_back(new Vector3f(-MAX_BOUNDS, MAX_BOUNDS, 0));
vl.push_back(new Vector3f(-MAX_BOUNDS, -MAX_BOUNDS, 0));
}
-
+
// calculate the x coordinate of each face vertex
for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- (*it)->z = ( -face->d() -
- face->normal().x * (*it)->x -
- face->normal().y * (*it)->y ) /
- face->normal().z;
+ (*it)->z = (-face->d() -
+ face->normal().x * (*it)->x -
+ face->normal().y * (*it)->y) /
+ face->normal().z;
}
}
-
- // intersect the face with every plane
+
+ // intersect the face with every plane
for (std::vector<Plane3f *>::iterator pit = planes.begin(); pit != planes.end(); pit++) {
Plane3f *plane = (*pit);
if (plane == face) {
continue;
}
-
+
Vector3f fn = crossproduct(face->point(1)-face->point(0), face->point(2)-face->point(0));
Vector3f pn = crossproduct(plane->point(1)-plane->point(0), plane->point(2)-plane->point(0));
Vector3f t = crossproduct(fn, pn);
- if ((t.x == 0) && (t.y == 0) && (t.z == 0) ) {
+ if ((t.x == 0) && (t.y == 0) && (t.z == 0)) {
continue;
}
-
+
//cout << " intersecting with plane with normal " << plane->normal() << std::endl;
- // using suggestions from
- // http://www.flipcode.com/archives/Level_Editing.shtml
-
+
// intersect face with plane
for (int i=0; vl.size() - i > 0; i++) {
-
+
Vector3f v(*vl.at(i));
-
+
Vector3f next;
if (vl.size() - i > 1) {
//cout << " -- at " << i+1 << std::endl;
@@ -314,7 +319,7 @@ void Model::make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes
} else {
next = *vl.front();
}
-
+
Vector3f prev;
if (i > 0) {
//cout << " -- at " << i-1 << std::endl;
@@ -322,65 +327,65 @@ void Model::make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes
} else {
prev = *vl.back();
}
-
+
//cout << " vertex " << i << " prev " << prev << " v " << v << " next " << next << std::endl;
- if ((v.x*plane->normal().x + v.y*plane->normal().y + v.z*plane->normal().z +plane->d()) < delta ) {
-
+ if ((v.x*plane->normal().x + v.y*plane->normal().y + v.z*plane->normal().z +plane->d()) < delta) {
+
// find current
std::vector<Vector3f *>::iterator vit = vl.begin();
while ((*vit) != vl.at(i)) {
vit++;
}
-
+
// check if prev - v intersects with plane
- if ((prev.x*plane->normal().x + prev.y*plane->normal().y + prev.z*plane->normal().z + plane->d()) > -delta ) {
-
+ if ((prev.x*plane->normal().x + prev.y*plane->normal().y + prev.z*plane->normal().z + plane->d()) > -delta) {
+
// calculate intersection
float t1 = -plane->normal().x * prev.x - plane->normal().y * prev.y - plane->normal().z * prev.z -plane->d();
- float t2 = (plane->normal().x * v.x - plane->normal().x * prev.x +
- plane->normal().y * v.y - plane->normal().y * prev.y +
- plane->normal().z * v.z - plane->normal().z * prev.z);
+ float t2 = (plane->normal().x * v.x - plane->normal().x * prev.x +
+ plane->normal().y * v.y - plane->normal().y * prev.y +
+ plane->normal().z * v.z - plane->normal().z * prev.z);
//cout << "prev t2 " << t2 << std::endl;
Vector3f *s = new Vector3f;
-
+
if (t2 == 0) {
*s = v;
} else {
for (int j = 0; j < 3; j++)
- (*s)[j] = prev [j] + t1 * ( v[j] - prev[j]) / t2;
+ (*s)[j] = prev [j] + t1 * (v[j] - prev[j]) / t2;
}
-
+
//cout << " added " << *s << std::endl;
vit = vl.insert(vit,s);
vit++;
i++;
}
-
+
// check if next - v intersects with plane
- if ((next.x*plane->normal().x + next.y*plane->normal().y + next.z*plane->normal().z + plane->d()) > -delta ) {
+ if ((next.x*plane->normal().x + next.y*plane->normal().y + next.z*plane->normal().z + plane->d()) > -delta) {
// calculate intersection
-
+
// calculate intersection
float t1 = -plane->normal().x * v.x - plane->normal().y * v.y - plane->normal().z * v.z -plane->d();
- float t2 = (plane->normal().x * next.x - plane->normal().x * v.x +
- plane->normal().y * next.y - plane->normal().y * v.y +
- plane->normal().z * next.z - plane->normal().z * v.z);
+ float t2 = (plane->normal().x * next.x - plane->normal().x * v.x +
+ plane->normal().y * next.y - plane->normal().y * v.y +
+ plane->normal().z * next.z - plane->normal().z * v.z);
//cout << "next t2 " << t2 << std::endl;
Vector3f *s = new Vector3f;
-
+
if (t2 == 0) {
*s = v;
} else {
for (int j = 0; j < 3; j++)
- (*s)[j] = v [j] + t1 * ( next[j] - v[j]) / t2;
+ (*s)[j] = v [j] + t1 * (next[j] - v[j]) / t2;
}
-
+
//cout << " added " << *s << std::endl;
vit = vl.insert(vit,s);
vit++;
i++;
}
-
+
// erase
delete *vit;
vl.erase(vit);
@@ -391,26 +396,45 @@ void Model::make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes
}
if (vl.size() > 2) {
+
+ math::Color *color = 0;
+ if (face->texture() == "colors/white") {
+ color = new math::Color(1, 1, 1);
+ } else if (face->texture() == "colors/grey90") {
+ color = new math::Color(0.9, 0.9, 0.9);
+ } else if (face->texture() == "colors/grey75") {
+ color = new math::Color(0.75, 0.75, 0.75);
+ } else if (face->texture() == "colors/grey50") {
+ color = new math::Color(0.5, 0.5, 0.5);
+ } else if (face->texture() == "colors/grey25") {
+ color = new math::Color(0.25, 0.25, 0.25);
+ } else if (face->texture() == "colors/black") {
+ color = new math::Color(0, 0, 0);
+ } else if (face->texture() == "common/entity") {
+ color = 0;
+ }
+
Vector3f n = face->normal();
n.normalize();
- Face *mf = new Face(n);
+ Face *mf = new Face(n, color);
+ if (color) delete color;
for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
mf->add_vertex(*(*it) * model_scale);
}
-
+
//con_debug << "adding face\n";
add_face(mf);
} else {
con_debug << "Unresolved face!\n";
}
-
+
for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- delete (*it);
+ delete(*it);
}
-
+
vl.clear();
-
+
}
void Model::add_face(Face *face)
@@ -423,31 +447,46 @@ void Model::add_engine(Engine *engine)
model_engine.push_back(engine);
}
-void Model::draw(core::Entity const * entity)
+void Model::draw(core::Entity const * entity, math::Vector3f const & eye)
{
//gl::scale(model_scale, model_scale, model_scale);
- render::gl::color(entity->color());
-
+
+ // calculate a normal from eye to entity location
+ math::Vector3f n = entity->location() - eye;
+ n.normalize();
+
// draw all faces
for (std::list<Face *>::iterator fit = model_face.begin(); fit != model_face.end(); fit++) {
+ // poor man's lighting
+ // set the face color depending on the viewing direction
+ float d = fabsf(math::dotproduct(n, (*fit)->normal()));
+
+ if (d > 1)
+ d = 1;
+ d = 0.5f + d/2;
+
+ if ((*fit)->color()) {
+ render::gl::color(*(*fit)->color() * d);
+ } else {
+ render::gl::color(entity->color() * d);
+ }
(*fit)->draw();
}
}
-void Model::draw(core::EntityControlable const * entity)
+void Model::draw(core::EntityControlable const * entity, math::Vector3f const & eye)
{
// draw the model
- draw((core::Entity *) entity);
-
+ draw((core::Entity *) entity, eye);
+
// draw engines
// all engines are assumed to point to the rear
- if(model_engine.size() && entity->thrust()) {
-
- gl::color(1.0f,0 ,0 );
+ if (model_engine.size() && entity->thrust()) {
+
+ gl::color(1.0f,0 ,0);
gl::begin(gl::Lines);
- for(std::list<Engine *>::iterator eit = model_engine.begin(); eit != model_engine.end(); eit++)
- {
+ for (std::list<Engine *>::iterator eit = model_engine.begin(); eit != model_engine.end(); eit++) {
math::Vector3f const & v = (*eit)->location();
gl::vertex(v);
gl::vertex(v.x - 0.0625f*entity->thrust(), v.y, v.z);
@@ -479,9 +518,16 @@ void Model::clear()
{
// delete all models in the registry
for (std::map<std::string, Model*>::iterator mit = registry.begin(); mit != registry.end(); mit++) {
- delete (*mit).second;
+ delete(*mit).second;
}
registry.clear();
}
+void Model::list()
+{
+ for (std::map<std::string, Model*>::iterator mit = registry.begin(); mit != registry.end(); mit++) {
+ con_print << " " << (*mit).second->model_name << " " << (*mit).second->model_face.size() << " polys\n";
+ }
+ con_print << registry.size() << " registered models" << std::endl;
+}
}
diff --git a/src/render/model.h b/src/render/model.h
index dfde809..eca896b 100644
--- a/src/render/model.h
+++ b/src/render/model.h
@@ -1,7 +1,7 @@
/*
render/model.h
- This file is part of the Osirion project and is distributed under
- the terms of the GNU General Public License version 2
+ 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_MODEL_H__
@@ -14,7 +14,8 @@
#include "core/entity.h"
#include "render/face.h"
-namespace render {
+namespace render
+{
/// a spacecraft engine
class Engine
@@ -22,9 +23,12 @@ class Engine
public:
Engine(math::Vector3f const & location);
~Engine();
-
- inline math::Vector3f const & location() const { return engine_location; }
-
+
+ inline math::Vector3f const & location() const
+ {
+ return engine_location;
+ }
+
private:
math::Vector3f engine_location;
};
@@ -36,45 +40,51 @@ public:
/// load a model from disk
Model(std::string const & name);
~Model();
-
+
/// the name of the model
- inline std::string const & name() const { return model_name; }
-
+ inline std::string const & name() const
+ {
+ return model_name;
+ }
+
/// the Model registry
static std::map<std::string, Model*> registry;
-
+
/// draw the model for an entity
/** This will not draw attached engines, turrents and cannons
*/
- void draw(core::Entity const * entity);
-
+ void draw(core::Entity const * entity, math::Vector3f const & eye);
+
/// draw the model for a controlable enity
/** This will draw all attached engines, turrents and cannons
*/
- void draw(core::EntityControlable const * entity);
-
-/* ---- static functions for the Model registry -------------------- */
-
+ void draw(core::EntityControlable const * entity, math::Vector3f const & eye);
+
+ /* ---- static functions for the Model registry -------------------- */
+
/// get name model, returns 0 if not found
static Model *find(std::string const & name);
-
+
/// get named model from the registry and load it if necessary
static Model *get(std::string const & name);
-
- /// clear the Model registry
+
+ /// clear the model registry
static void clear();
-
+
+ /// list the content of the model registry
+ static void list();
+
private:
void make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes);
void add_engine(Engine *engine);
void add_face(Face *face);
-
+
std::list<Face *> model_face;
std::list<Engine *> model_engine;
std::string model_name;
-
+
float model_scale;
-
+
};
}
diff --git a/src/render/render.cc b/src/render/render.cc
index 87f7424..a1a66f9 100644
--- a/src/render/render.cc
+++ b/src/render/render.cc
@@ -14,6 +14,12 @@ namespace render {
GLuint textures[32];
+void func_list_model(std::string const &args)
+{
+ Model::list();
+}
+
+
void init()
{
con_print << "Initializing renderer..." << std::endl;
@@ -34,6 +40,7 @@ void init()
}
Model::clear();
+ core::Func::add("list_model", (core::FuncPtr) func_list_model);
}
void shutdown()
@@ -41,6 +48,7 @@ void shutdown()
con_print << "Shutting down renderer..." << std::endl;
Model::clear();
+ core::Func::remove("list_model");
}
}