136 |
|
|
137 |
|
|
138 |
|
int |
139 |
< |
intersect_vector_plane(v,plane_n,plane_d,pd,r) |
139 |
> |
intersect_vector_plane(v,plane_n,plane_d,tptr,r) |
140 |
|
FVECT v,plane_n; |
141 |
|
double plane_d; |
142 |
< |
double *pd; |
142 |
> |
double *tptr; |
143 |
|
FVECT r; |
144 |
|
{ |
145 |
|
double t; |
160 |
|
r[0] = v[0]*t; |
161 |
|
r[1] = v[1]*t; |
162 |
|
r[2] = v[2]*t; |
163 |
< |
if(pd) |
164 |
< |
*pd = t; |
163 |
> |
if(tptr) |
164 |
> |
*tptr = t; |
165 |
|
return(hit); |
166 |
|
} |
167 |
|
|
179 |
|
Plane is Ax + By + Cz +D = 0: |
180 |
|
plane[0] = A,plane[1] = B,plane[2] = C,plane[3] = D |
181 |
|
*/ |
182 |
< |
/* A(orig[0] + dxt) + B(orig[1] + dyt) + C(orig[2] + dzt) + pd = 0 */ |
183 |
< |
/* t = -(DOT(plane_n,orig)+ plane_d)/(DOT(plane_n,d)) |
184 |
< |
/* line is l = p1 + (p2-p1)t */ |
182 |
> |
/* A(orig[0] + dxt) + B(orig[1] + dyt) + C(orig[2] + dzt) + pd = 0 |
183 |
> |
t = -(DOT(plane_n,orig)+ plane_d)/(DOT(plane_n,d)) |
184 |
> |
line is l = p1 + (p2-p1)t |
185 |
> |
*/ |
186 |
|
/* Solve for t: */ |
187 |
|
t = -(DOT(plane_n,orig) + plane_d)/(DOT(plane_n,dir)); |
188 |
|
if(ZERO(t) || t >0) |
880 |
|
return(FALSE); |
881 |
|
return(TRUE); |
882 |
|
} |
883 |
+ |
|
884 |
+ |
|
885 |
+ |
|
886 |
+ |
/* Find the normalized barycentric coordinates of p relative to |
887 |
+ |
* triangle v0,v1,v2. Return result in coord |
888 |
+ |
*/ |
889 |
+ |
bary2d(x1,y1,x2,y2,x3,y3,px,py,coord) |
890 |
+ |
double x1,y1,x2,y2,x3,y3; |
891 |
+ |
double px,py; |
892 |
+ |
double coord[3]; |
893 |
+ |
{ |
894 |
+ |
double a; |
895 |
+ |
|
896 |
+ |
a = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1); |
897 |
+ |
coord[0] = ((x2 - px) * (y3 - py) - (x3 - px) * (y2 - py)) / a; |
898 |
+ |
coord[1] = ((x3 - px) * (y1 - py) - (x1 - px) * (y3 - py)) / a; |
899 |
+ |
coord[2] = 1.0 - coord[0] - coord[1]; |
900 |
+ |
|
901 |
+ |
} |
902 |
+ |
|
903 |
+ |
int |
904 |
+ |
bary2d_child(coord) |
905 |
+ |
double coord[3]; |
906 |
+ |
{ |
907 |
+ |
int i; |
908 |
+ |
|
909 |
+ |
/* First check if one of the original vertices */ |
910 |
+ |
for(i=0;i<3;i++) |
911 |
+ |
if(EQUAL(coord[i],1.0)) |
912 |
+ |
return(i); |
913 |
+ |
|
914 |
+ |
/* Check if one of the new vertices: for all return center child */ |
915 |
+ |
if(ZERO(coord[0]) && EQUAL(coord[1],0.5)) |
916 |
+ |
{ |
917 |
+ |
coord[0] = 1.0f; |
918 |
+ |
coord[1] = 0.0f; |
919 |
+ |
coord[2] = 0.0f; |
920 |
+ |
return(3); |
921 |
+ |
} |
922 |
+ |
if(ZERO(coord[1]) && EQUAL(coord[0],0.5)) |
923 |
+ |
{ |
924 |
+ |
coord[0] = 0.0f; |
925 |
+ |
coord[1] = 1.0f; |
926 |
+ |
coord[2] = 0.0f; |
927 |
+ |
return(3); |
928 |
+ |
} |
929 |
+ |
if(ZERO(coord[2]) && EQUAL(coord[0],0.5)) |
930 |
+ |
{ |
931 |
+ |
coord[0] = 0.0f; |
932 |
+ |
coord[1] = 0.0f; |
933 |
+ |
coord[2] = 1.0f; |
934 |
+ |
return(3); |
935 |
+ |
} |
936 |
+ |
|
937 |
+ |
/* Otherwise return child */ |
938 |
+ |
if(coord[0] > 0.5) |
939 |
+ |
{ |
940 |
+ |
/* update bary for child */ |
941 |
+ |
coord[0] = 2.0*coord[0]- 1.0; |
942 |
+ |
coord[1] *= 2.0; |
943 |
+ |
coord[2] *= 2.0; |
944 |
+ |
return(0); |
945 |
+ |
} |
946 |
+ |
else |
947 |
+ |
if(coord[1] > 0.5) |
948 |
+ |
{ |
949 |
+ |
coord[0] *= 2.0; |
950 |
+ |
coord[1] = 2.0*coord[1]- 1.0; |
951 |
+ |
coord[2] *= 2.0; |
952 |
+ |
return(1); |
953 |
+ |
} |
954 |
+ |
else |
955 |
+ |
if(coord[2] > 0.5) |
956 |
+ |
{ |
957 |
+ |
coord[0] *= 2.0; |
958 |
+ |
coord[1] *= 2.0; |
959 |
+ |
coord[2] = 2.0*coord[2]- 1.0; |
960 |
+ |
return(2); |
961 |
+ |
} |
962 |
+ |
else |
963 |
+ |
{ |
964 |
+ |
coord[0] = 1.0 - 2.0*coord[0]; |
965 |
+ |
coord[1] = 1.0 - 2.0*coord[1]; |
966 |
+ |
coord[2] = 1.0 - 2.0*coord[2]; |
967 |
+ |
return(3); |
968 |
+ |
} |
969 |
+ |
} |
970 |
+ |
|
971 |
+ |
int |
972 |
+ |
max_index(v) |
973 |
+ |
FVECT v; |
974 |
+ |
{ |
975 |
+ |
double a,b,c; |
976 |
+ |
int i; |
977 |
+ |
|
978 |
+ |
a = fabs(v[0]); |
979 |
+ |
b = fabs(v[1]); |
980 |
+ |
c = fabs(v[2]); |
981 |
+ |
i = (a>=b)?((a>=c)?0:2):((b>=c)?1:2); |
982 |
+ |
return(i); |
983 |
+ |
} |
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 |
+ |
|
1065 |
+ |
|
1066 |
+ |
|
1067 |
+ |
|
1068 |
+ |
|
1069 |
|
|