ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm_qtree.c
(Generate patch)

Comparing ray/src/hd/sm_qtree.c (file contents):
Revision 3.6 by gwlarson, Wed Sep 16 18:16:29 1998 UTC vs.
Revision 3.9 by gwlarson, Mon Dec 28 18:07:36 1998 UTC

# Line 14 | Line 14 | static char SCCSid[] = "$SunId$ SGI";
14   */
15  
16   #include "standard.h"
17 <
17 > #include "sm_flag.h"
18   #include "sm_geom.h"
19   #include "sm_qtree.h"
20  
# Line 27 | Line 27 | int4 *quad_flag= NULL;
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 + extern int Pick_q[500];
31 +
32   #endif
33 + int Incnt=0;
34  
35   QUADTREE
36   qtAlloc()                       /* allocate a quadtree */
# Line 46 | Line 49 | qtAlloc()                      /* allocate a quadtree */
49             return(EMPTY);
50          if ((quad_block[QT_BLOCK(freet)] = (QUADTREE *)malloc(
51                          QT_BLOCK_SIZE*4*sizeof(QUADTREE))) == NULL)
52 <           return(EMPTY);
52 >           error(SYSTEM,"qtAlloc(): Unable to allocate memory\n");
53  
54 +        /* Realloc the per/node flags */
55          quad_flag = (int4 *)realloc((char *)quad_flag,
56 <                        (QT_BLOCK(freet)+1)*(QT_BLOCK_SIZE/8));
56 >                        (QT_BLOCK(freet)+1)*((QT_BLOCK_SIZE+7)>>3));
57          if (quad_flag == NULL)
58 <                return(EMPTY);
58 >           error(SYSTEM,"qtAlloc(): Unable to allocate memory\n");
59      }
60      treetop += 4;
61      return(freet);
# Line 60 | Line 64 | qtAlloc()                      /* allocate a quadtree */
64  
65   qtClearAllFlags()               /* clear all quadtree branch flags */
66   {
67 <        if (!treetop) return;
68 <        bzero((char *)quad_flag, (QT_BLOCK(treetop-4)+1)*(QT_BLOCK_SIZE/8));
67 >  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   }
75  
67
76   qtFree(qt)                      /* free a quadtree */
77     register QUADTREE  qt;
78   {
# Line 85 | Line 93 | qtFree(qt)                     /* free a quadtree */
93   qtDone()                        /* free EVERYTHING */
94   {
95          register int    i;
96 <
96 >        
97          qtfreeleaves();
98          for (i = 0; i < QT_MAX_BLK; i++)
99          {
# Line 94 | Line 102 | qtDone()                       /* free EVERYTHING */
102              free((char *)quad_block[i]);
103              quad_block[i] = NULL;
104          }
105 +        /* Free the flags */
106          if (i) free((char *)quad_flag);
107          quad_flag = NULL;
108          quad_free_list = EMPTY;
# Line 101 | Line 110 | qtDone()                       /* free EVERYTHING */
110   }
111  
112   QUADTREE
113 < *qtLocate_leaf(qtptr,bcoord,t0,t1,t2)
114 < QUADTREE *qtptr;
115 < double bcoord[3];
107 < FVECT t0,t1,t2;
113 > qtLocate(qt,bcoord)
114 > QUADTREE qt;
115 > BCOORD bcoord[3];
116   {
117    int i;
110  QUADTREE *child;
111  FVECT a,b,c;
118  
119 <    if(QT_IS_TREE(*qtptr))
120 <    {  
121 <      i = bary_child(bcoord);
116 < #ifdef DEBUG_TEST_DRIVER
117 <      qtSubdivide_tri(Pick_v0[Pick_cnt-1],Pick_v1[Pick_cnt-1],
118 <                      Pick_v2[Pick_cnt-1],a,b,c);
119 <      qtNth_child_tri(Pick_v0[Pick_cnt-1],Pick_v1[Pick_cnt-1],
120 <                           Pick_v2[Pick_cnt-1],a,b,c,i,
121 <                           Pick_v0[Pick_cnt],Pick_v1[Pick_cnt],
122 <                           Pick_v2[Pick_cnt]);
123 <           Pick_cnt++;
124 < #endif
119 >  if(QT_IS_TREE(qt))
120 >  {  
121 >    i = bary_child(bcoord);
122  
123 <      child = QT_NTH_CHILD_PTR(*qtptr,i);
124 <      if(t0)
123 >    return(qtLocate(QT_NTH_CHILD(qt,i),bcoord));
124 >  }
125 >  else
126 >    return(qt);
127 > }
128 >
129 > int
130 > move_to_nbr(b,db0,db1,db2,tptr)
131 > BCOORD b[3];
132 > BDIR db0,db1,db2;
133 > double *tptr;
134 > {
135 >  double t,dt;
136 >  BCOORD bc;
137 >  int nbr;
138 >  
139 >  nbr = -1;
140 >  *tptr = 0.0;
141 >  /* Advance to next node */
142 >  if(b[0]==0 && db0 < 0)
143 >    return(0);
144 >  if(b[1]==0 && db1 < 0)
145 >    return(1);
146 >  if(b[2]==0 && db2 < 0)
147 >    return(2);
148 >  if(db0 < 0)
149 >   {
150 >     t = ((double)b[0])/-db0;
151 >     nbr = 0;
152 >   }
153 >  else
154 >    t = MAXFLOAT;
155 >  if(db1 < 0)
156 >  {
157 >     dt = ((double)b[1])/-db1;
158 >    if( dt < t)
159 >    {
160 >      t = dt;
161 >      nbr = 1;
162 >    }
163 >  }
164 >  if(db2 < 0)
165 >  {
166 >     dt = ((double)b[2])/-db2;
167 >       if( dt < t)
168        {
169 <        qtSubdivide_tri(t0,t1,t2,a,b,c);
170 <        qtNth_child_tri(t0,t1,t2,a,b,c,i,t0,t1,t2);
169 >        t = dt;
170 >        nbr = 2;
171        }
132      return(qtLocate_leaf(child,bcoord,t0,t1,t2));
172      }
173 <    else
174 <      return(qtptr);
173 >  *tptr = t;
174 >  return(nbr);
175   }
176  
177 <
178 < QUADTREE
179 < *qtRoot_point_locate(qtptr,v0,v1,v2,pt,t0,t1,t2)
180 < QUADTREE *qtptr;
181 < FVECT v0,v1,v2;
182 < FVECT pt;
183 < FVECT t0,t1,t2;
177 > qtTrace_ray(qt,b,db0,db1,db2,nextptr,sign,sfactor,func,f)
178 >   QUADTREE qt;
179 >   BCOORD b[3];
180 >   BDIR db0,db1,db2;
181 >   int *nextptr;
182 >   int sign,sfactor;
183 >   FUNC func;
184 >   int *f;
185   {
186 <    int d;
187 <    int i,x,y;
188 <    QUADTREE *child;
189 <    FVECT n,i_pt,a,b,c;
150 <    double pd,bcoord[3];
186 >    int i,found;
187 >    QUADTREE child;
188 >    int nbr,next,w;
189 >    double t;
190  
191 <    /* Determine if point lies within pyramid (and therefore
192 <       inside a spherical quadtree cell):GT_INTERIOR, on one of the
193 <       pyramid sides (and on cell edge):GT_EDGE(1,2 or 3),
194 <       or on pyramid vertex (and on cell vertex):GT_VERTEX(1,2, or 3).
156 <       For each triangle edge: compare the
157 <       point against the plane formed by the edge and the view center
158 <    */
159 <    d = point_in_stri(v0,v1,v2,pt);  
191 >    if(QT_IS_TREE(qt))
192 >    {
193 >      /* Find the appropriate child and reset the coord */
194 >      i = bary_child(b);
195  
196 <    
162 <    /* Not in this triangle */
163 <    if(!d)
164 <      return(NULL);
165 <
166 <    /* Will return lowest level triangle containing point: It the
167 <       point is on an edge or vertex: will return first associated
168 <       triangle encountered in the child traversal- the others can
169 <       be derived using triangle adjacency information
170 <    */
171 <    if(QT_IS_TREE(*qtptr))
172 <    {  
173 <      /* Find the intersection point */
174 <      tri_plane_equation(v0,v1,v2,n,&pd,FALSE);
175 <      intersect_vector_plane(pt,n,pd,NULL,i_pt);
176 <
177 <      i = max_index(n,NULL);
178 <      x = (i+1)%3;
179 <      y = (i+2)%3;
180 <      /* Calculate barycentric coordinates of i_pt */
181 <      bary2d(v0[x],v0[y],v1[x],v1[y],v2[x],v2[y],i_pt[x],i_pt[y],bcoord);
182 <
183 <      i = bary_child(bcoord);
184 <      child = QT_NTH_CHILD_PTR(*qtptr,i);
185 < #ifdef DEBUG_TEST_DRIVER
186 <      Pick_cnt = 0;
187 <      VCOPY(Pick_v0[0],v0);
188 <      VCOPY(Pick_v1[0],v1);
189 <      VCOPY(Pick_v2[0],v2);
190 <      Pick_cnt++;
191 <      qtSubdivide_tri(Pick_v0[Pick_cnt-1],Pick_v1[Pick_cnt-1],
192 <                      Pick_v2[Pick_cnt-1],a,b,c);
193 <      qtNth_child_tri(Pick_v0[Pick_cnt-1],Pick_v1[Pick_cnt-1],
194 <                      Pick_v2[Pick_cnt-1],a,b,c,i,
195 <                             Pick_v0[Pick_cnt],Pick_v1[Pick_cnt],
196 <                             Pick_v2[Pick_cnt]);
197 <           Pick_cnt++;
198 < #endif
199 <      if(t0)
196 >      for(;;)
197        {
198 <        qtSubdivide_tri(v0,v1,v2,a,b,c);
199 <        qtNth_child_tri(v0,v1,v2,a,b,c,i,t0,t1,t2);
198 >        child = QT_NTH_CHILD(qt,i);
199 >        if(i != 3)
200 >          qtTrace_ray(child,b,db0,db1,db2,nextptr,sign,sfactor+1,func,f);
201 >        else
202 >          /* If the center cell- must flip direction signs */
203 >          qtTrace_ray(child,b,-db0,-db1,-db2,nextptr,1-sign,sfactor+1,func,f);
204 >
205 >        if(QT_FLAG_IS_DONE(*f))
206 >          return;
207 >        /* If in same block: traverse */
208 >        if(i==3)
209 >          next = *nextptr;
210 >        else
211 >          if(*nextptr == i)
212 >            next = 3;
213 >          else
214 >         {
215 >           /* reset the barycentric coordinates in the parents*/
216 >           bary_parent(b,i);
217 >           /* Else pop up to parent and traverse from there */
218 >           return(qt);
219 >         }
220 >        bary_from_child(b,i,next);
221 >        i = next;
222        }
204      return(qtLocate_leaf(child,bcoord,t0,t1,t2));
223      }
224      else
225 <    {
226 <        if(t0)
227 <        {
228 <            VCOPY(t0,v0);
229 <            VCOPY(t1,v1);
230 <            VCOPY(t2,v2);
231 <        }
232 <        return(qtptr);
233 <    }
234 < }
225 >   {
226 > #ifdef TEST_DRIVER
227 >       if(Pick_cnt < 500)
228 >          Pick_q[Pick_cnt++]=qt;
229 > #endif;
230 >       F_FUNC(func)(qt,F_ARGS(func),f);
231 >     if(QT_FLAG_IS_DONE(*f))
232 >       return;
233 >     /* Advance to next node */
234 >     nbr = move_to_nbr(b,db0,db1,db2,&t);
235  
236 +     if(nbr==-1)
237 +     {
238 +       QT_FLAG_SET_DONE(*f);
239 +       return;
240 +     }
241 +     b[0] += (BCOORD)(t *db0);
242 +     b[1] += (BCOORD)(t *db1);
243 +     b[2] += (BCOORD)(t *db2);
244 +     *nextptr = nbr;
245 +     return;
246 +    
247 +   }
248 + }    
249  
219 QUADTREE
220 qtSubdivide(qtptr)
221 QUADTREE *qtptr;
222 {
223  QUADTREE node;
224  node = qtAlloc();
225  QT_CLEAR_CHILDREN(node);
226  *qtptr = node;
227  return(node);
228 }
250  
251  
231 QUADTREE
232 qtSubdivide_nth_child(qt,n)
233 QUADTREE qt;
234 int n;
235 {
236  QUADTREE node;
252  
238  node = qtSubdivide(&(QT_NTH_CHILD(qt,n)));
239  
240  return(node);
241 }
253  
243 /* for triangle v0-v1-v2- returns a,b,c: children are:
254  
245        v2                     0: v0,a,c
246        /\                     1: a,v1,b                  
247       /2 \                    2: c,b,v2
248     c/____\b                  3: b,c,a
249     /\    /\  
250    /0 \3 /1 \
251  v0____\/____\v1
252        a
253 */
255  
255 qtSubdivide_tri(v0,v1,v2,a,b,c)
256 FVECT v0,v1,v2;
257 FVECT a,b,c;
258 {
259    EDGE_MIDPOINT_VEC3(a,v0,v1);
260    EDGE_MIDPOINT_VEC3(b,v1,v2);
261    EDGE_MIDPOINT_VEC3(c,v2,v0);
262 }
256  
257 < qtNth_child_tri(v0,v1,v2,a,b,c,i,r0,r1,r2)
258 < FVECT v0,v1,v2;
259 < FVECT a,b,c;
260 < int i;
261 < FVECT r0,r1,r2;
269 < {
257 > #define TEST_INT(tl,th,d,q0,q1,h,l) \
258 >                  tl=d>q0;th=d<q1; if(tl&&th) goto Lfunc_call; \
259 >                 if(tl) if(l) goto Lfunc_call; else h=TRUE; \
260 >                 if(th) if(h) goto Lfunc_call; else l = TRUE; \
261 >                 if(th) if(h) goto Lfunc_call; else l = TRUE;
262  
263 <  switch(i){
264 <  case 0:  
265 <  VCOPY(r0,v0); VCOPY(r1,a);    VCOPY(r2,c);
266 <    break;
267 <  case 1:  
268 <  VCOPY(r0,a); VCOPY(r1,v1);    VCOPY(r2,b);
269 <    break;
270 <  case 2:  
271 <  VCOPY(r0,c); VCOPY(r1,b);    VCOPY(r2,v2);
272 <    break;
273 <  case 3:  
282 <  VCOPY(r0,b); VCOPY(r1,c);    VCOPY(r2,a);
283 <    break;
284 <  }
285 < }
286 <
287 < /* Add triangle "id" to all leaf level cells that are children of
288 < quadtree pointed to by "qtptr" with cell vertices "t1,t2,t3"
289 < that it overlaps (vertex and edge adjacencies do not count
290 < as overlapping). If the addition of the triangle causes the cell to go over
291 < threshold- the cell is split- and the triangle must be recursively inserted
292 < into the new child cells: it is assumed that "v1,v2,v3" are normalized
293 < */
294 <
295 < int
296 < qtRoot_add_tri(qtptr,q0,q1,q2,t0,t1,t2,id,n)
297 < QUADTREE *qtptr;
298 < FVECT q0,q1,q2;
299 < FVECT t0,t1,t2;
300 < int id;
263 > /* Leaf node: Do definitive test */
264 > QUADTREE
265 > qtLeaf_insert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
266 >                 scale, s0,s1,s2,sq0,sq1,sq2,f,n)
267 > int root;
268 > QUADTREE qt;
269 > BCOORD q0[3],q1[3],q2[3];
270 > BCOORD t0[3],t1[3],t2[3];
271 > BCOORD dt10[3],dt21[3],dt02[3];
272 > unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
273 > FUNC f;
274   int n;
275 < {
276 <  int test;
277 <  int found;
275 > {
276 >  double db;
277 >  unsigned int e0,e1,e2;
278 >  char al,ah,bl,bh,cl,ch,testl,testh;
279 >  char test_t0t1,test_t1t2,test_t2t0;
280 >  BCOORD a,b,c;
281  
282 <  test = stri_intersect(q0,q1,q2,t0,t1,t2);
283 <  if(!test)
284 <    return(FALSE);
282 >  /* First check if can trivial accept: if vertex in cell */
283 >  if(s0 & s1 & s2)
284 >    goto Lfunc_call;
285 >
286 >  /* Assumption: Could not trivial reject*/
287 >  /* IF any coords lie on edge- must be in if couldnt reject */
288 >  a = q1[0];b= q0[1]; c= q0[2];
289 >  if(t0[0]== a || t0[1] == b || t0[2] == c)
290 >    goto Lfunc_call;
291 >  if(t1[0]== a || t1[1] == b || t1[2] == c)
292 >    goto Lfunc_call;
293 >  if(t2[0]== a || t2[1] == b || t2[2] == c)
294 >    goto Lfunc_call;
295    
296 <  found = qtAdd_tri(qtptr,q0,q1,q2,t0,t1,t2,id,n);
297 <  
298 <  return(found);
299 < }
296 >  /* Test for edge crossings */
297 >  /* Test t0t1,t1t2,t2t0 against a */
298 >  /* Calculate edge crossings */
299 >  e0  = (s0 ^ ((s0 >> 1) | (s0 << 2 & 4)));
300 >  /* See if edge can be trivially rejected from intersetion testing */
301 >  test_t0t1 = !(((s0 & 6)==0) || ((s1 & 6)==0)|| ((s2 & 6)==0) ||
302 >       ((sq0 & 6)==6) ||((sq1 & 6)==6)|| ((sq2 & 6)==6));
303 >  bl=bh=0;
304 >  if(test_t0t1 && (e0 & 2) )
305 >  {
306 >    /* Must do double calculation to avoid overflow */
307 >    db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
308 >    TEST_INT(testl,testh,db,b,q1[1],bl,bh)
309 >  }
310 >  test_t1t2= !(((s0 & 3)==0) || ((s1 & 3)==0)|| ((s2 & 3)==0) ||
311 >       ((sq0 & 3)==3) ||((sq1 & 3)==3)|| ((sq2 & 3)==3));
312 >  if(test_t1t2 && (e0 & 1))
313 >  {    /* test t1t2 against a */
314 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
315 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
316 >  }
317 >  test_t2t0 = !(((s0 & 5)==0) || ((s1 & 5)==0)|| ((s2 & 5)==0) ||
318 >       ((sq0 & 5)==5) ||((sq1 & 5)==5)|| ((sq2 & 5)==5));
319 >  if(test_t2t0 && (e0 & 4))
320 >  {
321 >      db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
322 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
323 >  }
324 >  e1  = (s1 ^ ((s1 >> 1) | (s1 << 2 & 4)));
325 >  cl = ch = 0;
326 >  if(test_t0t1 && (e1 & 2))
327 >  {/* test t0t1 against b */
328 >      db = t0[2] + dt10[2]*((double)(b-t0[1]))/dt10[1];
329 >      TEST_INT(testl,testh,db,c,q2[2],cl,ch)
330 >  }
331 >  if(test_t1t2 && (e1 & 1))
332 >  {/* test t1t2 against b */
333 >    db = t1[2] + dt21[2]*((double)(q0[1] - t1[1]))/dt21[1];
334 >    TEST_INT(testl,testh,db,c,q2[2],cl,ch)
335 >  }
336 >  if(test_t2t0 && (e1 & 4))
337 >  {/* test t2t0 against b */
338 >    db = t2[2] + dt02[2]*((double)(q0[1] - t2[1]))/dt02[1];
339 >    TEST_INT(testl,testh,db,c,q2[2],cl,ch)
340 >  }
341 >
342 >  /* test edges against c */
343 >  e2  = (s2 ^ ((s2 >> 1) | (s2 << 2 & 4)));
344 >  al = ah = 0;
345 >  if(test_t0t1 && (e2 & 2))
346 >  { /* test t0t1 against c */
347 >    db = t0[0] + dt10[0]*((double)(c-t0[2]))/dt10[2];
348 >    TEST_INT(testl,testh,db,a,q0[0],al,ah)
349 >   }
350 >  if(test_t1t2 && (e2 & 1))
351 >  {
352 >    db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
353 >    TEST_INT(testl,testh,db,a,q0[0],al,ah)
354 >  }
355 >  if(test_t2t0 && (e2 & 4))
356 >  { /* test t2t0 against c */
357 >    db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
358 >    TEST_INT(testl,testh,db,a,q0[0],al,ah)
359 >  }
360 >  /* Only remaining case is if some edge trivially rejected */
361 >  if(!e0 || !e1 || !e2)
362 >    return(qt);
363  
364 < int
365 < qtAdd_tri(qtptr,q0,q1,q2,t0,t1,t2,id,n)
366 < QUADTREE *qtptr;
318 < FVECT q0,q1,q2;
319 < FVECT t0,t1,t2;
320 < int id;
321 < int n;
322 < {
323 <  int i,index,test,found;
324 <  FVECT a,b,c;
325 <  OBJECT os[QT_MAXSET+1],*optr;
326 <  QUADTREE qt;
327 <  FVECT r0,r1,r2;
328 <
329 <  found = 0;
330 <  /* if this is tree: recurse */
331 <  if(QT_IS_TREE(*qtptr))
364 >  /* Only one/none got tested - pick either of other two/any two */
365 >  /* Only need to test one edge */
366 >  if(!test_t0t1 && (e0 & 2))
367    {
368 <    n++;
369 <    qtSubdivide_tri(q0,q1,q2,a,b,c);
335 <    test = stri_intersect(t0,t1,t2,q0,a,c);
336 <    if(test)
337 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,0),q0,a,c,t0,t1,t2,id,n);
338 <    test = stri_intersect(t0,t1,t2,a,q1,b);
339 <    if(test)
340 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,1),a,q1,b,t0,t1,t2,id,n);
341 <    test = stri_intersect(t0,t1,t2,c,b,q2);
342 <    if(test)
343 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,2),c,b,q2,t0,t1,t2,id,n);
344 <    test = stri_intersect(t0,t1,t2,b,c,a);
345 <    if(test)
346 <      found |= qtAdd_tri(QT_NTH_CHILD_PTR(*qtptr,3),b,c,a,t0,t1,t2,id,n);
368 >     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
369 >     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
370    }
371 <  else
371 >  if(!test_t1t2 && (e0 & 1))
372 >    {/* test t1t2 against a */
373 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
374 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
375 >   }
376 >  if(!test_t2t0 && (e0 & 4))
377    {
378 <      /* If this leave node emptry- create a new set */
379 <      if(QT_IS_EMPTY(*qtptr))
380 <        *qtptr = qtaddelem(*qtptr,id);
353 <      else
354 <      {
355 <          /* If the set is too large: subdivide */
356 <        optr = qtqueryset(*qtptr);
378 >    db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
379 >    TEST_INT(testl,testh,db,b,q1[1],bl,bh)
380 >  }
381  
382 <        if(QT_SET_CNT(optr) < QT_SET_THRESHOLD)
359 <          *qtptr = qtaddelem(*qtptr,id);
360 <          else
361 <          {
362 <            if (n < QT_MAX_LEVELS)
363 <            {
364 <                 /* If set size exceeds threshold: subdivide cell and
365 <                    reinsert set tris into cell
366 <                    */
367 <              qtgetset(os,*qtptr);      
382 >  return(qt);
383  
384 <              n++;
385 <              qtfreeleaf(*qtptr);
386 <              qtSubdivide(qtptr);
387 <              found = qtAdd_tri(qtptr,q0,q1,q2,t0,t1,t2,id,n);
384 > Lfunc_call:
385 >  qt = f.func(f.argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
386 >              s0,s1,s2,sq0,sq1,sq2,0,f,n);
387 >  return(qt);
388  
374              for(optr = QT_SET_PTR(os),i = QT_SET_CNT(os); i > 0; i--)
375                {
376                  id = QT_SET_NEXT_ELEM(optr);
377                  qtTri_from_id(id,r0,r1,r2,NULL,NULL,NULL,NULL,NULL,NULL);
378                  found=qtAdd_tri(qtptr,q0,q1,q2,r0,r1,r2,id,n);
379 #ifdef DEBUG
380                  if(!found)
381                    eputs("qtAdd_tri():Reinsert-in parent but not children\n");
382 #endif
383                }
384            }
385            else
386              if(QT_SET_CNT(optr) < QT_MAXSET)
387                  *qtptr = qtaddelem(*qtptr,id);
388              else
389                {
390 #ifdef DEBUG
391                    eputs("qtAdd_tri():two many levels\n");
392 #endif
393                    return(FALSE);
394                }
395          }
396      }
397  }
398  return(TRUE);
389   }
390  
391  
402 int
403 qtApply_to_tri_cells(qtptr,t0,t1,t2,v0,v1,v2,func,arg)
404 QUADTREE *qtptr;
405 FVECT t0,t1,t2;
406 FVECT v0,v1,v2;
407 int (*func)();
408 int *arg;
409 {
410  int test;
411  FVECT a,b,c;
392  
393 <  /* test if triangle (t0,t1,t2) overlaps cell triangle (v0,v1,v2) */
394 <  test = stri_intersect(t0,t1,t2,v0,v1,v2);
393 > /* Leaf node: Do definitive test */
394 > QUADTREE
395 > qtLeaf_insert_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
396 >                 scale, s0,s1,s2,sq0,sq1,sq2,f,n)
397 > int root;
398 > QUADTREE qt;
399 > BCOORD q0[3],q1[3],q2[3];
400 > BCOORD t0[3],t1[3],t2[3];
401 > BCOORD dt10[3],dt21[3],dt02[3];
402 > unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
403 > FUNC f;
404 > int n;
405 > {
406 >  double db;
407 >  unsigned int e0,e1,e2;
408 >  BCOORD a,b,c;
409 >  double p0[2], p1[2],cp;
410 >  char al,ah,bl,bh,cl,ch;
411 >  char testl,testh,test_t0t1,test_t1t2,test_t2t0;
412 >  unsigned int ls0,ls1,ls2;
413 >  
414 >  /* May have gotten passed trivial reject if one/two vertices are ON */
415 >  a = q1[0];b= q0[1]; c= q0[2];
416 >  SIDES_LESS(t0,t1,t2,ls0,ls1,ls2,a,b,c);
417 >  
418 >  /* First check if can trivial accept: if vertex in cell */
419 >  if(ls0 & ls1 & ls2)
420 >    goto Lfunc_call;
421  
422 <  /* If triangles do not overlap: done */
423 <  if(!test)
424 <    return(FALSE);
422 >  if(ls0==0 || ls1 == 0 || ls2 ==0)
423 >    return(qt);
424 >  /* Assumption: Could not trivial reject*/
425 >  /* IF any coords lie on edge- must be in if couldnt reject */
426  
427 <  /* if this is tree: recurse */
428 <  func(qtptr,arg);
427 >  if(t0[0]== a || t0[1] == b || t0[2] == c)
428 >    goto Lfunc_call;
429 >  if(t1[0]== a || t1[1] == b || t1[2] == c)
430 >    goto Lfunc_call;
431 >  if(t2[0]== a || t2[1] == b || t2[2] == c)
432 >    goto Lfunc_call;
433  
434 <  if(QT_IS_TREE(*qtptr))
434 >  /* Test for edge crossings */
435 >  /* Test t0t1 against a,b,c */
436 >  /* First test if t0t1 can be trivially rejected */
437 >  /* If both edges are outside bounds- dont need to test */
438 >  
439 >  /* Test t0t1,t1t2,t2t0 against a */
440 >  test_t0t1 = !(((ls0 & 6)==0) || ((ls1 & 6)==0)|| ((ls2 & 6)==0) ||
441 >       ((sq0 & 6)==0) ||((sq1 & 6)==0)|| ((sq2 & 6)==0));
442 >  e0  = (ls0 ^ ((ls0 >> 1) | (ls0 << 2 & 4)));
443 >  bl=bh=0;
444 >  /* Test t0t1,t1t2,t2t0 against a */
445 >  if(test_t0t1 && (e0 & 2) )
446    {
447 <     QT_SET_FLAG(*qtptr);
448 <     qtSubdivide_tri(v0,v1,v2,a,b,c);
427 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,0),t0,t1,t2,v0,a,c,func,arg);
428 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,1),t0,t1,t2,a,v1,b,func,arg);
429 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,2),t0,t1,t2,c,b,v2,func,arg);
430 <    qtApply_to_tri_cells(QT_NTH_CHILD_PTR(*qtptr,3),t0,t1,t2,b,c,a,func,arg);
447 >      db = t0[1] + dt10[1]*((double)(a-t0[0])/dt10[0]);
448 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
449    }
450 < }
451 <
452 < int
453 < qtRemove_tri(qtptr,id,t0,t1,t2,v0,v1,v2)
454 < QUADTREE *qtptr;
455 < int id;
456 < FVECT t0,t1,t2;
457 < FVECT v0,v1,v2;
458 < {
459 <  
442 <  int test;
443 <  int i;
444 <  FVECT a,b,c;
445 <  OBJECT os[QT_MAXSET+1];
446 <  
447 <  /* test if triangle (t0,t1,t2) overlaps cell triangle (v0,v1,v2) */
448 <  test = stri_intersect(t0,t1,t2,v0,v1,v2);
449 <
450 <  /* If triangles do not overlap: done */
451 <  if(!test)
452 <    return(FALSE);
453 <
454 <  /* if this is tree: recurse */
455 <  if(QT_IS_TREE(*qtptr))
450 >  test_t1t2= !(((ls0 & 3)==0) || ((ls1 & 3)==0)|| ((ls2 & 3)==0) ||
451 >       ((sq0 & 3)==0) ||((sq1 & 3)==0)|| ((sq2 & 3)==0));
452 >  if(test_t1t2 && (e0 & 1))
453 >  {    /* test t1t2 against a */
454 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
455 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
456 >  }
457 >  test_t2t0 = !(((ls0 & 5)==0) || ((ls1 & 5)==0)|| ((ls2 & 5)==0) ||
458 >       ((sq0 & 5)==0) ||((sq1 & 5)==0)|| ((sq2 & 5)==0));
459 >  if(test_t2t0 && (e0 & 4))
460    {
461 <    qtSubdivide_tri(v0,v1,v2,a,b,c);
462 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,0),id,t0,t1,t2,v0,a,c);
459 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,1),id,t0,t1,t2,a,v1,b);
460 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,2),id,t0,t1,t2,c,b,v2);
461 <    qtRemove_tri(QT_NTH_CHILD_PTR(*qtptr,3),id,t0,t1,t2,b,c,a);
461 >      db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
462 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
463    }
464 <  else
464 >  cl = ch = 0;
465 >  e1  = (ls1 ^ ((ls1 >> 1) | (ls1 << 2 & 4)));
466 >  if(test_t0t1 && (e1 & 2))
467 >  {/* test t0t1 against b */
468 >      db = t0[2] + dt10[2]*(((double)(b-t0[1]))/dt10[1]);
469 >      TEST_INT(testl,testh,db,q1[2],c,cl,ch)
470 >  }
471 >  if(test_t1t2 && (e1 & 1))
472 >  {/* test t1t2 against b */
473 >    db = t1[2] + dt21[2]*((double)(b - t1[1]))/dt21[1];
474 >    TEST_INT(testl,testh,db,q1[2],c,cl,ch)
475 >  }
476 >  if(test_t2t0 && (e1 & 4))
477 >  {/* test t2t0 against b */
478 >    db = t2[2] + dt02[2]*((double)(b - t2[1]))/dt02[1];
479 >    TEST_INT(testl,testh,db,q1[2],c,cl,ch)
480 >  }
481 >  al = ah = 0;
482 >  e2  = (ls2 ^ ((ls2 >> 1) | (ls2 << 2 & 4)));
483 >  if(test_t0t1 && (e2 & 2))
484 >  { /* test t0t1 against c */
485 >    db = t0[0] + dt10[0]*(((double)(c-t0[2]))/dt10[2]);
486 >    TEST_INT(testl,testh,db,q0[0],a,al,ah)
487 >   }
488 >  if(test_t1t2 && (e2 & 1))
489    {
490 <      if(QT_IS_EMPTY(*qtptr))
491 <      {
467 < #ifdef DEBUG    
468 <          eputs("qtRemove_tri(): triangle not found\n");
469 < #endif
470 <      }
471 <      /* remove id from set */
472 <      else
473 <      {
474 <          if(!qtinset(*qtptr,id))
475 <          {
476 < #ifdef DEBUG          
477 <              eputs("qtRemove_tri(): tri not in set\n");
478 < #endif
479 <          }
480 <          else
481 <          {
482 <            *qtptr = qtdelelem(*qtptr,id);
483 <        }
484 <      }
490 >    db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
491 >    TEST_INT(testl,testh,db,q0[0],a,al,ah)
492    }
493 <  return(TRUE);
494 < }
493 >  if(test_t2t0 && (e2 & 4))
494 >  { /* test t2t0 against c */
495 >    db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
496 >    TEST_INT(testl,testh,db,q0[0],a,al,ah)
497 >  }
498 >  /* Only remaining case is if some edge trivially rejected */
499 >  if(!e0 || !e1 || !e2)
500 >    return(qt);
501  
502 <
503 < int
504 < move_to_nbr(b,db0,db1,db2,tptr)
505 < double b[3],db0,db1,db2;
506 < double *tptr;
507 < {
508 <  double t,dt;
509 <  int nbr;
510 <
511 <  nbr = -1;
512 <  /* Advance to next node */
500 <  if(!ZERO(db0) && db0 < 0.0)
501 <   {
502 <     t = -b[0]/db0;
503 <     nbr = 0;
502 >  /* Only one/none got tested - pick either of other two/any two */
503 >  /* Only need to test one edge */
504 >  if(!test_t0t1 && (e0 & 2))
505 >  {
506 >     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
507 >     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
508 >  }
509 >  if(!test_t1t2 && (e0 & 1))
510 >    {/* test t1t2 against a */
511 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
512 >      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
513     }
514 <  else
506 <    t = FHUGE;
507 <  if(!ZERO(db1) && db1 < 0.0 )
514 >  if(!test_t2t0 && (e0 & 4))
515    {
516 <    dt = -b[1]/db1;
517 <    if( dt < t)
511 <    {
512 <      t = dt;
513 <      nbr = 1;
514 <    }
516 >    db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
517 >    TEST_INT(testl,testh,db,q1[1],b,bl,bh)
518    }
516  if(!ZERO(db2) && db2 < 0.0 )
517    {
518      dt = -b[2]/db2;
519      if( dt < t)
520      {
521        t = dt;
522        nbr = 2;
523      }
524    }
525  *tptr = t;
526  return(nbr);
527 }
519  
520 < int
521 < qtTrace_ray(qtptr,b,db0,db1,db2,orig,dir,func,arg1,arg2)
531 <   QUADTREE *qtptr;
532 <   double b[3],db0,db1,db2;
533 <   FVECT orig,dir;
534 <   int (*func)();
535 <   int *arg1,arg2;
536 < {
520 >  return(qt);
521 > Lfunc_call:
522  
523 <    int i,found;
524 <    QUADTREE *child;
525 <    int nbr,next;
526 <    double t;
542 < #ifdef DEBUG_TEST_DRIVER
543 <    
544 <    FVECT a1,b1,c1;
545 <    int Pick_parent = Pick_cnt-1;
546 <    qtSubdivide_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
547 <                           Pick_v2[Pick_parent],a1,b1,c1);
523 >  qt = f.func(f.argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
524 >              s0,s1,s2,sq0,sq1,sq2,1,f,n);
525 >  return(qt);
526 >  }
527  
549 #endif
550    if(QT_IS_TREE(*qtptr))
551    {
552        /* Find the appropriate child and reset the coord */
553        i = bary_child(b);
528  
555        QT_SET_FLAG(*qtptr);
529  
530 <        for(;;)
558 <        {
559 <           child = QT_NTH_CHILD_PTR(*qtptr,i);
530 > /* ASSUMPTION: that triangle t0,t1,t2 intersects quad cell q0,q1,q2 */
531  
532 <           if(i != 3)
533 <              nbr = qtTrace_ray(child,b,db0,db1,db2,orig,dir,func,arg1,arg2);
534 <           else
535 <               /* If the center cell- must flip direction signs */
536 <              nbr =qtTrace_ray(child,b,-db0,-db1,-db2,orig,dir,func,arg1,arg2);
537 <           if(nbr == QT_DONE)
538 <              return(nbr);
532 > /*-------q2--------- sq2
533 >        / \
534 > s1     /sc \ s0
535 >     qb_____qa
536 >     / \   / \
537 > \sq0/sa \ /sb \   /sq1
538 > \ q0____qc____q1/
539 >  \             /
540 >   \     s2    /
541 > */
542  
543 <           /* If in same block: traverse */
570 <           if(i==3)
571 <              next = nbr;
572 <             else
573 <                if(nbr == i)
574 <                   next = 3;
575 <             else
576 <               {
577 <                 /* reset the barycentric coordinates in the parents*/
578 <                 bary_parent(b,i);
579 <                 /* Else pop up to parent and traverse from there */
580 <                 return(nbr);
581 <               }
582 <             bary_from_child(b,i,next);
583 <             i = next;
584 <         }
585 <    }
586 <    else
587 <   {
588 < #ifdef DEBUG_TEST_DRIVER
589 <           qtNth_child_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
590 <                           Pick_v2[Pick_parent],a1,b1,c1,i,
591 <                           Pick_v0[Pick_cnt],Pick_v1[Pick_cnt],
592 <                           Pick_v2[Pick_cnt]);
593 <           Pick_cnt++;
594 < #endif
543 > int Find_id=0;
544  
545 <       if(func(qtptr,orig,dir,arg1,arg2) == QT_DONE)
546 <          return(QT_DONE);
545 > QUADTREE
546 > qtInsert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
547 >            s0,s1,s2,sq0,sq1,sq2,f,n)
548 > int root;
549 > QUADTREE qt;
550 > BCOORD q0[3],q1[3],q2[3];
551 > BCOORD t0[3],t1[3],t2[3];
552 > BCOORD dt10[3],dt21[3],dt02[3];
553 > BCOORD scale;
554 > unsigned int s0,s1,s2,sq0,sq1,sq2;
555 > FUNC f;
556 > int n;
557 > {
558 >  BCOORD a,b,c;
559 >  BCOORD va[3],vb[3],vc[3];
560 >  unsigned int sa,sb,sc;
561  
562 <       /* Advance to next node */
563 <       /* NOTE: Optimize: should only have to check 1/2 */
564 <       nbr = move_to_nbr(b,db0,db1,db2,&t);
562 >  /* If a tree: trivial reject and recurse on potential children */
563 >  if(QT_IS_TREE(qt))
564 >  {
565 >    /* Test against new a edge: if entirely to left: only need
566 >       to visit child 0
567 >    */
568 >    a = q1[0] + scale;
569 >    b = q0[1] + scale;
570 >    c = q0[2] + scale;
571  
572 <       if(nbr != -1)
573 <       {
574 <         b[0] += t * db0;
575 <         b[1] += t * db1;
576 <         b[2] += t * db2;
577 <       }
578 <       return(nbr);
572 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
573 >
574 >    if(sa==7)
575 >    {
576 >      vb[1] = q0[1];
577 >      vc[2] = q0[2];
578 >      vc[1] = b;
579 >      vb[2] = c;
580 >      vb[0] = vc[0] = a;
581 >      QT_NTH_CHILD(qt,0) = qtInsert_tri(root,QT_NTH_CHILD(qt,0),q0,vc,
582 >          vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
583 >      return(qt);
584 >    }
585 >   if(sb==7)
586 >   {
587 >     va[0] = q1[0];
588 >     vc[2] = q0[2];
589 >     va[1] = vc[1] = b;
590 >     va[2] = c;
591 >     vc[0] = a;
592 >     QT_NTH_CHILD(qt,1) = qtInsert_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,
593 >             t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
594 >     return(qt);
595     }
596 <    
597 < }
596 >   if(sc==7)
597 >   {
598 >     va[0] = q1[0];
599 >     vb[1] = q0[1];
600 >     va[1] = b;
601 >     va[2] = vb[2] = c;
602 >     vb[0] = a;
603 >     QT_NTH_CHILD(qt,2) = qtInsert_tri(root,QT_NTH_CHILD(qt,2),vb,va,
604 >       q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
605 >     return(qt);
606 >   }
607  
608 < int
609 < qtRoot_trace_ray(qtptr,q0,q1,q2,orig,dir,func,arg1,arg2)
610 <   QUADTREE *qtptr;
611 <   FVECT q0,q1,q2;
612 <   FVECT orig,dir;
613 <   int (*func)();
614 <   int *arg1,arg2;
615 < {
616 <  int i,x,y,nbr;
617 <  QUADTREE *child;
618 <  FVECT n,c,i_pt,d;
619 <  double pd,b[3],db[3],t;
620 <    /* Determine if point lies within pyramid (and therefore
627 <       inside a spherical quadtree cell):GT_INTERIOR, on one of the
628 <       pyramid sides (and on cell edge):GT_EDGE(1,2 or 3),
629 <       or on pyramid vertex (and on cell vertex):GT_VERTEX(1,2, or 3).
630 <       For each triangle edge: compare the
631 <       point against the plane formed by the edge and the view center
632 <    */
633 <  i = point_in_stri(q0,q1,q2,orig);  
634 <    
635 <  /* Not in this triangle */
636 <  if(!i)
637 <     return(INVALID);
638 <  /* Project the origin onto the root node plane */
608 >   va[0] = q1[0];
609 >   vb[1] = q0[1];
610 >   vc[2] = q0[2];
611 >   va[1] = vc[1] = b;
612 >   va[2] = vb[2] = c;
613 >   vb[0] = vc[0] = a;
614 >   /* If outside of all edges: only need to Visit 3  */
615 >   if(sa==0 && sb==0 && sc==0)
616 >   {
617 >      QT_NTH_CHILD(qt,3) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,
618 >       vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
619 >      return(qt);
620 >   }
621  
622 <  /* Find the intersection point of the origin */
623 <  tri_plane_equation(q0,q1,q2,n,&pd,FALSE);
624 <  intersect_vector_plane(orig,n,pd,NULL,i_pt);
625 <  /* project the dir as well */
626 <  VADD(c,orig,dir);
627 <  intersect_vector_plane(c,n,pd,&t,c);
628 <
629 <    /* map to 2d by dropping maximum magnitude component of normal */
630 <  i = max_index(n,NULL);
631 <  x = (i+1)%3;
632 <  y = (i+2)%3;
633 <  /* Calculate barycentric coordinates of orig */
634 <  bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b);
635 <  /* Calculate barycentric coordinates of dir */
654 <  bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],c[x],c[y],db);
655 <  if(t < 0.0)
656 <     VSUB(db,b,db);
622 >   if(sa)
623 >     QT_NTH_CHILD(qt,0) = qtInsert_tri(root,QT_NTH_CHILD(qt,0),q0,vc,vb,t0,
624 >          t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
625 >   if(sb)
626 >     QT_NTH_CHILD(qt,1) = qtInsert_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,t0,
627 >              t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
628 >   if(sc)
629 >        QT_NTH_CHILD(qt,2) = qtInsert_tri(root,QT_NTH_CHILD(qt,2),vb,va,q2,t0,
630 >              t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
631 >   QT_NTH_CHILD(qt,3) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,
632 >             t1,t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
633 >   return(qt);
634 >  }
635 >  /* Leaf node: Do definitive test */
636    else
637 <     VSUB(db,db,b);
637 >    return(qt = qtLeaf_insert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
638 >                         scale,s0,s1,s2,sq0,sq1,sq2,f,n));
639 > }
640  
641  
642 < #ifdef DEBUG_TEST_DRIVER
643 <    VCOPY(Pick_v0[Pick_cnt],q0);
644 <    VCOPY(Pick_v1[Pick_cnt],q1);
645 <    VCOPY(Pick_v2[Pick_cnt],q2);
646 <    Pick_cnt++;
647 < #endif
642 > QUADTREE
643 > qtInsert_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
644 >            s0,s1,s2,sq0,sq1,sq2,f,n)
645 > int root;
646 > QUADTREE qt;
647 > BCOORD q0[3],q1[3],q2[3];
648 > BCOORD t0[3],t1[3],t2[3];
649 > BCOORD dt10[3],dt21[3],dt02[3];
650 > BCOORD scale;
651 > unsigned int s0,s1,s2,sq0,sq1,sq2;
652 > FUNC f;
653 > {
654 >  BCOORD a,b,c;
655 >  BCOORD va[3],vb[3],vc[3];
656 >  unsigned int sa,sb,sc;
657  
658 <      /* trace the ray starting with this node */
659 <    nbr = qtTrace_ray(qtptr,b,db[0],db[1],db[2],orig,dir,func,arg1,arg2);
660 <    return(nbr);
661 <    
662 < }
658 >  /* If a tree: trivial reject and recurse on potential children */
659 >  if(QT_IS_TREE(qt))
660 >  {
661 >    /* Test against new a edge: if entirely to left: only need
662 >       to visit child 0
663 >    */
664 >    a = q1[0] - scale;
665 >    b = q0[1] - scale;
666 >    c = q0[2] - scale;
667  
668 < qtVisit_tri_interior(qtptr,q0,q1,q2,t0,t1,t2,n,func,arg1,arg2,arg3)
675 <   QUADTREE *qtptr;
676 <   FVECT q0,q1,q2;
677 <   FVECT t0,t1,t2;
678 <   int n;
679 <   int (*func)();
680 <   int *arg1,arg2,*arg3;
681 < {
682 <    int i,found,test;
683 <    QUADTREE *child;
684 <    FVECT c0,c1,c2,a,b,c;
685 <    OBJECT os[QT_MAXSET+1],*optr;
686 <    int w;
687 <    
688 <    /* If qt Flag set, or qt vertices interior to t0t1t2-descend */
689 < tree_modified:
668 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
669  
670 <    if(QT_IS_TREE(*qtptr))
671 <    {  
672 <        if(QT_IS_FLAG(*qtptr) ||  point_in_stri(t0,t1,t2,q0))
673 <        {
674 <            QT_SET_FLAG(*qtptr);
675 <            qtSubdivide_tri(q0,q1,q2,a,b,c);
676 <            /* descend to children */
677 <            for(i=0;i < 4; i++)
678 <            {
679 <                child = QT_NTH_CHILD_PTR(*qtptr,i);
680 <                qtNth_child_tri(q0,q1,q2,a,b,c,i,c0,c1,c2);
702 <                qtVisit_tri_interior(child,c0,c1,c2,t0,t1,t2,n+1,
703 <                                     func,arg1,arg2,arg3);
704 <            }
705 <        }
670 >    if(sa==0)
671 >    {
672 >      vb[1] = q0[1];
673 >      vc[2] = q0[2];
674 >      vc[1] = b;
675 >      vb[2] = c;
676 >      vb[0] = vc[0] = a;
677 >
678 >      QT_NTH_CHILD(qt,0) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,
679 >          vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
680 >      return(qt);
681      }
682 <    else
682 >    if(sb==0)
683      {
684 <      /* NOTE THIS IN TRI TEST Could be replaced by a flag */
685 <      if(!QT_IS_EMPTY(*qtptr))
686 <      {
687 <         if(qtinset(*qtptr,arg2))
688 <           if(func(qtptr,q0,q1,q2,t0,t1,t2,n,arg1,arg2,arg3)==QT_MODIFIED)
689 <             goto tree_modified;
690 <           else
691 <             return;
717 <      }
718 <      if(point_in_stri(t0,t1,t2,q0) )
719 <          if(func(qtptr,q0,q1,q2,t0,t1,t2,n,arg1,arg2,arg3)==QT_MODIFIED)
720 <            goto tree_modified;
684 >      va[0] = q1[0];
685 >      vc[2] = q0[2];
686 >      va[1] = vc[1] = b;
687 >      va[2] = c;
688 >      vc[0] = a;
689 >      QT_NTH_CHILD(qt,1) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
690 >         t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
691 >      return(qt);
692      }
693 +    if(sc==0)
694 +    {
695 +      va[0] = q1[0];
696 +      vb[1] = q0[1];
697 +      va[1] = b;
698 +      va[2] = vb[2] = c;
699 +      vb[0] = a;
700 +      QT_NTH_CHILD(qt,2) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,
701 +         q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
702 +      return(qt);
703 +    }
704 +    va[0] = q1[0];
705 +    vb[1] = q0[1];
706 +    vc[2] = q0[2];
707 +    va[1] = vc[1] = b;
708 +    va[2] = vb[2] = c;
709 +    vb[0] = vc[0] = a;
710 +    /* If outside of all edges: only need to Visit 3  */
711 +    if(sa==7 && sb==7 && sc==7)
712 +    {
713 +      QT_NTH_CHILD(qt,3) = qtInsert_tri(root,QT_NTH_CHILD(qt,3),va,vb,
714 +           vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
715 +      return(qt);
716 +    }
717 +    if(sa!=7)
718 +      QT_NTH_CHILD(qt,0) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,vb,
719 +           t0,t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f,n+1);
720 +    if(sb!=7)
721 +      QT_NTH_CHILD(qt,1) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
722 +           t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f,n+1);
723 +    if(sc!=7)
724 +      QT_NTH_CHILD(qt,2) = qtInsert_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,q2,
725 +           t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f,n+1);
726 +
727 +    QT_NTH_CHILD(qt,3) = qtInsert_tri(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,t1,
728 +              t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f,n+1);
729 +    return(qt);
730 +  }
731 +  /* Leaf node: Do definitive test */
732 +  else
733 +    return(qt = qtLeaf_insert_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
734 +                         scale,s0,s1,s2,sq0,sq1,sq2,f,n));
735   }
736  
737  
738  
739  
740 + /*************************************************************************/
741 + /* Visit code for applying functions: NOTE THIS IS THE SAME AS INSERT CODE:
742 +  except sets flags: wanted insert to be as efficient as possible: so
743 +  broke into two sets of routines
744 + */
745  
746 <
747 < /* NOTE: SINCE DIR could be unit: then we could use integer math */
748 < int
749 < qtVisit_tri_edges(qtptr,b,db0,db1,db2,
750 <                   db,wptr,t,sign,sfactor,func,arg1,arg2,arg3)
751 <   QUADTREE *qtptr;
752 <   double b[3],db0,db1,db2,db[3][3];
753 <   int *wptr;
754 <   double t[3];
755 <   int sign;
738 <   double sfactor;
739 <   int (*func)();
740 <   int *arg1,arg2,*arg3;
746 > qtVisit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
747 >            s0,s1,s2,sq0,sq1,sq2,f)
748 > int root;
749 > QUADTREE qt;
750 > BCOORD q0[3],q1[3],q2[3];
751 > BCOORD t0[3],t1[3],t2[3];
752 > BCOORD dt10[3],dt21[3],dt02[3];
753 > BCOORD scale;
754 > unsigned int s0,s1,s2,sq0,sq1,sq2;
755 > FUNC f;
756   {
757 <    int i,found;
758 <    QUADTREE *child;
759 <    int nbr,next,w;
745 <    double t_l,t_g;
746 < #ifdef DEBUG_TEST_DRIVER
747 <    FVECT a1,b1,c1;
748 <    int Pick_parent = Pick_cnt-1;
749 <    qtSubdivide_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
750 <                           Pick_v2[Pick_parent],a1,b1,c1);
751 < #endif
752 <    if(QT_IS_TREE(*qtptr))
753 <    {
754 <        /* Find the appropriate child and reset the coord */
755 <        i = bary_child(b);
757 >  BCOORD a,b,c;
758 >  BCOORD va[3],vb[3],vc[3];
759 >  unsigned int sa,sb,sc;
760  
761 <        QT_SET_FLAG(*qtptr);
761 >  /* If a tree: trivial reject and recurse on potential children */
762 >  if(QT_IS_TREE(qt))
763 >  {
764 >    QT_SET_FLAG(qt);
765  
766 <        for(;;)
767 <        {
768 <          w = *wptr;
769 <           child = QT_NTH_CHILD_PTR(*qtptr,i);
766 >    /* Test against new a edge: if entirely to left: only need
767 >       to visit child 0
768 >    */
769 >    a = q1[0] + scale;
770 >    b = q0[1] + scale;
771 >    c = q0[2] + scale;
772  
773 <           if(i != 3)
765 <               nbr = qtVisit_tri_edges(child,b,db0,db1,db2,
766 <                                        db,wptr,t,sign,
767 <                                        sfactor*2.0,func,arg1,arg2,arg3);
768 <           else
769 <             /* If the center cell- must flip direction signs */
770 <             nbr = qtVisit_tri_edges(child,b,-db0,-db1,-db2,
771 <                                     db,wptr,t,1-sign,
772 <                                     sfactor*2.0,func,arg1,arg2,arg3);
773 >    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
774  
775 <           if(nbr == QT_DONE)
776 <             return(nbr);
777 <           if(*wptr != w)
778 <           {
779 <             w = *wptr;
780 <             db0 = db[w][0];db1 = db[w][1];db2 = db[w][2];
781 <             if(sign)
782 <               {  db0 *= -1.0;db1 *= -1.0; db2 *= -1.0;}
783 <           }
784 <           /* If in same block: traverse */
784 <           if(i==3)
785 <              next = nbr;
786 <             else
787 <                if(nbr == i)
788 <                   next = 3;
789 <             else
790 <               {
791 <                 /* reset the barycentric coordinates in the parents*/
792 <                 bary_parent(b,i);
793 <                 /* Else pop up to parent and traverse from there */
794 <                 return(nbr);
795 <               }
796 <           bary_from_child(b,i,next);
797 <           i = next;
798 <        }
775 >    if(sa==7)
776 >    {
777 >      vb[1] = q0[1];
778 >      vc[2] = q0[2];
779 >      vc[1] = b;
780 >      vb[2] = c;
781 >      vb[0] = vc[0] = a;
782 >      qtVisit_tri(root,QT_NTH_CHILD(qt,0),q0,vc,
783 >          vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f);
784 >      return;
785      }
786 <    else
786 >   if(sb==7)
787     {
788 < #ifdef DEBUG_TEST_DRIVER
789 <           qtNth_child_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
790 <                           Pick_v2[Pick_parent],a1,b1,c1,i,Pick_v0[Pick_cnt],
791 <                           Pick_v1[Pick_cnt],Pick_v2[Pick_cnt]);
792 <           Pick_cnt++;
793 < #endif
788 >     va[0] = q1[0];
789 >     vc[2] = q0[2];
790 >     va[1] = vc[1] = b;
791 >     va[2] = c;
792 >     vc[0] = a;
793 >     qtVisit_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,
794 >             t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f);
795 >     return;
796 >   }
797 >   if(sc==7)
798 >   {
799 >     va[0] = q1[0];
800 >     vb[1] = q0[1];
801 >     va[1] = b;
802 >     va[2] = vb[2] = c;
803 >     vb[0] = a;
804 >     qtVisit_tri(root,QT_NTH_CHILD(qt,2),vb,va,
805 >       q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f);
806 >     return;
807 >   }
808  
809 <       if(func(qtptr,arg1,arg2,arg3) == QT_DONE)
810 <          return(QT_DONE);
809 >   va[0] = q1[0];
810 >   vb[1] = q0[1];
811 >   vc[2] = q0[2];
812 >   va[1] = vc[1] = b;
813 >   va[2] = vb[2] = c;
814 >   vb[0] = vc[0] = a;
815 >   /* If outside of all edges: only need to Visit 3  */
816 >   if(sa==0 && sb==0 && sc==0)
817 >   {
818 >     qtVisit_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,
819 >       vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f);
820 >      return;
821 >   }
822  
823 <       /* Advance to next node */
824 <       w = *wptr;
825 <       while(1)
826 <       {
827 <         nbr = move_to_nbr(b,db0,db1,db2,&t_l);
823 >   if(sa)
824 >     qtVisit_tri(root,QT_NTH_CHILD(qt,0),q0,vc,vb,t0,
825 >          t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f);
826 >   if(sb)
827 >     qtVisit_tri(root,QT_NTH_CHILD(qt,1),vc,q1,va,t0,
828 >              t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f);
829 >   if(sc)
830 >     qtVisit_tri(root,QT_NTH_CHILD(qt,2),vb,va,q2,t0,
831 >              t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f);
832 >   qtVisit_tri_rev(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,
833 >             t1,t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f);
834 >  }
835 >  /* Leaf node: Do definitive test */
836 >  else
837 >    qtLeaf_visit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
838 >                         scale,s0,s1,s2,sq0,sq1,sq2,f);
839  
818         t_g = t_l/sfactor;
819 #ifdef DEBUG
820         if(t[w] <= 0.0)
821           eputs("qtVisit_tri_edges():negative t\n");
822 #endif
823         if(t_g >= t[w])
824         {
825           if(w == 2)
826             return(QT_DONE);
827
828           b[0] += (t[w])*sfactor*db0;
829           b[1] += (t[w])*sfactor*db1;
830           b[2] += (t[w])*sfactor*db2;
831           w++;
832           db0 = db[w][0];
833           db1 = db[w][1];
834           db2 = db[w][2];
835           if(sign)
836          {  db0 *= -1.0;db1 *= -1.0; db2 *= -1.0;}
837         }
838       else
839         if(nbr != INVALID)
840         {
841           b[0] += t_l * db0;
842           b[1] += t_l * db1;
843           b[2] += t_l * db2;
844
845           t[w] -= t_g;
846           *wptr = w;
847           return(nbr);
848         }
849         else
850           return(INVALID);
851       }
852   }
853    
840   }
841  
842  
843 < int
844 < qtRoot_visit_tri_edges(qtptr,q0,q1,q2,tri,i_pt,wptr,func,arg1,arg2,arg3)
845 <   QUADTREE *qtptr;
846 <   FVECT q0,q1,q2;
847 <   FVECT tri[3],i_pt;
848 <   int *wptr;
849 <   int (*func)();
850 <   int *arg1,arg2,*arg3;
843 > qtVisit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale,
844 >            s0,s1,s2,sq0,sq1,sq2,f)
845 > int root;
846 > QUADTREE qt;
847 > BCOORD q0[3],q1[3],q2[3];
848 > BCOORD t0[3],t1[3],t2[3];
849 > BCOORD dt10[3],dt21[3],dt02[3];
850 > BCOORD scale;
851 > unsigned int s0,s1,s2,sq0,sq1,sq2;
852 > FUNC f;
853   {
854 <  int x,y,z,nbr,w,i,j;
855 <  QUADTREE *child;
856 <  FVECT n,c,d,v[3];
869 <  double pd,b[4][3],db[3][3],et[3],t[3],exit_pt;
870 <    
871 <  w = *wptr;
854 >  BCOORD a,b,c;
855 >  BCOORD va[3],vb[3],vc[3];
856 >  unsigned int sa,sb,sc;
857  
858 <  /* Project the origin onto the root node plane */
859 <
875 <  /* Find the intersection point of the origin */
876 <  tri_plane_equation(q0,q1,q2,n,&pd,FALSE);
877 <  /* map to 2d by dropping maximum magnitude component of normal */
878 <  z = max_index(n,NULL);
879 <  x = (z+1)%3;
880 <  y = (z+2)%3;
881 <  /* Calculate barycentric coordinates for current vertex */
882 <  if(w != -1)
858 >  /* If a tree: trivial reject and recurse on potential children */
859 >  if(QT_IS_TREE(qt))
860    {
861 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b[3]);  
862 <    intersect_vector_plane(tri[w],n,pd,&(et[w]),v[w]);
863 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[w][x],v[w][y],b[w]);  
864 <  }
865 <  else
866 <  /* Just starting: b[0] is the origin point: guaranteed to be valid b*/
867 <  {
891 <    w = 0;
892 <    intersect_vector_plane(tri[0],n,pd,&(et[0]),v[0]);
893 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[0][x],v[0][y],b[0]);  
894 <    VCOPY(b[3],b[0]);
895 <  }
861 >    QT_SET_FLAG(qt);
862 >    /* Test against new a edge: if entirely to left: only need
863 >       to visit child 0
864 >    */
865 >    a = q1[0] - scale;
866 >    b = q0[1] - scale;
867 >    c = q0[2] - scale;
868  
869 +    SIDES_GTR(t0,t1,t2,sa,sb,sc,a,b,c);
870  
871 <  j = (w+1)%3;
899 <  intersect_vector_plane(tri[j],n,pd,&(et[j]),v[j]);
900 <  bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[j][x],v[j][y],b[j]);  
901 <  if(et[j] < 0.0)
902 <  {
903 <      VSUB(db[w],b[3],b[j]);
904 <      t[w] = FHUGE;
905 <  }
906 <  else
907 < {
908 <   /* NOTE: for stability: do not increment with ipt- use full dir and
909 <      calculate t: but for wrap around case: could get same problem?
910 <      */
911 <   VSUB(db[w],b[j],b[3]);
912 <   t[w] = 1.0;
913 <   move_to_nbr(b[3],db[w][0],db[w][1],db[w][2],&exit_pt);
914 <   if(exit_pt >= 1.0)
915 <   {
916 <     for(;j < 3;j++)
917 <      {
918 <          i = (j+1)%3;
919 <          if(i!= w)
920 <            {
921 <              intersect_vector_plane(tri[i],n,pd,&(et[i]),v[i]);
922 <              bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[i][x],
923 <                     v[i][y],b[i]);
924 <            }
925 <          if(et[i] < 0.0)
926 <             {
927 <                 VSUB(db[j],b[j],b[i]);
928 <                 t[j] = FHUGE;
929 <                 break;
930 <             }
931 <          else
932 <             {
933 <                 VSUB(db[j],b[i],b[j]);
934 <                 t[j] = 1.0;
935 <             }
936 <          move_to_nbr(b[j],db[j][0],db[j][1],db[j][2],&exit_pt);
937 <          if(exit_pt < 1.0)
938 <             break;
939 <      }
940 <   }
941 < }
942 <  *wptr = w;
943 <  /* trace the ray starting with this node */
944 <    nbr = qtVisit_tri_edges(qtptr,b[3],db[w][0],db[w][1],db[w][2],
945 <                             db,wptr,t,0,1.0,func,arg1,arg2,arg3);
946 <    if(nbr != INVALID && nbr != QT_DONE)
871 >    if(sa==0)
872      {
873 <      i_pt[x] = b[3][0]*q0[x] + b[3][1]*q1[x] + b[3][2]*q2[x];
874 <      i_pt[y] = b[3][0]*q0[y] + b[3][1]*q1[y] + b[3][2]*q2[y];
875 <      i_pt[z] = (-n[x]*i_pt[x] - n[y]*i_pt[y] -pd)/n[z];
873 >      vb[1] = q0[1];
874 >      vc[2] = q0[2];
875 >      vc[1] = b;
876 >      vb[2] = c;
877 >      vb[0] = vc[0] = a;
878 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,
879 >          vb,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,s1,s2,sq0,sb,sc,f);
880 >      return;
881      }
882 <    return(nbr);
953 <    
954 < }
955 <
956 < int
957 < move_to_nbri(b,db0,db1,db2,tptr)
958 < BCOORD b[3];
959 < BDIR db0,db1,db2;
960 < TINT *tptr;
961 < {
962 <  TINT t,dt;
963 <  BCOORD bc;
964 <  int nbr;
965 <  
966 <  nbr = -1;
967 <  /* Advance to next node */
968 <  if(db0 < 0)
969 <   {
970 <     bc = MAXBCOORD*b[0];
971 <     t = bc/-db0;
972 <     nbr = 0;
973 <   }
974 <  else
975 <    t = HUGET;
976 <  if(db1 < 0)
977 <  {
978 <     bc = MAXBCOORD*b[1];
979 <     dt = bc/-db1;
980 <    if( dt < t)
882 >    if(sb==0)
883      {
884 <      t = dt;
885 <      nbr = 1;
884 >      va[0] = q1[0];
885 >      vc[2] = q0[2];
886 >      va[1] = vc[1] = b;
887 >      va[2] = c;
888 >      vc[0] = a;
889 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
890 >         t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f);
891 >      return;
892      }
893 <  }
894 <  if(db2 < 0)
895 <  {
896 <     bc = MAXBCOORD*b[2];
897 <     dt = bc/-db2;
898 <       if( dt < t)
899 <      {
900 <        t = dt;
901 <        nbr = 2;
902 <      }
893 >    if(sc==0)
894 >    {
895 >      va[0] = q1[0];
896 >      vb[1] = q0[1];
897 >      va[1] = b;
898 >      va[2] = vb[2] = c;
899 >      vb[0] = a;
900 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,
901 >         q2,t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f);
902 >      return;
903      }
904 <  *tptr = t;
905 <  return(nbr);
906 < }
907 < /* NOTE: SINCE DIR could be unit: then we could use integer math */
908 < int
909 < qtVisit_tri_edgesi(qtptr,b,db0,db1,db2,
910 <                   db,wptr,t,sign,sfactor,func,arg1,arg2,arg3)
911 <   QUADTREE *qtptr;
1004 <   BCOORD b[3];
1005 <   BDIR db0,db1,db2,db[3][3];
1006 <   int *wptr;
1007 <   TINT t[3];
1008 <   int sign;
1009 <   int sfactor;
1010 <   int (*func)();
1011 <   int *arg1,arg2,*arg3;
1012 < {
1013 <    int i,found;
1014 <    QUADTREE *child;
1015 <    int nbr,next,w;
1016 <    TINT t_g,t_l,t_i;
1017 < #ifdef DEBUG_TEST_DRIVER
1018 <    FVECT a1,b1,c1;
1019 <    int Pick_parent = Pick_cnt-1;
1020 <    qtSubdivide_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
1021 <                           Pick_v2[Pick_parent],a1,b1,c1);
1022 < #endif
1023 <    if(QT_IS_TREE(*qtptr))
904 >    va[0] = q1[0];
905 >    vb[1] = q0[1];
906 >    vc[2] = q0[2];
907 >    va[1] = vc[1] = b;
908 >    va[2] = vb[2] = c;
909 >    vb[0] = vc[0] = a;
910 >    /* If outside of all edges: only need to Visit 3  */
911 >    if(sa==7 && sb==7 && sc==7)
912      {
913 <        /* Find the appropriate child and reset the coord */
914 <        i = baryi_child(b);
915 <
1028 <        QT_SET_FLAG(*qtptr);
1029 <
1030 <        for(;;)
1031 <        {
1032 <          w = *wptr;
1033 <           child = QT_NTH_CHILD_PTR(*qtptr,i);
1034 <
1035 <           if(i != 3)
1036 <               nbr = qtVisit_tri_edgesi(child,b,db0,db1,db2,
1037 <                                        db,wptr,t,sign,
1038 <                                        sfactor+1,func,arg1,arg2,arg3);
1039 <           else
1040 <             /* If the center cell- must flip direction signs */
1041 <             nbr = qtVisit_tri_edgesi(child,b,-db0,-db1,-db2,
1042 <                                     db,wptr,t,1-sign,
1043 <                                     sfactor+1,func,arg1,arg2,arg3);
1044 <
1045 <           if(nbr == QT_DONE)
1046 <             return(nbr);
1047 <           if(*wptr != w)
1048 <           {
1049 <             w = *wptr;
1050 <             db0 = db[w][0];db1 = db[w][1];db2 = db[w][2];
1051 <             if(sign)
1052 <               {  db0 *= -1;db1 *= -1; db2 *= -1;}
1053 <           }
1054 <           /* If in same block: traverse */
1055 <           if(i==3)
1056 <              next = nbr;
1057 <             else
1058 <                if(nbr == i)
1059 <                   next = 3;
1060 <             else
1061 <               {
1062 <                 /* reset the barycentric coordinates in the parents*/
1063 <                 baryi_parent(b,i);
1064 <                 /* Else pop up to parent and traverse from there */
1065 <                 return(nbr);
1066 <               }
1067 <           baryi_from_child(b,i,next);
1068 <           i = next;
1069 <        }
913 >     qtVisit_tri(root,QT_NTH_CHILD(qt,3),va,vb,
914 >           vc,t0,t1,t2,dt10,dt21,dt02, scale>>1,sa,sb,sc,s0,s1,s2,f);
915 >      return;
916      }
917 <    else
918 <   {
919 < #ifdef DEBUG_TEST_DRIVER
920 <           qtNth_child_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent],
921 <                           Pick_v2[Pick_parent],a1,b1,c1,i,Pick_v0[Pick_cnt],
922 <                           Pick_v1[Pick_cnt],Pick_v2[Pick_cnt]);
923 <           Pick_cnt++;
924 < #endif
917 >    if(sa!=7)
918 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,0),q0,vc,vb,
919 >           t0,t1,t2,dt10,dt21,dt02,scale>>1,sa,s1,s2,sq0,sb,sc,f);
920 >    if(sb!=7)
921 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,1),vc,q1,va,
922 >           t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,sb,s2,sa,sq1,sc,f);
923 >    if(sc!=7)
924 >      qtVisit_tri_rev(root,QT_NTH_CHILD(qt,2),vb,va,q2,
925 >           t0,t1,t2,dt10,dt21,dt02,scale>>1,s0,s1,sc,sa,sb,sq2,f);
926  
927 <       if(func(qtptr,arg1,arg2,arg3) == QT_DONE)
928 <          return(QT_DONE);
929 <
930 <       /* Advance to next node */
931 <       w = *wptr;
932 <       while(1)
933 <       {
934 <           nbr = move_to_nbri(b,db0,db1,db2,&t_i);
1088 <
1089 <         t_g = t_i >> sfactor;
1090 <                
1091 <         if(t_g >= t[w])
1092 <         {
1093 <           if(w == 2)
1094 <             return(QT_DONE);
1095 <
1096 <           /* The edge fits in the cell- therefore the result of shifting db by
1097 <              sfactor is guaranteed to be less than MAXBCOORD
1098 <            */
1099 <           /* Caution: (t[w]*db) must occur before divide by MAXBCOORD
1100 <              since t[w] will always be < MAXBCOORD
1101 <           */
1102 <           b[0] = b[0] + (t[w]*db0*(1 << sfactor))/MAXBCOORD;
1103 <           b[1] = b[1] + (t[w]*db1*(1 << sfactor))/MAXBCOORD;
1104 <           b[2] = b[2] + (t[w]*db2*(1 << sfactor))/MAXBCOORD;
1105 <           w++;
1106 <           db0 = db[w][0]; db1 = db[w][1]; db2 = db[w][2];
1107 <           if(sign)
1108 <           {  db0 *= -1;db1 *= -1; db2 *= -1;}
1109 <         }
1110 <       else
1111 <         if(nbr != INVALID)
1112 <         {
1113 <           /* Caution: (t_i*db) must occur before divide by MAXBCOORD
1114 <              since t_i will always be < MAXBCOORD
1115 <           */
1116 <           b[0] = b[0] + (t_i *db0) / MAXBCOORD;
1117 <           b[1] = b[1] + (t_i *db1) / MAXBCOORD;
1118 <           b[2] = b[2] + (t_i *db2) / MAXBCOORD;
1119 <
1120 <           t[w] -= t_g;
1121 <           *wptr = w;
1122 <           return(nbr);
1123 <         }
1124 <         else
1125 <           return(INVALID);
1126 <       }
1127 <   }    
927 >    qtVisit_tri(root,QT_NTH_CHILD(qt,3),va,vb,vc,t0,t1,
928 >              t2,dt10,dt21,dt02,scale>>1,sa,sb,sc,s0,s1,s2,f);
929 >    return;
930 >  }
931 >  /* Leaf node: Do definitive test */
932 >  else
933 >    qtLeaf_visit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
934 >                         scale,s0,s1,s2,sq0,sq1,sq2,f);
935   }
936  
937  
1131 int
1132 qtRoot_visit_tri_edgesi(qtptr,q0,q1,q2,tri,i_pt,wptr,func,arg1,arg2,arg3)
1133   QUADTREE *qtptr;
1134   FVECT q0,q1,q2;
1135   FVECT tri[3],i_pt;
1136   int *wptr;
1137   int (*func)();
1138   int *arg1,arg2,*arg3;
1139 {
1140  int x,y,z,nbr,w,i,j;
1141  QUADTREE *child;
1142  FVECT n,c,d,v[3];
1143  double pd,b[4][3],db[3][3],et[3],exit_pt;
1144  BCOORD bi[3];
1145  TINT t[3];
1146  BDIR dbi[3][3];
1147  w = *wptr;
938  
939 <  /* Project the origin onto the root node plane */
939 > qtLeaf_visit_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
940 >                 scale, s0,s1,s2,sq0,sq1,sq2,f)
941 > int root;
942 > QUADTREE qt;
943 > BCOORD q0[3],q1[3],q2[3];
944 > BCOORD t0[3],t1[3],t2[3];
945 > BCOORD dt10[3],dt21[3],dt02[3];
946 > unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
947 > FUNC f;
948 > {
949 >  double db;
950 >  unsigned int e0,e1,e2;
951 >  char al,ah,bl,bh,cl,ch,testl,testh;
952 >  char test_t0t1,test_t1t2,test_t2t0;
953 >  BCOORD a,b,c;
954  
955 <  t[0] = t[1] = t[2] = 0;
956 <  /* Find the intersection point of the origin */
957 <  tri_plane_equation(q0,q1,q2,n,&pd,FALSE);
958 <  /* map to 2d by dropping maximum magnitude component of normal */
959 <  z = max_index(n,NULL);
960 <  x = (z+1)%3;
961 <  y = (z+2)%3;
962 <  /* Calculate barycentric coordinates for current vertex */
963 <  if(w != -1)
955 >  /* First check if can trivial accept: if vertex in cell */
956 >  if(s0 & s1 & s2)
957 >    goto Lfunc_call;
958 >
959 >  /* Assumption: Could not trivial reject*/
960 >  /* IF any coords lie on edge- must be in if couldnt reject */
961 >  a = q1[0];b= q0[1]; c= q0[2];
962 >  if(t0[0]== a || t0[1] == b || t0[2] == c)
963 >    goto Lfunc_call;
964 >  if(t1[0]== a || t1[1] == b || t1[2] == c)
965 >    goto Lfunc_call;
966 >  if(t2[0]== a || t2[1] == b || t2[2] == c)
967 >    goto Lfunc_call;
968 >  
969 >  /* Test for edge crossings */
970 >  /* Test t0t1,t1t2,t2t0 against a */
971 >  /* Calculate edge crossings */
972 >  e0  = (s0 ^ ((s0 >> 1) | (s0 << 2 & 4)));
973 >  /* See if edge can be trivially rejected from intersetion testing */
974 >  test_t0t1 = !(((s0 & 6)==0) || ((s1 & 6)==0)|| ((s2 & 6)==0) ||
975 >       ((sq0 & 6)==6) ||((sq1 & 6)==6)|| ((sq2 & 6)==6));
976 >  bl=bh=0;
977 >  if(test_t0t1 && (e0 & 2) )
978    {
979 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b[3]);  
980 <    intersect_vector_plane(tri[w],n,pd,&(et[w]),v[w]);
981 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[w][x],v[w][y],b[w]);  
979 >    /* Must do double calculation to avoid overflow */
980 >    db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
981 >    TEST_INT(testl,testh,db,b,q1[1],bl,bh)
982    }
983 <  else
984 <  /* Just starting: b[0] is the origin point: guaranteed to be valid b*/
983 >  test_t1t2= !(((s0 & 3)==0) || ((s1 & 3)==0)|| ((s2 & 3)==0) ||
984 >       ((sq0 & 3)==3) ||((sq1 & 3)==3)|| ((sq2 & 3)==3));
985 >  if(test_t1t2 && (e0 & 1))
986 >  {    /* test t1t2 against a */
987 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
988 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
989 >  }
990 >  test_t2t0 = !(((s0 & 5)==0) || ((s1 & 5)==0)|| ((s2 & 5)==0) ||
991 >       ((sq0 & 5)==5) ||((sq1 & 5)==5)|| ((sq2 & 5)==5));
992 >  if(test_t2t0 && (e0 & 4))
993    {
994 <    w = 0;
995 <    intersect_vector_plane(tri[0],n,pd,&(et[0]),v[0]);
1170 <    bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[0][x],v[0][y],b[0]);  
1171 <    VCOPY(b[3],b[0]);
994 >      db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
995 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
996    }
997 +  e1  = (s1 ^ ((s1 >> 1) | (s1 << 2 & 4)));
998 +  cl = ch = 0;
999 +  if(test_t0t1 && (e1 & 2))
1000 +  {/* test t0t1 against b */
1001 +      db = t0[2] + dt10[2]*((double)(b-t0[1]))/dt10[1];
1002 +      TEST_INT(testl,testh,db,c,q2[2],cl,ch)
1003 +  }
1004 +  if(test_t1t2 && (e1 & 1))
1005 +  {/* test t1t2 against b */
1006 +    db = t1[2] + dt21[2]*((double)(q0[1] - t1[1]))/dt21[1];
1007 +    TEST_INT(testl,testh,db,c,q2[2],cl,ch)
1008 +  }
1009 +  if(test_t2t0 && (e1 & 4))
1010 +  {/* test t2t0 against b */
1011 +    db = t2[2] + dt02[2]*((double)(q0[1] - t2[1]))/dt02[1];
1012 +    TEST_INT(testl,testh,db,c,q2[2],cl,ch)
1013 +  }
1014 +
1015 +  /* test edges against c */
1016 +  e2  = (s2 ^ ((s2 >> 1) | (s2 << 2 & 4)));
1017 +  al = ah = 0;
1018 +  if(test_t0t1 && (e2 & 2))
1019 +  { /* test t0t1 against c */
1020 +    db = t0[0] + dt10[0]*((double)(c-t0[2]))/dt10[2];
1021 +    TEST_INT(testl,testh,db,a,q0[0],al,ah)
1022 +   }
1023 +  if(test_t1t2 && (e2 & 1))
1024 +  {
1025 +    db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
1026 +    TEST_INT(testl,testh,db,a,q0[0],al,ah)
1027 +  }
1028 +  if(test_t2t0 && (e2 & 4))
1029 +  { /* test t2t0 against c */
1030 +    db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
1031 +    TEST_INT(testl,testh,db,a,q0[0],al,ah)
1032 +  }
1033 +  /* Only remaining case is if some edge trivially rejected */
1034 +  if(!e0 || !e1 || !e2)
1035 +    return;
1036  
1037 <
1038 <  j = (w+1)%3;
1039 <  intersect_vector_plane(tri[j],n,pd,&(et[j]),v[j]);
1177 <  bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[j][x],v[j][y],b[j]);  
1178 <  if(et[j] < 0.0)
1037 >  /* Only one/none got tested - pick either of other two/any two */
1038 >  /* Only need to test one edge */
1039 >  if(!test_t0t1 && (e0 & 2))
1040    {
1041 <      VSUB(db[w],b[3],b[j]);
1042 <      t[w] = HUGET;
1041 >     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
1042 >     TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1043    }
1044 <  else
1045 < {
1046 <   /* NOTE: for stability: do not increment with ipt- use full dir and
1047 <      calculate t: but for wrap around case: could get same problem?
1187 <      */
1188 <   VSUB(db[w],b[j],b[3]);
1189 <   /* Check if the point is out side of the triangle: if so t[w] =HUGET */
1190 <   if((fabs(b[j][0])>(FTINY+1.0)) ||(fabs(b[j][1])>(FTINY+1.0)) ||
1191 <      (fabs(b[j][2])>(FTINY+1.0)))
1192 <      t[w] = HUGET;
1193 <   else
1194 <   {
1195 <       /* The next point is in the triangle- so db values will be in valid
1196 <          range and t[w]= MAXT
1197 <        */  
1198 <       t[w] = MAXT;
1199 <       if(j != 0)
1200 <          for(;j < 3;j++)
1201 <             {
1202 <                 i = (j+1)%3;
1203 <                 if(i!= w)
1204 <                 {
1205 <                     intersect_vector_plane(tri[i],n,pd,&(et[i]),v[i]);
1206 <                     bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[i][x],
1207 <                            v[i][y],b[i]);
1208 <                 }
1209 <                 if(et[i] < 0.0)
1210 <                 {
1211 <                     VSUB(db[j],b[j],b[i]);
1212 <                     t[j] = HUGET;
1213 <                     break;
1214 <                 }
1215 <                 else
1216 <                 {
1217 <                     VSUB(db[j],b[i],b[j]);
1218 <                     if((fabs(b[j][0])>(FTINY+1.0)) ||
1219 <                        (fabs(b[j][1])>(FTINY+1.0)) ||
1220 <                        (fabs(b[j][2])>(FTINY+1.0)))
1221 <                        {
1222 <                            t[j] = HUGET;
1223 <                            break;
1224 <                        }
1225 <                     else
1226 <                        t[j] = MAXT;
1227 <                 }
1228 <             }
1044 >  if(!test_t1t2 && (e0 & 1))
1045 >    {/* test t1t2 against a */
1046 >      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
1047 >      TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1048     }
1049 < }
1050 <  *wptr = w;
1051 <  bary_dtol(b[3],db,bi,dbi,t);
1049 >  if(!test_t2t0 && (e0 & 4))
1050 >  {
1051 >    db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1052 >    TEST_INT(testl,testh,db,b,q1[1],bl,bh)
1053 >  }
1054  
1055 <  /* trace the ray starting with this node */
1056 <    nbr = qtVisit_tri_edgesi(qtptr,bi,dbi[w][0],dbi[w][1],dbi[w][2],
1057 <                             dbi,wptr,t,0,0,func,arg1,arg2,arg3);
1058 <    if(nbr != INVALID && nbr != QT_DONE)
1059 <    {
1060 <        b[3][0] = (double)bi[0]/(double)MAXBCOORD;
1240 <        b[3][1] = (double)bi[1]/(double)MAXBCOORD;
1241 <        b[3][2] = (double)bi[2]/(double)MAXBCOORD;
1242 <        i_pt[x] = b[3][0]*q0[x] + b[3][1]*q1[x] + b[3][2]*q2[x];
1243 <        i_pt[y] = b[3][0]*q0[y] + b[3][1]*q1[y] + b[3][2]*q2[y];
1244 <        i_pt[z] = (-n[x]*i_pt[x] - n[y]*i_pt[y] -pd)/n[z];
1245 <    }
1246 <    return(nbr);
1247 <    
1055 >  return;
1056 >
1057 > Lfunc_call:
1058 >  f.func(f.argptr,root,qt);
1059 >  if(!QT_IS_EMPTY(qt))
1060 >    QT_LEAF_SET_FLAG(qt);
1061   }
1062  
1063  
1064  
1065 + /* Leaf node: Do definitive test */
1066 + QUADTREE
1067 + qtLeaf_visit_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,
1068 +                 scale, s0,s1,s2,sq0,sq1,sq2,f)
1069 + int root;
1070 + QUADTREE qt;
1071 + BCOORD q0[3],q1[3],q2[3];
1072 + BCOORD t0[3],t1[3],t2[3];
1073 + BCOORD dt10[3],dt21[3],dt02[3];
1074 + unsigned int scale,s0,s1,s2,sq0,sq1,sq2;
1075 + FUNC f;
1076 + {
1077 +  double db;
1078 +  unsigned int e0,e1,e2;
1079 +  BCOORD a,b,c;
1080 +  double p0[2], p1[2],cp;
1081 +  char al,ah,bl,bh,cl,ch;
1082 +  char testl,testh,test_t0t1,test_t1t2,test_t2t0;
1083 +  unsigned int ls0,ls1,ls2;
1084 +  
1085 +  /* May have gotten passed trivial reject if one/two vertices are ON */
1086 +  a = q1[0];b= q0[1]; c= q0[2];
1087 +  SIDES_LESS(t0,t1,t2,ls0,ls1,ls2,a,b,c);
1088 +  
1089 +  /* First check if can trivial accept: if vertex in cell */
1090 +  if(ls0 & ls1 & ls2)
1091 +    goto Lfunc_call;
1092  
1093 +  if(ls0==0 || ls1 == 0 || ls2 ==0)
1094 +    return;
1095 +  /* Assumption: Could not trivial reject*/
1096 +  /* IF any coords lie on edge- must be in if couldnt reject */
1097  
1098 +  if(t0[0]== a || t0[1] == b || t0[2] == c)
1099 +    goto Lfunc_call;
1100 +  if(t1[0]== a || t1[1] == b || t1[2] == c)
1101 +    goto Lfunc_call;
1102 +  if(t2[0]== a || t2[1] == b || t2[2] == c)
1103 +    goto Lfunc_call;
1104  
1105 +  /* Test for edge crossings */
1106 +  /* Test t0t1 against a,b,c */
1107 +  /* First test if t0t1 can be trivially rejected */
1108 +  /* If both edges are outside bounds- dont need to test */
1109 +  
1110 +  /* Test t0t1,t1t2,t2t0 against a */
1111 +  test_t0t1 = !(((ls0 & 6)==0) || ((ls1 & 6)==0)|| ((ls2 & 6)==0) ||
1112 +       ((sq0 & 6)==0) ||((sq1 & 6)==0)|| ((sq2 & 6)==0));
1113 +  e0  = (ls0 ^ ((ls0 >> 1) | (ls0 << 2 & 4)));
1114 +  bl=bh=0;
1115 +  /* Test t0t1,t1t2,t2t0 against a */
1116 +  if(test_t0t1 && (e0 & 2) )
1117 +  {
1118 +      db = t0[1] + dt10[1]*((double)(a-t0[0])/dt10[0]);
1119 +      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1120 +  }
1121 +  test_t1t2= !(((ls0 & 3)==0) || ((ls1 & 3)==0)|| ((ls2 & 3)==0) ||
1122 +       ((sq0 & 3)==0) ||((sq1 & 3)==0)|| ((sq2 & 3)==0));
1123 +  if(test_t1t2 && (e0 & 1))
1124 +  {    /* test t1t2 against a */
1125 +      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
1126 +      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1127 +  }
1128 +  test_t2t0 = !(((ls0 & 5)==0) || ((ls1 & 5)==0)|| ((ls2 & 5)==0) ||
1129 +       ((sq0 & 5)==0) ||((sq1 & 5)==0)|| ((sq2 & 5)==0));
1130 +  if(test_t2t0 && (e0 & 4))
1131 +  {
1132 +      db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1133 +      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1134 +  }
1135 +  cl = ch = 0;
1136 +  e1  = (ls1 ^ ((ls1 >> 1) | (ls1 << 2 & 4)));
1137 +  if(test_t0t1 && (e1 & 2))
1138 +  {/* test t0t1 against b */
1139 +      db = t0[2] + dt10[2]*(((double)(b-t0[1]))/dt10[1]);
1140 +      TEST_INT(testl,testh,db,q1[2],c,cl,ch)
1141 +  }
1142 +  if(test_t1t2 && (e1 & 1))
1143 +  {/* test t1t2 against b */
1144 +    db = t1[2] + dt21[2]*((double)(b - t1[1]))/dt21[1];
1145 +    TEST_INT(testl,testh,db,q1[2],c,cl,ch)
1146 +  }
1147 +  if(test_t2t0 && (e1 & 4))
1148 +  {/* test t2t0 against b */
1149 +    db = t2[2] + dt02[2]*((double)(b - t2[1]))/dt02[1];
1150 +    TEST_INT(testl,testh,db,q1[2],c,cl,ch)
1151 +  }
1152 +  al = ah = 0;
1153 +  e2  = (ls2 ^ ((ls2 >> 1) | (ls2 << 2 & 4)));
1154 +  if(test_t0t1 && (e2 & 2))
1155 +  { /* test t0t1 against c */
1156 +    db = t0[0] + dt10[0]*(((double)(c-t0[2]))/dt10[2]);
1157 +    TEST_INT(testl,testh,db,q0[0],a,al,ah)
1158 +   }
1159 +  if(test_t1t2 && (e2 & 1))
1160 +  {
1161 +    db = t1[0] + dt21[0]*((double)(c - t1[2]))/dt21[2];
1162 +    TEST_INT(testl,testh,db,q0[0],a,al,ah)
1163 +  }
1164 +  if(test_t2t0 && (e2 & 4))
1165 +  { /* test t2t0 against c */
1166 +    db = t2[0] + dt02[0]*((double)(c - t2[2]))/dt02[2];
1167 +    TEST_INT(testl,testh,db,q0[0],a,al,ah)
1168 +  }
1169 +  /* Only remaining case is if some edge trivially rejected */
1170 +  if(!e0 || !e1 || !e2)
1171 +    return;
1172  
1173 +  /* Only one/none got tested - pick either of other two/any two */
1174 +  /* Only need to test one edge */
1175 +  if(!test_t0t1 && (e0 & 2))
1176 +  {
1177 +     db = t0[1] + dt10[1]*((double)(a-t0[0]))/dt10[0];
1178 +     TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1179 +  }
1180 +  if(!test_t1t2 && (e0 & 1))
1181 +    {/* test t1t2 against a */
1182 +      db = t1[1] + dt21[1]*((double)(a - t1[0]))/dt21[0];
1183 +      TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1184 +   }
1185 +  if(!test_t2t0 && (e0 & 4))
1186 +  {
1187 +    db = t2[1] + dt02[1]*((double)(a - t2[0]))/dt02[0];
1188 +    TEST_INT(testl,testh,db,q1[1],b,bl,bh)
1189 +  }
1190  
1191 +  return;
1192  
1193 <
1194 <
1195 <
1196 <
1193 > Lfunc_call:
1194 >  f.func(f.argptr,root,qt);
1195 >  if(!QT_IS_EMPTY(qt))
1196 >    QT_LEAF_SET_FLAG(qt);
1197 > }
1198  
1199  
1200  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines