Ejemplo n.º 1
0
long check_point(Point3 p1, Point3 p2, float alpha, long mask)
{
Point3 plane_point;

   plane_point.x = LERP(alpha, p1.x, p2.x);
   plane_point.y = LERP(alpha, p1.y, p2.y);
   plane_point.z = LERP(alpha, p1.z, p2.z);
   return(face_plane(plane_point) & mask);
}
Ejemplo n.º 2
0
Mesh::Mesh(const std::vector<Point3D>& verts,
           const std::vector< std::vector<int> >& faces)
    : m_verts(verts),
      m_faces(faces)
{

    Point3D firstPoint = m_verts[0];

    double minX = firstPoint[0];
    double maxX = firstPoint[0];
    double minY = firstPoint[1];
    double maxY = firstPoint[1];
    double minZ = firstPoint[2];
    double maxZ = firstPoint[2];

    for (unsigned int i = 0; i < m_verts.size(); i++) {
        Point3D p = m_verts[i];
        minX = min(p[0], minX);
        maxX = max(p[0], maxX);
        minY = min(p[1], minY);
        maxY = min(p[1], maxY);
        minZ = min(p[2], minZ);
        maxZ = min(p[2], maxZ);
    }

    Point3D minPoint = Point3D(minX, minY, maxZ);
    double size = max(max(maxX - minX, maxY - minY), maxZ - minZ);

    aabb = new NonhierBox(minPoint, size);

    for (unsigned int i = 0; i < m_faces.size(); i++) {
        Face f = m_faces[i];
        vector<Point3D> points;

        for (unsigned int j = 0; j < f.size(); j++) {
            Point3D p = m_verts[f[j]];
            points.push_back(p);
        }

        facePlanes.push_back(face_plane(points));
    }
}
Ejemplo n.º 3
0
long t_c_intersection(Triangle3 t)
{
long v1_test,v2_test,v3_test;
float d,denom;
Point3 vect12,vect13,norm;
Point3 hitpp,hitpn,hitnp,hitnn;

/* First compare all three vertexes with all six face-planes */
/* If any vertex is inside the cube, return immediately!     */

   if ((v1_test = face_plane(t.v1)) == INSIDE) return(INSIDE);
   if ((v2_test = face_plane(t.v2)) == INSIDE) return(INSIDE);
   if ((v3_test = face_plane(t.v3)) == INSIDE) return(INSIDE);

/* If all three vertexes were outside of one or more face-planes, */
/* return immediately with a trivial rejection!                   */

   if ((v1_test & v2_test & v3_test) != 0) return(OUTSIDE);

/* Now do the same trivial rejection test for the 12 edge planes */

   v1_test |= bevel_2d(t.v1) << 8; 
   v2_test |= bevel_2d(t.v2) << 8; 
   v3_test |= bevel_2d(t.v3) << 8;
   if ((v1_test & v2_test & v3_test) != 0) return(OUTSIDE);  

/* Now do the same trivial rejection test for the 8 corner planes */

   v1_test |= bevel_3d(t.v1) << 24; 
   v2_test |= bevel_3d(t.v2) << 24; 
   v3_test |= bevel_3d(t.v3) << 24; 
   if ((v1_test & v2_test & v3_test) != 0) return(OUTSIDE);   

/* If vertex 1 and 2, as a pair, cannot be trivially rejected */
/* by the above tests, then see if the v1-->v2 triangle edge  */
/* intersects the cube.  Do the same for v1-->v3 and v2-->v3. */
/* Pass to the intersection algorithm the "OR" of the outcode */
/* bits, so that only those cube faces which are spanned by   */
/* each triangle edge need be tested.                         */

   if ((v1_test & v2_test) == 0)
      if (check_line(t.v1,t.v2,v1_test|v2_test) == INSIDE) return(INSIDE);
   if ((v1_test & v3_test) == 0)
      if (check_line(t.v1,t.v3,v1_test|v3_test) == INSIDE) return(INSIDE);
   if ((v2_test & v3_test) == 0)
      if (check_line(t.v2,t.v3,v2_test|v3_test) == INSIDE) return(INSIDE);

/* By now, we know that the triangle is not off to any side,     */
/* and that its sides do not penetrate the cube.  We must now    */
/* test for the cube intersecting the interior of the triangle.  */
/* We do this by looking for intersections between the cube      */
/* diagonals and the triangle...first finding the intersection   */
/* of the four diagonals with the plane of the triangle, and     */
/* then if that intersection is inside the cube, pursuing        */
/* whether the intersection point is inside the triangle itself. */

/* To find plane of the triangle, first perform crossproduct on  */
/* two triangle side vectors to compute the normal vector.       */  
                                
   SUB(t.v1,t.v2,vect12);
   SUB(t.v1,t.v3,vect13);
   CROSS(vect12,vect13,norm)

/* The normal vector "norm" X,Y,Z components are the coefficients */
/* of the triangles AX + BY + CZ + D = 0 plane equation.  If we   */
/* solve the plane equation for X=Y=Z (a diagonal), we get        */
/* -D/(A+B+C) as a metric of the distance from cube center to the */
/* diagonal/plane intersection.  If this is between -0.5 and 0.5, */
/* the intersection is inside the cube.  If so, we continue by    */
/* doing a point/triangle intersection.                           */
/* Do this for all four diagonals.                                */

   d = norm.x * t.v1.x + norm.y * t.v1.y + norm.z * t.v1.z;

   /* if one of the diagonals is parallel to the plane, the other will intersect the plane */
   if(fabs(denom=(norm.x + norm.y + norm.z))>EPS)
   /* skip parallel diagonals to the plane; division by 0 can occur */
   {
      hitpp.x = hitpp.y = hitpp.z = d / denom;
      if (fabs(hitpp.x) <= 0.5)
         if (point_triangle_intersection(hitpp,t) == INSIDE) return(INSIDE);
   }
   if(fabs(denom=(norm.x + norm.y - norm.z))>EPS)
   {
      hitpn.z = -(hitpn.x = hitpn.y = d / denom);
      if (fabs(hitpn.x) <= 0.5)
         if (point_triangle_intersection(hitpn,t) == INSIDE) return(INSIDE);
   }       
   if(fabs(denom=(norm.x - norm.y + norm.z))>EPS)
   {       
      hitnp.y = -(hitnp.x = hitnp.z = d / denom);
      if (fabs(hitnp.x) <= 0.5)
         if (point_triangle_intersection(hitnp,t) == INSIDE) return(INSIDE);
   }
   if(fabs(denom=(norm.x - norm.y - norm.z))>EPS)
   {
      hitnn.y = hitnn.z = -(hitnn.x = d / denom);
      if (fabs(hitnn.x) <= 0.5)
         if (point_triangle_intersection(hitnn,t) == INSIDE) return(INSIDE);
   }
   
/* No edge touched the cube; no cube diagonal touched the triangle. */
/* We're done...there was no intersection.                          */

   return(OUTSIDE);

}
extern int
trivial_vertex_tests(int nverts, const real verts[][3],
        int already_know_verts_are_outside_cube)
{
    /*register*/ unsigned long cum_and;  /* cumulative logical ANDs */
    /*register*/ int i;

    /*
     * Compare the vertices with all six face-planes.
     * If it's known that no vertices are inside the unit cube
     * we can exit the loop early if we run out of bounding
     * planes that all vertices might be outside of.  That simply means
     * that this test failed and we can go on to the next one.
     * If we must test for vertices within the cube, the loop is slightly
     * different in that we can trivially accept if we ever do find a
     * vertex within the cube, but we can't break the loop early if we run
     * out of planes to reject against because subsequent vertices might
     * still be within the cube.
     */
    cum_and = ~0L;  /* Set to all "1" bits */
    if(already_know_verts_are_outside_cube)
    {
        for(i=0; i<nverts; i++)
            if(0L == (cum_and = face_plane(verts[i], cum_and)))
                break; /* No planes left to trivially reject */
    }
    else
    {
        for(i=0; i<nverts; i++)
        {
            /* Note the ~0L mask below to always test all planes */
            unsigned long face_bits = face_plane(verts[i], ~0L);
            if(0L == face_bits)  /* vertex is inside the cube */
                return 1; /* trivial accept */
            cum_and &= face_bits;
        }
    }
    if(cum_and != 0L)  /* All vertices outside some face plane. */
        return 0;  /* Trivial reject */

    /*
     * Now do the just the trivial reject test against the 12 edge planes.
     */
    cum_and = ~0L;  /* Set to all "1" bits */
    for(i=0; i<nverts; i++)
        if(0L == (cum_and = bevel_2d(verts[i], cum_and)))
            break; /* No planes left that might trivially reject */
    if(cum_and != 0L)  /* All vertices outside some edge plane. */
        return 0;  /* Trivial reject */

    /*
     * Now do the trivial reject test against the 8 corner planes.
     */
    cum_and = ~0L;  /* Set to all "1" bits */
    for(i=0; i<nverts; i++)
        if(0L == (cum_and = bevel_3d(verts[i], cum_and)))
            break; /* No planes left that might trivially reject */
    if(cum_and != 0L)  /* All vertices outside some corner plane. */
        return 0;  /* Trivial reject */

    /*
     * By now we know that the polygon is not to the outside of any of the
     * test planes and can't be trivially accepted *or* rejected.
     */
    return -1;
}