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/asefile.cc169
-rw-r--r--src/model/asefile.h16
-rw-r--r--src/model/triangle.cc2
-rw-r--r--src/model/triangle.h11
4 files changed, 156 insertions, 42 deletions
diff --git a/src/model/asefile.cc b/src/model/asefile.cc
index 657d73c..d94f103 100644
--- a/src/model/asefile.cc
+++ b/src/model/asefile.cc
@@ -53,10 +53,17 @@ ASEFile::~ASEFile()
}
ase_facelist.clear();
- for (MaterialList::iterator it = ase_materiallist.begin(); it != ase_materiallist.end(); it++) {
- (*it).second = 0;
+ for (MaterialList::iterator it = ase_materials.begin(); it != ase_materials.end(); it++) {
+ SubMaterialList *submaterials = (*it).second;
+
+ for (SubMaterialList::iterator smit = submaterials->begin(); smit != submaterials->end(); smit++) {
+ (*smit).second = 0;
+ }
+ submaterials->clear();
+ delete submaterials;
+ (*it).second = 0;
}
- ase_materiallist.clear();
+ ase_materials.clear();
if (asefile_ifs.is_open())
asefile_ifs.close();
@@ -86,7 +93,7 @@ bool ASEFile::read_header(std::istream &is)
return true;
}
-Material *ASEFile::read_material(std::istream &is)
+Material *ASEFile::read_submaterial(std::istream &is)
{
Material *material = 0;
char data[1024];
@@ -107,16 +114,6 @@ Material *ASEFile::read_material(std::istream &is)
while ((line.get(c)) && (c != '"'))
n += c;
- // ignore caulk
- if (n.compare("common/caulk") == 0) {
- material = 0;
- continue;
- }
- if (n.compare("textures/common/caulk") == 0) {
- material = 0;
- continue;
- }
-
// find material
material = Material::find(n);
if (!material) {
@@ -124,7 +121,7 @@ Material *ASEFile::read_material(std::istream &is)
Material::add(material);
material->set_texture(material->name());
}
-
+
} else {
do {
if (word.compare("{") == 0) {
@@ -135,13 +132,80 @@ Material *ASEFile::read_material(std::istream &is)
} while (line >> word);
}
- if (level == 0)
+ if (level == 0) {
return material;
+ }
}
return material;
}
+ASEFile::SubMaterialList *ASEFile::read_material(std::istream &is)
+{
+ SubMaterialList *submaterials = new SubMaterialList;
+ std::string materialname;
+
+ char data[1024];
+ memset(data, 0, sizeof(data));
+ int level = 1;
+ size_t index = 0;
+
+ while (is.getline(data, sizeof(data) - 1)) {
+
+ std::istringstream line(data);
+ std::string word;
+ line >> word;
+
+ if ((level == 1) && (word.compare("*MATERIAL_NAME") == 0)) {
+ // read material name
+ std::string n;
+ char c;
+ while ((line.get(c)) && (c != '"'));
+ while ((line.get(c)) && (c != '"'))
+ n += c;
+
+ materialname.assign(n);
+
+ } else if ((level == 1) && (word.compare("*SUBMATERIAL") == 0)) {
+
+ if ((line >> index) && (line >> word) && (word.compare("{") == 0)) {
+ // this material defines submaterials, we ignore the parent definition
+ materialname.clear();
+
+ // add material to the submaterial list
+ (*submaterials)[index] = read_submaterial(is);
+ }
+
+ } else {
+ do {
+ if (word.compare("{") == 0) {
+ level++;
+ } else if (word.compare("}") == 0) {
+ level--;
+ }
+ } while (line >> word);
+ }
+
+ if (level == 0) {
+
+ if (materialname.size()) {
+ // no submaterials, add a single material to the submaterial list
+ Material *material = Material::find(materialname);
+ if (!material) {
+ material = new Material(materialname);
+ Material::add(material);
+ material->set_texture(materialname);
+ }
+ (*submaterials)[0] = material;
+ }
+
+ return submaterials;
+ }
+ }
+
+ return submaterials;
+}
+
bool ASEFile::read_material_list(std::istream &is)
{
char data[1024];
@@ -158,8 +222,8 @@ bool ASEFile::read_material_list(std::istream &is)
if ((level == 1) && (word.compare("*MATERIAL") == 0)) {
if ((line >> index) && (line >> word) && (word.compare("{") == 0)) {
// add material to the ase material list
- ase_materiallist[index] = read_material(is);
- //con_debug << " " << name() << " " << "*MATERIAL " << index << " " << ase_materiallist[index]->name() << std::endl;
+ ase_materials[index] = read_material(is);
+ //con_debug << " " << name() << " " << "*MATERIAL " << index << " " << ase_materials[index]->name() << std::endl;
}
} else {
@@ -237,17 +301,28 @@ bool ASEFile::read_mesh_face_list(std::istream &is)
(line >> word) && (line >> a) &&
(line >> word) && (line >> b) &&
(line >> word) && (line >> c)) {
-
+
+ size_t index;
+
if (facestr.size() && facestr[facestr.size()-1] == ':') {
facestr.erase(facestr.size() - 1);
}
-
- size_t index;
+
std::istringstream faceindexstr(facestr);
- faceindexstr >> index;
-
- Triangle *triangle = new Triangle(*ase_vertexlist[a], *ase_vertexlist[b], *ase_vertexlist[c]);
- ase_facelist[index] = triangle;
+ if (faceindexstr >> index) {
+ Triangle *triangle = new Triangle(*ase_vertexlist[a], *ase_vertexlist[b], *ase_vertexlist[c]);
+ ase_facelist[index] = triangle;
+
+ while (line >> word) {
+ if (word.compare("*MESH_MTLID") == 0) {
+ size_t submaterial_index = 0;
+ if (line >> submaterial_index) {
+ triangle->set_material_index(submaterial_index);
+ }
+ }
+ }
+ }
+
}
ase_facecount++;
}
@@ -472,7 +547,7 @@ bool ASEFile::read_geom(std::istream &is)
char data[1024];
memset(data, 0, sizeof(data));
int level = 1;
- Material *material = 0;
+ SubMaterialList *submateriallist = 0;
while (is.getline(data, sizeof(data) - 1)) {
@@ -492,9 +567,11 @@ bool ASEFile::read_geom(std::istream &is)
//con_debug << " " << name() << " " << "*MATERIAL_REF " << index << std::endl;
// find the Material for index
- MaterialList::iterator it = ase_materiallist.find(index);
- if (it != ase_materiallist.end()) {
- material = (*it).second;
+ MaterialList::iterator it = ase_materials.find(index);
+ if (it != ase_materials.end()) {
+ submateriallist = (*it).second;
+ } else {
+ submateriallist = 0;
}
}
} else {
@@ -510,16 +587,30 @@ bool ASEFile::read_geom(std::istream &is)
if (level == 0) {
// import only if the material is defined and there actually are triangles to import
- if (material && ase_facelist.size()) {
- // load GEOMOBJECT triangles in a model fragment
- Fragment *fragment = new Fragment(Fragment::Triangles, material);
- ase_fragmentgroup->add_fragment(fragment);
-
- for (FaceList::iterator it = ase_facelist.begin(); it != ase_facelist.end(); it++) {
- Triangle *triangle = (*it).second;
- fragment->add_vertex((triangle->v0() * SCALE) , triangle->n0(), triangle->t0(), false);
- fragment->add_vertex((triangle->v1() * SCALE) , triangle->n1(), triangle->t1(), false);
- fragment->add_vertex((triangle->v2() * SCALE) , triangle->n2(), triangle->t2(), false);
+ if (submateriallist && ase_facelist.size()) {
+
+ // iterate submaterial list, create a fragment per material
+ for (SubMaterialList::iterator smit = submateriallist->begin(); smit != submateriallist->end(); smit++) {
+ size_t submaterial_index = (*smit).first;
+ Material *material = (*smit).second;
+
+ // load GEOMOBJECT triangles with matching material into the fragment
+ Fragment *fragment = new Fragment(Fragment::Triangles, material);
+ for (FaceList::iterator it = ase_facelist.begin(); it != ase_facelist.end(); it++) {
+
+ Triangle *triangle = (*it).second;
+ if (triangle->material_index() == submaterial_index) {
+ fragment->add_vertex((triangle->v0() * SCALE) , triangle->n0(), triangle->t0(), false);
+ fragment->add_vertex((triangle->v1() * SCALE) , triangle->n1(), triangle->t1(), false);
+ fragment->add_vertex((triangle->v2() * SCALE) , triangle->n2(), triangle->t2(), false);
+ }
+ }
+
+ if (fragment->structural_size() + fragment->detail_size() > 0) {
+ ase_fragmentgroup->add_fragment(fragment);
+ } else {
+ delete fragment;
+ }
}
}
diff --git a/src/model/asefile.h b/src/model/asefile.h
index d8e3aea..9e3fea6 100644
--- a/src/model/asefile.h
+++ b/src/model/asefile.h
@@ -35,9 +35,14 @@ public:
private:
/**
+ * @brief type definition for a list of submaterials in the ASE file
+ */
+ typedef std::map<size_t, Material *> SubMaterialList;
+
+ /**
* @brief type definition for a list of materials in the ASE file
*/
- typedef std::map<size_t, Material *> MaterialList;
+ typedef std::map<size_t, SubMaterialList *> MaterialList;
/**
* @brief type definition for a list of vertices in a GEOMOBJECT
@@ -53,9 +58,14 @@ private:
~ASEFile();
/**
+ * @brief read *SUBMATERIAL
+ */
+ Material *read_submaterial(std::istream &is);
+
+ /**
* @brief read *MATERIAL
*/
- Material *read_material(std::istream &is);
+ SubMaterialList *read_material(std::istream &is);
/**
* @brief read *MATERIAL_LIST
@@ -142,7 +152,7 @@ private:
FaceList ase_facelist;
- MaterialList ase_materiallist;
+ MaterialList ase_materials;
math::Vector3f ase_maxbbox;
diff --git a/src/model/triangle.cc b/src/model/triangle.cc
index 0fb7224..47b5ac3 100644
--- a/src/model/triangle.cc
+++ b/src/model/triangle.cc
@@ -15,6 +15,7 @@ Triangle::Triangle(const math::Vector3f &v0, const math::Vector3f &v1, const mat
triangle_v2(v2)
{
triangle_detail = false;
+ triangle_material_index = 0;
}
Triangle::Triangle(const math::Vector3f &v0, const math::Vector3f &v1, const math::Vector3f &v2, const math::Vector3f &normal, const bool detail) :
@@ -27,6 +28,7 @@ Triangle::Triangle(const math::Vector3f &v0, const math::Vector3f &v1, const ma
triangle_normal(normal)
{
triangle_detail = detail;
+ triangle_material_index = 0;
}
Triangle::~Triangle()
diff --git a/src/model/triangle.h b/src/model/triangle.h
index 06a8810..d07f67d 100644
--- a/src/model/triangle.h
+++ b/src/model/triangle.h
@@ -86,6 +86,16 @@ public:
inline math::Vector3f &normal() {
return triangle_normal;
}
+
+ /// material inde
+ inline size_t material_index() const {
+ return triangle_material_index;
+ }
+
+ /// set material index
+ inline void set_material_index(const size_t index) {
+ triangle_material_index = index;
+ }
private:
@@ -103,6 +113,7 @@ private:
math::Vector3f triangle_normal;
bool triangle_detail;
+ size_t triangle_material_index;
};
}