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>2010-10-15 13:02:33 +0000
committerStijn Buys <ingar@osirion.org>2010-10-15 13:02:33 +0000
commitc3097a768077fa9251a70de10bd29aff3c8553e1 (patch)
treedebfce077e8d16ee8772cf1bb8532975a5e2507a /src/model/asefile.cc
parent862f1dc0ae63b476b620a817bb2ea73d9b35ef3f (diff)
added parsing of ASE submaterial definitions
Diffstat (limited to 'src/model/asefile.cc')
-rw-r--r--src/model/asefile.cc169
1 files changed, 130 insertions, 39 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;
+ }
}
}