void Rotation(Point2d previous_mouse_coord, Point2d current_mouse_coord) { // calculation of p float x_p = static_cast<float>(previous_mouse_coord.x); x_p = 2*x_p/window_width - 1; float y_p = static_cast<float>(previous_mouse_coord.y); y_p = 2*(window_height - y_p)/window_height - 1; float z_p; float root_p = (1- pow(x_p, 2) - pow(y_p, 2)); if (root_p < 0) { // if the point is outside of the unit sphere, then the point lies // somewhere in the xy plane, so z = 0 z_p = 0; } else { z_p = sqrt(1- pow(x_p, 2) - pow(y_p, 2)); } Vec3f p = {x_p, y_p, z_p}; // calculation of q float x_q = static_cast<float>(current_mouse_coord.x); x_q = 2*x_q/window_width - 1; float y_q = static_cast<float>(current_mouse_coord.y); y_q = 2*(window_height - y_q)/window_height - 1; float z_q; float root_q = (1- pow(x_q, 2) - pow(y_q, 2)); if (root_q < 0) { z_q = 0; } else { z_q = sqrt(1- pow(x_q, 2) - pow(y_q, 2)); } Vec3f q = {x_q, y_q, z_q}; // calculation of angle with unitary p and q float angle = acos(p.unit() * q.unit())*180.0/PI; // if for some reason the angle comes out as NaN, change it to zero if (angle != angle) angle = 0; // calculation of normal Vec3f origin = {0, 0, 0}; p = p - origin; Vec3f n = p.crossProduct(q - origin); // store the this rotation with all previous rotations glLoadIdentity(); glRotatef(angle, n.x[0], n.x[1], n.x[2]); glMultMatrixf(current_matrix); glGetFloatv(GL_MODELVIEW_MATRIX, current_matrix); }
// [comment] // The main ray-triangle intersection routine. You can test both methoods: the // geometric method and the Moller-Trumbore algorithm (use the flag -DMOLLER_TRUMBORE // when you compile. // [/comment] bool rayTriangleIntersect( const Vec3f &orig, const Vec3f &dir, const Vec3f &v0, const Vec3f &v1, const Vec3f &v2, float &t, float &u, float &v) { #ifdef MOLLER_TRUMBORE Vec3f v0v1 = v1 - v0; Vec3f v0v2 = v2 - v0; Vec3f pvec = dir.crossProduct(v0v2); float det = v0v1.dotProduct(pvec); #ifdef CULLING // if the determinant is negative the triangle is backfacing // if the determinant is close to 0, the ray misses the triangle if (det < kEpsilon) return false; #else // ray and triangle are parallel if det is close to 0 if (fabs(det) < kEpsilon) return false; #endif float invDet = 1 / det; Vec3f tvec = orig - v0; u = tvec.dotProduct(pvec) * invDet; if (u < 0 || u > 1) return false; Vec3f qvec = tvec.crossProduct(v0v1); v = dir.dotProduct(qvec) * invDet; if (v < 0 || u + v > 1) return false; t = v0v2.dotProduct(qvec) * invDet; return true; #else // compute plane's normal Vec3f v0v1 = v1 - v0; Vec3f v0v2 = v2 - v0; // no need to normalize Vec3f N = v0v1.crossProduct(v0v2); // N float denom = N.dotProduct(N); // Step 1: finding P // check if ray and plane are parallel ? float NdotRayDirection = N.dotProduct(dir); if (fabs(NdotRayDirection) < kEpsilon) // almost 0 return false; // they are parallel so they don't intersect ! // compute d parameter using equation 2 float d = N.dotProduct(v0); // compute t (equation 3) t = (N.dotProduct(orig) + d) / NdotRayDirection; // check if the triangle is in behind the ray if (t < 0) return false; // the triangle is behind // compute the intersection point using equation 1 Vec3f P = orig + t * dir; // Step 2: inside-outside test Vec3f C; // vector perpendicular to triangle's plane // edge 0 Vec3f edge0 = v1 - v0; Vec3f vp0 = P - v0; C = edge0.crossProduct(vp0); if (N.dotProduct(C) < 0) return false; // P is on the right side // edge 1 Vec3f edge1 = v2 - v1; Vec3f vp1 = P - v1; C = edge1.crossProduct(vp1); if ((u = N.dotProduct(C)) < 0) return false; // P is on the right side // edge 2 Vec3f edge2 = v0 - v2; Vec3f vp2 = P - v2; C = edge2.crossProduct(vp2); if ((v = N.dotProduct(C)) < 0) return false; // P is on the right side; u /= denom; v /= denom; return true; // this ray hits the triangle #endif }