From 035653e94a3d74b8f18c993034199d7cd08a895a Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Fri, 21 Jan 2011 14:41:35 +0000 Subject: Support structures for complex entity collision, renamed sv_arrysize cvar to mem_vertex. --- src/model/mapfile.cc | 146 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 94 insertions(+), 52 deletions(-) (limited to 'src/model/mapfile.cc') diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc index 5e18a0d..bfe19c0 100644 --- a/src/model/mapfile.cc +++ b/src/model/mapfile.cc @@ -7,6 +7,7 @@ #include "auxiliary/functions.h" #include "filesystem/filesystem.h" #include "math/mathlib.h" +#include "model/collisionmesh.h" #include "model/mapfile.h" #include "model/material.h" #include "model/model.h" @@ -147,6 +148,8 @@ MapFile::MapFile() map_brushes = 0; map_faces = 0; map_faces_detail = 0; + + map_load_clip = false; in_patchdef = false; warning_q2brush = false; @@ -924,32 +927,36 @@ void MapFile::make_brushface(Face *face) Vector3f face_normal(face->normal()* -1); face_normal.normalize(); - // split polygon into quads - while (vl.size() > 3) { - std::vector::iterator v0 = vl.begin(); - std::vector::reverse_iterator vn = vl.rbegin(); - std::vector::reverse_iterator vn1 = vl.rbegin(); - ++vn1; - std::vector::reverse_iterator vn2 = vl.rbegin(); - ++vn2; - ++vn2; - - Quad *quad = new Quad(*(*vn2) * SCALE, *(*vn1) * SCALE, *(*vn) * SCALE, *(*v0) * SCALE, face_normal, face->detail()); - primitives->add_quad(quad); + // clip faces have to be triangulated and can not be split into quads + if (!(face->material()->flags() & Material::Clip)) { + + // split polygon into quads + while (vl.size() > 3) { + std::vector::iterator v0 = vl.begin(); + std::vector::reverse_iterator vn = vl.rbegin(); + std::vector::reverse_iterator vn1 = vl.rbegin(); + ++vn1; + std::vector::reverse_iterator vn2 = vl.rbegin(); + ++vn2; + ++vn2; + + Quad *quad = new Quad(*(*vn2) * SCALE, *(*vn1) * SCALE, *(*vn) * SCALE, *(*v0) * SCALE, face_normal, face->detail()); + primitives->add_quad(quad); + + if (face->material()->flags() & Material::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))); + quad->t3().assign(map_texture_coords(face, *(*v0))); + } - if (face->material()->flags() & Material::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))); - quad->t3().assign(map_texture_coords(face, *(*v0))); + delete(*vn); + delete(*vn1); + vl.pop_back(); + vl.pop_back(); } - - delete(*vn); - delete(*vn1); - vl.pop_back(); - vl.pop_back(); } - + // split polygon into triangles while (vl.size() > 2) { std::vector::iterator v0 = vl.begin(); @@ -965,11 +972,12 @@ void MapFile::make_brushface(Face *face) triangle->t1().assign(map_texture_coords(face, *(*vn))); triangle->t2().assign(map_texture_coords(face, *(*v0))); } + delete(*vn); vl.pop_back(); } } else { - con_warn << name() << " unresolved face at line " << line() << std::endl; + con_warn << name() << " unresolved brush face at line " << line() << std::endl; } // clean up the vertex list @@ -1170,38 +1178,47 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t // store triangles if (primitives->triangles().size()) { - Fragment *fragment = new Fragment(Fragment::Triangles, primitives->material()); - - // add structural triangles to the fragment - for (Primitives::Triangles::iterator tris_it = primitives->triangles().begin(); tris_it != primitives->triangles().end(); tris_it++) { - Triangle *triangle = (*tris_it); - if (!triangle->detail()) { - size_t count = 0; - count += fragment->add_vertex(triangle->v0() - translation, triangle->normal(), triangle->t0(), false); - count += fragment->add_vertex(triangle->v1() - translation, triangle->normal(), triangle->t1(), false); - count += fragment->add_vertex(triangle->v2() - translation, triangle->normal(), triangle->t2(), false); - if (count == 3) - model->model_tris_count++; + if (!(primitives->material()->flags() & Material::Clip)) { + Fragment *fragment = new Fragment(Fragment::Triangles, primitives->material()); + + // add structural triangles to the fragment + for (Primitives::Triangles::iterator tris_it = primitives->triangles().begin(); tris_it != primitives->triangles().end(); tris_it++) { + Triangle *triangle = (*tris_it); + if (!triangle->detail()) { + size_t count = 0; + count += fragment->add_vertex(triangle->v0() - translation, triangle->normal(), triangle->t0(), false); + count += fragment->add_vertex(triangle->v1() - translation, triangle->normal(), triangle->t1(), false); + count += fragment->add_vertex(triangle->v2() - translation, triangle->normal(), triangle->t2(), false); + if (count == 3) + model->model_tris_count++; + } } - } - // add detail triangles to the fragment - for (Primitives::Triangles::iterator tris_it = primitives->triangles().begin(); tris_it != primitives->triangles().end(); tris_it++) { - Triangle *triangle = (*tris_it); - if (triangle->detail()) { - size_t count = 0; - count += fragment->add_vertex(triangle->v0() - translation, triangle->normal(), triangle->t0(), true); - count += fragment->add_vertex(triangle->v1() - translation, triangle->normal(), triangle->t1(), true); - count += fragment->add_vertex(triangle->v2() - translation, triangle->normal(), triangle->t2(), true); - if (count == 3) { - model->model_tris_count++; - model->model_tris_detail_count++; + // add detail triangles to the fragment + for (Primitives::Triangles::iterator tris_it = primitives->triangles().begin(); tris_it != primitives->triangles().end(); tris_it++) { + Triangle *triangle = (*tris_it); + if (triangle->detail()) { + size_t count = 0; + count += fragment->add_vertex(triangle->v0() - translation, triangle->normal(), triangle->t0(), true); + count += fragment->add_vertex(triangle->v1() - translation, triangle->normal(), triangle->t1(), true); + count += fragment->add_vertex(triangle->v2() - translation, triangle->normal(), triangle->t2(), true); + if (count == 3) { + model->model_tris_count++; + model->model_tris_detail_count++; + } } } - } - // add the fragment to the group - group->add_fragment(fragment); + // add the fragment to the group + group->add_fragment(fragment); + + } else if (map_load_clip) { + // clip materials are loaded into the CollisionArray + for (Primitives::Triangles::iterator tris_it = primitives->triangles().begin(); tris_it != primitives->triangles().end(); tris_it++) { + Triangle *triangle = (*tris_it); + model->collisionmesh()->add_triangle(triangle->v0(), triangle->v1(), triangle->v2()); + } + } } // store quads @@ -1309,9 +1326,23 @@ Model * MapFile::load(std::string const &name) unsigned int u; float r, s; std::string str; + + // load clip into collision mesh + // if the model has been loaded before (e.g. on r_restart), the collision mesh won't be reloaded + // submodel clip will not be imported + model->set_collisionmesh(CollisionMesh::find(name)); + + if (CollisionMesh::initialized() && !model->collisionmesh()) { + mapfile.map_load_clip = true; + + // create a collision mesh instance for the model + model->set_collisionmesh(new CollisionMesh(name)); + + } else { + mapfile.map_load_clip = false; + } while (mapfile.getline()) { - if (mapfile.got_classname("worldspawn")) { mapfile.clear_bbox(); @@ -1861,6 +1892,17 @@ Model * MapFile::load(std::string const &name) model->model_tris_detail_count << "/" << model->model_tris_count << " detail/tris " << model->model_quad_detail_count << "/" << model->model_quad_count << " detail/quads" << std::endl; + if (mapfile.map_load_clip) { + if (!model->collisionmesh()->size()) { + // delete empty collision meshes + delete model->collisionmesh(); + model->set_collisionmesh(0); + } else { + // add the collision mesh to the registry + CollisionMesh::add(model->collisionmesh()); + con_debug << " " << mapfile.name() << " " << model->collisionmesh()->size() << " collision triangles" << std::endl; + } + } return model; } -- cgit v1.2.3