Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2011-01-21 14:41:35 +0000
committerStijn Buys <ingar@osirion.org>2011-01-21 14:41:35 +0000
commit035653e94a3d74b8f18c993034199d7cd08a895a (patch)
tree6acc56c14a86b499657b6e7faaf50f9e6f7ff57d /src/model/mapfile.cc
parent4af61dca099d2b7010d4fa83833ceeeef01b0b0f (diff)
Support structures for complex entity collision,
renamed sv_arrysize cvar to mem_vertex.
Diffstat (limited to 'src/model/mapfile.cc')
-rw-r--r--src/model/mapfile.cc146
1 files changed, 94 insertions, 52 deletions
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<Vector3f *>::iterator v0 = vl.begin();
- std::vector<Vector3f *>::reverse_iterator vn = vl.rbegin();
- std::vector<Vector3f *>::reverse_iterator vn1 = vl.rbegin();
- ++vn1;
- std::vector<Vector3f *>::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<Vector3f *>::iterator v0 = vl.begin();
+ std::vector<Vector3f *>::reverse_iterator vn = vl.rbegin();
+ std::vector<Vector3f *>::reverse_iterator vn1 = vl.rbegin();
+ ++vn1;
+ std::vector<Vector3f *>::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<Vector3f *>::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;
}