From 302f11ce816ffe4b51f48c42972bb58475bcca5d Mon Sep 17 00:00:00 2001 From: Stijn Buys 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(-) 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::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::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::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::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 class_origin_vertices; + /** + * @brief list of vertices with bounds material + */ + std::vector 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 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