X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Fmesh.cc;h=e380adfd19d6eb2ea9e9bc2bc9799eb0c2bf8362;hp=ee4d4b62540c22c3ff5a19c891cf145fe238ed49;hb=e9a16d767785b1a903a4466ff26265a5f7dae9e5;hpb=1fb5f7e36af1a4de040bc2989133703b0e0d4a9f diff --git a/src/moof/mesh.cc b/src/moof/mesh.cc index ee4d4b6..e380adf 100644 --- a/src/moof/mesh.cc +++ b/src/moof/mesh.cc @@ -25,6 +25,8 @@ #include "mesh.hh" #include "opengl.hh" +// TODO: this file needs to be cleaned up + #define AC3D_FORMAT_VERSION (0x0b) #define ZLIB_BUF_SIZE (262114) @@ -33,6 +35,9 @@ namespace moof { +MOOF_REGISTER_RESOURCE(mesh, ac, models); + + static std::string read_string(std::istream& stream) { std::string str; @@ -85,15 +90,21 @@ inline vector2 read_pair(std::istream& stream) return triplet; } - -template -inline vector< scalar, fixed > read_triplet(std::istream& stream) +inline vector3 read_triplet(std::istream& stream) { - vector< scalar, fixed > triplet; + vector3 triplet; stream >> triplet[0] >> triplet[1] >> triplet[2]; return triplet; } +inline vector4 read_color(std::istream& stream) +{ + vector4 color; + stream >> color[0] >> color[1] >> color[2]; + color[3] = SCALAR(1.0); + return color; +} + void mesh::import(std::istream& stream) { @@ -130,20 +141,18 @@ void mesh::import(std::istream& stream) materials_.push_back(material(read_string(stream))); stream >> atom; - materials_.back().diffuse = read_triplet<4>(stream); + materials_.back().diffuse = read_color(stream); stream >> atom; - materials_.back().ambient = read_triplet<3>(stream); + materials_.back().ambient = read_color(stream); stream >> atom; - materials_.back().emissive = read_triplet<3>(stream); + materials_.back().emissive = read_color(stream); stream >> atom; - materials_.back().specular = read_triplet<3>(stream); + materials_.back().specular = read_color(stream); stream >> atom >> materials_.back().shininess; - stream >> atom >> materials_.back().diffuse[3]; // transparency - materials_.back().diffuse[3] = 1.0; - - log_info("read material", materials_.back().name, - materials_.back().diffuse); + stream >> atom >> materials_.back().diffuse[3]; + materials_.back().diffuse[3] = SCALAR(1.0) - + materials_.back().diffuse[3]; } else if (atom == "OBJECT") { @@ -153,7 +162,7 @@ void mesh::import(std::istream& stream) throw std::runtime_error("unexpected object type " + atom); } - object_ptr newObj = object::alloc(); + object_ptr newObj = object::alloc(*this); if (obj) { @@ -169,7 +178,12 @@ void mesh::import(std::istream& stream) } else if (atom == "name") { - if (obj) obj->name = read_string(stream); + if (obj) + { + obj->name = read_string(stream); + object_ptr parent = obj->parent.lock(); + if (parent) parent->kids_byname.insert(std::make_pair(obj->name, obj)); + } else throw std::runtime_error("unexpected atom: " + atom); } else if (atom == "data") @@ -208,12 +222,9 @@ void mesh::import(std::istream& stream) int numvert = 0; stream >> numvert; - log_warning("adding verts", numvert); - for (int i = 0; i < numvert; ++i) { - obj->verts.push_back(read_triplet<3>(stream)); - log_error("vert", obj->verts.back()); + obj->verts.push_back(read_triplet(stream)); } } else if (atom == "numsurf") @@ -228,8 +239,7 @@ void mesh::import(std::istream& stream) stream >> atom; if (atom != "SURF") throw std::runtime_error("uh oh"); - int flags = read_hex(stream); - log_info(flags); + read_hex(stream); int material = 0; stream >> atom; @@ -242,68 +252,134 @@ void mesh::import(std::istream& stream) int numrefs = 0; stream >> numrefs; - ASSERT(numrefs == 3 || numrefs == 4); + ASSERT(numrefs >= 3); if ((int)obj->faces.size() <= material) { - log_info("inserting face..."); - //obj->faces.insert(obj->faces.begin() + material, - //material_group()); obj->faces.resize(material + 1); - log_info("inserted face", material, obj->faces.size()); } - material_group& face = obj->faces[material]; - for (int j = 0; j < numrefs; ++j) + + unsigned vert; + stream >> vert; + vector2 uv = read_pair(stream); + if (vert < face.triangles_uv.size()) { - int vert; - stream >> vert; + 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); - vector2 uv = read_pair(stream); + 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); - if (numrefs == 3) + stream >> vert; + uv = read_pair(stream); + if (vert < face.triangles_uv.size()) + { + if (uv != face.triangles_uv[vert]) { - face.triangles.push_back(vert); - face.triangles_uv.push_back(uv); + obj->verts.push_back(obj->verts[vert]); + face.triangles_uv.resize(obj->verts.size()); + vert = obj->verts.size() - 1; } - else + } + 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()) { - face.quads.push_back(vert); - face.quads_uv.push_back(uv); + 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(); } } } else if (atom == "kids") { - for (int i = kids.size(); i > 0; --i) - { - if (--kids.top() <= 0) - { - ASSERT(obj && "should be an object"); - obj = obj->parent; - kids.pop(); - } - else break; - } + //while (0 < kids.size()) + //{ + //if (--kids.top() <= 0) + //{ + //ASSERT(obj && "should be an object"); + //obj = obj->parent; + //kids.pop(); + //} + //else break; + //} int numkids = 0; stream >> numkids; - if (numkids > 0) kids.push(numkids); - - if (kids.size() > 0) + if (0 < numkids) kids.push(numkids); + else { - log_info("KIDS", kids.top(), "|", kids.size()); + if (0 < kids.size() && 0 < --kids.top()) kids.pop(); + obj = obj->parent.lock(); } } - else - { - log_warning("UNKNOWN ATOM:", atom); - } } while (stream); } +//unsigned mesh::read_vertex_line(std::istream& stream) +//{ + //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); +//} + + mesh::mesh(const std::string& path) { @@ -382,16 +458,15 @@ mesh::mesh(const std::string& path) void mesh::draw(scalar alpha) const { - //glEnableClientState(GL_VERTEX_ARRAY); - //glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - std::vector::const_iterator it; for (it = objects_.begin(); it != objects_.end(); ++it) { - (*it)->draw(*this, alpha); + (*it)->draw(alpha); } + + // TODO: disable vertex array? } @@ -402,116 +477,68 @@ void mesh::set_material(int index) const void mesh::set_material(const material& material) const { - //glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material.diffuse.data()); - //glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material.ambient.data()); - //glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material.specular.data()); - //glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material.emissive.data()); - //glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.shininess); glColor(material.diffuse); + glMaterial(GL_FRONT, GL_DIFFUSE, material.diffuse); + glMaterial(GL_FRONT, GL_AMBIENT, material.ambient); + glMaterial(GL_FRONT, GL_SPECULAR, material.specular); + glMaterial(GL_FRONT, GL_EMISSION, material.emissive); + glMaterial(GL_FRONT, GL_SHININESS, material.shininess); } -void mesh::object::draw(const mesh& mesh, scalar alpha) const +void mesh::object::draw(scalar alpha, bool recurse) const { - //log_info("cool", verts.size()); - //{ - //image::reset_binding(); - //std::vector::const_iterator it; - //glBegin(GL_LINE_STRIP); - //for (it = verts.begin(); it != verts.end(); ++it) - //{ - //glVertex(*it); - //} - //glEnd(); - //} - - glPolygonMode(GL_BACK, GL_LINE); - //glVertexPointer(3, GL_SCALAR, 0, verts[0].data()); - if (texture) texture->bind(); - else image::reset_binding(); + glVertexPointer(verts); - for (int i = 0; i < faces.size(); ++i) + if (texture) { - const material_group& face = faces[i]; - mesh.set_material(i); - //it->draw(alpha); - //std::vector::const_iterator jt; - int count = face.triangles.size(); - for (int j = 0; j < count; j += 3) - { - glBegin(GL_TRIANGLES); - glTexCoord(face.triangles_uv[j]); - glVertex(verts[face.triangles[j]]); - glTexCoord(face.triangles_uv[j+1]); - glVertex(verts[face.triangles[j+1]]); - glTexCoord(face.triangles_uv[j+2]); - glVertex(verts[face.triangles[j+2]]); - glEnd(); - } - - count = face.quads.size(); - for (int j = 0; j < count; j += 4) - { - glBegin(GL_QUADS); - glTexCoord(face.quads_uv[j]); - glVertex(verts[face.quads[j]]); - glTexCoord(face.quads_uv[j+1]); - glVertex(verts[face.quads[j+1]]); - glTexCoord(face.quads_uv[j+2]); - glVertex(verts[face.quads[j+2]]); - glTexCoord(face.quads_uv[j+3]); - glVertex(verts[face.quads[j+3]]); - glEnd(); - } + texture->bind(); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); } - - std::vector::const_iterator jt; - for (jt = kids.begin(); jt != kids.end(); ++jt) + else { - (*jt)->draw(mesh, alpha); + image::reset_binding(); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); } -} -void mesh::material_group::draw(scalar alpha) const -{ - // TODO: setup material - - /* - if (triangles.size() > 0) + for (size_t i = 0; i < faces.size(); ++i) { - //log_info("drawing triangles:", triangles.size()/3); - glTexCoordPointer(2, GL_SCALAR, 0, triangles_uv[0].data()); - glDrawElements(GL_TRIANGLES, - triangles.size(), GL_UNSIGNED_INT, - &triangles[0]); + const material_group& face = faces[i]; + if (face.triangles.size() == 0) continue; + + mesh.set_material(i); + + if (texture) glTexCoordPointer(face.triangles_uv); + glDrawElements(GL_TRIANGLES, face.triangles); } - if (quads.size() > 0) + if (recurse) { - //log_info("drawing quads:", quads.size()/4); - glTexCoordPointer(2, GL_SCALAR, 0, quads_uv[0].data()); - glDrawElements(GL_QUADS, quads.size(), GL_UNSIGNED_INT, &quads[0]); + std::vector::const_iterator jt; + for (jt = kids.begin(); jt != kids.end(); ++jt) + { + (*jt)->draw(alpha); + } } - */ } -class mesh_resource_loader -{ -public: +//class mesh_resource_loader +//{ +//public: - mesh_resource_loader() - { - resource::register_type("ac", "models"); - } + //mesh_resource_loader() + //{ + //resource::register_type("ac", "models"); + //} - ~mesh_resource_loader() - { - resource::unregister_type("ac"); - } -}; + //~mesh_resource_loader() + //{ + //resource::unregister_type("ac"); + //} +//}; -static mesh_resource_loader loader; +//static mesh_resource_loader loader; } // namespace moof