1 //------------------------------------------------------------------------------
3 //------------------------------------------------------------------------------
4 // GLVU : Copyright 1997 - 2002
5 // The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its
8 // documentation for any purpose is hereby granted without fee, provided that
9 // the above copyright notice appear in all copies and that both that copyright
10 // notice and this permission notice appear in supporting documentation.
11 // Binaries may be compiled with this software without any royalties or
14 // The University of North Carolina at Chapel Hill makes no representations
15 // about the suitability of this software for any purpose. It is provided
16 // "as is" without express or implied warranty.
18 //============================================================================
19 // tri.cpp : triangle defs and intersection routines.
20 //============================================================================
24 //----------------------------------------------------------------------------
25 // CHECKS IF 2D POINT P IS IN A 2D TRI ABC.
26 //----------------------------------------------------------------------------
27 int PtInTri2D(float Px, float Py,
28 float Ax, float Ay, float Bx, float By, float Cx, float Cy)
30 float dABx=Bx-Ax, dABy=By-Ay, dBCx=Cx-Bx, dBCy=Cy-By; // "REPEATS"
31 if (dABx*dBCy < dABy*dBCx) // CW
33 if (dABx*(Py-Ay) >= dABy*(Px-Ax)) return(0); // ABxAP
34 if (dBCx*(Py-By) >= dBCy*(Px-Bx)) return(0); // BCxBP
35 if ((Ax-Cx)*(Py-Cy) >= (Ay-Cy)*(Px-Cx)) return(0); // CAxCP
39 if (dABx*(Py-Ay) < dABy*(Px-Ax)) return(0); // ABxAP
40 if (dBCx*(Py-By) < dBCy*(Px-Bx)) return(0); // BCxBP
41 if ((Ax-Cx)*(Py-Cy) < (Ay-Cy)*(Px-Cx)) return(0); // CAxCP
43 return(1); // "INSIDE" EACH EDGE'S IN-HALF-SPACE (PT P IS INSIDE TRIANGLE)
46 //----------------------------------------------------------------------------
47 // CHECKS IF 3D POINT P (ON ABC'S PLANE) IS IN 3D TRI ABC.
48 // P=PtOnTriPlane, N=PlaneNormal (does not have to be normalized)
49 //----------------------------------------------------------------------------
50 int PtInTri3D(const float P[3], float N[3],
51 const float A[3], const float B[3], const float C[3])
53 #define ABS(x) (((x)<0)?(-(x)):x) // HANDY UNIVERSAL ABSOLUTE VALUE FUNC
55 // DETERMINE LARGEST COMPONENT OF NORMAL (magnitude, since we want the largest projection)
56 N[0]=ABS(N[0]); N[1]=ABS(N[1]); N[2]=ABS(N[2]);
58 // PROJECT ONTO PLANE WHERE PERPENDICULAR TO LARGEST NORMAL COMPONENT AXIS
59 if (N[0]>N[1] && N[0]>N[2]) // X IS LARGEST SO PROJECT ONTO YZ-PLANE
60 return( PtInTri2D(P[1],P[2], A[1],A[2], B[1],B[2], C[1],C[2]) );
61 else if (N[1]>N[0] && N[1]>N[2]) // Y IS LARGEST SO PROJECT ONTO XZ-PLANE
62 return( PtInTri2D(P[0],P[2], A[0],A[2], B[0],B[2], C[0],C[2]) );
63 else // Z IS LARGEST SO PROJECT ONTO XY-PLANE
64 return( PtInTri2D(P[0],P[1], A[0],A[1], B[0],B[1], C[0],C[1]) );
67 //--------------------------------------------------------------------------
68 // Checks if an edge UV intersects a triangle ABC. Returns whether or
69 // not the edge intersects the plane (0 or 1) and the IsectPt.
70 //--------------------------------------------------------------------------
71 int EdgeTriIsect(const float U[3], const float V[3],
72 const float A[3], const float B[3], const float C[3],
75 // CALCULATE PLANE EQUATION COEFFICIENTS P FOR TRI ABC
77 float u[3] = {B[0]-A[0],B[1]-A[1],B[2]-A[2]};
78 float v[3] = {C[0]-A[0],C[1]-A[1],C[2]-A[2]};
79 P[0] = u[1]*v[2] - u[2]*v[1]; // CROSS-PROD BETWEEN u AND v
80 P[1] = u[2]*v[0] - u[0]*v[2]; // DEFINES UNNORMALIZED NORMAL
81 P[2] = u[0]*v[1] - u[1]*v[0];
82 float l = (float)sqrt(P[0]*P[0] + P[1]*P[1] + P[2]*P[2]); // NORMALIZE NORMAL
83 P[0]/=l; P[1]/=l; P[2]/=l;
84 P[3] = -(P[0]*A[0] + P[1]*A[1] + P[2]*A[2]);
86 // FIND INTERSECTION OF EDGE UV WITH PLANE P
87 int EdgeIsectsPlane=0;
88 float Dir[3] = { V[0]-U[0], V[1]-U[1], V[2]-U[2] };
89 float NdotDir = P[0]*Dir[0] + P[1]*Dir[1] + P[2]*Dir[2];
90 float NdotU = P[0]*U[0] + P[1]*U[1] + P[2]*U[2];
91 if (NdotDir==(float)0) return(0);
92 float t = (-P[3] - NdotU) / NdotDir;
95 IsectPt[0] = U[0] + Dir[0]*t;
96 IsectPt[1] = U[1] + Dir[1]*t;
97 IsectPt[2] = U[2] + Dir[2]*t;
101 // FIRST, DOES THE EDGE INTERSECT THE PLANE?
102 if (!EdgeIsectsPlane) return(0);
104 // SEE IF ISECT PT IS IN THE TRI
105 return( PtInTri3D(IsectPt,P,A,B,C) );