// Given an edge, the constructor for EdgeRecord finds the // optimal point associated with the edge's current quadric, // and assigns this edge a cost based on how much quadric // error is observed at this optimal point. EdgeRecord::EdgeRecord( EdgeIter& _edge ) : edge( _edge ) { // TODO Compute the combined quadric from the edge endpoints. Matrix4x4 q = _edge->halfedge()->vertex()->quadric + _edge->halfedge()->twin()->vertex()->quadric; // TODO Build the 3x3 linear system whose solution minimizes // the quadric error associated with these two endpoints. Matrix3x3 quadratic; quadratic(0,0) = q(0,0); quadratic(0,1) = q(0,1); quadratic(0,2) = q(0,2); quadratic(1,0) = q(1,0); quadratic(1,1) = q(1,1); quadratic(1,2) = q(1,2); quadratic(2,0) = q(2,0); quadratic(2,1) = q(2,1); quadratic(2,2) = q(2,2); Vector3D linear(q(3,0), q(3,1), q(3,2)); // TODO Use this system to solve for the optimal position, and // TODO store it in EdgeRecord::optimalPoint. optimalPoint = - quadratic.inv() * linear; // TODO Also store the cost associated with collapsing this edge // TODO in EdgeRecord::Cost. Vector4D optH(optimalPoint); optH.w = 1.0; score = dot(optH, q * optH); }
bool Triangle::intersect(const Ray& r, Intersection *isect) const { // TODO: // implement ray-triangle intersection. When an intersection takes // place, the Intersection data should be updated accordingly Vector3D p0 = mesh->positions[v1]; Vector3D p1 = mesh->positions[v2]; Vector3D p2 = mesh->positions[v3]; Vector3D e1 = p1 - p0; Vector3D e2 = p2 - p0; Vector3D s = r.o - p0; Matrix3x3 A; for (size_t i = 0; i < 3; i++) { A(i,0) = e1[i]; A(i,1) = e2[i]; A(i,2) = -r.d[i]; } if (A.det() == 0) { return false; } bool tri_intersect = false; Vector3D uvt = A.inv() * s; if (uvt.z < r.min_t || uvt.z > r.max_t) { return false; }else if (uvt.x < 0 || uvt.x > 1) { return false; }else if (uvt.y < 0 || uvt.y > 1) { return false; }else if (uvt.x + uvt.y > 1) { return false; }else { tri_intersect = true; } isect->t = uvt.z; isect->bsdf = get_bsdf(); isect->primitive = this; isect->n = (1 - uvt.x - uvt.y) * mesh->normals[v1] + uvt.x * mesh->normals[v2] + uvt.y * mesh->normals[v3]; r.max_t = uvt.z; isect->n.normalize(); // bool tri_intersect = false; // double u, v, t; // double ede = 1 / dot(cross(e1, r.d), e2); // t = - (dot(cross(s, e2), e1)) * ede; // if (t < r.min_t || t > r.max_t) { // return false; // }else { // u = - (dot(cross(s, e2), r.d)) * ede; // if (u < 0 || u > 1) { // return false; // }else { // v = (dot(cross(e1, r.d), s)) * ede; // if (v < 0 || v > 1) { // return false; // }else{ // if (u + v > 1) { // return false; // }else{ // tri_intersect = true; // } // } // } // } // isect->t = t; // isect->bsdf = get_bsdf(); // isect->primitive = this; // isect->n = (1 - u - v) * mesh->normals[v1] + u * mesh->normals[v2] + v * mesh->normals[v3]; // r.max_t = t; // isect->n.normalize(); return tri_intersect; }