+
+void mesh::load_material(std::istream& stream)
+{
+ materials_.push_back(material(read_string(stream)));
+
+ std::string atom;
+ stream >> atom;
+ materials_.back().diffuse = read_color(stream);
+ stream >> atom;
+ materials_.back().ambient = read_color(stream);
+ stream >> atom;
+ materials_.back().emissive = read_color(stream);
+ stream >> atom;
+ materials_.back().specular = read_color(stream);
+
+ stream >> atom >> materials_.back().shininess;
+ stream >> atom >> materials_.back().diffuse[3];
+ materials_.back().diffuse[3] = SCALAR(1.0) - materials_.back().diffuse[3];
+}
+
+mesh::object_ptr mesh::load_object(std::istream& stream, object_ptr parent)
+{
+ std::string atom;
+ stream >> atom;
+ if (atom != "world" && atom != "group" && atom != "poly")
+ {
+ throw_invalid_atom(atom);
+ }
+
+ object_ptr obj = object::alloc(*this);
+
+ if (parent)
+ {
+ parent->kids.push_back(obj);
+ obj->parent = parent;
+ }
+ else
+ {
+ objects_.push_back(obj);
+ }
+
+ return obj;
+}
+
+void mesh::load_surface(std::istream& stream, object_ptr obj)
+{
+ std::string atom;
+ read_hex(stream);
+
+ int material = 0;
+ stream >> atom;
+ if (atom == "mat") stream >> material >> atom;
+ if (atom != "refs") throw_invalid_atom(atom);
+
+ int numrefs = 0;
+ stream >> numrefs;
+ ASSERT(numrefs >= 3);
+
+ if ((int)obj->faces.size() <= material) obj->faces.resize(material + 1);
+ material_group& face = obj->faces[material];
+
+ std::vector<unsigned> verts(numrefs);
+ std::vector<vector2> uv(numrefs);
+
+ for (int i = 0; i < numrefs; ++i)
+ {
+ stream >> verts[i];
+ uv[i] = read_pair(stream);
+ }
+
+ // translate texture coordinates
+ if (obj->texture) obj->texture->fix_uv(uv);
+ // TODO why isn't texture always defined at this point?
+
+ for (int i = 0; i < numrefs; ++i)
+ {
+ scalar vert = verts[i];
+ vector2 texcoord = uv[i];
+ if (vert < face.triangles_uv.size())
+ {
+ if (texcoord != face.triangles_uv[vert])
+ {
+ obj->verts.push_back(obj->verts[vert]);
+ face.triangles_uv.resize(obj->verts.size());
+ vert = obj->verts.size() - 1;
+ }
+ }
+ else face.triangles_uv.resize(vert + 1);
+ face.triangles_uv[vert] = texcoord;
+ verts[i] = vert;
+ }
+
+ face.triangles.push_back(verts[0]);
+ face.triangles.push_back(verts[1]);
+ face.triangles.push_back(verts[2]);
+ for (int i = 3; i < numrefs; ++i)
+ {
+ face.triangles.push_back(verts[0]);
+ face.triangles.push_back(verts[i-1]);
+ face.triangles.push_back(verts[i]);
+ }
+
+#if 0
+ unsigned vert;
+ stream >> vert;
+ vector2 uv = read_pair(stream);
+ if (vert < face.triangles_uv.size())
+ {
+ if (uv != face.triangles_uv[vert])
+ {
+ obj->verts.push_back(obj->verts[vert]);
+ face.triangles_uv.resize(obj->verts.size());
+ vert = obj->verts.size() - 1;
+ }
+ }
+ else face.triangles_uv.resize(vert + 1);
+ face.triangles_uv[vert] = uv;
+ face.triangles.push_back(vert);
+
+ unsigned first = vert;
+
+ stream >> vert;
+ uv = read_pair(stream);
+ if (vert < face.triangles_uv.size())
+ {
+ if (uv != face.triangles_uv[vert])
+ {
+ obj->verts.push_back(obj->verts[vert]);
+ face.triangles_uv.resize(obj->verts.size());
+ vert = obj->verts.size() - 1;
+ }
+ }
+ else face.triangles_uv.resize(vert + 1);
+ face.triangles_uv[vert] = uv;
+ face.triangles.push_back(vert);
+
+ stream >> vert;
+ uv = read_pair(stream);
+ if (vert < face.triangles_uv.size())
+ {
+ if (uv != face.triangles_uv[vert])
+ {
+ obj->verts.push_back(obj->verts[vert]);
+ face.triangles_uv.resize(obj->verts.size());
+ vert = obj->verts.size() - 1;
+ }
+ }
+ else face.triangles_uv.resize(vert + 1);
+ face.triangles_uv[vert] = uv;
+ face.triangles.push_back(vert);
+
+ unsigned last = vert;
+
+ for (int j = 3; j < numrefs; ++j)
+ {
+ face.triangles.push_back(first);
+ face.triangles.push_back(last);
+
+ stream >> vert;
+ uv = read_pair(stream);
+ if (vert < face.triangles_uv.size())
+ {
+ if (uv != face.triangles_uv[vert])
+ {
+ obj->verts.push_back(obj->verts[vert]);
+ face.triangles_uv.resize(obj->verts.size());
+ vert = obj->verts.size() - 1;
+ }
+ }
+ else face.triangles_uv.resize(vert + 1);
+ face.triangles_uv[vert] = uv;
+ face.triangles.push_back(vert);
+
+ last = face.triangles.back();
+ }
+#endif
+}
+