From 302f11ce816ffe4b51f48c42972bb58475bcca5d Mon Sep 17 00:00:00 2001
From: Stijn Buys <ingar@osirion.org>
Date: Sat, 16 Nov 2013 18:25:03 +0000
Subject: Material API cleanups, added support for bounds materials.

---
 src/model/asefile.cc   |  2 +-
 src/model/mapfile.cc   | 42 +++++++++++++++++++++++++++++++-----------
 src/model/mapfile.h    |  9 ++++++++-
 src/model/material.cc  |  6 +++++-
 src/model/material.h   | 44 ++++++++++++++++++++++++++++++++++++++------
 src/render/state.cc    | 10 +++++-----
 src/render/textures.cc |  2 +-
 7 files changed, 89 insertions(+), 26 deletions(-)

(limited to 'src')

diff --git a/src/model/asefile.cc b/src/model/asefile.cc
index 608dac3..ffc0e9d 100644
--- a/src/model/asefile.cc
+++ b/src/model/asefile.cc
@@ -583,7 +583,7 @@ bool ASEFile::read_geom(std::istream &is)
 					size_t submaterial_index = (*smit).first;
 					Material *material = (*smit).second;
 
-					if (!material->ignore_is_set()) {
+					if (!material->has_flag_ignore()) {
 						
 						// load GEOMOBJECT triangles with matching material into the fragment
 						Fragment *fragment = new Fragment(Fragment::Triangles, material);
diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc
index d4632e2..c687124 100644
--- a/src/model/mapfile.cc
+++ b/src/model/mapfile.cc
@@ -165,6 +165,12 @@ MapFile::MapFile()
 MapFile::~MapFile()
 {
 	clear_materials();
+	
+	// delete bounds vertices
+	for (std::vector<math::Vector3f *>::iterator bvit = map_bounds_vertices.begin(); bvit != map_bounds_vertices.end(); ++bvit) {
+		delete (*bvit);
+	}
+	map_bounds_vertices.clear();
 }
 
 void MapFile::clear_materials()
@@ -397,7 +403,7 @@ bool MapFile::read_patchdef()
 	}
 	
 	// ignore materials with the 'Ignore' flag set
-	if (material->ignore_is_set()) {
+	if (material->has_flag_ignore()) {
 		return true;
 	}
 	
@@ -527,7 +533,7 @@ bool MapFile::read_patchdef()
 			for (size_t i = 0; i < subdivide_u; i++) {
 				for (size_t j = 0; j < subdivide_v; j++) {
 				
-					if (material->flag_is_set(Material::FlagClip)) {
+					if (material->has_flag_clip()) {
 						
 						// if the current material is clip, the patch needs to be converted to triangles
 						if (map_load_clip) {
@@ -754,7 +760,7 @@ void MapFile::make_brushface(Face *face)
 	using math::Vector3f;
 
 	// ignore materials with the 'Ignore' flag set
-	if (face->material()->ignore_is_set()) {
+	if (face->material()->has_flag_ignore()) {
 		return;
 	}
 
@@ -954,12 +960,17 @@ void MapFile::make_brushface(Face *face)
 			primitives = (*mit).second;
 		}
 
-		if (face->material()->origin_is_set()) {
+		if (face->material()->has_flag_origin()) {
 			// add vertices to the origin list
 			for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); ++it) {
 				class_origin_vertices.push_back(new math::Vector3f((*(*it) * SCALE)));
 			}
 			
+		} else if (face->material()->has_flag_bounds()) {
+			// add vertices to the bounds list
+			for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); ++it) {
+				map_bounds_vertices.push_back(new math::Vector3f((*(*it) * SCALE)));
+			}
 		} else {
 		
 			// add vertices to the bounding box
@@ -972,7 +983,7 @@ void MapFile::make_brushface(Face *face)
 			face_normal.normalize();
 
 			// clip faces have to be triangulated and can not be split into quads
-			if (!face->material()->flag_is_set(Material::FlagClip)) {
+			if (!face->material()->has_flag_clip()) {
 				
 				// split polygon into quads
 				while (vl.size() > 3) {
@@ -987,7 +998,7 @@ void MapFile::make_brushface(Face *face)
 					Quad *quad = new Quad(*(*vn2) * SCALE, *(*vn1) * SCALE, *(*vn) * SCALE, *(*v0) * SCALE, face_normal, face->detail());
 					primitives->add_quad(quad);
 
-					if (face->material()->flag_is_set(Material::FlagTexture)) {
+					if (face->material()->has_flag_texture()) {
 						quad->t0().assign(map_texture_coords(face, *(*vn2)));
 						quad->t1().assign(map_texture_coords(face, *(*vn1)));
 						quad->t2().assign(map_texture_coords(face, *(*vn)));
@@ -1011,7 +1022,7 @@ void MapFile::make_brushface(Face *face)
 				Triangle * triangle = new Triangle(*(*vn1) * SCALE, *(*vn) * SCALE, *(*v0) * SCALE, face_normal, face->detail());
 				primitives->add_triangle(triangle);
 
-				if (face->material()->flag_is_set(Material::FlagTexture)) {
+				if (face->material()->has_flag_texture()) {
 					triangle->t0().assign(map_texture_coords(face, *(*vn1)));
 					triangle->t1().assign(map_texture_coords(face, *(*vn)));
 					triangle->t2().assign(map_texture_coords(face, *(*v0)));
@@ -1245,7 +1256,7 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t
 		// store triangles
 		if (primitives->triangles().size()) {
 			
-			if (primitives->material()->flag_is_set(Material::FlagClip)) {
+			if (primitives->material()->has_flag_clip()) {
 				
 				if (map_load_clip) {
 					// clip materials are loaded into the CollisionMesh
@@ -2048,16 +2059,25 @@ Model * MapFile::load(std::string const &name)
 		delete tag_submodel;
 	}		
 	
-	// center model around (0,0,0) and set the bounding box
+	// center model around (0,0,0) and set the bounding box	
+	if (mapfile.map_bounds_vertices.size()) {
+		
+		// bounds vertices override the calculated box
+		mapfile.map_box.assign(MAX_BOUNDS, -MAX_BOUNDS);
+		for (std::vector<math::Vector3f *>::iterator bvit = mapfile.map_bounds_vertices.begin(); bvit != mapfile.map_bounds_vertices.end(); ++bvit) {
+			mapfile.map_box.expand(*(*bvit));
+		}
+	}
+	
 	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 * -1.0f);
-
+	
 	// translate transformed vertex groups
 	size_t frags = 0;
 	for (Model::Groups::iterator git = model->groups().begin(); git != model->groups().end(); ++git) {
diff --git a/src/model/mapfile.h b/src/model/mapfile.h
index 551943e..32b2c84 100644
--- a/src/model/mapfile.h
+++ b/src/model/mapfile.h
@@ -203,9 +203,16 @@ private:
 	bool			class_engine;
 
 	
-	/// list of vertices with the origin material within the current map class
+	/**
+	 *@brief  list of vertices with origin material
+	 * */
 	std::vector<math::Vector3f *> class_origin_vertices;
 	
+	/**
+	 * @brief list of vertices with bounds material
+	*/
+	std::vector<math::Vector3f *> map_bounds_vertices;
+	
 	Materials		map_materials;
 	TriangleList		map_collisiontriangles;
 
diff --git a/src/model/material.cc b/src/model/material.cc
index f8ffbc0..25c1f27 100644
--- a/src/model/material.cc
+++ b/src/model/material.cc
@@ -81,6 +81,9 @@ void Material::print()
 		if (flags() & FlagDecal) {
 			con_print << "decal ";
 		}
+		if (flags() & FlagBounds) {
+			con_print << "bounds ";
+		}
 	}	
 	con_print << std::endl;
 	
@@ -279,7 +282,8 @@ void Material::load_shader(const std::string &shadername)
 					material->set_flags(FlagOrigin);
 				} else if (firstword.compare("decal") == 0) {
 					material->set_flags(FlagDecal);
-
+				} else if (firstword.compare("bounds") == 0) {
+					material->set_flags(FlagBounds);
 				} else if (firstword.compare("qer_editorimage") == 0) {
 					// keyword qer_editorimage is ignored
 					continue;
diff --git a/src/model/material.h b/src/model/material.h
index 6c332e2..94b4418 100644
--- a/src/model/material.h
+++ b/src/model/material.h
@@ -27,7 +27,7 @@ public:
 	enum ColorType {ColorMaterial = 0, ColorPrimary = 1, ColorSecondary = 2, ColorTertiary = 3, ColorEngine = 4 };
 	
 	/// surface flags
-	enum SurfaceFlags { FlagNone = 0, FlagBright = 1,FlagEnvironment = 2, FlagTexture = 4, FlagIgnore = 8, FlagClip = 16, FlagOrigin = 32, FlagDecal = 64 };
+	enum SurfaceFlags { FlagNone = 0, FlagBright = 1,FlagEnvironment = 2, FlagTexture = 4, FlagIgnore = 8, FlagClip = 16, FlagOrigin = 32, FlagDecal = 64, FlagBounds = 128 };
 
 	/// type definition for the material registry
 	typedef std::map<std::string, Material *> Registry;
@@ -78,24 +78,48 @@ public:
 	/**
 	 * @brief returns true if the material has the requested flag set
 	 * */
-	inline bool flag_is_set(const SurfaceFlags surfaceflag) const {
+	inline bool has_flag(const SurfaceFlags surfaceflag) const {
 		return (((int) material_flags & surfaceflag) == surfaceflag);
 	}
 	
+	/**
+	 * @brief returns true if the material has the Texture flag set
+	 * @see flags()
+	 * */
+	inline bool has_flag_texture() const {
+		return (has_flag(FlagTexture));
+	}
+	
+	/**
+	 * @brief returns true if the material has the Clip flag set
+	 * @see flags()
+	 * */
+	inline bool has_flag_clip() const {
+		return (has_flag(FlagClip));
+	}
+	
 	/**
 	 * @brief returns true if the material has the Ignore flag set
 	 * @see flags()
 	 * */
-	inline bool ignore_is_set() const {
-		return (flag_is_set(FlagIgnore));
+	inline bool has_flag_ignore() const {
+		return (has_flag(FlagIgnore));
+	}
+	
+	/**
+	 * @brief returns true if the material has the Origin flag set
+	 * @see flags()
+	 * */
+	inline bool has_flag_origin() const {
+		return (has_flag(FlagOrigin));
 	}
 	
 	/**
 	 * @brief returns true if the material has the Origin flag set
 	 * @see flags()
 	 * */
-	inline bool origin_is_set() const {
-		return (flag_is_set(FlagOrigin));
+	inline bool has_flag_bounds() const {
+		return (has_flag(FlagBounds));
 	}
 		
 	/* ---- mutators ------------------------------------------- */
@@ -130,10 +154,18 @@ public:
 	void set_colortype(ColorType colortype);
 	
 
+	/**
+	 * @brief set a specified surface flag
+	 * @see flags()
+	 * */
 	inline void set_flags(SurfaceFlags flags) {
 		material_flags |= flags;
 	}
 
+	/**
+	 * @brief clear a specified surface flag
+	 * @see flags()
+	 * */
 	inline void unset_flags(SurfaceFlags flags) {
 		material_flags &= ~flags;
 	}
diff --git a/src/render/state.cc b/src/render/state.cc
index df9a001..400a186 100644
--- a/src/render/state.cc
+++ b/src/render/state.cc
@@ -237,7 +237,7 @@ void State::use_material(const model::Material * material) {
 	}
 
 	// material has the decal flag set
-	if (material->flag_is_set(model::Material::FlagDecal)) {
+	if (material->has_flag(model::Material::FlagDecal)) {
 		gl::enable(GL_POLYGON_OFFSET_FILL);
 		gl::enable(GL_ALPHA_TEST);
 		gl::polygonoffset(-1,-1);
@@ -289,7 +289,7 @@ void State::use_material(const model::Material * material) {
 	}
 
 	// lighted or fullbright
-	if (state_power && (material->flag_is_set(model::Material::FlagBright))) {
+	if (state_power && (material->has_flag(model::Material::FlagBright))) {
 		gl::disable(GL_LIGHTING);
 		
 	} else if (state_power && (material->colortype() == model::Material::ColorEngine)) {
@@ -300,12 +300,12 @@ void State::use_material(const model::Material * material) {
 	}
 	
 	// texture
-	if (material->flag_is_set(model::Material::FlagTexture)) {
+	if (material->has_flag(model::Material::FlagTexture)) {
 
 		Textures::bind(material->texture_id());
 		gl::enable(GL_TEXTURE_2D);
 		
-		if (material->flag_is_set(model::Material::FlagEnvironment)) {
+		if (material->has_flag(model::Material::FlagEnvironment)) {
 			gl::texgen(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
 			gl::texgen(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
 				
@@ -315,7 +315,7 @@ void State::use_material(const model::Material * material) {
 
 	} else {	
 		// envmapped without texture: use the skybox as envmap
-		if (material->flag_is_set(model::Material::FlagEnvironment)) {
+		if (material->has_flag(model::Material::FlagEnvironment)) {
 			if (core::localplayer()->zone()->sky().size()) {
 				gl::enable(GL_TEXTURE_CUBE_MAP);
 				
diff --git a/src/render/textures.cc b/src/render/textures.cc
index 05c73da..5a90640 100644
--- a/src/render/textures.cc
+++ b/src/render/textures.cc
@@ -418,7 +418,7 @@ size_t Textures::bind(const size_t texture, const bool filter)
 
 void Textures::material_loader(model::Material *material)
 {
-	if (material->flag_is_set(model::Material::FlagTexture) && (material->texture().size() > 0)) {
+	if (material->has_flag(model::Material::FlagTexture) && (material->texture().size() > 0)) {
 		size_t id = load(material->texture());
 		material->set_texture_id(id);
 		material->set_size(texture_size[id]);
-- 
cgit v1.2.3