ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm_geom.c
Revision: 3.7
Committed: Tue Oct 6 18:16:53 1998 UTC (25 years, 7 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.6: +270 -52 lines
Log Message:
new triangulate routine
added smTestSample to check for occlusion
added frustum culling before rebuild
changed base quadtree to use octahedron and created new point locate
added "sample active" flags and implemented LRU replacement
started handling case of too many triangles
set sizes are now unbounded
changed all quadtree pointers to quadtrees

File Contents

# User Rev Content
1 gwlarson 3.1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ SGI";
5     #endif
6    
7     /*
8     * sm_geom.c
9     */
10    
11     #include "standard.h"
12     #include "sm_geom.h"
13    
14     tri_centroid(v0,v1,v2,c)
15     FVECT v0,v1,v2,c;
16     {
17     /* Average three triangle vertices to give centroid: return in c */
18     c[0] = (v0[0] + v1[0] + v2[0])/3.0;
19     c[1] = (v0[1] + v1[1] + v2[1])/3.0;
20     c[2] = (v0[2] + v1[2] + v2[2])/3.0;
21     }
22    
23    
24     int
25     vec3_equal(v1,v2)
26     FVECT v1,v2;
27     {
28     return(EQUAL(v1[0],v2[0]) && EQUAL(v1[1],v2[1])&& EQUAL(v1[2],v2[2]));
29     }
30    
31    
32     int
33     convex_angle(v0,v1,v2)
34     FVECT v0,v1,v2;
35     {
36 gwlarson 3.7 FVECT cp,cp01,cp12,v10,v02;
37     double dp;
38     /*
39     VSUB(v10,v1,v0);
40     VSUB(v02,v0,v2);
41     VCROSS(cp,v10,v02);
42     */
43     /* test sign of (v0Xv1)X(v1Xv2). v1 */
44 gwlarson 3.1 VCROSS(cp01,v0,v1);
45     VCROSS(cp12,v1,v2);
46     VCROSS(cp,cp01,cp12);
47 gwlarson 3.7
48     dp = DOT(cp,v1);
49     if(ZERO(dp) || dp < 0.0)
50 gwlarson 3.1 return(FALSE);
51     return(TRUE);
52     }
53    
54     /* calculates the normal of a face contour using Newell's formula. e
55    
56     a = SUMi (yi - yi+1)(zi + zi+1)
57     b = SUMi (zi - zi+1)(xi + xi+1)
58     c = SUMi (xi - xi+1)(yi + yi+1)
59     */
60     double
61     tri_normal(v0,v1,v2,n,norm)
62     FVECT v0,v1,v2,n;
63 gwlarson 3.4 int norm;
64 gwlarson 3.1 {
65     double mag;
66    
67     n[0] = (v0[2] + v1[2]) * (v0[1] - v1[1]) +
68     (v1[2] + v2[2]) * (v1[1] - v2[1]) +
69     (v2[2] + v0[2]) * (v2[1] - v0[1]);
70    
71     n[1] = (v0[2] - v1[2]) * (v0[0] + v1[0]) +
72     (v1[2] - v2[2]) * (v1[0] + v2[0]) +
73     (v2[2] - v0[2]) * (v2[0] + v0[0]);
74    
75     n[2] = (v0[1] + v1[1]) * (v0[0] - v1[0]) +
76     (v1[1] + v2[1]) * (v1[0] - v2[0]) +
77     (v2[1] + v0[1]) * (v2[0] - v0[0]);
78    
79     if(!norm)
80     return(0);
81    
82    
83     mag = normalize(n);
84    
85     return(mag);
86     }
87    
88    
89 gwlarson 3.7 tri_plane_equation(v0,v1,v2,peqptr,norm)
90     FVECT v0,v1,v2;
91     FPEQ *peqptr;
92 gwlarson 3.4 int norm;
93 gwlarson 3.1 {
94 gwlarson 3.7 tri_normal(v0,v1,v2,FP_N(*peqptr),norm);
95 gwlarson 3.1
96 gwlarson 3.7 FP_D(*peqptr) = -(DOT(FP_N(*peqptr),v0));
97 gwlarson 3.1 }
98    
99     /* From quad_edge-code */
100     int
101     point_in_circle_thru_origin(p,p0,p1)
102     FVECT p;
103     FVECT p0,p1;
104     {
105    
106     double dp0,dp1;
107     double dp,det;
108    
109     dp0 = DOT_VEC2(p0,p0);
110     dp1 = DOT_VEC2(p1,p1);
111     dp = DOT_VEC2(p,p);
112    
113     det = -dp0*CROSS_VEC2(p1,p) + dp1*CROSS_VEC2(p0,p) - dp*CROSS_VEC2(p0,p1);
114    
115     return (det > 0);
116     }
117    
118    
119    
120     point_on_sphere(ps,p,c)
121     FVECT ps,p,c;
122     {
123     VSUB(ps,p,c);
124     normalize(ps);
125     }
126    
127    
128 gwlarson 3.4 /* returns TRUE if ray from origin in direction v intersects plane defined
129     * by normal plane_n, and plane_d. If plane is not parallel- returns
130     * intersection point if r != NULL. If tptr!= NULL returns value of
131     * t, if parallel, returns t=FHUGE
132     */
133 gwlarson 3.1 int
134 gwlarson 3.7 intersect_vector_plane(v,peq,tptr,r)
135     FVECT v;
136     FPEQ peq;
137 gwlarson 3.2 double *tptr;
138 gwlarson 3.1 FVECT r;
139     {
140 gwlarson 3.4 double t,d;
141 gwlarson 3.1 int hit;
142     /*
143     Plane is Ax + By + Cz +D = 0:
144     plane[0] = A,plane[1] = B,plane[2] = C,plane[3] = D
145     */
146    
147     /* line is l = p1 + (p2-p1)t, p1=origin */
148    
149     /* Solve for t: */
150 gwlarson 3.7 d = -(DOT(FP_N(peq),v));
151 gwlarson 3.4 if(ZERO(d))
152     {
153     t = FHUGE;
154     hit = 0;
155     }
156     else
157     {
158 gwlarson 3.7 t = FP_D(peq)/d;
159 gwlarson 3.4 if(t < 0 )
160     hit = 0;
161     else
162     hit = 1;
163     if(r)
164     {
165     r[0] = v[0]*t;
166     r[1] = v[1]*t;
167     r[2] = v[2]*t;
168     }
169     }
170 gwlarson 3.2 if(tptr)
171     *tptr = t;
172 gwlarson 3.1 return(hit);
173     }
174    
175     int
176 gwlarson 3.7 intersect_ray_plane(orig,dir,peq,pd,r)
177 gwlarson 3.1 FVECT orig,dir;
178 gwlarson 3.7 FPEQ peq;
179 gwlarson 3.1 double *pd;
180     FVECT r;
181     {
182     double t;
183     int hit;
184     /*
185     Plane is Ax + By + Cz +D = 0:
186     plane[0] = A,plane[1] = B,plane[2] = C,plane[3] = D
187     */
188 gwlarson 3.2 /* A(orig[0] + dxt) + B(orig[1] + dyt) + C(orig[2] + dzt) + pd = 0
189     t = -(DOT(plane_n,orig)+ plane_d)/(DOT(plane_n,d))
190     line is l = p1 + (p2-p1)t
191     */
192 gwlarson 3.1 /* Solve for t: */
193 gwlarson 3.7 t = -(DOT(FP_N(peq),orig) + FP_D(peq))/(DOT(FP_N(peq),dir));
194 gwlarson 3.4 if(t < 0)
195     hit = 0;
196     else
197 gwlarson 3.1 hit = 1;
198 gwlarson 3.4
199     if(r)
200     VSUM(r,orig,dir,t);
201    
202     if(pd)
203     *pd = t;
204     return(hit);
205     }
206    
207    
208     int
209 gwlarson 3.7 intersect_ray_oplane(orig,dir,n,pd,r)
210     FVECT orig,dir;
211     FVECT n;
212     double *pd;
213     FVECT r;
214     {
215     double t;
216     int hit;
217     /*
218     Plane is Ax + By + Cz +D = 0:
219     plane[0] = A,plane[1] = B,plane[2] = C,plane[3] = D
220     */
221     /* A(orig[0] + dxt) + B(orig[1] + dyt) + C(orig[2] + dzt) + pd = 0
222     t = -(DOT(plane_n,orig)+ plane_d)/(DOT(plane_n,d))
223     line is l = p1 + (p2-p1)t
224     */
225     /* Solve for t: */
226     t = -(DOT(n,orig))/(DOT(n,dir));
227     if(t < 0)
228     hit = 0;
229     else
230     hit = 1;
231    
232     if(r)
233     VSUM(r,orig,dir,t);
234    
235     if(pd)
236     *pd = t;
237     return(hit);
238     }
239    
240    
241     int
242     intersect_edge_plane(e0,e1,peq,pd,r)
243 gwlarson 3.4 FVECT e0,e1;
244 gwlarson 3.7 FPEQ peq;
245 gwlarson 3.4 double *pd;
246     FVECT r;
247     {
248     double t;
249     int hit;
250     FVECT d;
251     /*
252     Plane is Ax + By + Cz +D = 0:
253     plane[0] = A,plane[1] = B,plane[2] = C,plane[3] = D
254     */
255     /* A(orig[0] + dxt) + B(orig[1] + dyt) + C(orig[2] + dzt) + pd = 0
256     t = -(DOT(plane_n,orig)+ plane_d)/(DOT(plane_n,d))
257     line is l = p1 + (p2-p1)t
258     */
259     /* Solve for t: */
260     VSUB(d,e1,e0);
261 gwlarson 3.7 t = -(DOT(FP_N(peq),e0) + FP_D(peq))/(DOT(FP_N(peq),d));
262 gwlarson 3.4 if(t < 0)
263     hit = 0;
264 gwlarson 3.1 else
265 gwlarson 3.4 hit = 1;
266 gwlarson 3.1
267 gwlarson 3.4 VSUM(r,e0,d,t);
268 gwlarson 3.1
269     if(pd)
270     *pd = t;
271     return(hit);
272     }
273    
274    
275     int
276     point_in_cone(p,p0,p1,p2)
277     FVECT p;
278     FVECT p0,p1,p2;
279     {
280     FVECT np,x_axis,y_axis;
281 gwlarson 3.7 double d1,d2;
282     FPEQ peq;
283 gwlarson 3.1
284     /* Find the equation of the circle defined by the intersection
285     of the cone with the plane defined by p1,p2,p3- project p into
286     that plane and do an in-circle test in the plane
287     */
288    
289     /* find the equation of the plane defined by p1-p3 */
290 gwlarson 3.7 tri_plane_equation(p0,p1,p2,&peq,FALSE);
291 gwlarson 3.1
292     /* define a coordinate system on the plane: the x axis is in
293     the direction of np2-np1, and the y axis is calculated from
294     n cross x-axis
295     */
296     /* Project p onto the plane */
297 gwlarson 3.4 /* NOTE: check this: does sideness check?*/
298 gwlarson 3.7 if(!intersect_vector_plane(p,peq,NULL,np))
299 gwlarson 3.1 return(FALSE);
300    
301     /* create coordinate system on plane: p2-p1 defines the x_axis*/
302     VSUB(x_axis,p1,p0);
303     normalize(x_axis);
304     /* The y axis is */
305 gwlarson 3.7 VCROSS(y_axis,FP_N(peq),x_axis);
306 gwlarson 3.1 normalize(y_axis);
307    
308     VSUB(p1,p1,p0);
309     VSUB(p2,p2,p0);
310     VSUB(np,np,p0);
311    
312     p1[0] = VLEN(p1);
313     p1[1] = 0;
314    
315     d1 = DOT(p2,x_axis);
316     d2 = DOT(p2,y_axis);
317     p2[0] = d1;
318     p2[1] = d2;
319    
320     d1 = DOT(np,x_axis);
321     d2 = DOT(np,y_axis);
322     np[0] = d1;
323     np[1] = d2;
324    
325     /* perform the in-circle test in the new coordinate system */
326     return(point_in_circle_thru_origin(np,p1,p2));
327     }
328    
329     int
330 gwlarson 3.4 point_set_in_stri(v0,v1,v2,p,n,nset,sides)
331 gwlarson 3.1 FVECT v0,v1,v2,p;
332     FVECT n[3];
333 gwlarson 3.4 int *nset;
334     int sides[3];
335 gwlarson 3.1
336     {
337 gwlarson 3.4 double d;
338 gwlarson 3.1 /* Find the normal to the triangle ORIGIN:v0:v1 */
339     if(!NTH_BIT(*nset,0))
340     {
341     VCROSS(n[0],v1,v0);
342     SET_NTH_BIT(*nset,0);
343     }
344     /* Test the point for sidedness */
345     d = DOT(n[0],p);
346    
347 gwlarson 3.4 if(d > 0.0)
348     {
349     sides[0] = GT_OUT;
350     sides[1] = sides[2] = GT_INVALID;
351     return(FALSE);
352 gwlarson 3.1 }
353     else
354     sides[0] = GT_INTERIOR;
355    
356     /* Test next edge */
357     if(!NTH_BIT(*nset,1))
358     {
359     VCROSS(n[1],v2,v1);
360     SET_NTH_BIT(*nset,1);
361     }
362     /* Test the point for sidedness */
363     d = DOT(n[1],p);
364 gwlarson 3.4 if(d > 0.0)
365 gwlarson 3.1 {
366     sides[1] = GT_OUT;
367     sides[2] = GT_INVALID;
368     return(FALSE);
369     }
370     else
371     sides[1] = GT_INTERIOR;
372     /* Test next edge */
373     if(!NTH_BIT(*nset,2))
374     {
375     VCROSS(n[2],v0,v2);
376     SET_NTH_BIT(*nset,2);
377     }
378     /* Test the point for sidedness */
379     d = DOT(n[2],p);
380 gwlarson 3.4 if(d > 0.0)
381 gwlarson 3.1 {
382 gwlarson 3.4 sides[2] = GT_OUT;
383     return(FALSE);
384 gwlarson 3.1 }
385     else
386     sides[2] = GT_INTERIOR;
387     /* Must be interior to the pyramid */
388     return(GT_INTERIOR);
389     }
390    
391    
392    
393 gwlarson 3.7
394 gwlarson 3.1 int
395 gwlarson 3.4 point_in_stri(v0,v1,v2,p)
396 gwlarson 3.1 FVECT v0,v1,v2,p;
397     {
398 gwlarson 3.4 double d;
399 gwlarson 3.1 FVECT n;
400    
401     VCROSS(n,v1,v0);
402     /* Test the point for sidedness */
403     d = DOT(n,p);
404 gwlarson 3.4 if(d > 0.0)
405     return(FALSE);
406    
407 gwlarson 3.1 /* Test next edge */
408     VCROSS(n,v2,v1);
409     /* Test the point for sidedness */
410     d = DOT(n,p);
411 gwlarson 3.4 if(d > 0.0)
412 gwlarson 3.1 return(FALSE);
413    
414     /* Test next edge */
415     VCROSS(n,v0,v2);
416     /* Test the point for sidedness */
417     d = DOT(n,p);
418 gwlarson 3.4 if(d > 0.0)
419 gwlarson 3.1 return(FALSE);
420     /* Must be interior to the pyramid */
421 gwlarson 3.4 return(GT_INTERIOR);
422 gwlarson 3.1 }
423    
424     int
425 gwlarson 3.4 vertices_in_stri(t0,t1,t2,p0,p1,p2,nset,n,avg,pt_sides)
426 gwlarson 3.1 FVECT t0,t1,t2,p0,p1,p2;
427 gwlarson 3.4 int *nset;
428 gwlarson 3.1 FVECT n[3];
429     FVECT avg;
430 gwlarson 3.4 int pt_sides[3][3];
431 gwlarson 3.1
432     {
433 gwlarson 3.4 int below_plane[3],test;
434 gwlarson 3.1
435     SUM_3VEC3(avg,t0,t1,t2);
436     *nset = 0;
437     /* Test vertex v[i] against triangle j*/
438     /* Check if v[i] lies below plane defined by avg of 3 vectors
439     defining triangle
440     */
441    
442     /* test point 0 */
443 gwlarson 3.4 if(DOT(avg,p0) < 0.0)
444 gwlarson 3.1 below_plane[0] = 1;
445     else
446 gwlarson 3.4 below_plane[0] = 0;
447 gwlarson 3.1 /* Test if b[i] lies in or on triangle a */
448 gwlarson 3.4 test = point_set_in_stri(t0,t1,t2,p0,n,nset,pt_sides[0]);
449 gwlarson 3.1 /* If pts[i] is interior: done */
450     if(!below_plane[0])
451     {
452     if(test == GT_INTERIOR)
453     return(TRUE);
454     }
455     /* Now test point 1*/
456    
457 gwlarson 3.4 if(DOT(avg,p1) < 0.0)
458 gwlarson 3.1 below_plane[1] = 1;
459     else
460     below_plane[1]=0;
461     /* Test if b[i] lies in or on triangle a */
462 gwlarson 3.4 test = point_set_in_stri(t0,t1,t2,p1,n,nset,pt_sides[1]);
463 gwlarson 3.1 /* If pts[i] is interior: done */
464     if(!below_plane[1])
465     {
466     if(test == GT_INTERIOR)
467     return(TRUE);
468     }
469    
470     /* Now test point 2 */
471 gwlarson 3.4 if(DOT(avg,p2) < 0.0)
472 gwlarson 3.1 below_plane[2] = 1;
473     else
474 gwlarson 3.4 below_plane[2] = 0;
475 gwlarson 3.1 /* Test if b[i] lies in or on triangle a */
476 gwlarson 3.4 test = point_set_in_stri(t0,t1,t2,p2,n,nset,pt_sides[2]);
477 gwlarson 3.1
478     /* If pts[i] is interior: done */
479     if(!below_plane[2])
480     {
481     if(test == GT_INTERIOR)
482     return(TRUE);
483     }
484    
485     /* If all three points below separating plane: trivial reject */
486     if(below_plane[0] && below_plane[1] && below_plane[2])
487     return(FALSE);
488     /* Now check vertices in a against triangle b */
489     return(FALSE);
490     }
491    
492    
493     set_sidedness_tests(t0,t1,t2,p0,p1,p2,test,sides,nset,n)
494     FVECT t0,t1,t2,p0,p1,p2;
495 gwlarson 3.4 int test[3];
496     int sides[3][3];
497     int nset;
498 gwlarson 3.1 FVECT n[3];
499     {
500 gwlarson 3.4 int t;
501 gwlarson 3.1 double d;
502    
503    
504     /* p=0 */
505     test[0] = 0;
506     if(sides[0][0] == GT_INVALID)
507     {
508     if(!NTH_BIT(nset,0))
509     VCROSS(n[0],t1,t0);
510     /* Test the point for sidedness */
511     d = DOT(n[0],p0);
512 gwlarson 3.4 if(d >= 0.0)
513 gwlarson 3.1 SET_NTH_BIT(test[0],0);
514     }
515     else
516     if(sides[0][0] != GT_INTERIOR)
517     SET_NTH_BIT(test[0],0);
518    
519     if(sides[0][1] == GT_INVALID)
520     {
521     if(!NTH_BIT(nset,1))
522     VCROSS(n[1],t2,t1);
523     /* Test the point for sidedness */
524     d = DOT(n[1],p0);
525 gwlarson 3.4 if(d >= 0.0)
526 gwlarson 3.1 SET_NTH_BIT(test[0],1);
527     }
528     else
529     if(sides[0][1] != GT_INTERIOR)
530     SET_NTH_BIT(test[0],1);
531    
532     if(sides[0][2] == GT_INVALID)
533     {
534     if(!NTH_BIT(nset,2))
535     VCROSS(n[2],t0,t2);
536     /* Test the point for sidedness */
537     d = DOT(n[2],p0);
538 gwlarson 3.4 if(d >= 0.0)
539 gwlarson 3.1 SET_NTH_BIT(test[0],2);
540     }
541     else
542     if(sides[0][2] != GT_INTERIOR)
543     SET_NTH_BIT(test[0],2);
544    
545     /* p=1 */
546     test[1] = 0;
547     /* t=0*/
548     if(sides[1][0] == GT_INVALID)
549     {
550     if(!NTH_BIT(nset,0))
551     VCROSS(n[0],t1,t0);
552     /* Test the point for sidedness */
553     d = DOT(n[0],p1);
554 gwlarson 3.4 if(d >= 0.0)
555 gwlarson 3.1 SET_NTH_BIT(test[1],0);
556     }
557     else
558     if(sides[1][0] != GT_INTERIOR)
559     SET_NTH_BIT(test[1],0);
560    
561     /* t=1 */
562     if(sides[1][1] == GT_INVALID)
563     {
564     if(!NTH_BIT(nset,1))
565     VCROSS(n[1],t2,t1);
566     /* Test the point for sidedness */
567     d = DOT(n[1],p1);
568 gwlarson 3.4 if(d >= 0.0)
569 gwlarson 3.1 SET_NTH_BIT(test[1],1);
570     }
571     else
572     if(sides[1][1] != GT_INTERIOR)
573     SET_NTH_BIT(test[1],1);
574    
575     /* t=2 */
576     if(sides[1][2] == GT_INVALID)
577     {
578     if(!NTH_BIT(nset,2))
579     VCROSS(n[2],t0,t2);
580     /* Test the point for sidedness */
581     d = DOT(n[2],p1);
582 gwlarson 3.4 if(d >= 0.0)
583 gwlarson 3.1 SET_NTH_BIT(test[1],2);
584     }
585     else
586     if(sides[1][2] != GT_INTERIOR)
587     SET_NTH_BIT(test[1],2);
588    
589     /* p=2 */
590     test[2] = 0;
591     /* t = 0 */
592     if(sides[2][0] == GT_INVALID)
593     {
594     if(!NTH_BIT(nset,0))
595     VCROSS(n[0],t1,t0);
596     /* Test the point for sidedness */
597     d = DOT(n[0],p2);
598 gwlarson 3.4 if(d >= 0.0)
599 gwlarson 3.1 SET_NTH_BIT(test[2],0);
600     }
601     else
602     if(sides[2][0] != GT_INTERIOR)
603     SET_NTH_BIT(test[2],0);
604     /* t=1 */
605     if(sides[2][1] == GT_INVALID)
606     {
607     if(!NTH_BIT(nset,1))
608     VCROSS(n[1],t2,t1);
609     /* Test the point for sidedness */
610     d = DOT(n[1],p2);
611 gwlarson 3.4 if(d >= 0.0)
612 gwlarson 3.1 SET_NTH_BIT(test[2],1);
613     }
614     else
615     if(sides[2][1] != GT_INTERIOR)
616     SET_NTH_BIT(test[2],1);
617     /* t=2 */
618     if(sides[2][2] == GT_INVALID)
619     {
620     if(!NTH_BIT(nset,2))
621     VCROSS(n[2],t0,t2);
622     /* Test the point for sidedness */
623     d = DOT(n[2],p2);
624 gwlarson 3.4 if(d >= 0.0)
625 gwlarson 3.1 SET_NTH_BIT(test[2],2);
626     }
627     else
628     if(sides[2][2] != GT_INTERIOR)
629     SET_NTH_BIT(test[2],2);
630     }
631    
632    
633     int
634 gwlarson 3.4 stri_intersect(a1,a2,a3,b1,b2,b3)
635 gwlarson 3.1 FVECT a1,a2,a3,b1,b2,b3;
636     {
637 gwlarson 3.4 int which,test,n_set[2];
638     int sides[2][3][3],i,j,inext,jnext;
639     int tests[2][3];
640 gwlarson 3.1 FVECT n[2][3],p,avg[2];
641    
642     /* Test the vertices of triangle a against the pyramid formed by triangle
643     b and the origin. If any vertex of a is interior to triangle b, or
644     if all 3 vertices of a are ON the edges of b,return TRUE. Remember
645     the results of the edge normal and sidedness tests for later.
646     */
647 gwlarson 3.4 if(vertices_in_stri(a1,a2,a3,b1,b2,b3,&(n_set[0]),n[0],avg[0],sides[1]))
648 gwlarson 3.1 return(TRUE);
649    
650 gwlarson 3.4 if(vertices_in_stri(b1,b2,b3,a1,a2,a3,&(n_set[1]),n[1],avg[1],sides[0]))
651 gwlarson 3.1 return(TRUE);
652    
653    
654     set_sidedness_tests(b1,b2,b3,a1,a2,a3,tests[0],sides[0],n_set[1],n[1]);
655     if(tests[0][0]&tests[0][1]&tests[0][2])
656     return(FALSE);
657    
658     set_sidedness_tests(a1,a2,a3,b1,b2,b3,tests[1],sides[1],n_set[0],n[0]);
659     if(tests[1][0]&tests[1][1]&tests[1][2])
660     return(FALSE);
661    
662     for(j=0; j < 3;j++)
663     {
664     jnext = (j+1)%3;
665     /* IF edge b doesnt cross any great circles of a, punt */
666     if(tests[1][j] & tests[1][jnext])
667     continue;
668     for(i=0;i<3;i++)
669     {
670     inext = (i+1)%3;
671     /* IF edge a doesnt cross any great circles of b, punt */
672     if(tests[0][i] & tests[0][inext])
673     continue;
674     /* Now find the great circles that cross and test */
675     if((NTH_BIT(tests[0][i],j)^(NTH_BIT(tests[0][inext],j)))
676     && (NTH_BIT(tests[1][j],i)^NTH_BIT(tests[1][jnext],i)))
677     {
678     VCROSS(p,n[0][i],n[1][j]);
679    
680     /* If zero cp= done */
681     if(ZERO_VEC3(p))
682     continue;
683     /* check above both planes */
684     if(DOT(avg[0],p) < 0 || DOT(avg[1],p) < 0)
685     {
686     NEGATE_VEC3(p);
687     if(DOT(avg[0],p) < 0 || DOT(avg[1],p) < 0)
688     continue;
689     }
690     return(TRUE);
691     }
692     }
693     }
694     return(FALSE);
695     }
696    
697     int
698 gwlarson 3.4 ray_intersect_tri(orig,dir,v0,v1,v2,pt)
699 gwlarson 3.1 FVECT orig,dir;
700     FVECT v0,v1,v2;
701     FVECT pt;
702     {
703 gwlarson 3.7 FVECT p0,p1,p2,p;
704     FPEQ peq;
705 gwlarson 3.4 int type;
706    
707 gwlarson 3.5 VSUB(p0,v0,orig);
708     VSUB(p1,v1,orig);
709     VSUB(p2,v2,orig);
710    
711 gwlarson 3.4 if(point_in_stri(p0,p1,p2,dir))
712 gwlarson 3.1 {
713     /* Intersect the ray with the triangle plane */
714 gwlarson 3.7 tri_plane_equation(v0,v1,v2,&peq,FALSE);
715     return(intersect_ray_plane(orig,dir,peq,NULL,pt));
716 gwlarson 3.1 }
717 gwlarson 3.4 return(FALSE);
718 gwlarson 3.1 }
719    
720    
721     calculate_view_frustum(vp,hv,vv,horiz,vert,near,far,fnear,ffar)
722     FVECT vp,hv,vv;
723     double horiz,vert,near,far;
724     FVECT fnear[4],ffar[4];
725     {
726     double height,width;
727     FVECT t,nhv,nvv,ndv;
728     double w2,h2;
729     /* Calculate the x and y dimensions of the near face */
730     /* hv and vv are the horizontal and vertical vectors in the
731     view frame-the magnitude is the dimension of the front frustum
732     face at z =1
733     */
734     VCOPY(nhv,hv);
735     VCOPY(nvv,vv);
736     w2 = normalize(nhv);
737     h2 = normalize(nvv);
738     /* Use similar triangles to calculate the dimensions at z=near */
739     width = near*0.5*w2;
740     height = near*0.5*h2;
741    
742     VCROSS(ndv,nvv,nhv);
743     /* Calculate the world space points corresponding to the 4 corners
744     of the front face of the view frustum
745     */
746     fnear[0][0] = width*nhv[0] + height*nvv[0] + near*ndv[0] + vp[0] ;
747     fnear[0][1] = width*nhv[1] + height*nvv[1] + near*ndv[1] + vp[1];
748     fnear[0][2] = width*nhv[2] + height*nvv[2] + near*ndv[2] + vp[2];
749     fnear[1][0] = -width*nhv[0] + height*nvv[0] + near*ndv[0] + vp[0];
750     fnear[1][1] = -width*nhv[1] + height*nvv[1] + near*ndv[1] + vp[1];
751     fnear[1][2] = -width*nhv[2] + height*nvv[2] + near*ndv[2] + vp[2];
752     fnear[2][0] = -width*nhv[0] - height*nvv[0] + near*ndv[0] + vp[0];
753     fnear[2][1] = -width*nhv[1] - height*nvv[1] + near*ndv[1] + vp[1];
754     fnear[2][2] = -width*nhv[2] - height*nvv[2] + near*ndv[2] + vp[2];
755     fnear[3][0] = width*nhv[0] - height*nvv[0] + near*ndv[0] + vp[0];
756     fnear[3][1] = width*nhv[1] - height*nvv[1] + near*ndv[1] + vp[1];
757     fnear[3][2] = width*nhv[2] - height*nvv[2] + near*ndv[2] + vp[2];
758    
759     /* Now do the far face */
760     width = far*0.5*w2;
761     height = far*0.5*h2;
762     ffar[0][0] = width*nhv[0] + height*nvv[0] + far*ndv[0] + vp[0] ;
763     ffar[0][1] = width*nhv[1] + height*nvv[1] + far*ndv[1] + vp[1] ;
764     ffar[0][2] = width*nhv[2] + height*nvv[2] + far*ndv[2] + vp[2] ;
765     ffar[1][0] = -width*nhv[0] + height*nvv[0] + far*ndv[0] + vp[0] ;
766     ffar[1][1] = -width*nhv[1] + height*nvv[1] + far*ndv[1] + vp[1] ;
767     ffar[1][2] = -width*nhv[2] + height*nvv[2] + far*ndv[2] + vp[2] ;
768     ffar[2][0] = -width*nhv[0] - height*nvv[0] + far*ndv[0] + vp[0] ;
769     ffar[2][1] = -width*nhv[1] - height*nvv[1] + far*ndv[1] + vp[1] ;
770     ffar[2][2] = -width*nhv[2] - height*nvv[2] + far*ndv[2] + vp[2] ;
771     ffar[3][0] = width*nhv[0] - height*nvv[0] + far*ndv[0] + vp[0] ;
772     ffar[3][1] = width*nhv[1] - height*nvv[1] + far*ndv[1] + vp[1] ;
773     ffar[3][2] = width*nhv[2] - height*nvv[2] + far*ndv[2] + vp[2] ;
774     }
775    
776 gwlarson 3.6 int
777     max_index(v,r)
778     FVECT v;
779     double *r;
780     {
781     double p[3];
782     int i;
783 gwlarson 3.1
784 gwlarson 3.6 p[0] = fabs(v[0]);
785     p[1] = fabs(v[1]);
786     p[2] = fabs(v[2]);
787     i = (p[0]>=p[1])?((p[0]>=p[2])?0:2):((p[1]>=p[2])?1:2);
788     if(r)
789     *r = p[i];
790     return(i);
791     }
792 gwlarson 3.1
793 gwlarson 3.6 int
794     closest_point_in_tri(p0,p1,p2,p,p0id,p1id,p2id)
795     FVECT p0,p1,p2,p;
796     int p0id,p1id,p2id;
797     {
798     double d,d1;
799     int i;
800    
801     d = DIST_SQ(p,p0);
802     d1 = DIST_SQ(p,p1);
803     if(d < d1)
804     {
805     d1 = DIST_SQ(p,p2);
806     i = (d1 < d)?p2id:p0id;
807     }
808     else
809     {
810     d = DIST_SQ(p,p2);
811     i = (d < d1)? p2id:p1id;
812     }
813     return(i);
814     }
815 gwlarson 3.1
816 gwlarson 3.6
817 gwlarson 3.1 int
818 gwlarson 3.4 sedge_intersect(a0,a1,b0,b1)
819 gwlarson 3.1 FVECT a0,a1,b0,b1;
820     {
821     FVECT na,nb,avga,avgb,p;
822     double d;
823     int sb0,sb1,sa0,sa1;
824    
825     /* First test if edge b straddles great circle of a */
826     VCROSS(na,a0,a1);
827     d = DOT(na,b0);
828     sb0 = ZERO(d)?0:(d<0)? -1: 1;
829     d = DOT(na,b1);
830     sb1 = ZERO(d)?0:(d<0)? -1: 1;
831     /* edge b entirely on one side of great circle a: edges cannot intersect*/
832     if(sb0*sb1 > 0)
833     return(FALSE);
834     /* test if edge a straddles great circle of b */
835     VCROSS(nb,b0,b1);
836     d = DOT(nb,a0);
837     sa0 = ZERO(d)?0:(d<0)? -1: 1;
838     d = DOT(nb,a1);
839     sa1 = ZERO(d)?0:(d<0)? -1: 1;
840     /* edge a entirely on one side of great circle b: edges cannot intersect*/
841     if(sa0*sa1 > 0)
842     return(FALSE);
843    
844     /* Find one of intersection points of the great circles */
845     VCROSS(p,na,nb);
846     /* If they lie on same great circle: call an intersection */
847     if(ZERO_VEC3(p))
848     return(TRUE);
849    
850     VADD(avga,a0,a1);
851     VADD(avgb,b0,b1);
852     if(DOT(avga,p) < 0 || DOT(avgb,p) < 0)
853     {
854     NEGATE_VEC3(p);
855     if(DOT(avga,p) < 0 || DOT(avgb,p) < 0)
856     return(FALSE);
857     }
858     if((!sb0 || !sb1) && (!sa0 || !sa1))
859     return(FALSE);
860     return(TRUE);
861     }
862 gwlarson 3.2
863    
864    
865     /* Find the normalized barycentric coordinates of p relative to
866     * triangle v0,v1,v2. Return result in coord
867     */
868     bary2d(x1,y1,x2,y2,x3,y3,px,py,coord)
869     double x1,y1,x2,y2,x3,y3;
870     double px,py;
871     double coord[3];
872     {
873     double a;
874    
875     a = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
876     coord[0] = ((x2 - px) * (y3 - py) - (x3 - px) * (y2 - py)) / a;
877     coord[1] = ((x3 - px) * (y1 - py) - (x1 - px) * (y3 - py)) / a;
878 gwlarson 3.6 coord[2] = ((x1 - px) * (y2 - py) - (x2 - px) * (y1 - py)) / a;
879 gwlarson 3.2
880     }
881    
882 gwlarson 3.4 bary_ith_child(coord,i)
883     double coord[3];
884     int i;
885     {
886    
887     switch(i){
888     case 0:
889     /* update bary for child */
890     coord[0] = 2.0*coord[0]- 1.0;
891     coord[1] *= 2.0;
892     coord[2] *= 2.0;
893     break;
894     case 1:
895     coord[0] *= 2.0;
896     coord[1] = 2.0*coord[1]- 1.0;
897     coord[2] *= 2.0;
898     break;
899     case 2:
900     coord[0] *= 2.0;
901     coord[1] *= 2.0;
902     coord[2] = 2.0*coord[2]- 1.0;
903     break;
904     case 3:
905     coord[0] = 1.0 - 2.0*coord[0];
906     coord[1] = 1.0 - 2.0*coord[1];
907     coord[2] = 1.0 - 2.0*coord[2];
908     break;
909     #ifdef DEBUG
910     default:
911     eputs("bary_ith_child():Invalid child\n");
912     break;
913     #endif
914     }
915     }
916    
917    
918 gwlarson 3.2 int
919 gwlarson 3.4 bary_child(coord)
920 gwlarson 3.2 double coord[3];
921     {
922     int i;
923    
924     if(coord[0] > 0.5)
925     {
926     /* update bary for child */
927     coord[0] = 2.0*coord[0]- 1.0;
928     coord[1] *= 2.0;
929     coord[2] *= 2.0;
930     return(0);
931     }
932     else
933     if(coord[1] > 0.5)
934     {
935     coord[0] *= 2.0;
936     coord[1] = 2.0*coord[1]- 1.0;
937     coord[2] *= 2.0;
938     return(1);
939     }
940     else
941     if(coord[2] > 0.5)
942     {
943     coord[0] *= 2.0;
944     coord[1] *= 2.0;
945     coord[2] = 2.0*coord[2]- 1.0;
946     return(2);
947     }
948     else
949     {
950     coord[0] = 1.0 - 2.0*coord[0];
951     coord[1] = 1.0 - 2.0*coord[1];
952     coord[2] = 1.0 - 2.0*coord[2];
953     return(3);
954     }
955     }
956    
957 gwlarson 3.4 /* Coord was the ith child of the parent: set the coordinate
958     relative to the parent
959     */
960     bary_parent(coord,i)
961     double coord[3];
962     int i;
963     {
964    
965     switch(i) {
966     case 0:
967     /* update bary for child */
968     coord[0] = coord[0]*0.5 + 0.5;
969     coord[1] *= 0.5;
970     coord[2] *= 0.5;
971     break;
972     case 1:
973     coord[0] *= 0.5;
974     coord[1] = coord[1]*0.5 + 0.5;
975     coord[2] *= 0.5;
976     break;
977    
978     case 2:
979     coord[0] *= 0.5;
980     coord[1] *= 0.5;
981     coord[2] = coord[2]*0.5 + 0.5;
982     break;
983    
984     case 3:
985     coord[0] = 0.5 - 0.5*coord[0];
986     coord[1] = 0.5 - 0.5*coord[1];
987     coord[2] = 0.5 - 0.5*coord[2];
988     break;
989     #ifdef DEBUG
990     default:
991     eputs("bary_parent():Invalid child\n");
992     break;
993     #endif
994     }
995     }
996    
997     bary_from_child(coord,child,next)
998     double coord[3];
999     int child,next;
1000     {
1001     #ifdef DEBUG
1002     if(child <0 || child > 3)
1003     {
1004     eputs("bary_from_child():Invalid child\n");
1005     return;
1006     }
1007     if(next <0 || next > 3)
1008     {
1009     eputs("bary_from_child():Invalid next\n");
1010     return;
1011     }
1012     #endif
1013     if(next == child)
1014     return;
1015    
1016     switch(child){
1017     case 0:
1018     switch(next){
1019     case 1:
1020     coord[0] += 1.0;
1021     coord[1] -= 1.0;
1022     break;
1023     case 2:
1024     coord[0] += 1.0;
1025     coord[2] -= 1.0;
1026     break;
1027     case 3:
1028     coord[0] *= -1.0;
1029     coord[1] = 1 - coord[1];
1030     coord[2] = 1 - coord[2];
1031     break;
1032    
1033     }
1034     break;
1035     case 1:
1036     switch(next){
1037     case 0:
1038     coord[0] -= 1.0;
1039     coord[1] += 1.0;
1040     break;
1041     case 2:
1042     coord[1] += 1.0;
1043     coord[2] -= 1.0;
1044     break;
1045     case 3:
1046     coord[0] = 1 - coord[0];
1047     coord[1] *= -1.0;
1048     coord[2] = 1 - coord[2];
1049     break;
1050     }
1051     break;
1052     case 2:
1053     switch(next){
1054     case 0:
1055     coord[0] -= 1.0;
1056     coord[2] += 1.0;
1057     break;
1058     case 1:
1059     coord[1] -= 1.0;
1060     coord[2] += 1.0;
1061     break;
1062     case 3:
1063     coord[0] = 1 - coord[0];
1064     coord[1] = 1 - coord[1];
1065     coord[2] *= -1.0;
1066     break;
1067     }
1068     break;
1069     case 3:
1070     switch(next){
1071     case 0:
1072     coord[0] *= -1.0;
1073     coord[1] = 1 - coord[1];
1074     coord[2] = 1 - coord[2];
1075     break;
1076     case 1:
1077     coord[0] = 1 - coord[0];
1078     coord[1] *= -1.0;
1079     coord[2] = 1 - coord[2];
1080     break;
1081     case 2:
1082     coord[0] = 1 - coord[0];
1083     coord[1] = 1 - coord[1];
1084     coord[2] *= -1.0;
1085     break;
1086     }
1087     break;
1088     }
1089     }
1090    
1091 gwlarson 3.6
1092     baryi_parent(coord,i)
1093     BCOORD coord[3];
1094     int i;
1095 gwlarson 3.2 {
1096    
1097 gwlarson 3.6 switch(i) {
1098     case 0:
1099     /* update bary for child */
1100     coord[0] = (coord[0] >> 1) + MAXBCOORD2;
1101     coord[1] >>= 1;
1102     coord[2] >>= 1;
1103     break;
1104     case 1:
1105     coord[0] >>= 1;
1106     coord[1] = (coord[1] >> 1) + MAXBCOORD2;
1107     coord[2] >>= 1;
1108     break;
1109    
1110     case 2:
1111     coord[0] >>= 1;
1112     coord[1] >>= 1;
1113     coord[2] = (coord[2] >> 1) + MAXBCOORD2;
1114     break;
1115    
1116     case 3:
1117     coord[0] = MAXBCOORD2 - (coord[0] >> 1);
1118     coord[1] = MAXBCOORD2 - (coord[1] >> 1);
1119     coord[2] = MAXBCOORD2 - (coord[2] >> 1);
1120     break;
1121     #ifdef DEBUG
1122     default:
1123     eputs("baryi_parent():Invalid child\n");
1124     break;
1125     #endif
1126     }
1127 gwlarson 3.2 }
1128    
1129 gwlarson 3.6 baryi_from_child(coord,child,next)
1130     BCOORD coord[3];
1131     int child,next;
1132     {
1133     #ifdef DEBUG
1134     if(child <0 || child > 3)
1135     {
1136     eputs("baryi_from_child():Invalid child\n");
1137     return;
1138     }
1139     if(next <0 || next > 3)
1140     {
1141     eputs("baryi_from_child():Invalid next\n");
1142     return;
1143     }
1144     #endif
1145     if(next == child)
1146     return;
1147    
1148     switch(child){
1149     case 0:
1150     coord[0] = 0;
1151     coord[1] = MAXBCOORD - coord[1];
1152     coord[2] = MAXBCOORD - coord[2];
1153     break;
1154     case 1:
1155     coord[0] = MAXBCOORD - coord[0];
1156     coord[1] = 0;
1157     coord[2] = MAXBCOORD - coord[2];
1158     break;
1159     case 2:
1160     coord[0] = MAXBCOORD - coord[0];
1161     coord[1] = MAXBCOORD - coord[1];
1162     coord[2] = 0;
1163     break;
1164     case 3:
1165     switch(next){
1166     case 0:
1167     coord[0] = 0;
1168     coord[1] = MAXBCOORD - coord[1];
1169     coord[2] = MAXBCOORD - coord[2];
1170     break;
1171     case 1:
1172     coord[0] = MAXBCOORD - coord[0];
1173     coord[1] = 0;
1174     coord[2] = MAXBCOORD - coord[2];
1175     break;
1176     case 2:
1177     coord[0] = MAXBCOORD - coord[0];
1178     coord[1] = MAXBCOORD - coord[1];
1179     coord[2] = 0;
1180     break;
1181     }
1182     break;
1183     }
1184     }
1185    
1186 gwlarson 3.4 int
1187 gwlarson 3.6 baryi_child(coord)
1188     BCOORD coord[3];
1189 gwlarson 3.4 {
1190 gwlarson 3.6 int i;
1191    
1192     if(coord[0] > MAXBCOORD2)
1193     {
1194     /* update bary for child */
1195     coord[0] = (coord[0]<< 1) - MAXBCOORD;
1196     coord[1] <<= 1;
1197     coord[2] <<= 1;
1198     return(0);
1199     }
1200     else
1201     if(coord[1] > MAXBCOORD2)
1202 gwlarson 3.4 {
1203 gwlarson 3.6 coord[0] <<= 1;
1204     coord[1] = (coord[1] << 1) - MAXBCOORD;
1205     coord[2] <<= 1;
1206     return(1);
1207 gwlarson 3.4 }
1208     else
1209 gwlarson 3.6 if(coord[2] > MAXBCOORD2)
1210     {
1211     coord[0] <<= 1;
1212     coord[1] <<= 1;
1213     coord[2] = (coord[2] << 1) - MAXBCOORD;
1214     return(2);
1215     }
1216     else
1217     {
1218     coord[0] = MAXBCOORD - (coord[0] << 1);
1219     coord[1] = MAXBCOORD - (coord[1] << 1);
1220     coord[2] = MAXBCOORD - (coord[2] << 1);
1221     return(3);
1222     }
1223     }
1224    
1225 gwlarson 3.7 int
1226     baryi_nth_child(coord,i)
1227     BCOORD coord[3];
1228     int i;
1229     {
1230    
1231     switch(i){
1232     case 0:
1233     /* update bary for child */
1234     coord[0] = (coord[0]<< 1) - MAXBCOORD;
1235     coord[1] <<= 1;
1236     coord[2] <<= 1;
1237     break;
1238     case 1:
1239     coord[0] <<= 1;
1240     coord[1] = (coord[1] << 1) - MAXBCOORD;
1241     coord[2] <<= 1;
1242     break;
1243     case 2:
1244     coord[0] <<= 1;
1245     coord[1] <<= 1;
1246     coord[2] = (coord[2] << 1) - MAXBCOORD;
1247     break;
1248     case 3:
1249     coord[0] = MAXBCOORD - (coord[0] << 1);
1250     coord[1] = MAXBCOORD - (coord[1] << 1);
1251     coord[2] = MAXBCOORD - (coord[2] << 1);
1252     break;
1253     }
1254     }
1255    
1256    
1257     baryi_children(coord,i,in_tri,rcoord,rin_tri)
1258     BCOORD coord[3][3];
1259     int i;
1260     int in_tri[3];
1261     BCOORD rcoord[3][3];
1262     int rin_tri[3];
1263     {
1264     int j;
1265    
1266     for(j=0; j< 3; j++)
1267     {
1268     if(!in_tri[j])
1269     {
1270     rin_tri[j]=0;
1271     continue;
1272     }
1273    
1274     if(i != 3)
1275     {
1276     if(coord[j][i] < MAXBCOORD2)
1277     {
1278     rin_tri[j] = 0;
1279     continue;
1280     }
1281     }
1282     else
1283     if( !(coord[j][0] <= MAXBCOORD2 && coord[j][1] <= MAXBCOORD2 &&
1284     coord[j][2] <= MAXBCOORD2))
1285     {
1286     rin_tri[j] = 0;
1287     continue;
1288     }
1289    
1290     rin_tri[j]=1;
1291     VCOPY(rcoord[j],coord[j]);
1292     baryi_nth_child(rcoord[j],i);
1293     }
1294    
1295     }
1296    
1297     convert_dtol(b,bi)
1298     double b[3];
1299 gwlarson 3.6 BCOORD bi[3];
1300     {
1301 gwlarson 3.7 int i;
1302 gwlarson 3.6
1303     for(i=0; i < 2;i++)
1304     {
1305 gwlarson 3.7
1306 gwlarson 3.6 if(b[i] <= 0.0)
1307 gwlarson 3.4 {
1308 gwlarson 3.7 #ifdef EXTRA_DEBUG
1309     if(b[i] < 0.0)
1310     printf("under %f\n",b[i]);
1311     #endif
1312 gwlarson 3.6 bi[i]= 0;
1313 gwlarson 3.4 }
1314 gwlarson 3.6 else
1315     if(b[i] >= 1.0)
1316     {
1317 gwlarson 3.7 #ifdef EXTRA_DEBUG
1318     if(b[i] > 1.0)
1319     printf("over %f\n",b[i]);
1320     #endif
1321 gwlarson 3.6 bi[i]= MAXBCOORD;
1322     }
1323     else
1324     bi[i] = (BCOORD)(b[i]*MAXBCOORD);
1325     }
1326 gwlarson 3.7 bi[2] = bi[0] + bi[1];
1327     if(bi[2] > MAXBCOORD)
1328 gwlarson 3.6 {
1329 gwlarson 3.7 #ifdef EXTRA_DEBUG
1330     printf("sum over %f\n",b[0]+b[1]);
1331     #endif
1332 gwlarson 3.6 bi[2] = 0;
1333     bi[1] = MAXBCOORD - bi[0];
1334     }
1335 gwlarson 3.7 else
1336     bi[2] = MAXBCOORD - bi[2];
1337    
1338     }
1339    
1340     /* convert barycentric coordinate b in [-eps,1+eps] to [0,MAXLONG],
1341     dir unbounded to [-MAXLONG,MAXLONG]
1342     */
1343     bary_dtol(b,db,bi,dbi,t,w)
1344     double b[3],db[3][3];
1345     BCOORD bi[3];
1346     BDIR dbi[3][3];
1347     TINT t[3];
1348     int w;
1349     {
1350     int i,id,j,k;
1351     double d;
1352    
1353     convert_dtol(b,bi);
1354    
1355     for(j=w; j< 3; j++)
1356     {
1357     if(t[j] == HUGET)
1358     {
1359     max_index(db[j],&d);
1360     for(i=0; i< 3; i++)
1361     dbi[j][i] = (BDIR)(db[j][i]/d*MAXBDIR);
1362     break;
1363     }
1364     else
1365     {
1366     for(i=0; i< 3; i++)
1367     dbi[j][i] = (BDIR)(db[j][i]*MAXBDIR);
1368     }
1369     }
1370     }
1371    
1372    
1373     /* convert barycentric coordinate b in [-eps,1+eps] to [0,MAXLONG],
1374     dir unbounded to [-MAXLONG,MAXLONG]
1375     */
1376     bary_dtol_new(b,db,bi,boi,dbi,t)
1377     double b[4][3],db[3][3];
1378     BCOORD bi[3],boi[3][3];
1379     BDIR dbi[3][3];
1380     int t[3];
1381     {
1382     int i,id,j,k;
1383     double d;
1384    
1385     convert_dtol(b[3],bi);
1386    
1387     for(j=0; j<3;j++)
1388     {
1389     if(t[j] != 1)
1390     continue;
1391     convert_dtol(b[j],boi[j]);
1392     }
1393 gwlarson 3.6 for(j=0; j< 3; j++)
1394     {
1395 gwlarson 3.7 k = (j+1)%3;
1396     if(t[k]==0)
1397 gwlarson 3.6 continue;
1398 gwlarson 3.7 if(t[k] == -1)
1399     {
1400     max_index(db[j],&d);
1401     for(i=0; i< 3; i++)
1402     dbi[j][i] = (BDIR)(db[j][i]/d*MAXBDIR);
1403     t[k] = 0;
1404     }
1405     else
1406     if(t[j] != 1)
1407     for(i=0; i< 3; i++)
1408 gwlarson 3.6 dbi[j][i] = (BDIR)(db[j][i]*MAXBDIR);
1409 gwlarson 3.7 else
1410     for(i=0; i< 3; i++)
1411     dbi[j][i] = boi[k][i] - boi[j][i];
1412    
1413 gwlarson 3.6 }
1414 gwlarson 3.4 }
1415 gwlarson 3.7
1416    
1417     bary_dtolb(b,bi,in_tri)
1418     double b[3][3];
1419     BCOORD bi[3][3];
1420     int in_tri[3];
1421     {
1422     int i,j;
1423    
1424     for(j=0; j<3;j++)
1425     {
1426     if(!in_tri[j])
1427     continue;
1428     for(i=0; i < 2;i++)
1429     {
1430     if(b[j][i] <= 0.0)
1431     {
1432     bi[j][i]= 0;
1433     }
1434     else
1435     if(b[j][i] >= 1.0)
1436     {
1437     bi[j][i]= MAXBCOORD;
1438     }
1439     else
1440     bi[j][i] = (BCOORD)(b[j][i]*MAXBCOORD);
1441     }
1442     bi[j][2] = MAXBCOORD - bi[j][0] - bi[j][1];
1443     if(bi[j][2] < 0)
1444     {
1445     bi[j][2] = 0;
1446     bi[j][1] = MAXBCOORD - bi[j][0];
1447     }
1448     }
1449     }
1450    
1451    
1452 gwlarson 3.6
1453    
1454 gwlarson 3.2
1455    
1456    
1457    
1458    
1459    
1460 gwlarson 3.1