コード例 #1
0
ファイル: main.cpp プロジェクト: HenrYxZ/GraphicsII
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);
}
コード例 #2
0
ファイル: raytri.cpp プロジェクト: exopole/gitVTK
// [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
}