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/soundext.cc2
-rw-r--r--src/core/entity.cc4
-rw-r--r--src/core/gameserver.cc15
-rw-r--r--src/game/base/game.cc118
-rw-r--r--src/game/base/game.h10
-rw-r--r--src/math/Makefile.am20
-rw-r--r--src/math/boundingbox3f.cc53
-rw-r--r--src/math/boundingbox3f.h113
-rw-r--r--src/math/mathlib.h2
-rw-r--r--src/model/asefile.cc34
-rw-r--r--src/model/asefile.h8
-rw-r--r--src/model/mapfile.cc83
-rw-r--r--src/model/mapfile.h10
-rw-r--r--src/model/model.h13
-rw-r--r--src/render/camera.cc6
-rw-r--r--src/render/draw.cc32
16 files changed, 351 insertions, 172 deletions
diff --git a/src/client/soundext.cc b/src/client/soundext.cc
index 117c62d..9ab32a6 100644
--- a/src/client/soundext.cc
+++ b/src/client/soundext.cc
@@ -185,7 +185,7 @@ void SoundExt::frame(float elapsed)
float speed = 0;
float pitch = 1.0f;
float gain = 0.0;
- float r = (entity()->model() ? entity()->model()->maxbbox().x() : entity()->radius());
+ float r = (entity()->model() ? entity()->model()->box().max().x() : entity()->radius());
math::Vector3f velocity;
diff --git a/src/core/entity.cc b/src/core/entity.cc
index 4f13efa..af100a9 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -512,7 +512,7 @@ void Entity::reset()
if (!entity_body) {
// create collision shape
if (model()) {
- entity_collision_shape = new btBoxShape(to_btVector3(model()->maxbbox()));
+ entity_collision_shape = new btBoxShape(to_btVector3(model()->box().max()));
} else {
entity_collision_shape = new btSphereShape(radius());
}
@@ -938,7 +938,7 @@ void EntityControlable::reset()
if (!entity_body) {
// create collision shape
if (model()) {
- entity_collision_shape = new btBoxShape(to_btVector3(model()->maxbbox()));
+ entity_collision_shape = new btBoxShape(to_btVector3(model()->box().max()));
} else {
entity_collision_shape = new btSphereShape(radius());
}
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index f84e228..412c554 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -209,10 +209,13 @@ GameServer::~GameServer()
delete server_network;
server_network = 0;
}
-
+
if (server_module->interactive())
save_config();
+ // clear game data
+ clear();
+
if (server_module) {
if (!Cvar::sv_dedicated->value())
player_disconnect(localplayer());
@@ -520,9 +523,17 @@ void GameServer::frame(unsigned long timestamp)
math::Vector3f keepalive_minbox;
// run a game frame on all dynamic and controlable entities
- for (Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) {
+ for (Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) {
Entity *entity = (*it);
+
+ // FIXME
+ // if a controlable changes zone during the entity frame (like when using jumpgates)
+ // the zone content iterator will become invalid
+ // possible solutions
+ // 1) move the actual zone change into the entity_destroyed sequence (renamed entity.oldzone to newzone and track changes)
+ // 2) revert to using the entity iterator and add the keep_alive min- and maxbox to the zone class
+
if (entity->type() == Entity::Dynamic) {
entity->frame(elapsed);
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index 40c7c28..f110962 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -11,6 +11,7 @@
#include "auxiliary/functions.h"
#include "core/gameserver.h"
#include "core/parser.h"
+#include "core/range.h"
#include "core/descriptions.h"
#include "filesystem/filesystem.h"
#include "filesystem/inifile.h"
@@ -114,34 +115,6 @@ void Game::func_spectate(core::Player *player, std::string const &args)
player->set_view(0);
}
-// a player sends standard hails
-void Game::func_hail(core::Player *player, std::string const &args)
-{
- if (player->mute()) {
- player->send("^WYou have been muted");
- return;
- }
-
- std::string target;
- std::istringstream is(args);
- if (!(is >> target)) {
- player->send("Usage: hail [player]");
- return;
- }
-
- core::Player *targetplayer = core::server()->find_player(target);
- if (!targetplayer) {
- player->send("Player " + target + "^N not found");
- return;
- }
-
- player->send("^BYou hail " + targetplayer->name());
- player->sound("com/hail");
-
- targetplayer->send("^B" + player->name() + "^B hails you");
- targetplayer->sound("com/hail");
-}
-
// a player actives the hyperspace jump drive on his ship
void Game::func_jump(core::Player *player, std::string const &args)
{
@@ -165,7 +138,7 @@ void Game::func_impulse(core::Player *player, std::string const &args)
}
// a player sends a docking request
-void Game::func_dock(core::Player *player, core::Entity *entity)
+void Game::func_target_dock(core::Player *player, core::Entity *entity)
{
if (!player->control())
return;
@@ -214,12 +187,12 @@ void Game::func_dock(core::Player *player, core::Entity *entity)
return;
if (entity->moduletype() == jumpgate_enttype) {
- // jumpgates their own docking function
+ // jumpgates have their own docking function
JumpGate *jumpgate = static_cast<JumpGate *>(entity);
jumpgate->func_dock(ship);
return;
- } else {
+ } else {
ship->get_location().assign(entity->location());
ship->set_state(core::Entity::Docked);
ship->reset();
@@ -235,6 +208,64 @@ void Game::func_dock(core::Player *player, core::Entity *entity)
}
}
+// a player sends a standard hail
+void Game::func_target_hail(core::Player *player, core::Entity *entity)
+{
+ // TODO spam protection
+ if (!entity)
+ return;
+
+ if (!player->control())
+ return;
+
+ if (player->control()->zone() != entity->zone())
+ return;
+
+ if (player->mute()) {
+ player->send("^WYou have been muted");
+ return;
+ }
+
+ core::Player *target = (entity->type() == core::Entity::Controlable ? static_cast<core::EntityControlable *>(entity)->owner() : 0 );
+ if (!target)
+ return;
+
+ if (math::distance(player->control()->location(), entity->location()) > core::range::fxdistance) {
+ player->send("^WTarget " + target->name() + " ^Wout of range");
+ }
+ player->send("^BYou hail " + target->name());
+ player->sound("com/hail");
+
+ target->send("^B" + player->name() + "^B hails you");
+ target->sound("com/hail");
+}
+
+// a player sends a trade request
+void Game::func_target_trade(core::Player *player, core::Entity *entity)
+{
+ if (!entity)
+ return;
+
+ if (!player->control())
+ return;
+
+ core::Player *target = (entity->type() == core::Entity::Controlable ? static_cast<core::EntityControlable *>(entity)->owner() : 0 );
+ if ((!target) || (target == player))
+ return;
+
+ if (entity != target->control())
+ return;
+
+ if (target->control()->state() != core::Entity::Normal)
+ return;
+
+ if (player->control()->state() != core::Entity::Normal)
+ return;
+
+
+ player->send("^WTrade requests are not implemented at this time");
+}
+
// cheats
void Game::func_give(core::Player *player, const std::string &args)
{
@@ -850,9 +881,6 @@ Game::Game() : core::Module("Project::OSiRiON", true)
func = core::Func::add("join", Game::func_join);
func->set_info("join the game");
- func = core::Func::add("hail", Game::func_hail);
- func->set_info("send a standard hail");
-
func = core::Func::add("spectate", Game::func_spectate);
func->set_info("leave the game and spectate");
@@ -889,8 +917,14 @@ Game::Game() : core::Module("Project::OSiRiON", true)
func = core::Func::add("goto", Game::func_goto);
func->set_info("[string] goto to an entity within the zone");
- func = core::Func::add("@dock", Game::func_dock);
- func->set_info("dock with target object");
+ func = core::Func::add("@dock", Game::func_target_dock);
+ func->set_info("send a docking request to target");
+
+ func = core::Func::add("@hail", Game::func_target_hail);
+ func->set_info("send a standard hail to target");
+
+ func = core::Func::add("@trade", Game::func_target_trade);
+ func->set_info("send a trade request to target");
// add engine variables
g_impulsespeed = core::Cvar::get("g_impulsespeed", "1500", core::Cvar::Game | core::Cvar::Archive);
@@ -899,13 +933,13 @@ Game::Game() : core::Module("Project::OSiRiON", true)
g_jumppointrange = core::Cvar::get("g_jumppointrange", "512", core::Cvar::Game | core::Cvar::Archive);
g_jumppointrange->set_info("[float] jumppoint range");
- g_devel = core::Cvar::get("g_devel", "0", core::Cvar::Archive);
+ g_devel = core::Cvar::get("g_devel", "0", core::Cvar::Game | core::Cvar::Archive);
g_devel->set_info("[bool] enable or disable developer mode");
- g_damping = core::Cvar::get("g_damping", "0.1", core::Cvar::Archive);
+ g_damping = core::Cvar::get("g_damping", "0.1", core::Cvar::Game | core::Cvar::Archive);
g_damping->set_info("[float] physics damping factor (0-1)");
- g_deplete = core::Cvar::get("g_deplete", "60", core::Cvar::Archive);
+ g_deplete = core::Cvar::get("g_deplete", "60", core::Cvar::Game | core::Cvar::Archive);
g_deplete->set_info("[int] number of seconds to deplete 1 unit of cargo from inventories");
}
@@ -915,11 +949,7 @@ Game::~Game()
g_jumppointrange = 0;
g_devel = 0;
g_damping = 0;
- // game functions are automaticly removed
-
- // FIXME move cleanup sequence to core::
- // we explicity clear game data to prevent bullet from beeing confused
- core::game()->clear();
+ g_deplete = 0;
Default::clear();
}
diff --git a/src/game/base/game.h b/src/game/base/game.h
index dd47cef..3859122 100644
--- a/src/game/base/game.h
+++ b/src/game/base/game.h
@@ -107,14 +107,12 @@ private:
bool load_settings();
- /* ---- engine functions ----------------------------------- */
+ /* ---- game functions ------------------------------------- */
static void func_join(core::Player *player, std::string const &args);
static void func_spectate(core::Player *player, std::string const &args);
- static void func_hail(core::Player *player, std::string const &args);
static void func_jump(core::Player *player, std::string const &args);
static void func_impulse(core::Player *player, std::string const &args);
- static void func_dock(core::Player *player, core::Entity *entity);
static void func_launch(core::Player *player, std::string const &args);
static void func_respawn(core::Player *player, std::string const &args);
static void func_goto(core::Player *player, const std::string &args);
@@ -124,6 +122,12 @@ private:
static void func_specs(core::Player *player, const std::string &args);
static void func_eject(core::Player *player, const std::string &args);
static void func_beam(core::Player *player, const std::string &args);
+
+ /* ---- target functions ----------------------------------- */
+
+ static void func_target_dock(core::Player *player, core::Entity *entity);
+ static void func_target_hail(core::Player *player, core::Entity *entity);
+ static void func_target_trade(core::Player *player, core::Entity *entity);
};
/// factory function
diff --git a/src/math/Makefile.am b/src/math/Makefile.am
index df180dd..d032cb4 100644
--- a/src/math/Makefile.am
+++ b/src/math/Makefile.am
@@ -1,11 +1,25 @@
METASOURCES = AUTO
-libmath_la_SOURCES = axis.cc color.cc functions.cc matrix4f.cc vector2f.cc \
+libmath_la_SOURCES = \
+ axis.cc \
+ boundingbox3f.cc \
+ color.cc \
+ functions.cc \
+ matrix4f.cc \
+ vector2f.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 matrix4f.h vector2f.h \
- vector3f.h
+noinst_HEADERS = \
+ axis.h \
+ boundingbox3f.h \
+ color.h \
+ functions.h \
+ mathlib.h \
+ matrix4f.h \
+ vector2f.h \
+ vector3f.h
INCLUDES = -I$(top_srcdir)/src
diff --git a/src/math/boundingbox3f.cc b/src/math/boundingbox3f.cc
new file mode 100644
index 0000000..933d783
--- /dev/null
+++ b/src/math/boundingbox3f.cc
@@ -0,0 +1,53 @@
+/*
+ math/boundingbox3f.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "math/boundingbox3f.h"
+
+namespace math {
+
+BoundingBox3f::BoundingBox3f() :
+ boundingbox_min(),
+ boundingbox_max()
+{
+}
+
+BoundingBox3f::BoundingBox3f(const Vector3f &center) :
+ boundingbox_min(center),
+ boundingbox_max(center)
+{
+}
+
+void BoundingBox3f::assign(const BoundingBox3f & other)
+{
+ boundingbox_min.assign(other.boundingbox_min);
+ boundingbox_max.assign(other.boundingbox_max);
+}
+
+void BoundingBox3f::assign(const Vector3f &center)
+{
+ boundingbox_min.assign(center);
+ boundingbox_max.assign(center);
+}
+void BoundingBox3f::assign(const Vector3f & min, const Vector3f & max)
+{
+ boundingbox_min.assign(min);
+ boundingbox_max.assign(max);
+}
+
+void BoundingBox3f::assign(const float min, const float max)
+{
+ boundingbox_min.assign(min, min, min);
+ boundingbox_max.assign(max, max, max);
+}
+
+void BoundingBox3f::clear()
+{
+ boundingbox_min.clear();
+ boundingbox_max.clear();
+}
+
+
+} // namespace math
diff --git a/src/math/boundingbox3f.h b/src/math/boundingbox3f.h
new file mode 100644
index 0000000..54b846b
--- /dev/null
+++ b/src/math/boundingbox3f.h
@@ -0,0 +1,113 @@
+/*
+ math/boundingbox3f.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_MATH_BOUNDINGBOX3F_H__
+#define __INCLUDED_MATH_BOUNDINGBOX3F_H__
+
+#include "math/vector3f.h"
+
+namespace math {
+
+/**
+ * @brief a bounding box class
+ */
+class BoundingBox3f {
+public:
+ BoundingBox3f();
+ BoundingBox3f(const Vector3f &center);
+
+ /**
+ * @brief returns the minimum coordinates of the bounding box
+ */
+ inline const Vector3f & min() const {
+ return boundingbox_min;
+ }
+
+ /**
+ * @brief returns the maximum coordinates of the bounding box
+ */
+ inline const Vector3f & max() const {
+ return boundingbox_max;
+ }
+
+ /**
+ * @brief test if a point is located inside the bounding box
+ */
+ inline const bool inside(const Vector3f & point) const {
+ for (size_t i =0; i < 3; i++) {
+ if ((point[i] < boundingbox_min[i]) || (point[i] > boundingbox_max[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @brief test if a point is located outside the bounding box
+ */
+ inline const bool outside(const Vector3f & point) const {
+ for (size_t i =0; i < 3; i++) {
+ if ((point[i] < boundingbox_min[i]) || (point[i] > boundingbox_max[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void assign(const BoundingBox3f & other);
+
+ void assign(const Vector3f & min, const Vector3f & max);
+
+ void assign(const Vector3f &center);
+
+ void assign(const float min, const float max);
+
+ void clear();
+
+ /**
+ * @brief expand the bounding box to contain a point
+ */
+ inline void expand(const Vector3f & point) {
+ for (size_t i =0; i < 3; i++) {
+ if (point[i] < boundingbox_min[i]) {
+ boundingbox_min[i] = point[i];
+ }
+
+ if (point[i] > boundingbox_max[i]) {
+ boundingbox_max[i] = point[i];
+ }
+ }
+ }
+
+ /**
+ * @brief expand the bounding box to contain another bounding box
+ */
+ inline void expand(const Vector3f & min, const Vector3f & max) {
+ for (size_t i =0; i < 3; i++) {
+ if (min[i] < boundingbox_min[i]) {
+ boundingbox_min[i] = min[i];
+ }
+
+ if (max[i] > boundingbox_max[i]) {
+ boundingbox_max[i] = max[i];
+ }
+ }
+ }
+
+ /**
+ * @brief expand the bounding box to contain another bounding box
+ */
+ inline void expand(const BoundingBox3f & other) {
+ expand(other.boundingbox_min, other.boundingbox_max);
+ }
+
+private:
+ Vector3f boundingbox_min;
+ Vector3f boundingbox_max;
+};
+
+} // namespace math
+#endif // __INCLUDED_MATH_BOUNDINGBOX3F_H__
diff --git a/src/math/mathlib.h b/src/math/mathlib.h
index ee1e43e..b29edee 100644
--- a/src/math/mathlib.h
+++ b/src/math/mathlib.h
@@ -13,11 +13,13 @@
namespace math {}
#include "math/axis.h"
+#include "math/boundingbox3f.h"
#include "math/color.h"
#include "math/matrix4f.h"
#include "math/functions.h"
#include "math/vector2f.h"
#include "math/vector3f.h"
+
#endif // __INCLUDED_MATH_MATHLIB_H__
diff --git a/src/model/asefile.cc b/src/model/asefile.cc
index c9dfe1c..64b38d3 100644
--- a/src/model/asefile.cc
+++ b/src/model/asefile.cc
@@ -22,10 +22,7 @@ ASEFile::ASEFile(std::string const &name)
asefile_name.append(".ase");
asefile_ifs.open(asefile_name);
- for (int i = 0; i < 3; i++) {
- ase_minbbox[i] = 0;
- ase_maxbbox[i] = 0;
- }
+ ase_box.assign(MAX_BOUNDS, - MAX_BOUNDS);
// a single fragmentgroup wil contain all the model triangles
ase_fragmentgroup = new FragmentGroup();
@@ -263,15 +260,7 @@ bool ASEFile::read_mesh_vertex_list(std::istream &is)
if (line >> index >> x >> y >> z) {
math::Vector3f *v = new math::Vector3f(x, y, z);
ase_vertexlist[index] = v;
-
- for (size_t i = 0; i < 3; i++) {
- if ((*v)[i] > ase_maxbbox[i]) {
- ase_maxbbox[i] = (*v)[i];
- }
- if ((*v)[i] < ase_minbbox[i]) {
- ase_minbbox[i] = (*v)[i];
- }
- }
+ ase_box.expand(*v * SCALE);
ase_vertexcount++;
}
}
@@ -679,19 +668,18 @@ Model *ASEFile::load(const std::string &name)
// create a new model
Model *model = new Model(name);
- // set bounding box properties
- asefile.ase_minbbox *= SCALE;
- asefile.ase_maxbbox *= SCALE;
-
- math::Vector3f ase_center((asefile.ase_maxbbox + asefile.ase_minbbox) * 0.5f);
+ // center model around (0,0,0) and set the bounding box
+ math::Vector3f ase_center((asefile.box().min() + asefile.box().max()) * 0.5f);
+ model->model_box.assign(
+ asefile.box().min() - ase_center,
+ asefile.box().max() - ase_center
+ );
+ model->set_radius(model->box().max().length());
+ model->set_origin(ase_center);
+
asefile.fragmentgroup()->set_transform(true);
asefile.fragmentgroup()->set_location(ase_center * -1.0f);
- model->model_minbbox.assign(asefile.ase_minbbox - ase_center);
- model->model_maxbbox.assign(asefile.ase_maxbbox - ase_center);
- model->set_radius(asefile.ase_maxbbox.length());
- model->set_origin(ase_center);
-
for (FragmentGroup::Fragments::const_iterator fit = asefile.fragmentgroup()->fragments().begin(); fit != asefile.fragmentgroup()->fragments().end(); fit++) {
const Fragment *fragment = (*fit);
model->model_tris_count += (fragment->structural_size() + fragment->detail_size()) / 3;
diff --git a/src/model/asefile.h b/src/model/asefile.h
index 9e3fea6..c16bf5c 100644
--- a/src/model/asefile.h
+++ b/src/model/asefile.h
@@ -141,6 +141,10 @@ private:
inline FragmentGroup *fragmentgroup() {
return ase_fragmentgroup;
}
+
+ inline const math::BoundingBox3f & box() const {
+ return ase_box;
+ }
std::string asefile_name;
@@ -154,9 +158,7 @@ private:
MaterialList ase_materials;
- math::Vector3f ase_maxbbox;
-
- math::Vector3f ase_minbbox;
+ math::BoundingBox3f ase_box;
FragmentGroup *ase_fragmentgroup;
diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc
index 9fbcbc5..2eac688 100644
--- a/src/model/mapfile.cc
+++ b/src/model/mapfile.cc
@@ -152,14 +152,10 @@ MapFile::MapFile()
warning_q2brush = false;
class_engine = false;
class_speed = 0;
-
- for (size_t i = 0; i < 3; i++) {
- class_minbbox[i] = MAX_BOUNDS;
- class_maxbbox[i] = -MAX_BOUNDS;
-
- map_minbbox[i] = MAX_BOUNDS;
- map_maxbbox[i] = -MAX_BOUNDS;
- }
+
+ // the initial bounding box value is invalid: max and min are switched
+ class_box.assign(MAX_BOUNDS, -MAX_BOUNDS);
+ map_box.assign(MAX_BOUNDS, -MAX_BOUNDS);
}
MapFile::~MapFile()
@@ -452,8 +448,6 @@ void MapFile::make_brushface(Face *face)
// vertex list
std::vector<math::Vector3f *> vl;
- // calculate initial vertices on the bounding box
-
// 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()))) {
@@ -639,24 +633,13 @@ void MapFile::make_brushface(Face *face)
// scale vertices and calculate the bounding box
for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- //*(*it) *= SCALE;
- for (int i = 0; i < 3; i++) {
- if (class_maxbbox[i] < (*(*it))[i] * SCALE)
- class_maxbbox[i] = (*(*it))[i] * SCALE;
-
- if (class_minbbox[i] > (*(*it))[i] * SCALE)
- class_minbbox[i] = (*(*it))[i] * SCALE;
- }
+ class_box.expand(*(*it) * SCALE);
}
// the actual polygon normal is on the other side
Vector3f face_normal(face->normal()* -1);
face_normal.normalize();
-//#ifndef HAVE_BULLET
-
- // Quads are disable to use model data for bullet physics
-
// split polygon into quads
while (vl.size() > 3) {
std::vector<Vector3f *>::iterator v0 = vl.begin();
@@ -682,7 +665,7 @@ void MapFile::make_brushface(Face *face)
vl.pop_back();
vl.pop_back();
}
-//#endif
+
// split polygon into triangles
while (vl.size() > 2) {
std::vector<Vector3f *>::iterator v0 = vl.begin();
@@ -813,11 +796,7 @@ void MapFile::close()
void MapFile::clear_bbox()
{
- for (int i = 0; i < 3; i++) {
- class_minbbox[i] = MAX_BOUNDS;
- class_maxbbox[i] = -MAX_BOUNDS;
- }
-
+ class_box.assign(MAX_BOUNDS, -MAX_BOUNDS);
class_axis.clear();
class_speed = 0;
class_engine = false;
@@ -838,20 +817,14 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t
// default rotation speed 45 degrees per second
class_speed = 45.0f;
}
-// group->set_engine(class_engine);
+ //group->set_engine(class_engine);
}
- // calculate map bbox
- for (size_t i = 0; i < 3 ; i++) {
- if (class_minbbox[i] < map_minbbox[i])
- map_minbbox[i] = class_minbbox[i];
-
- if (class_maxbbox[i] > map_maxbbox[i])
- map_maxbbox[i] = class_maxbbox[i];
- }
+ // expand bounding box
+ map_box.expand(class_box);
// special groups like func_door and func_group are re-centered
- math::Vector3f translation((class_minbbox + class_maxbbox) * 0.5f);
+ math::Vector3f translation((class_box.min() + class_box.max()) * 0.5f);
group->set_transform(true);
group->set_location(translation);
@@ -1459,21 +1432,12 @@ Model * MapFile::load(std::string const &name)
}
}
- // recalculate bbox
- for (size_t i = 0; i < 3; i ++) {
- float c;
- c = tag_submodel->location()[i] + submodel_model->model_maxbbox[i] * tag_submodel->scale();
- if (c > mapfile.map_maxbbox[i]) {
- mapfile.map_maxbbox[i] = c;
- }
-
- c = tag_submodel->location()[i] + submodel_model->model_minbbox[i] * tag_submodel->scale();
- if (c < mapfile.map_minbbox[i]) {
- mapfile.map_minbbox[i] = c;
- }
-
- }
-
+ // add the scaled submodel bounding box to the map bounding box
+ mapfile.map_box.expand(
+ tag_submodel->location() + submodel_model->model_box.min() * tag_submodel->scale(),
+ tag_submodel->location() + submodel_model->model_box.max() * tag_submodel->scale()
+ );
+
// copy light tags
for (Model::Lights::const_iterator lit = submodel_model->lights().begin(); lit != submodel_model->lights().end(); lit++) {
tag_light = new Light(*(*lit));
@@ -1514,11 +1478,14 @@ Model * MapFile::load(std::string const &name)
delete tag_submodel;
}
- // center model around (0,0,0)
- math::Vector3f map_center = (mapfile.map_minbbox + mapfile.map_maxbbox) * 0.5f;
- model->model_minbbox.assign(mapfile.map_minbbox - map_center);
- model->model_maxbbox.assign(mapfile.map_maxbbox - map_center);
- model->set_radius(model->model_maxbbox.length());
+ // center model around (0,0,0) and set the bounding box
+ math::Vector3f map_center = (mapfile.box().min() + mapfile.box().max()) * 0.5f;
+ model->model_box.assign(
+ mapfile.box().min() - map_center,
+ mapfile.box().max() - map_center
+ );
+
+ model->set_radius(model->box().max().length());
model->set_origin(map_center);
// translate transformed vertex groups
diff --git a/src/model/mapfile.h b/src/model/mapfile.h
index fbb594c..4cea7f0 100644
--- a/src/model/mapfile.h
+++ b/src/model/mapfile.h
@@ -121,6 +121,10 @@ private:
inline std::string const & name() const {
return mapfile_name;
}
+
+ inline const math::BoundingBox3f & box() const {
+ return map_box;
+ }
/// close the file
void close();
@@ -164,11 +168,9 @@ private:
filesystem::IFileStream mapfile_ifs;
std::string mapfile_name;
- math::Vector3f map_minbbox;
- math::Vector3f map_maxbbox;
+ math::BoundingBox3f map_box;
- math::Vector3f class_minbbox;
- math::Vector3f class_maxbbox;
+ math::BoundingBox3f class_box;
math::Axis class_axis;
float class_speed;
bool class_engine;
diff --git a/src/model/model.h b/src/model/model.h
index 287b0cf..9495285 100644
--- a/src/model/model.h
+++ b/src/model/model.h
@@ -101,14 +101,8 @@ public:
return model_particles;
}
- /// maximum values of the bounding box
- inline const math::Vector3f & maxbbox() const {
- return model_maxbbox;
- }
-
- /// minimum values of the bounding box
- inline const math::Vector3f & minbbox() const {
- return model_minbbox;
+ inline const math::BoundingBox3f & box() const {
+ return model_box;
}
/// engine sound loop for this model
@@ -156,8 +150,7 @@ public:
void set_origin(const math::Vector3f &origin);
math::Vector3f model_origin;
- math::Vector3f model_maxbbox;
- math::Vector3f model_minbbox;
+ math::BoundingBox3f model_box;
unsigned int model_enginesound;
unsigned int model_impulsesound;
diff --git a/src/render/camera.cc b/src/render/camera.cc
index d13a532..37453b9 100644
--- a/src/render/camera.cc
+++ b/src/render/camera.cc
@@ -290,8 +290,8 @@ void Camera::frame(float seconds)
}
if (core::localcontrol()->model()) {
- camera_target -= camera_axis.forward() * math::max(FRUSTUMFRONT / WORLDSCALE, core::localcontrol()->model()->maxbbox().x());
- camera_target += camera_axis.up() * math::max(FRUSTUMFRONT / WORLDSCALE, core::localcontrol()->model()->maxbbox().z() * 2.0f);
+ camera_target -= camera_axis.forward() * math::max(FRUSTUMFRONT / WORLDSCALE, core::localcontrol()->model()->box().max().x());
+ camera_target += camera_axis.up() * math::max(FRUSTUMFRONT / WORLDSCALE, core::localcontrol()->model()->box().max().z() * 2.0f);
} else {
camera_target -= camera_axis.forward() * math::max(FRUSTUMFRONT / WORLDSCALE, FRUSTUMFRONT / WORLDSCALE + core::localcontrol()->radius());
camera_target += camera_axis.up() * math::max(FRUSTUMFRONT / WORLDSCALE, FRUSTUMFRONT / WORLDSCALE + core::localcontrol()->radius());
@@ -323,7 +323,7 @@ void Camera::frame(float seconds)
camera_axis.assign(target_axis);
if (core::localcontrol()->model()) {
- camera_target += (core::localcontrol()->model()->maxbbox().x()) *
+ camera_target += (core::localcontrol()->model()->box().max().x()) *
core::localcontrol()->axis().forward();
} else {
camera_target += (core::localcontrol()->radius()) *
diff --git a/src/render/draw.cc b/src/render/draw.cc
index 945e04b..3aa9371 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -759,30 +759,30 @@ void draw_model_bbox(model::Model *model)
{
// top
gl::begin(gl::LineLoop);
- gl::vertex(model->model_maxbbox.x(), model->model_maxbbox.y(), model->model_maxbbox.z());
- gl::vertex(model->model_minbbox.x(), model->model_maxbbox.y(), model->model_maxbbox.z());
- gl::vertex(model->model_minbbox.x(), model->model_minbbox.y(), model->model_maxbbox.z());
- gl::vertex(model->model_maxbbox.x(), model->model_minbbox.y(), model->model_maxbbox.z());
+ gl::vertex(model->box().max().x(), model->box().max().y(), model->box().max().z());
+ gl::vertex(model->box().min().x(), model->box().max().y(), model->box().max().z());
+ gl::vertex(model->box().min().x(), model->box().min().y(), model->box().max().z());
+ gl::vertex(model->box().max().x(), model->box().min().y(), model->box().max().z());
gl::end();
// bottom
gl::begin(gl::LineLoop);
- gl::vertex(model->model_maxbbox.x(), model->model_maxbbox.y(), model->model_minbbox.z());
- gl::vertex(model->model_minbbox.x(), model->model_maxbbox.y(), model->model_minbbox.z());
- gl::vertex(model->model_minbbox.x(), model->model_minbbox.y(), model->model_minbbox.z());
- gl::vertex(model->model_maxbbox.x(), model->model_minbbox.y(), model->model_minbbox.z());
+ gl::vertex(model->box().max().x(), model->box().max().y(), model->box().min().z());
+ gl::vertex(model->box().min().x(), model->box().max().y(), model->box().min().z());
+ gl::vertex(model->box().min().x(), model->box().min().y(), model->box().min().z());
+ gl::vertex(model->box().max().x(), model->box().min().y(), model->box().min().z());
gl::end();
// body
gl::begin(gl::Lines);
- gl::vertex(model->model_maxbbox.x(), model->model_maxbbox.y(), model->model_maxbbox.z());
- gl::vertex(model->model_maxbbox.x(), model->model_maxbbox.y(), model->model_minbbox.z());
- gl::vertex(model->model_minbbox.x(), model->model_maxbbox.y(), model->model_maxbbox.z());
- gl::vertex(model->model_minbbox.x(), model->model_maxbbox.y(), model->model_minbbox.z());
- gl::vertex(model->model_minbbox.x(), model->model_minbbox.y(), model->model_maxbbox.z());
- gl::vertex(model->model_minbbox.x(), model->model_minbbox.y(), model->model_minbbox.z());
- gl::vertex(model->model_maxbbox.x(), model->model_minbbox.y(), model->model_maxbbox.z());
- gl::vertex(model->model_maxbbox.x(), model->model_minbbox.y(), model->model_minbbox.z());
+ gl::vertex(model->box().max().x(), model->box().max().y(), model->box().max().z());
+ gl::vertex(model->box().max().x(), model->box().max().y(), model->box().min().z());
+ gl::vertex(model->box().min().x(), model->box().max().y(), model->box().max().z());
+ gl::vertex(model->box().min().x(), model->box().max().y(), model->box().min().z());
+ gl::vertex(model->box().min().x(), model->box().min().y(), model->box().max().z());
+ gl::vertex(model->box().min().x(), model->box().min().y(), model->box().min().z());
+ gl::vertex(model->box().max().x(), model->box().min().y(), model->box().max().z());
+ gl::vertex(model->box().max().x(), model->box().min().y(), model->box().min().z());
gl::end();
}