Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@telenet.be>2020-07-16 17:02:49 +0200
committerStijn Buys <ingar@telenet.be>2020-07-16 17:02:49 +0200
commit6521936cdaa2132ee6860dfda335d0afbe958484 (patch)
tree67c496c44c83c7c7f1ee42ee240498a760904307
parent01f4578c8ee667f0357f6967f89f8e03462041cd (diff)
Read collision meshes from OBJ files. Do not read meshes if the material has the Ignore flag set.
-rw-r--r--src/model/objfile.cc128
-rw-r--r--src/model/objfile.h7
2 files changed, 93 insertions, 42 deletions
diff --git a/src/model/objfile.cc b/src/model/objfile.cc
index 49a691f..323986b 100644
--- a/src/model/objfile.cc
+++ b/src/model/objfile.cc
@@ -34,6 +34,9 @@ OBJFile::OBJFile(std::string const &name)
// reset counters
obj_normalcount = 0;
+
+ obj_collisionmodel = nullptr;
+ obj_load_clip = false;
}
OBJFile::~OBJFile()
@@ -132,9 +135,11 @@ bool OBJFile::read()
std::string materialname;
material = 0;
- if (line >> materialname) {
- for(MaterialList::iterator it = obj_materiallist.begin(); it != obj_materiallist.end(); ++it) {
- if( (*it).second->name() == materialname) {
+ if (line >> materialname)
+ {
+ for(MaterialList::iterator it = obj_materiallist.begin(); it != obj_materiallist.end(); ++it)
+ {
+ if( (*it).second->name().compare(materialname) == 0) {
material = (*it).second;
current_m = (*it).first;
break;
@@ -146,12 +151,12 @@ bool OBJFile::read()
obj_materiallist[obj_materiallist.size()] = material;
current_m = obj_materiallist.size()-1;
}
- }
- else
+ } else {
con_warn << objfile_name << " invalid material definition at line " << index_line << std::endl;
+ }
- } else if (word.compare("v") == 0) { /* new wertex */
+ } else if (word.compare("v") == 0) { /* new vertex */
float x, y, z;
line >> x >> y >> z;
@@ -159,14 +164,14 @@ bool OBJFile::read()
obj_vertexlist[obj_vertexlist.size()] = v;
obj_box.expand(*v * SCALE);
- } else if (word.compare("vt") == 0) { /* wertex texture coordinate */
+ } else if (word.compare("vt") == 0) { /* vertex texture coordinate */
float u, v;
line >> u >> v;
math::Vector2f *uv = new math::Vector2f(u, v);
obj_uvlist[obj_uvlist.size()] = uv;
- } else if (word.compare("vn") == 0) { /* wertex wormal */
+ } else if (word.compare("vn") == 0) { /* vertex normal */
float x, y, z;
line >> x >> y >> z;
@@ -352,34 +357,64 @@ bool OBJFile::read()
//Go through tri and quad lists and create fragments for each material
size_t total_m = obj_materiallist.size();
- for(size_t i = 0; i <= total_m; i++) {
+ for(size_t i = 0; i < total_m; i++)
+ {
material = obj_materiallist[i];
- fragment = new Fragment(Fragment::Triangles, material);
- for(TriList::iterator it = obj_trilist.begin(); it != obj_trilist.end(); ++it) {
- if((*it).first == i) {
- fragment->add_vertex(((*it).second->v0() * SCALE) , (*it).second->n0(), (*it).second->t0(), false);
- fragment->add_vertex(((*it).second->v1() * SCALE) , (*it).second->n1(), (*it).second->t1(), false);
- fragment->add_vertex(((*it).second->v2() * SCALE) , (*it).second->n2(), (*it).second->t2(), false);
+ if (material->has_flag_clip()) // add mesh to the collision model if the material has the Clip flag set
+ {
+ CollisionMesh *collisionmesh = new CollisionMesh();
+
+ // add triangles to the collision mesh
+ for(TriList::iterator it = obj_trilist.begin(); it != obj_trilist.end(); ++it)
+ {
+ if((*it).first == i)
+ {
+ collisionmesh->add_triangle((*it).second->v0() * SCALE, (*it).second->v1() * SCALE, (*it).second->v2() * SCALE);
+ }
}
- }
-
- if( fragment->structural_size() + fragment->detail_size() > 0 )
- obj_fragmentgroup->add_fragment(fragment);
- fragment = new Fragment(Fragment::Quads, material);
-
- for(QuadList::iterator it = obj_quadlist.begin(); it != obj_quadlist.end(); ++it) {
- if((*it).first == i) {
- fragment->add_vertex(((*it).second->v0() * SCALE) , (*it).second->n0(), (*it).second->t0(), false);
- fragment->add_vertex(((*it).second->v1() * SCALE) , (*it).second->n1(), (*it).second->t1(), false);
- fragment->add_vertex(((*it).second->v2() * SCALE) , (*it).second->n2(), (*it).second->t2(), false);
- fragment->add_vertex(((*it).second->v3() * SCALE) , (*it).second->n3(), (*it).second->t3(), false);
+ for(QuadList::iterator it = obj_quadlist.begin(); it != obj_quadlist.end(); ++it)
+ {
+ if((*it).first == i)
+ {
+ collisionmesh->add_triangle((*it).second->v0() * SCALE, (*it).second->v1() * SCALE, (*it).second->v2() * SCALE);
+ collisionmesh->add_triangle((*it).second->v2() * SCALE, (*it).second->v3() * SCALE, (*it).second->v0() * SCALE);
+ }
}
+
+ obj_collisionmodel->add_mesh(collisionmesh);
+ }
+ else if (!material->has_flag_ignore()) // do not load meshes if the material has the Ignore flag
+ {
+
+ fragment = new Fragment(Fragment::Triangles, material);
+
+ for(TriList::iterator it = obj_trilist.begin(); it != obj_trilist.end(); ++it) {
+ if((*it).first == i) {
+ fragment->add_vertex(((*it).second->v0() * SCALE) , (*it).second->n0(), (*it).second->t0(), false);
+ fragment->add_vertex(((*it).second->v1() * SCALE) , (*it).second->n1(), (*it).second->t1(), false);
+ fragment->add_vertex(((*it).second->v2() * SCALE) , (*it).second->n2(), (*it).second->t2(), false);
+ }
+ }
+
+ if( fragment->structural_size() + fragment->detail_size() > 0 )
+ obj_fragmentgroup->add_fragment(fragment);
+
+ fragment = new Fragment(Fragment::Quads, material);
+
+ for(QuadList::iterator it = obj_quadlist.begin(); it != obj_quadlist.end(); ++it) {
+ if((*it).first == i) {
+ fragment->add_vertex(((*it).second->v0() * SCALE) , (*it).second->n0(), (*it).second->t0(), false);
+ fragment->add_vertex(((*it).second->v1() * SCALE) , (*it).second->n1(), (*it).second->t1(), false);
+ fragment->add_vertex(((*it).second->v2() * SCALE) , (*it).second->n2(), (*it).second->t2(), false);
+ fragment->add_vertex(((*it).second->v3() * SCALE) , (*it).second->n3(), (*it).second->t3(), false);
+ }
+ }
+
+ if( fragment->structural_size() + fragment->detail_size() > 0 )
+ obj_fragmentgroup->add_fragment(fragment);
}
-
- if( fragment->structural_size() + fragment->detail_size() > 0 )
- obj_fragmentgroup->add_fragment(fragment);
}
return true;
@@ -387,22 +422,34 @@ bool OBJFile::read()
Model *OBJFile::load(const std::string &name)
{
+
OBJFile objfile(name);
-
if (!objfile.is_open()) {
- return 0;
+ return nullptr;
}
- if (!objfile.read()) {
- return 0;
- }
-
- if (!objfile.fragmentgroup()->size())
- return 0;
-
// create a new model
Model *model = new Model(name);
+ // load clip into collision meshes
+ // if the model has been loaded before (e.g. on r_restart), the collision model won't be reloaded
+ objfile.obj_collisionmodel = CollisionModel::find(name);
+ if (!objfile.obj_collisionmodel)
+ {
+ objfile.obj_load_clip = true;
+ objfile.obj_collisionmodel = new CollisionModel(name);
+ CollisionModel::add(objfile.obj_collisionmodel);
+ } else {
+ objfile.obj_load_clip = false;
+ }
+ model->set_collisionmodel(objfile.obj_collisionmodel);
+
+ if (!objfile.read() || !objfile.fragmentgroup()->size())
+ {
+ con_warn << " " << objfile.name() << " empty model" << std::endl;
+ return model;
+ }
+
// center model around (0,0,0) and set the bounding box
math::Vector3f obj_center((objfile.box().min() + objfile.box().max()) * 0.5f);
model->model_box.assign(
@@ -414,7 +461,8 @@ Model *OBJFile::load(const std::string &name)
objfile.fragmentgroup()->set_location(obj_center * -1.0f);
- for (FragmentGroup::Fragments::const_iterator fit = objfile.fragmentgroup()->fragments().begin(); fit != objfile.fragmentgroup()->fragments().end(); fit++) {
+ for (FragmentGroup::Fragments::const_iterator fit = objfile.fragmentgroup()->fragments().begin(); fit != objfile.fragmentgroup()->fragments().end(); ++fit)
+ {
const Fragment *fragment = (*fit);
if(fragment->type() == Fragment::Triangles)
diff --git a/src/model/objfile.h b/src/model/objfile.h
index 7db90bc..b8286dc 100644
--- a/src/model/objfile.h
+++ b/src/model/objfile.h
@@ -32,7 +32,7 @@ class OBJFile
public:
/**
* @brief load a .obj file into a Model
- * @param name name of the model to be loaded, without .obj extension or models/ prefix
+ * @param name name of the model to be loaded, without .obj extension.
* If the file can not be read, load() returns the NULL-pointer
*/
static Model *load(std::string const &name);
@@ -66,7 +66,7 @@ private:
bool read();
/**
- * @brief parse a line in the .obj file.
+ * @brief parse a line in the .obj file
*/
void readline(std::string const &line);
@@ -112,6 +112,9 @@ private:
FragmentGroup *obj_fragmentgroup;
size_t obj_normalcount;
+
+ bool obj_load_clip;
+ CollisionModel *obj_collisionmodel;
};
} // namespace model