#include #include #include #include #include "model.h" // fills verts and faces arrays, supposes .obj file to have "f " entries without slashes Model::Model(const char *filename) : verts(), faces() { std::ifstream in; in.open (filename, std::ifstream::in); if (in.fail()) { std::cerr << "Failed to open " << filename << std::endl; return; } std::string line; while (!in.eof()) { std::getline(in, line); std::istringstream iss(line.c_str()); char trash; if (!line.compare(0, 2, "v ")) { iss >> trash; Vec3f v; for (int i=0;i<3;i++) iss >> v[i]; verts.push_back(v); } else if (!line.compare(0, 2, "f ")) { Vec3i f; int idx, cnt=0; iss >> trash; while (iss >> idx) { idx--; // in wavefront obj all indices start at 1, not zero f[cnt++] = idx; } if (3==cnt) faces.push_back(f); } } std::cerr << "# v# " << verts.size() << " f# " << faces.size() << std::endl; Vec3f min, max; get_bbox(min, max); } // Moller and Trumbore bool Model::ray_triangle_intersect(const int &fi, const Vec3f &orig, const Vec3f &dir, float &tnear) { Vec3f edge1 = point(vert(fi,1)) - point(vert(fi,0)); Vec3f edge2 = point(vert(fi,2)) - point(vert(fi,0)); Vec3f pvec = cross(dir, edge2); float det = edge1*pvec; if (det<1e-5) return false; Vec3f tvec = orig - point(vert(fi,0)); float u = tvec*pvec; if (u < 0 || u > det) return false; Vec3f qvec = cross(tvec, edge1); float v = dir*qvec; if (v < 0 || u + v > det) return false; tnear = edge2*qvec * (1./det); return tnear>1e-5; } int Model::nverts() const { return (int)verts.size(); } int Model::nfaces() const { return (int)faces.size(); } void Model::get_bbox(Vec3f &min, Vec3f &max) { min = max = verts[0]; for (int i=1; i<(int)verts.size(); ++i) { for (int j=0; j<3; j++) { min[j] = std::min(min[j], verts[i][j]); max[j] = std::max(max[j], verts[i][j]); } } std::cerr << "bbox: [" << min << " : " << max << "]" << std::endl; } const Vec3f &Model::point(int i) const { assert(i>=0 && i=0 && i=0 && fi=0 && li<3); return faces[fi][li]; } std::ostream& operator<<(std::ostream& out, Model &m) { for (int i=0; i