984 |
|
|
985 |
|
|
986 |
|
|
987 |
+ |
/* |
988 |
+ |
* int |
989 |
+ |
* smRay(FVECT orig, FVECT dir,FVECT v0,FVECT v1,FVECT v2,FVECT r) |
990 |
+ |
* |
991 |
+ |
* Intersect the ray with triangle v0v1v2, return intersection point in r |
992 |
+ |
* |
993 |
+ |
* Assumes orig,v0,v1,v2 are in spherical coordinates, and orig is |
994 |
+ |
* unit |
995 |
+ |
*/ |
996 |
+ |
int |
997 |
+ |
traceRay(orig,dir,v0,v1,v2,r) |
998 |
+ |
FVECT orig,dir; |
999 |
+ |
FVECT v0,v1,v2; |
1000 |
+ |
FVECT r; |
1001 |
+ |
{ |
1002 |
+ |
FVECT n,p[3],d; |
1003 |
+ |
double pt[3],r_eps; |
1004 |
+ |
char i; |
1005 |
+ |
int which; |
1006 |
+ |
|
1007 |
+ |
/* Find the plane equation for the triangle defined by the edge v0v1 and |
1008 |
+ |
the view center*/ |
1009 |
+ |
VCROSS(n,v0,v1); |
1010 |
+ |
/* Intersect the ray with this plane */ |
1011 |
+ |
i = intersect_ray_plane(orig,dir,n,0.0,&(pt[0]),p[0]); |
1012 |
+ |
if(i) |
1013 |
+ |
which = 0; |
1014 |
+ |
else |
1015 |
+ |
which = -1; |
1016 |
+ |
|
1017 |
+ |
VCROSS(n,v1,v2); |
1018 |
+ |
i = intersect_ray_plane(orig,dir,n,0.0,&(pt[1]),p[1]); |
1019 |
+ |
if(i) |
1020 |
+ |
if((which==-1) || pt[1] < pt[0]) |
1021 |
+ |
which = 1; |
1022 |
+ |
|
1023 |
+ |
VCROSS(n,v2,v0); |
1024 |
+ |
i = intersect_ray_plane(orig,dir,n,0.0,&(pt[2]),p[2]); |
1025 |
+ |
if(i) |
1026 |
+ |
if((which==-1) || pt[2] < pt[which]) |
1027 |
+ |
which = 2; |
1028 |
+ |
|
1029 |
+ |
if(which != -1) |
1030 |
+ |
{ |
1031 |
+ |
/* Return point that is K*eps along projection of the ray on |
1032 |
+ |
the sphere to push intersection point p[which] into next cell |
1033 |
+ |
*/ |
1034 |
+ |
normalize(p[which]); |
1035 |
+ |
/* Calculate the ray perpendicular to the intersection point: approx |
1036 |
+ |
the direction moved along the sphere a distance of K*epsilon*/ |
1037 |
+ |
r_eps = -DOT(p[which],dir); |
1038 |
+ |
VSUM(n,dir,p[which],r_eps); |
1039 |
+ |
/* Calculate the length along ray p[which]-dir needed to move to |
1040 |
+ |
cause a move along the sphere of k*epsilon |
1041 |
+ |
*/ |
1042 |
+ |
r_eps = DOT(n,dir); |
1043 |
+ |
VSUM(r,p[which],dir,(20*FTINY)/r_eps); |
1044 |
+ |
normalize(r); |
1045 |
+ |
return(TRUE); |
1046 |
+ |
} |
1047 |
+ |
else |
1048 |
+ |
{ |
1049 |
+ |
/* Unable to find intersection: move along ray and try again */ |
1050 |
+ |
r_eps = -DOT(orig,dir); |
1051 |
+ |
VSUM(n,dir,orig,r_eps); |
1052 |
+ |
r_eps = DOT(n,dir); |
1053 |
+ |
VSUM(r,orig,dir,(20*FTINY)/r_eps); |
1054 |
+ |
normalize(r); |
1055 |
+ |
#ifdef DEBUG |
1056 |
+ |
eputs("traceRay:Ray does not intersect triangle"); |
1057 |
+ |
#endif |
1058 |
+ |
return(FALSE); |
1059 |
+ |
} |
1060 |
+ |
} |
1061 |
+ |
|
1062 |
|
|
1063 |
|
|
1064 |
|
|