X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Fmesh.cc;fp=src%2Fmoof%2Fmesh.cc;h=023138b6df39fa8a79aa8f043b62bc5a5a58f5ea;hp=b41c377f29429514a1bcfffe48b91e16e877f3cc;hb=6f1b787a10d8ab1a3117a4b8c004dd2d90599608;hpb=c143f7e806766a73cd69dc6e084e977641019ce6 diff --git a/src/moof/mesh.cc b/src/moof/mesh.cc index b41c377..023138b 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; // FIXME: temporary - - 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; @@ -246,77 +256,104 @@ void mesh::import(std::istream& stream) 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]; - int vert; + 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); - face.triangles_uv.push_back(uv); - unsigned first = face.triangles.back(); - vector2 first_uv = face.triangles_uv.back(); + 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); - face.triangles_uv.push_back(uv); 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); - face.triangles_uv.push_back(uv); - unsigned last = face.triangles.back(); - vector2 last_uv = face.triangles_uv.back(); + unsigned last = vert; for (int j = 3; j < numrefs; ++j) { - // first face.triangles.push_back(first); - face.triangles_uv.push_back(first_uv); - - // last face.triangles.push_back(last); - face.triangles_uv.push_back(last_uv); 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); - face.triangles_uv.push_back(uv); last = face.triangles.back(); - last_uv = face.triangles_uv.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 @@ -325,8 +362,41 @@ void mesh::import(std::istream& stream) } } while (stream); + + std::vector::iterator meh; + for (meh = objects_.begin(); meh != objects_.end(); ++meh) + { + object_ptr cow = *meh; + log_info("OBJ: -", cow->name, cow->kids.size()); + + std::vector::iterator foo; + for (foo = cow->kids.begin(); foo != cow->kids.end(); ++foo) + { + log_info("OBJ: -", (*foo)->name, (*foo)->kids.size()); + } + } } +//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) { @@ -405,16 +475,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? } @@ -425,94 +494,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); + 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); + + if (texture) + { + texture->bind(); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + else + { + image::reset_binding(); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } for (size_t i = 0; i < faces.size(); ++i) { const material_group& face = faces[i]; + if (face.triangles.size() == 0) continue; + 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(); - } - } - std::vector::const_iterator jt; - for (jt = kids.begin(); jt != kids.end(); ++jt) - { - (*jt)->draw(mesh, alpha); + if (texture) glTexCoordPointer(face.triangles_uv); + glDrawElements(GL_TRIANGLES, face.triangles); } -} -void mesh::material_group::draw(scalar alpha) const -{ - // TODO: setup material - - /* - if (triangles.size() > 0) + if (recurse) { - //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]); + 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