#include "mesh.hh"
#include "opengl.hh"
+// TODO: this file needs to be cleaned up
+
#define AC3D_FORMAT_VERSION (0x0b)
#define ZLIB_BUF_SIZE (262114)
namespace moof {
+MOOF_REGISTER_RESOURCE(mesh, ac, models);
+
+
static std::string read_string(std::istream& stream)
{
std::string str;
return triplet;
}
-
-template <int D>
-inline vector< scalar, fixed<D> > read_triplet(std::istream& stream)
+inline vector3 read_triplet(std::istream& stream)
{
- vector< scalar, fixed<D> > 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)
{
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")
{
throw std::runtime_error("unexpected object type " + atom);
}
- object_ptr newObj = object::alloc();
+ object_ptr newObj = object::alloc(*this);
if (obj)
{
}
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")
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")
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;
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
}
}
while (stream);
+
+ std::vector<object_ptr>::iterator meh;
+ for (meh = objects_.begin(); meh != objects_.end(); ++meh)
+ {
+ object_ptr cow = *meh;
+ log_info("OBJ: -", cow->name, cow->kids.size());
+
+ std::vector<object_ptr>::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)
{
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<object_ptr>::const_iterator it;
for (it = objects_.begin(); it != objects_.end(); ++it)
{
- (*it)->draw(*this, alpha);
+ (*it)->draw(alpha);
}
+
+ // TODO: disable vertex array?
}
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<vector3>::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<unsigned>::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<object_ptr>::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<object_ptr>::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<mesh>("ac", "models");
- }
+ //mesh_resource_loader()
+ //{
+ //resource::register_type<mesh>("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