diff options
| -rw-r--r-- | src/client/soundext.cc | 2 | ||||
| -rw-r--r-- | src/core/entity.cc | 4 | ||||
| -rw-r--r-- | src/core/gameserver.cc | 15 | ||||
| -rw-r--r-- | src/game/base/game.cc | 118 | ||||
| -rw-r--r-- | src/game/base/game.h | 10 | ||||
| -rw-r--r-- | src/math/Makefile.am | 20 | ||||
| -rw-r--r-- | src/math/boundingbox3f.cc | 53 | ||||
| -rw-r--r-- | src/math/boundingbox3f.h | 113 | ||||
| -rw-r--r-- | src/math/mathlib.h | 2 | ||||
| -rw-r--r-- | src/model/asefile.cc | 34 | ||||
| -rw-r--r-- | src/model/asefile.h | 8 | ||||
| -rw-r--r-- | src/model/mapfile.cc | 83 | ||||
| -rw-r--r-- | src/model/mapfile.h | 10 | ||||
| -rw-r--r-- | src/model/model.h | 13 | ||||
| -rw-r--r-- | src/render/camera.cc | 6 | ||||
| -rw-r--r-- | src/render/draw.cc | 32 | 
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 ¢er) : +	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 ¢er) +{ +	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 ¢er); +	 +	/** +	 * @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 ¢er); +	 +	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();  }  | 
