Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
Diffstat (limited to 'src/model')
-rw-r--r--src/model/Makefile.am2
-rw-r--r--src/model/collisionmesh.cc27
-rw-r--r--src/model/collisionmesh.h31
-rw-r--r--src/model/collisionmodel.cc76
-rw-r--r--src/model/collisionmodel.h111
-rw-r--r--src/model/mapfile.cc83
-rw-r--r--src/model/mapfile.h1
-rw-r--r--src/model/model.cc6
-rw-r--r--src/model/model.h12
9 files changed, 279 insertions, 70 deletions
diff --git a/src/model/Makefile.am b/src/model/Makefile.am
index de6d902..3552392 100644
--- a/src/model/Makefile.am
+++ b/src/model/Makefile.am
@@ -6,6 +6,7 @@ noinst_LTLIBRARIES = libmodel.la
noinst_HEADERS = \
asefile.h \
collisionmesh.h \
+ collisionmodel.h \
face.h \
fragment.h \
mapfile.h \
@@ -21,6 +22,7 @@ noinst_HEADERS = \
libmodel_la_SOURCES = \
asefile.cc \
collisionmesh.cc \
+ collisionmodel.cc \
face.cc \
fragment.cc \
mapfile.cc \
diff --git a/src/model/collisionmesh.cc b/src/model/collisionmesh.cc
index 5d4505a..5d2328a 100644
--- a/src/model/collisionmesh.cc
+++ b/src/model/collisionmesh.cc
@@ -26,7 +26,7 @@ void CollisionMesh::shutdown()
void CollisionMesh::add(CollisionMesh *collisionmesh)
{
- collisionmesh_registry[collisionmesh->name()] = collisionmesh;
+ collisionmesh_registry.push_back(collisionmesh);
}
void CollisionMesh::clear()
@@ -34,26 +34,16 @@ void CollisionMesh::clear()
con_debug << " clearing collision meshes" << std::endl;
for (Registry::iterator i = collisionmesh_registry.begin(); i != collisionmesh_registry.end(); ++i) {
- delete (*i).second;
- (*i).second = 0;
+ delete (*i);
+ (*i) = 0;
}
collisionmesh_registry.clear();
}
-CollisionMesh *CollisionMesh::find(const std::string &name)
-{
- for (Registry::iterator i = collisionmesh_registry.begin(); i != collisionmesh_registry.end(); ++i) {
- if ((*i).first.compare(name) == 0)
- return (*i).second;
- }
-
- return 0;
-}
-
-CollisionMesh::CollisionMesh(const std::string &name) :
- collisionmesh_name(name)
+CollisionMesh::CollisionMesh()
{
+ collisionmesh_type = FragmentGroup::None;
collisionmesh_size = 0;
// btTriangleMesh (bool use32bitIndices=true, bool use4componentVertices=true)
collisionmesh_triangles = new btTriangleMesh(true, false);
@@ -64,6 +54,11 @@ CollisionMesh::~CollisionMesh()
delete collisionmesh_triangles;
}
+void CollisionMesh::set_type(const FragmentGroup::Type type)
+{
+ collisionmesh_type = type;
+}
+
void CollisionMesh::add_triangle(const math::Vector3f & v0, const math::Vector3f & v1, const math::Vector3f & v2)
{
collisionmesh_triangles->addTriangle(
@@ -72,7 +67,7 @@ void CollisionMesh::add_triangle(const math::Vector3f & v0, const math::Vector3f
to_btVector3(v2),
true
);
- collisionmesh_size += 1;
+ collisionmesh_size++;
}
} // namespace model
diff --git a/src/model/collisionmesh.h b/src/model/collisionmesh.h
index 9efd21a..cbd063a 100644
--- a/src/model/collisionmesh.h
+++ b/src/model/collisionmesh.h
@@ -8,6 +8,7 @@
#define __INCLUDED_MODEL_COLLISIONMESH_H__
#include "math/mathlib.h"
+#include "model/fragment.h"
#include "BulletCollision/CollisionShapes/btTriangleMesh.h"
@@ -17,23 +18,23 @@
namespace model
{
+/**
+ * @brief a collection of triangles, representing the collision geometry of a model
+ * A CollisionModel consists of a number of collisionmeshes.
+ * */
class CollisionMesh
{
public:
- /// type definition for the material registry
- typedef std::map<std::string, CollisionMesh *> Registry;
+ /// type definition for the collisionmesh registry
+ typedef std::list<CollisionMesh *> Registry;
- CollisionMesh(const std::string &name);
+ CollisionMesh();
~CollisionMesh();
/* ---- inspectors ----------------------------------------- */
- inline const std::string &name() const {
- return collisionmesh_name;
- }
-
/**
* @brief the number of triangles in the collision mesh
*/
@@ -41,10 +42,6 @@ public:
return collisionmesh_size;
}
- static bool initialized() {
- return collisionmesh_initialized;
- }
-
/**
* @brief the bullet triangle mesh object
*/
@@ -53,6 +50,11 @@ public:
}
/* ---- mutators ------------------------------------------- */
+
+ /**
+ * @brief change the group type
+ * */
+ void set_type(const FragmentGroup::Type type);
/**
* @brief add a triangle to the collision mesh
@@ -86,15 +88,20 @@ public:
*/
static void add(CollisionMesh *collisionmesh);
+
+ static bool initialized() {
+ return collisionmesh_initialized;
+ }
+
private:
/// the materials registry
static Registry collisionmesh_registry;
static bool collisionmesh_initialized;
- std::string collisionmesh_name;
size_t collisionmesh_size;
btTriangleMesh *collisionmesh_triangles;
+ FragmentGroup::Type collisionmesh_type;
};
} // namespace model
diff --git a/src/model/collisionmodel.cc b/src/model/collisionmodel.cc
new file mode 100644
index 0000000..d52c9bc
--- /dev/null
+++ b/src/model/collisionmodel.cc
@@ -0,0 +1,76 @@
+/*
+ model/collisionmodel.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "sys/sys.h"
+#include "model/collisionmodel.h"
+
+namespace model {
+
+CollisionModel::CollisionModel(const std::string & label) :
+ collisionmodel_label(label)
+{
+
+}
+
+CollisionModel::~CollisionModel()
+{
+ // clear the list of meshes, do not delete the meshes
+ for (CollisionMeshes::iterator it = collisionmodel_meshes.begin(); it != collisionmodel_meshes.end(); it++) {
+ (*it) = 0;
+ }
+ collisionmodel_meshes.clear();
+}
+
+void CollisionModel::add_mesh(CollisionMesh *mesh)
+{
+ collisionmodel_meshes.push_back(mesh);
+}
+
+/* ---- static methods --------------------------------------------- */
+
+CollisionModel::Registry CollisionModel::collisionmodel_registry;
+
+void CollisionModel::init()
+{
+ CollisionMesh::init();
+ clear();
+}
+
+void CollisionModel::shutdown()
+{
+ clear();
+ CollisionMesh::shutdown();
+}
+
+CollisionModel *CollisionModel::find(const std::string & label)
+{
+ for (Registry::iterator it = collisionmodel_registry.begin(); it != collisionmodel_registry.end(); it++) {
+ CollisionModel *cmodel = (*it);
+ if (cmodel->label().compare(label) == 0)
+ return cmodel;
+
+ }
+ return 0;
+}
+
+void CollisionModel::clear()
+{
+ for (Registry::iterator it = collisionmodel_registry.begin(); it != collisionmodel_registry.end(); it++) {
+ CollisionModel *collisionmodel = (*it);
+ delete collisionmodel;
+ (*it) = 0;
+ }
+ collisionmodel_registry.clear();
+ con_debug << " clearing collision models" << std::endl;
+
+}
+
+void CollisionModel::add(CollisionModel *collisionmodel)
+{
+ collisionmodel_registry.push_back(collisionmodel);
+}
+
+} //namespace model \ No newline at end of file
diff --git a/src/model/collisionmodel.h b/src/model/collisionmodel.h
new file mode 100644
index 0000000..04268d2
--- /dev/null
+++ b/src/model/collisionmodel.h
@@ -0,0 +1,111 @@
+/*
+ model/collisionmodel.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_MODEL_COLLISIONMODEL_H__
+#define __INCLUDED_MODEL_COLLISIONMODEL_H__
+
+#include <list>
+#include <string>
+
+#include "math/mathlib.h"
+#include "model/collisionmesh.h"
+
+namespace model
+{
+
+/**
+ * @brief a container class for collision geometry
+ * The CollisionModel class holds a list of references to one or more CollisionMeshes.
+ * It is referenced by a single Model, and the static registry takes ownership of the
+ * CollisionModel instances. This is because a Model can be reloaded while the game is running,
+ * but the CollisionMeshes are tied to bullet physics and can not be reloaded on the fly.
+ * Note that the CollisionModel doesn't own its meshes either, it merely reference them.
+ * CollisionMeshes are stored in the static CollisionMesh::registry() and can be referenced
+ * by multiple CollisionModels.
+ */
+class CollisionModel
+{
+public:
+ /**
+ * @brief type definition for the CollisionModel registry
+ * */
+ typedef std::list<CollisionModel *> Registry;
+
+ /**
+ * @brief type definition for a lost of collision meshes
+ * */
+ typedef std::list<CollisionMesh *> CollisionMeshes;
+
+ /**
+ * @brief create a new collisionmodel with a give label
+ * */
+ CollisionModel(const std::string & label);
+ ~CollisionModel();
+
+ inline const std::string &label() const {
+ return collisionmodel_label;
+ }
+
+ /**
+ * @brief returns the number of meshes this collision model consists of
+ * */
+ inline const size_t size() const {
+ return collisionmodel_meshes.size();
+ }
+
+ /**
+ * @brief the collection of meshes this model consists of
+ * */
+ inline CollisionMeshes & meshes() {
+ return collisionmodel_meshes;
+ }
+
+ /**
+ * @brief add a mesh to the CollisionModel
+ * CollisionModel does not take ownership of the COllisionMesh,
+ * the mesh should be registered with the CollisionMesh::registry
+ * */
+ void add_mesh(CollisionMesh *mesh);
+
+ /**
+ * @brief initialize the CollisionModel registry
+ * init() calls clear()
+ * */
+ static void init();
+
+ /**
+ * @brief shutdown the CollisionModel registry
+ * shutdown() calls clear()
+ * */
+ static void shutdown();
+
+ /**
+ * @brief clear the CollisionModel registry and delete all CollisionModel instances it holds
+ * */
+ static void clear();
+
+ /**
+ * @brief add a CollisionModel to the registry
+ * the models label should be unique and not yet exist in the registry.
+ * */
+ static void add(CollisionModel *collisionmodel);
+
+ /**
+ * @brief search the registry for a model with a particular label, returns 0 if not found.
+ * */
+ static CollisionModel *find(const std::string & label);
+
+private:
+ std::string collisionmodel_label;
+ CollisionMeshes collisionmodel_meshes;
+
+ static Registry collisionmodel_registry;
+
+}; // class CollisionModel
+
+} // namespace model
+
+#endif // __INCLUDED_MODEL_COLLISIONMODEL_H__
diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc
index 20d4c5c..92349c0 100644
--- a/src/model/mapfile.cc
+++ b/src/model/mapfile.cc
@@ -174,6 +174,8 @@ void MapFile::clear_materials()
delete(*mit).second;
}
map_materials.clear();
+
+ map_collisiontriangles.clear();
}
bool MapFile::open(std::string const & mapname)
@@ -357,12 +359,12 @@ bool MapFile::read_patchdef()
std::string word;
if (!(linestream >> word)) {
- //con_debug << "Error reading trialing line ')'" << std::endl;
+ //con_debug << "Error reading trailing line ')'" << std::endl;
return false;
}
if (word.compare(")") != 0) {
- //con_debug << "No trialing line ')'" << std::endl;
+ //con_debug << "No trailing line ')'" << std::endl;
return false;
}
}
@@ -1300,8 +1302,25 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t
}
- // add the group to the model
+ // add the vertexgroup to the model
model->add_group(group);
+
+ // add collision triangles
+ if (map_load_clip) {
+ if (map_collisiontriangles.size()) {
+ CollisionMesh *collisionmesh = new CollisionMesh();
+
+ // add clip triangles to collision mesh
+ for (TriangleList::iterator it = map_collisiontriangles.begin(); it != map_collisiontriangles.end(); it++) {
+ Triangle *triangle = (*it);
+ collisionmesh->add_triangle(triangle->v0() - translation, triangle->v1() - translation, triangle->v2() - translation);
+ }
+
+ // add the collision mesh to the collision model
+ model->collisionmodel()->add_mesh(collisionmesh);
+ }
+ }
+
}
void MapFile::unknown_value() const
@@ -1365,17 +1384,18 @@ Model * MapFile::load(std::string const &name)
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;
+ // load clip into collision meshes
+ // if the model has been loaded before (e.g. on r_restart), the collision model won't be reloaded
+ mapfile.map_collisionmodel = CollisionModel::find(name);
+ if (!mapfile.map_collisionmodel) {
+ mapfile.map_load_clip = true;
+ mapfile.map_collisionmodel = new CollisionModel(name);
+ CollisionModel::add(mapfile.map_collisionmodel);
} else {
mapfile.map_load_clip = false;
}
-
+ model->set_collisionmodel(mapfile.map_collisionmodel);
+
while (mapfile.getline()) {
if (mapfile.got_classname("worldspawn")) {
mapfile.clear_bbox();
@@ -1840,6 +1860,12 @@ Model * MapFile::load(std::string const &name)
delete groupdst;
}
}
+
+ /* TODO
+ *
+ * import submodel collision meshes
+ */
+
// copy light tags
for (Model::Lights::const_iterator lit = submodel_model->lights().begin(); lit != submodel_model->lights().end(); lit++) {
@@ -1921,31 +1947,22 @@ Model * MapFile::load(std::string const &name)
con_warn << mapfile.name() << " quake2 style brushes detected" << std::endl;
con_debug << " " << mapfile.name() << " " << mapfile.map_brushes << " brushes " <<
- model->model_tris_detail_count << "/" << model->model_tris_count << " detail/tris " <<
- model->model_quad_detail_count << "/" << model->model_quad_count << " detail/quads" << std::endl;
+ model->model_tris_count << " triangles " <<
+ model->model_quad_count << " quads" << std::endl;
- if (mapfile.map_load_clip) {
- if (mapfile.map_collisiontriangles.size()) {
-
- CollisionMesh *collisionmesh = new CollisionMesh(name);
-
- // add clip triangles to collision mesh
- for (TriangleList::iterator it = mapfile.map_collisiontriangles.begin(); it != mapfile.map_collisiontriangles.end(); it++) {
- Triangle *triangle = (*it);
- collisionmesh->add_triangle(triangle->v0() - map_center, triangle->v1() - map_center, triangle->v2() - map_center);
- }
-
- // TODO merge submodel collision meshes
- // seperate collision meshes for movers
-
- // register the mesh
- CollisionMesh::add(collisionmesh);
- model->set_collisionmesh(collisionmesh);
-
- con_debug << " " << mapfile.name() << " " << model->collisionmesh()->size() << " collision triangles" << std::endl;
+ if (mapfile.map_load_clip && model->collisionmodel() && model->collisionmodel()->meshes().size()) {
+ size_t collision_tris_count = 0; // total number of triangles in the collision model
+ size_t collision_mesh_count = 0; // number of meshes in the collision model
+
+ for (CollisionModel::CollisionMeshes::const_iterator cmit = model->collisionmodel()->meshes().begin();
+ cmit != model->collisionmodel()->meshes().end(); cmit++) {
+ collision_tris_count += (*cmit)->size();
+ collision_mesh_count++;
}
+
+ con_debug << " " << mapfile.name() << " collision " << collision_tris_count << " triangles " << collision_mesh_count << " meshes" << std::endl;
}
-
+
return model;
}
diff --git a/src/model/mapfile.h b/src/model/mapfile.h
index b576384..011c01d 100644
--- a/src/model/mapfile.h
+++ b/src/model/mapfile.h
@@ -184,6 +184,7 @@ private:
bool last_read_was_classend;
bool map_load_clip;
+ CollisionModel *map_collisionmodel;
unsigned int map_brushes;
unsigned int map_faces;
diff --git a/src/model/model.cc b/src/model/model.cc
index d1805df..ab89dae 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -30,7 +30,7 @@ Model::Model(const std::string & name) :
model_quad_detail_count = 0;
model_quad_count = 0;
- model_collisionmesh = 0;
+ model_collisionmodel = 0;
}
Model::~Model()
@@ -72,8 +72,8 @@ Model::~Model()
model_sounds.clear();
}
-void Model::set_collisionmesh(CollisionMesh *collisionmesh)
-{ model_collisionmesh = collisionmesh;
+void Model::set_collisionmodel(CollisionModel *collisionmodel)
+{ model_collisionmodel = collisionmodel;
}
diff --git a/src/model/model.h b/src/model/model.h
index 8e3d82d..c15213c 100644
--- a/src/model/model.h
+++ b/src/model/model.h
@@ -13,7 +13,7 @@
#include "math/mathlib.h"
-#include "model/collisionmesh.h"
+#include "model/collisionmodel.h"
#include "model/tags.h"
#include "model/fragment.h"
@@ -76,8 +76,8 @@ public:
return model_groups;
}
- inline CollisionMesh *collisionmesh() {
- return model_collisionmesh;
+ inline CollisionModel *collisionmodel() {
+ return model_collisionmodel;
}
/// list of model light tags
@@ -150,8 +150,8 @@ public:
/// set model radius
void set_radius(const float radius);
- /// set model collision mesh
- void set_collisionmesh(CollisionMesh *collisionmesh);
+ /// set collision model
+ void set_collisionmodel(CollisionModel *collisionmodel);
/// set model origin
void set_origin(const math::Vector3f &origin);
@@ -206,7 +206,7 @@ private:
Groups model_groups;
float model_radius;
static Registry model_registry;
- CollisionMesh *model_collisionmesh;
+ CollisionModel *model_collisionmodel;
};
}