ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm_qtree.c
Revision: 3.8
Committed: Wed Nov 11 12:05:39 1998 UTC (25 years, 5 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.7: +7 -3 lines
Log Message:
new triangulation code
changed triangle vertex order to CCW
changed numbering of triangle neighbors to match quadtree
fixed tone-mapping bug
removed errant printf() statements
redid logic for adding and testing samples with new epsilon

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_qtree.c: adapted from octree.c from radiance code
9     */
10     /*
11     * octree.c - routines dealing with octrees and cubes.
12     *
13     * 7/28/85
14     */
15    
16     #include "standard.h"
17 gwlarson 3.7 #include "sm_flag.h"
18 gwlarson 3.1 #include "sm_geom.h"
19     #include "sm_qtree.h"
20    
21     QUADTREE *quad_block[QT_MAX_BLK]; /* our quadtree */
22     static QUADTREE quad_free_list = EMPTY; /* freed octree nodes */
23     static QUADTREE treetop = 0; /* next free node */
24 gwlarson 3.4 int4 *quad_flag= NULL;
25 gwlarson 3.1
26 gwlarson 3.4 #ifdef TEST_DRIVER
27     extern FVECT Pick_v0[500],Pick_v1[500],Pick_v2[500];
28     extern int Pick_cnt,Pick_tri,Pick_samp;
29     extern FVECT Pick_point[500];
30 gwlarson 3.8 extern int Pick_q[500];
31 gwlarson 3.7
32 gwlarson 3.4 #endif
33 gwlarson 3.7 int Incnt=0;
34 gwlarson 3.4
35 gwlarson 3.1 QUADTREE
36     qtAlloc() /* allocate a quadtree */
37     {
38     register QUADTREE freet;
39    
40     if ((freet = quad_free_list) != EMPTY)
41     {
42     quad_free_list = QT_NTH_CHILD(freet, 0);
43     return(freet);
44     }
45     freet = treetop;
46     if (QT_BLOCK_INDEX(freet) == 0)
47     {
48     if (QT_BLOCK(freet) >= QT_MAX_BLK)
49     return(EMPTY);
50     if ((quad_block[QT_BLOCK(freet)] = (QUADTREE *)malloc(
51 gwlarson 3.3 QT_BLOCK_SIZE*4*sizeof(QUADTREE))) == NULL)
52 gwlarson 3.7 error(SYSTEM,"qtAlloc(): Unable to allocate memory\n");
53 gwlarson 3.4
54 gwlarson 3.7 /* Realloc the per/node flags */
55 gwlarson 3.3 quad_flag = (int4 *)realloc((char *)quad_flag,
56 gwlarson 3.7 (QT_BLOCK(freet)+1)*((QT_BLOCK_SIZE+7)>>3));
57 gwlarson 3.3 if (quad_flag == NULL)
58 gwlarson 3.7 error(SYSTEM,"qtAlloc(): Unable to allocate memory\n");
59 gwlarson 3.1 }
60     treetop += 4;
61     return(freet);
62     }
63    
64    
65 gwlarson 3.3 qtClearAllFlags() /* clear all quadtree branch flags */
66     {
67 gwlarson 3.7 if (!treetop)
68     return;
69    
70     /* Clear the node flags*/
71     bzero((char *)quad_flag, (QT_BLOCK(treetop-4)+1)*((QT_BLOCK_SIZE+7)>>3));
72     /* Clear set flags */
73     qtclearsetflags();
74 gwlarson 3.3 }
75    
76 gwlarson 3.1 qtFree(qt) /* free a quadtree */
77     register QUADTREE qt;
78     {
79     register int i;
80    
81     if (!QT_IS_TREE(qt))
82     {
83     qtfreeleaf(qt);
84     return;
85     }
86     for (i = 0; i < 4; i++)
87     qtFree(QT_NTH_CHILD(qt, i));
88     QT_NTH_CHILD(qt, 0) = quad_free_list;
89     quad_free_list = qt;
90     }
91    
92    
93     qtDone() /* free EVERYTHING */
94     {
95     register int i;
96 gwlarson 3.7
97 gwlarson 3.4 qtfreeleaves();
98 gwlarson 3.1 for (i = 0; i < QT_MAX_BLK; i++)
99     {
100 gwlarson 3.3 if (quad_block[i] == NULL)
101     break;
102     free((char *)quad_block[i]);
103 gwlarson 3.1 quad_block[i] = NULL;
104     }
105 gwlarson 3.7 /* Free the flags */
106 gwlarson 3.3 if (i) free((char *)quad_flag);
107     quad_flag = NULL;
108 gwlarson 3.1 quad_free_list = EMPTY;
109     treetop = 0;
110     }
111    
112     QUADTREE
113 gwlarson 3.7 qtLocate_leaf(qt,bcoord)
114     QUADTREE qt;
115     BCOORD bcoord[3];
116 gwlarson 3.2 {
117     int i;
118    
119 gwlarson 3.7 if(QT_IS_TREE(qt))
120     {
121     i = baryi_child(bcoord);
122 gwlarson 3.4
123 gwlarson 3.7 return(qtLocate_leaf(QT_NTH_CHILD(qt,i),bcoord));
124     }
125     else
126     return(qt);
127 gwlarson 3.2 }
128    
129 gwlarson 3.7 /*
130     Return the quadtree node containing pt. It is assumed that pt is in
131     the root node qt with ws vertices q0,q1,q2 and plane equation peq.
132     */
133 gwlarson 3.2 QUADTREE
134 gwlarson 3.7 qtRoot_point_locate(qt,q0,q1,q2,peq,pt)
135     QUADTREE qt;
136     FVECT q0,q1,q2;
137     FPEQ peq;
138 gwlarson 3.1 FVECT pt;
139     {
140 gwlarson 3.2 int i,x,y;
141 gwlarson 3.7 FVECT i_pt;
142     double bcoord[3];
143     BCOORD bcoordi[3];
144 gwlarson 3.1
145 gwlarson 3.7 /* Will return lowest level triangle containing point: It the
146 gwlarson 3.1 point is on an edge or vertex: will return first associated
147     triangle encountered in the child traversal- the others can
148     be derived using triangle adjacency information
149     */
150 gwlarson 3.7 if(QT_IS_TREE(qt))
151 gwlarson 3.1 {
152 gwlarson 3.2 /* Find the intersection point */
153 gwlarson 3.7 intersect_vector_plane(pt,peq,NULL,i_pt);
154 gwlarson 3.2
155 gwlarson 3.7 x = FP_X(peq);
156     y = FP_Y(peq);
157 gwlarson 3.2 /* Calculate barycentric coordinates of i_pt */
158 gwlarson 3.7 bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],bcoord);
159    
160     /* convert to integer coordinate */
161     convert_dtol(bcoord,bcoordi);
162 gwlarson 3.2
163 gwlarson 3.7 i = baryi_child(bcoordi);
164    
165     return(qtLocate_leaf(QT_NTH_CHILD(qt,i),bcoordi));
166 gwlarson 3.1 }
167     else
168 gwlarson 3.7 return(qt);
169 gwlarson 3.1 }
170    
171 gwlarson 3.4
172 gwlarson 3.1
173    
174 gwlarson 3.2 /* for triangle v0-v1-v2- returns a,b,c: children are:
175 gwlarson 3.1
176 gwlarson 3.2 v2 0: v0,a,c
177     /\ 1: a,v1,b
178     /2 \ 2: c,b,v2
179     c/____\b 3: b,c,a
180 gwlarson 3.1 /\ /\
181 gwlarson 3.2 /0 \3 /1 \
182     v0____\/____\v1
183 gwlarson 3.1 a
184     */
185    
186    
187 gwlarson 3.2 qtNth_child_tri(v0,v1,v2,a,b,c,i,r0,r1,r2)
188     FVECT v0,v1,v2;
189 gwlarson 3.1 FVECT a,b,c;
190     int i;
191 gwlarson 3.2 FVECT r0,r1,r2;
192 gwlarson 3.1 {
193 gwlarson 3.4
194 gwlarson 3.7 if(!a)
195     {
196     /* Caution: r's must not be equal to v's:will be incorrect */
197     switch(i){
198     case 0:
199     VCOPY(r0,v0);
200     EDGE_MIDPOINT_VEC3(r1,v0,v1);
201     EDGE_MIDPOINT_VEC3(r2,v2,v0);
202     break;
203     case 1:
204     EDGE_MIDPOINT_VEC3(r0,v0,v1);
205     VCOPY(r1,v1);
206     EDGE_MIDPOINT_VEC3(r2,v1,v2);
207     break;
208     case 2:
209     EDGE_MIDPOINT_VEC3(r0,v2,v0);
210     EDGE_MIDPOINT_VEC3(r1,v1,v2);
211     VCOPY(r2,v2);
212     break;
213     case 3:
214     EDGE_MIDPOINT_VEC3(r0,v1,v2);
215     EDGE_MIDPOINT_VEC3(r1,v2,v0);
216     EDGE_MIDPOINT_VEC3(r2,v0,v1);
217     break;
218     }
219 gwlarson 3.1 }
220 gwlarson 3.7 else
221     {
222     switch(i){
223     case 0:
224     VCOPY(r0,v0); VCOPY(r1,a); VCOPY(r2,c);
225     break;
226     case 1:
227     VCOPY(r0,a); VCOPY(r1,v1); VCOPY(r2,b);
228     break;
229     case 2:
230     VCOPY(r0,c); VCOPY(r1,b); VCOPY(r2,v2);
231     break;
232     case 3:
233     VCOPY(r0,b); VCOPY(r1,c); VCOPY(r2,a);
234     break;
235     }
236     }
237 gwlarson 3.1 }
238    
239     /* Add triangle "id" to all leaf level cells that are children of
240     quadtree pointed to by "qtptr" with cell vertices "t1,t2,t3"
241     that it overlaps (vertex and edge adjacencies do not count
242     as overlapping). If the addition of the triangle causes the cell to go over
243     threshold- the cell is split- and the triangle must be recursively inserted
244     into the new child cells: it is assumed that "v1,v2,v3" are normalized
245     */
246    
247 gwlarson 3.7 QUADTREE
248     qtRoot_add_tri(qt,q0,q1,q2,t0,t1,t2,id,n)
249     QUADTREE qt;
250 gwlarson 3.4 FVECT q0,q1,q2;
251     FVECT t0,t1,t2;
252 gwlarson 3.7 int id,n;
253 gwlarson 3.3 {
254 gwlarson 3.7 if(stri_intersect(q0,q1,q2,t0,t1,t2))
255     qt = qtAdd_tri(qt,q0,q1,q2,t0,t1,t2,id,n);
256 gwlarson 3.3
257 gwlarson 3.7 return(qt);
258 gwlarson 3.3 }
259    
260 gwlarson 3.7 QUADTREE
261     qtRoot_remove_tri(qt,q0,q1,q2,t0,t1,t2,id,n)
262     QUADTREE qt;
263 gwlarson 3.4 FVECT q0,q1,q2;
264 gwlarson 3.3 FVECT t0,t1,t2;
265 gwlarson 3.7 int id,n;
266     {
267    
268     if(stri_intersect(q0,q1,q2,t0,t1,t2))
269     qt = qtRemove_tri(qt,q0,q1,q2,t0,t1,t2,id,n);
270     return(qt);
271     }
272    
273    
274     QUADTREE
275     qtAdd_tri(qt,q0,q1,q2,t0,t1,t2,id,n)
276     QUADTREE qt;
277     FVECT q0,q1,q2;
278     FVECT t0,t1,t2;
279 gwlarson 3.1 int id;
280     int n;
281     {
282     FVECT a,b,c;
283 gwlarson 3.7 OBJECT tset[QT_MAXSET+1],*optr,*tptr;
284 gwlarson 3.2 FVECT r0,r1,r2;
285 gwlarson 3.7 int i;
286 gwlarson 3.1
287     /* if this is tree: recurse */
288 gwlarson 3.7 if(QT_IS_TREE(qt))
289 gwlarson 3.1 {
290 gwlarson 3.7 QT_SET_FLAG(qt);
291 gwlarson 3.1 n++;
292 gwlarson 3.4 qtSubdivide_tri(q0,q1,q2,a,b,c);
293 gwlarson 3.7
294     if(stri_intersect(t0,t1,t2,q0,a,c))
295     QT_NTH_CHILD(qt,0) = qtAdd_tri(QT_NTH_CHILD(qt,0),q0,a,c,t0,t1,t2,id,n);
296     if(stri_intersect(t0,t1,t2,a,q1,b))
297     QT_NTH_CHILD(qt,1) = qtAdd_tri(QT_NTH_CHILD(qt,1),a,q1,b,t0,t1,t2,id,n);
298     if(stri_intersect(t0,t1,t2,c,b,q2))
299     QT_NTH_CHILD(qt,2) = qtAdd_tri(QT_NTH_CHILD(qt,2),c,b,q2,t0,t1,t2,id,n);
300     if(stri_intersect(t0,t1,t2,b,c,a))
301     QT_NTH_CHILD(qt,3) = qtAdd_tri(QT_NTH_CHILD(qt,3),b,c,a,t0,t1,t2,id,n);
302     return(qt);
303 gwlarson 3.1 }
304     else
305     {
306     /* If this leave node emptry- create a new set */
307 gwlarson 3.7 if(QT_IS_EMPTY(qt))
308     qt = qtaddelem(qt,id);
309 gwlarson 3.1 else
310     {
311     /* If the set is too large: subdivide */
312 gwlarson 3.7 optr = qtqueryset(qt);
313 gwlarson 3.4
314     if(QT_SET_CNT(optr) < QT_SET_THRESHOLD)
315 gwlarson 3.7 qt = qtaddelem(qt,id);
316     else
317     {
318     if (n < QT_MAX_LEVELS)
319     {
320     /* If set size exceeds threshold: subdivide cell and
321     reinsert set tris into cell
322     */
323     /* CAUTION:If QT_SET_THRESHOLD << QT_MAXSET, and dont add
324     more than a few triangles before expanding: then are safe here
325     otherwise must check to make sure set size is < MAXSET,
326     or qtgetset could overflow os.
327     */
328     tptr = qtqueryset(qt);
329     if(QT_SET_CNT(tptr) > QT_MAXSET)
330     tptr = (OBJECT *)malloc((QT_SET_CNT(tptr)+1)*sizeof(OBJECT));
331     else
332     tptr = tset;
333     if(!tptr)
334     goto memerr;
335 gwlarson 3.4
336 gwlarson 3.7 qtgetset(tptr,qt);
337     n++;
338     qtfreeleaf(qt);
339     qtSubdivide(qt);
340     qt = qtAdd_tri(qt,q0,q1,q2,t0,t1,t2,id,n);
341 gwlarson 3.4
342 gwlarson 3.7 for(optr = QT_SET_PTR(tptr),i = QT_SET_CNT(tptr); i > 0; i--)
343     {
344     id = QT_SET_NEXT_ELEM(optr);
345     if(!qtTri_from_id(id,r0,r1,r2))
346     continue;
347     qt = qtAdd_tri(qt,q0,q1,q2,r0,r1,r2,id,n);
348     }
349     if(tptr != tset)
350     free(tptr);
351 gwlarson 3.4 }
352 gwlarson 3.1 else
353 gwlarson 3.7 qt = qtaddelem(qt,id);
354     }
355 gwlarson 3.1 }
356     }
357 gwlarson 3.7 return(qt);
358     memerr:
359     error(SYSTEM,"qtAdd_tri():Unable to allocate memory");
360 gwlarson 3.1 }
361    
362    
363 gwlarson 3.7 QUADTREE
364     qtRemove_tri(qt,id,q0,q1,q2,t0,t1,t2)
365     QUADTREE qt;
366 gwlarson 3.1 int id;
367 gwlarson 3.7 FVECT q0,q1,q2;
368 gwlarson 3.2 FVECT t0,t1,t2;
369 gwlarson 3.1 {
370     FVECT a,b,c;
371    
372 gwlarson 3.2 /* test if triangle (t0,t1,t2) overlaps cell triangle (v0,v1,v2) */
373 gwlarson 3.7 if(!stri_intersect(t0,t1,t2,q0,q1,q2))
374     return(qt);
375 gwlarson 3.1
376     /* if this is tree: recurse */
377 gwlarson 3.7 if(QT_IS_TREE(qt))
378 gwlarson 3.1 {
379 gwlarson 3.7 qtSubdivide_tri(q0,q1,q2,a,b,c);
380     QT_NTH_CHILD(qt,0) = qtRemove_tri(QT_NTH_CHILD(qt,0),id,t0,t1,t2,q0,a,c);
381     QT_NTH_CHILD(qt,1) = qtRemove_tri(QT_NTH_CHILD(qt,1),id,t0,t1,t2,a,q1,b);
382     QT_NTH_CHILD(qt,2) = qtRemove_tri(QT_NTH_CHILD(qt,2),id,t0,t1,t2,c,b,q2);
383     QT_NTH_CHILD(qt,3) = qtRemove_tri(QT_NTH_CHILD(qt,3),id,t0,t1,t2,b,c,a);
384     return(qt);
385 gwlarson 3.1 }
386     else
387     {
388 gwlarson 3.7 if(QT_IS_EMPTY(qt))
389 gwlarson 3.1 {
390     #ifdef DEBUG
391     eputs("qtRemove_tri(): triangle not found\n");
392     #endif
393     }
394     /* remove id from set */
395     else
396     {
397 gwlarson 3.7 if(!qtinset(qt,id))
398 gwlarson 3.1 {
399     #ifdef DEBUG
400     eputs("qtRemove_tri(): tri not in set\n");
401     #endif
402     }
403     else
404 gwlarson 3.7 qt = qtdelelem(qt,id);
405 gwlarson 3.1 }
406     }
407 gwlarson 3.7 return(qt);
408 gwlarson 3.1 }
409 gwlarson 3.4
410    
411 gwlarson 3.7 QUADTREE
412     qtVisit_tri_interior(qt,q0,q1,q2,t0,t1,t2,n0,n1,n2,n,func,f,argptr)
413     QUADTREE qt;
414 gwlarson 3.4 FVECT q0,q1,q2;
415     FVECT t0,t1,t2;
416 gwlarson 3.7 FVECT n0,n1,n2;
417 gwlarson 3.4 int n;
418 gwlarson 3.7 int (*func)(),*f;
419     int *argptr;
420 gwlarson 3.4 {
421 gwlarson 3.7 FVECT a,b,c;
422 gwlarson 3.4
423     /* If qt Flag set, or qt vertices interior to t0t1t2-descend */
424     tree_modified:
425    
426 gwlarson 3.7 if(QT_IS_TREE(qt))
427 gwlarson 3.4 {
428 gwlarson 3.7 if(QT_IS_FLAG(qt) || point_in_stri_n(n0,n1,n2,q0))
429 gwlarson 3.4 {
430 gwlarson 3.7 QT_SET_FLAG(qt);
431 gwlarson 3.4 qtSubdivide_tri(q0,q1,q2,a,b,c);
432     /* descend to children */
433 gwlarson 3.7 QT_NTH_CHILD(qt,0) = qtVisit_tri_interior(QT_NTH_CHILD(qt,0),
434     q0,a,c,t0,t1,t2,n0,n1,n2,n+1,func,f,argptr);
435     QT_NTH_CHILD(qt,1) = qtVisit_tri_interior(QT_NTH_CHILD(qt,1),
436     a,q1,b,t0,t1,t2,n0,n1,n2,n+1,func,f,argptr);
437     QT_NTH_CHILD(qt,2) = qtVisit_tri_interior(QT_NTH_CHILD(qt,2),
438     c,b,q2,t0,t1,t2,n0,n1,n2,n+1,func,f,argptr);
439     QT_NTH_CHILD(qt,3) = qtVisit_tri_interior(QT_NTH_CHILD(qt,3),
440     b,c,a,t0,t1,t2,n0,n1,n2,n+1,func,f,argptr);
441 gwlarson 3.4 }
442     }
443     else
444 gwlarson 3.7 if((!QT_IS_EMPTY(qt) && QT_LEAF_IS_FLAG(qt)) ||
445     point_in_stri_n(n0,n1,n2,q0))
446 gwlarson 3.4 {
447 gwlarson 3.7 func(&qt,f,argptr,q0,q1,q2,t0,t1,t2,n);
448     if(QT_FLAG_IS_MODIFIED(*f))
449 gwlarson 3.4 {
450 gwlarson 3.7 QT_SET_FLAG(qt);
451     goto tree_modified;
452 gwlarson 3.4 }
453 gwlarson 3.7 if(QT_IS_LEAF(qt))
454     QT_LEAF_SET_FLAG(qt);
455     else
456     if(QT_IS_TREE(qt))
457     QT_SET_FLAG(qt);
458     }
459     return(qt);
460 gwlarson 3.4 }
461    
462    
463    
464 gwlarson 3.6 int
465     move_to_nbri(b,db0,db1,db2,tptr)
466     BCOORD b[3];
467     BDIR db0,db1,db2;
468     TINT *tptr;
469     {
470     TINT t,dt;
471     BCOORD bc;
472     int nbr;
473    
474     nbr = -1;
475 gwlarson 3.7 *tptr = 0;
476 gwlarson 3.6 /* Advance to next node */
477 gwlarson 3.7 if(b[0]==0 && db0 < 0)
478     return(0);
479     if(b[1]==0 && db1 < 0)
480     return(1);
481     if(b[2]==0 && db2 < 0)
482     return(2);
483    
484 gwlarson 3.6 if(db0 < 0)
485     {
486 gwlarson 3.7 bc = b[0]<<SHIFT_MAXBCOORD;
487 gwlarson 3.6 t = bc/-db0;
488     nbr = 0;
489     }
490     else
491     t = HUGET;
492     if(db1 < 0)
493     {
494 gwlarson 3.7 bc = b[1] <<SHIFT_MAXBCOORD;
495 gwlarson 3.6 dt = bc/-db1;
496     if( dt < t)
497     {
498     t = dt;
499     nbr = 1;
500     }
501     }
502     if(db2 < 0)
503     {
504 gwlarson 3.7 bc = b[2] << SHIFT_MAXBCOORD;
505 gwlarson 3.6 dt = bc/-db2;
506     if( dt < t)
507     {
508     t = dt;
509     nbr = 2;
510     }
511     }
512     *tptr = t;
513     return(nbr);
514     }
515 gwlarson 3.7
516     QUADTREE
517     qtVisit_tri_edges(qt,b,db0,db1,db2,db,wptr,nextptr,t,sign,sfactor,func,f,argptr)
518     QUADTREE qt;
519 gwlarson 3.6 BCOORD b[3];
520     BDIR db0,db1,db2,db[3][3];
521 gwlarson 3.7 int *wptr,*nextptr;
522 gwlarson 3.6 TINT t[3];
523 gwlarson 3.7 int sign,sfactor;
524 gwlarson 3.4 int (*func)();
525 gwlarson 3.7 int *f,*argptr;
526 gwlarson 3.4 {
527     int i,found;
528 gwlarson 3.7 QUADTREE child;
529 gwlarson 3.4 int nbr,next,w;
530 gwlarson 3.7 TINT t_g,t_l,t_i,l;
531    
532     if(QT_IS_TREE(qt))
533 gwlarson 3.4 {
534 gwlarson 3.7 /* Find the appropriate child and reset the coord */
535     i = baryi_child(b);
536 gwlarson 3.4
537 gwlarson 3.7 QT_SET_FLAG(qt);
538 gwlarson 3.4
539 gwlarson 3.7 for(;;)
540     {
541     w = *wptr;
542     child = QT_NTH_CHILD(qt,i);
543     if(i != 3)
544     QT_NTH_CHILD(qt,i) =
545     qtVisit_tri_edges(child,b,db0,db1,db2,db,wptr,nextptr,t,sign,
546     sfactor+1,func,f,argptr);
547     else
548     /* If the center cell- must flip direction signs */
549     QT_NTH_CHILD(qt,i) =
550     qtVisit_tri_edges(child,b,-db0,-db1,-db2,db,wptr,nextptr,t,1-sign,
551     sfactor+1,func,f,argptr);
552    
553     if(QT_FLAG_IS_DONE(*f))
554     return(qt);
555     if(*wptr != w)
556     {
557 gwlarson 3.4 w = *wptr;
558 gwlarson 3.7 db0 = db[w][0];db1 = db[w][1];db2 = db[w][2];
559     if(sign)
560     { db0 *= -1;db1 *= -1; db2 *= -1;}
561 gwlarson 3.4 }
562 gwlarson 3.7 /* If in same block: traverse */
563     if(i==3)
564     next = *nextptr;
565     else
566     if(*nextptr == i)
567     next = 3;
568     else
569     {
570     /* reset the barycentric coordinates in the parents*/
571     baryi_parent(b,i);
572     /* Else pop up to parent and traverse from there */
573     return(qt);
574     }
575     baryi_from_child(b,i,next);
576     i = next;
577     }
578 gwlarson 3.4 }
579     else
580     {
581 gwlarson 3.8 #ifdef TEST_DRIVER
582     if(Pick_cnt < 500)
583     Pick_q[Pick_cnt++]=qt;
584     #endif;
585     func(&qt,f,argptr);
586 gwlarson 3.7 if(QT_FLAG_IS_DONE(*f))
587     {
588     if(!QT_IS_EMPTY(qt))
589     QT_LEAF_SET_FLAG(qt);
590     return(qt);
591     }
592    
593     if(!QT_IS_EMPTY(qt))
594     QT_LEAF_SET_FLAG(qt);
595     /* Advance to next node */
596     w = *wptr;
597     while(1)
598 gwlarson 3.4 {
599 gwlarson 3.7 nbr = move_to_nbri(b,db0,db1,db2,&t_i);
600    
601 gwlarson 3.6 t_g = t_i >> sfactor;
602    
603 gwlarson 3.4 if(t_g >= t[w])
604     {
605     if(w == 2)
606 gwlarson 3.7 {
607     QT_FLAG_SET_DONE(*f);
608     return(qt);
609     }
610     /* The edge fits in the cell- therefore the result of shifting
611     db by sfactor is guaranteed to be less than MAXBCOORD
612     */
613 gwlarson 3.6 /* Caution: (t[w]*db) must occur before divide by MAXBCOORD
614     since t[w] will always be < MAXBCOORD
615 gwlarson 3.7 */
616     l = t[w] << sfactor;
617     /* NOTE: Change divides to Shift and multiply by sign*/
618     b[0] += (l*db0)/MAXBCOORD;
619     b[1] += (l*db1)/MAXBCOORD;
620     b[2] += (l*db2)/MAXBCOORD;
621 gwlarson 3.4 w++;
622 gwlarson 3.6 db0 = db[w][0]; db1 = db[w][1]; db2 = db[w][2];
623 gwlarson 3.4 if(sign)
624 gwlarson 3.7 { db0 *= -1;db1 *= -1; db2 *= -1;}
625 gwlarson 3.4 }
626 gwlarson 3.7 else
627     {
628 gwlarson 3.6 /* Caution: (t_i*db) must occur before divide by MAXBCOORD
629 gwlarson 3.7 since t_i will always be < MAXBCOORD*/
630     /* NOTE: Change divides to Shift and by sign*/
631     b[0] += (t_i *db0) / MAXBCOORD;
632     b[1] += (t_i *db1) / MAXBCOORD;
633     b[2] += (t_i *db2) / MAXBCOORD;
634    
635 gwlarson 3.4 t[w] -= t_g;
636     *wptr = w;
637 gwlarson 3.7 *nextptr = nbr;
638     return(qt);
639 gwlarson 3.4 }
640     }
641 gwlarson 3.6 }
642 gwlarson 3.4 }
643    
644    
645 gwlarson 3.7 QUADTREE
646     qtRoot_visit_tri_edges(qt,q0,q1,q2,peq,tri,i_pt,wptr,nextptr,func,f,argptr)
647     QUADTREE qt;
648 gwlarson 3.4 FVECT q0,q1,q2;
649 gwlarson 3.7 FPEQ peq;
650 gwlarson 3.4 FVECT tri[3],i_pt;
651 gwlarson 3.7 int *wptr,*nextptr;
652 gwlarson 3.4 int (*func)();
653 gwlarson 3.7 int *f,*argptr;
654 gwlarson 3.4 {
655 gwlarson 3.7 int x,y,z,w,i,j,first;
656     QUADTREE child;
657     FVECT c,d,v[3];
658     double b[4][3],db[3][3],et[3],exit_pt;
659 gwlarson 3.6 BCOORD bi[3];
660     TINT t[3];
661     BDIR dbi[3][3];
662 gwlarson 3.7
663     first =0;
664 gwlarson 3.4 w = *wptr;
665 gwlarson 3.7 if(w==-1)
666     {
667     first = 1;
668     *wptr = w = 0;
669     }
670 gwlarson 3.4 /* Project the origin onto the root node plane */
671    
672 gwlarson 3.6 t[0] = t[1] = t[2] = 0;
673 gwlarson 3.4 /* Find the intersection point of the origin */
674     /* map to 2d by dropping maximum magnitude component of normal */
675 gwlarson 3.7
676     x = FP_X(peq);
677     y = FP_Y(peq);
678     z = FP_Z(peq);
679 gwlarson 3.4 /* Calculate barycentric coordinates for current vertex */
680 gwlarson 3.7 if(!first)
681 gwlarson 3.4 bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b[3]);
682     else
683     /* Just starting: b[0] is the origin point: guaranteed to be valid b*/
684     {
685 gwlarson 3.7 intersect_vector_plane(tri[0],peq,&(et[0]),v[0]);
686 gwlarson 3.4 bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[0][x],v[0][y],b[0]);
687     VCOPY(b[3],b[0]);
688     }
689    
690     j = (w+1)%3;
691 gwlarson 3.7 intersect_vector_plane(tri[j],peq,&(et[j]),v[j]);
692 gwlarson 3.4 bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[j][x],v[j][y],b[j]);
693     if(et[j] < 0.0)
694     {
695     VSUB(db[w],b[3],b[j]);
696 gwlarson 3.6 t[w] = HUGET;
697 gwlarson 3.4 }
698     else
699     {
700 gwlarson 3.5 /* NOTE: for stability: do not increment with ipt- use full dir and
701     calculate t: but for wrap around case: could get same problem?
702     */
703 gwlarson 3.4 VSUB(db[w],b[j],b[3]);
704 gwlarson 3.6 /* Check if the point is out side of the triangle: if so t[w] =HUGET */
705     if((fabs(b[j][0])>(FTINY+1.0)) ||(fabs(b[j][1])>(FTINY+1.0)) ||
706 gwlarson 3.7 (fabs(b[j][2])>(FTINY+1.0))||(b[j][0] <-FTINY) ||
707     (b[j][1]<-FTINY) ||(b[j][2]<-FTINY))
708     t[w] = HUGET;
709 gwlarson 3.6 else
710 gwlarson 3.4 {
711 gwlarson 3.6 /* The next point is in the triangle- so db values will be in valid
712     range and t[w]= MAXT
713     */
714     t[w] = MAXT;
715     if(j != 0)
716 gwlarson 3.7 for(;j < 3;j++)
717     {
718     i = (j+1)%3;
719     if(!first || i != 0)
720     {
721     intersect_vector_plane(tri[i],peq,&(et[i]),v[i]);
722     bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[i][x],
723     v[i][y],b[i]);
724     }
725     if(et[i] < 0.0)
726     {
727     VSUB(db[j],b[j],b[i]);
728     t[j] = HUGET;
729     break;
730     }
731     else
732     {
733     VSUB(db[j],b[i],b[j]);
734     if((fabs(b[j][0])>(FTINY+1.0))||(fabs(b[j][1])>(FTINY+1.0)) ||
735     (fabs(b[j][2])>(FTINY+1.0))||(b[i][0] <-FTINY) ||
736     (b[i][1]<-FTINY) ||(b[i][2]<-FTINY))
737     {
738     t[j] = HUGET;
739     break;
740     }
741     else
742     t[j] = MAXT;
743     }
744     }
745 gwlarson 3.4 }
746 gwlarson 3.7 }
747     bary_dtol(b[3],db,bi,dbi,t,w);
748    
749 gwlarson 3.4 /* trace the ray starting with this node */
750 gwlarson 3.7 qt = qtVisit_tri_edges(qt,bi,dbi[w][0],dbi[w][1],dbi[w][2],
751     dbi,wptr,nextptr,t,0,0,func,f,argptr);
752     if(!QT_FLAG_IS_DONE(*f))
753     {
754     b[3][0] = (double)bi[0]/(double)MAXBCOORD;
755     b[3][1] = (double)bi[1]/(double)MAXBCOORD;
756     b[3][2] = (double)bi[2]/(double)MAXBCOORD;
757     i_pt[x] = b[3][0]*q0[x] + b[3][1]*q1[x] + b[3][2]*q2[x];
758     i_pt[y] = b[3][0]*q0[y] + b[3][1]*q1[y] + b[3][2]*q2[y];
759     i_pt[z] = (-FP_N(peq)[x]*i_pt[x] - FP_N(peq)[y]*i_pt[y]-FP_D(peq))/FP_N(peq)[z];
760     }
761     return(qt);
762 gwlarson 3.4
763     }
764    
765    
766 gwlarson 3.7 QUADTREE
767     qtRoot_trace_ray(qt,q0,q1,q2,peq,orig,dir,nextptr,func,f,argptr)
768     QUADTREE qt;
769     FVECT q0,q1,q2;
770     FPEQ peq;
771     FVECT orig,dir;
772     int *nextptr;
773     int (*func)();
774     int *f,*argptr;
775     {
776     int x,y,z,nbr,w,i;
777     QUADTREE child;
778     FVECT v,i_pt;
779     double b[2][3],db[3],et[2],d,br[3];
780     BCOORD bi[3];
781     TINT t[3];
782     BDIR dbi[3][3];
783    
784     /* Project the origin onto the root node plane */
785     t[0] = t[1] = t[2] = 0;
786 gwlarson 3.4
787 gwlarson 3.7 VADD(v,orig,dir);
788     /* Find the intersection point of the origin */
789     /* map to 2d by dropping maximum magnitude component of normal */
790     x = FP_X(peq);
791     y = FP_Y(peq);
792     z = FP_Z(peq);
793    
794     /* Calculate barycentric coordinates for current vertex */
795     intersect_vector_plane(orig,peq,&(et[0]),i_pt);
796     bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b[0]);
797    
798     intersect_vector_plane(v,peq,&(et[1]),i_pt);
799     bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b[1]);
800     if(et[1] < 0.0)
801     VSUB(db,b[0],b[1]);
802     else
803     VSUB(db,b[1],b[0]);
804     t[0] = HUGET;
805     convert_dtol(b[0],bi);
806 gwlarson 3.8 if(et[1]<0.0 ||(fabs(b[1][0])>(FTINY+1.0))||(fabs(b[1][1])>(FTINY+1.0)) ||
807 gwlarson 3.7 (fabs(b[1][2])>(FTINY+1.0))||(b[1][0] <-FTINY) ||
808     (b[1][1]<-FTINY) ||(b[1][2]<-FTINY))
809     {
810     max_index(db,&d);
811     for(i=0; i< 3; i++)
812     dbi[0][i] = (BDIR)(db[i]/d*MAXBDIR);
813     }
814     else
815     for(i=0; i< 3; i++)
816     dbi[0][i] = (BDIR)(db[i]*MAXBDIR);
817     w=0;
818     /* trace the ray starting with this node */
819     qt = qtVisit_tri_edges(qt,bi,dbi[0][0],dbi[0][1],dbi[0][2], dbi,&w,
820     nextptr,t,0,0,func,f,argptr);
821     if(!QT_FLAG_IS_DONE(*f))
822     {
823     br[0] = (double)bi[0]/(double)MAXBCOORD;
824     br[1] = (double)bi[1]/(double)MAXBCOORD;
825     br[2] = (double)bi[2]/(double)MAXBCOORD;
826     orig[x] = br[0]*q0[x] + br[1]*q1[x] + br[2]*q2[x];
827     orig[y] = br[0]*q0[y] + br[1]*q1[y] + br[2]*q2[y];
828     orig[z]=(-FP_N(peq)[x]*orig[x] -
829     FP_N(peq)[y]*orig[y]-FP_D(peq))/FP_N(peq)[z];
830     }
831     return(qt);
832    
833     }
834 gwlarson 3.4
835 gwlarson 3.3
836 gwlarson 3.2
837    
838    
839    
840    
841    
842    
843    
844    
845    
846