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

Comparing ray/src/hd/sm.c (file contents):
Revision 3.4 by gwlarson, Tue Aug 25 11:03:27 1998 UTC vs.
Revision 3.7 by gwlarson, Wed Sep 16 18:16:28 1998 UTC

# Line 8 | Line 8 | static char SCCSid[] = "$SunId$ SGI";
8   *  sm.c
9   */
10   #include "standard.h"
11
12 #include "object.h"
13
11   #include "sm_list.h"
12   #include "sm_geom.h"
13   #include "sm.h"
# Line 20 | Line 17 | SM *smMesh = NULL;
17   double smDist_sum=0;
18   int smNew_tri_cnt=0;
19  
20 + static int smBase_nbrs[4][3] =  { {3,2,1},{3,0,2},{3,1,0},{1,2,0}};
21 +
22   #ifdef TEST_DRIVER
24 VIEW  View = {0,{0,0,0},{0,0,-1},{0,1,0},60,60,0};
23   VIEW  Current_View = {0,{0,0,0},{0,0,-1},{0,1,0},60,60,0};
24   int Pick_cnt =0;
25 < int Pick_tri = -1,Picking = FALSE;
25 > int Pick_tri = -1,Picking = FALSE,Pick_samp=-1;
26   FVECT Pick_point[500],Pick_origin,Pick_dir;
27   FVECT  Pick_v0[500], Pick_v1[500], Pick_v2[500];
28   FVECT P0,P1,P2;
# Line 42 | Line 40 | smDir(sm,ps,id)
40      VCOPY(p,SM_NTH_WV(sm,id));
41      point_on_sphere(ps,p,SM_VIEW_CENTER(sm));
42   }
43 + smDir_in_cone(sm,ps,id)
44 +   SM *sm;
45 +   FVECT ps;
46 +   int id;
47 + {
48 +    FVECT p;
49 +    
50 +    VCOPY(p,SM_NTH_WV(sm,id));
51 +    point_on_sphere(ps,p,SM_VIEW_CENTER(sm));
52 + }
53  
54   smClear_mesh(sm)
55      SM *sm;
# Line 226 | Line 234 | smInit(n)
234   {
235    int max_vertices;
236  
229  sleep(10);
230  
237    /* If n <=0, Just clear the existing structures */
238    if(n <= 0)
239    {
# Line 255 | Line 261 | smInit(n)
261   }
262  
263  
264 < int
265 < smLocator_apply_func(sm,v0,v1,v2,func,arg)
266 < SM *sm;
267 < FVECT v0,v1,v2;
268 < int (*func)();
269 < char *arg;
264 > smLocator_apply_func(sm,v0,v1,v2,edge_func,interior_func,arg1,arg2)
265 >   SM *sm;
266 >   FVECT v0,v1,v2;
267 >   int (*edge_func)();
268 >   int (*interior_func)();
269 >   int *arg1,arg2;
270   {
271    STREE *st;
266  char found;
272    FVECT p0,p1,p2;
273  
274    st = SM_LOCATOR(sm);
275  
276 <  point_on_sphere(p0,v0,SM_VIEW_CENTER(sm));
277 <  point_on_sphere(p1,v1,SM_VIEW_CENTER(sm));
278 <  point_on_sphere(p2,v2,SM_VIEW_CENTER(sm));
276 >  VSUB(p0,v0,SM_VIEW_CENTER(sm));
277 >  VSUB(p1,v1,SM_VIEW_CENTER(sm));
278 >  VSUB(p2,v2,SM_VIEW_CENTER(sm));
279  
280 <  found = stApply_to_tri_cells(st,p0,p1,p2,func,arg);
280 >  stApply_to_tri(st,p0,p1,p2,edge_func,interior_func,arg1,arg2);
281  
277  return(found);
282   }
283  
284  
285   int
286 < smLocator_add_tri(sm,t_id,v0_id,v1_id,v2_id)
286 > add_tri_expand(qtptr,q0,q1,q2,t0,t1,t2,n,arg,t_id,del_set)
287 > QUADTREE *qtptr;
288 > FVECT q0,q1,q2;
289 > FVECT t0,t1,t2;
290 > int n;
291 > int *arg;
292 > int t_id;
293 > OBJECT *del_set;
294 > {
295 >    OBJECT t_set[QT_MAXSET+1],*optr,*tptr,r_set[QT_MAXSET+1];
296 >    int i,id,found;
297 >    FVECT v0,v1,v2;
298 >    TRI *tri;
299 >    
300 > #ifdef DEBUG_TEST_DRIVER
301 >    Pick_tri = t_id;
302 >    Picking = TRUE;
303 > #endif    
304 >    
305 >    if(QT_IS_EMPTY(*qtptr))
306 >    {
307 >      *qtptr = qtaddelem(*qtptr,t_id);
308 >      return(TRUE);
309 >    }
310 >
311 >    optr = qtqueryset(*qtptr);
312 >    if(del_set)
313 >    {
314 >        setintersect(r_set,del_set,optr);
315 >        if(QT_SET_CNT(r_set) > 0)
316 >         {
317 >             qtgetset(t_set,*qtptr);
318 >             optr = QT_SET_PTR(r_set);
319 >             for(i = QT_SET_CNT(r_set); i > 0; i--)
320 >             {
321 >                 id = QT_SET_NEXT_ELEM(optr);
322 >                 deletelem(t_set,id);
323 >             }
324 >             qtfreeleaf(*qtptr);
325 >             *qtptr = qtnewleaf(t_set);
326 >             optr = t_set;
327 >         }
328 >    }
329 >    if(!inset(optr,t_id))
330 >    {
331 >      if(QT_SET_CNT(optr) < QT_MAXSET)
332 >        *qtptr = qtaddelem(*qtptr,t_id);
333 >      else
334 >        {
335 > #ifdef DEBUG
336 >          eputs("add_tri_expand():no room in set\n");
337 > #endif
338 >          return(FALSE);
339 >        }
340 >    }
341 >    optr = qtqueryset(*qtptr);
342 >    if(QT_SET_CNT(optr) >= QT_SET_THRESHOLD)
343 >      if (n < QT_MAX_LEVELS)
344 >      {
345 >        qtgetset(t_set,*qtptr);
346 >        /* If set size exceeds threshold: subdivide cell and reinsert tris*/
347 >        qtfreeleaf(*qtptr);
348 >        qtSubdivide(qtptr);
349 >
350 >        for(optr = QT_SET_PTR(t_set),i=QT_SET_CNT(t_set); i > 0; i--)
351 >        {
352 >          id = QT_SET_NEXT_ELEM(optr);
353 >          tri = SM_NTH_TRI(smMesh,id);
354 >          VSUB(v0,SM_T_NTH_WV(smMesh,tri,0),SM_VIEW_CENTER(smMesh));
355 >          VSUB(v1,SM_T_NTH_WV(smMesh,tri,1),SM_VIEW_CENTER(smMesh));
356 >          VSUB(v2,SM_T_NTH_WV(smMesh,tri,2),SM_VIEW_CENTER(smMesh));
357 >          found = qtAdd_tri(qtptr,q0,q1,q2,v0,v1,v2,id,n);
358 > #ifdef DEBUG
359 >          if(!found)
360 >            eputs("add_tri_expand():Reinsert\n");
361 > #endif
362 >        }
363 >        return(QT_MODIFIED);
364 >      }
365 >      else
366 >        if(QT_SET_CNT(optr) < QT_MAXSET)
367 >        {
368 > #ifdef DEBUG_TEST_DRIVER              
369 >          eputs("add_tri_expand():too many levels:can't expand\n");
370 > #endif
371 >          return(TRUE);
372 >        }
373 >        else
374 >          {
375 > #ifdef DEBUG          
376 >            eputs("add_tri_expand():too many tris inset:can't add\n");
377 > #endif
378 >            return(FALSE);
379 >          }
380 > }
381 >
382 >
383 > int
384 > add_tri(qtptr,fptr,t_id,del_set)
385 >   QUADTREE *qtptr;
386 >   int *fptr;
387 >   int t_id;
388 >   OBJECT *del_set;
389 > {
390 >
391 >  OBJECT *optr,*tptr;
392 >  OBJECT t_set[QT_MAXSET +1],r_set[QT_MAXSET +1];
393 >  int i,id,found;
394 > #ifdef DEBUG_TEST_DRIVER
395 >    Pick_tri = t_id;
396 >    Picking = TRUE;
397 > #endif    
398 >    if(QT_IS_EMPTY(*qtptr))
399 >    {
400 >        *qtptr = qtaddelem(*qtptr,t_id);
401 >        if(!QT_FLAG_FILL_TRI(*fptr))
402 >          (*fptr)++;
403 >    }
404 >    else
405 >     {
406 >         optr = qtqueryset(*qtptr);
407 >         if(del_set)
408 >          {
409 >              setintersect(r_set,del_set,optr);
410 >              if(QT_SET_CNT(r_set) > 0)
411 >              {
412 >                  qtgetset(t_set,*qtptr);
413 >                  optr = QT_SET_PTR(r_set);
414 >                  for(i = QT_SET_CNT(r_set); i > 0; i--)
415 >                     {
416 >                         id = QT_SET_NEXT_ELEM(optr);
417 >                         deletelem(t_set,id);
418 >                     }
419 >                  qtfreeleaf(*qtptr);
420 >                  *qtptr = qtnewleaf(t_set);
421 >                  optr = t_set;
422 >              }
423 >          }
424 >         if(!inset(optr,t_id))
425 >         {
426 >             if(QT_SET_CNT(optr) < QT_MAXSET)
427 >             {
428 >                 if(QT_SET_CNT(optr) >= QT_SET_THRESHOLD)
429 >                    (*fptr) |= QT_EXPAND;
430 >                 if(!QT_FLAG_FILL_TRI(*fptr))
431 >                    (*fptr)++;
432 >                 *qtptr = qtaddelem(*qtptr,t_id);
433 >             }
434 >             else
435 >                {
436 > #ifdef DEBUG_TESTDRIVER      
437 >                    eputs("add_tri():exceeded set size\n");
438 > #endif
439 >                    return(FALSE);
440 >                }
441 >         }
442 >     }
443 >    return(TRUE);
444 > }
445 >
446 >
447 > smLocator_add_tri(sm,t_id,v0_id,v1_id,v2_id,del_set)
448   SM *sm;
449   int t_id;
450 < int v0_id,v1_id,v2_id;  
450 > int v0_id,v1_id,v2_id;
451 > OBJECT *del_set;
452   {
453    STREE *st;
454 <  FVECT p0,p1,p2;
454 >  FVECT v0,v1,v2;
455    
456    st = SM_LOCATOR(sm);
457  
458 <  smDir(sm,p0,v0_id);
459 <  smDir(sm,p1,v1_id);
460 <  smDir(sm,p2,v2_id);
458 >  VSUB(v0,SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm));
459 >  VSUB(v1,SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm));
460 >  VSUB(v2,SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm));
461  
462 <  stAdd_tri(st,t_id,p0,p1,p2);
462 >  qtClearAllFlags();
463 >  
464 >  stApply_to_tri(st,v0,v1,v2,add_tri,add_tri_expand,t_id,del_set);
465  
298  return(1);
466   }
467  
468   /* Add a triangle to the base array with vertices v1-v2-v3 */
# Line 383 | Line 550 | double eps;
550             }
551        }
552        else
553 <        if(d1 < d2)
553 >        if(d1 < d0)
554          {
555            if((eps < 0) ||  d1 < eps)
556            {
# Line 391 | Line 558 | double eps;
558              d = d1;
559            }
560          }
561 <      else
395 <         if((eps < 0) ||  d2 < eps)
396 <          {
397 <            closest = v2_id;
398 <            d = d2;
399 <          }
400 <  }
561 >    }
562      if(v2_id != -1)
563      {
564        smDir(sm,v,v2_id);
565        d2 = DIST(p,v);
566        if((eps < 0) ||  d2 < eps)
567 <         if(closest== -1 ||(d2 < d))
567 >         if(closest == -1 ||(d2 < d))
568               return(v2_id);
569      }
570      return(closest);
# Line 426 | Line 587 | FVECT p;
587      
588      VCOPY(v,SM_NTH_WV(sm,v1_id));
589      d1 = DIST(p,v);
590 <    if(d1 < d2)
590 >    if(d1 < d0)
591      {
592        closest = v1_id;
593        d = d1;
# Line 440 | Line 601 | FVECT p;
601   }
602  
603   void
604 < smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add,del)
604 > smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_ptr,del_set)
605     SM *sm;
606     int t_id,t1_id;
607     int e,e1;
608 <   int **tn_id,**tn1_id;
609 <   LIST **add,**del;
608 >   int *tn_id,*tn1_id;
609 >   LIST **add_ptr;
610 >   OBJECT *del_set;
611  
612   {
613      TRI *t,*t1;
# Line 468 | Line 630 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add,d
630      verts[enext] = T_NTH_V(t1,e1prev);
631      verts[eprev] = T_NTH_V(t,eprev);
632      ta_id = smAdd_tri(sm,verts[0],verts[1],verts[2],&ta);
633 <    *add = push_data(*add,ta_id);
472 <
633 >    *add_ptr = push_data(*add_ptr,ta_id);
634      verts[e1] = T_NTH_V(t1,e1);
635      verts[e1next] = T_NTH_V(t,eprev);
636      verts[e1prev] = T_NTH_V(t1,e1prev);
637      tb_id = smAdd_tri(sm,verts[0],verts[1],verts[2],&tb);
638 <    *add = push_data(*add,tb_id);
638 >    *add_ptr = push_data(*add_ptr,tb_id);
639  
640      /* set the neighbors */
641      T_NTH_NBR(ta,e) = T_NTH_NBR(t1,e1next);
# Line 496 | Line 657 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add,d
657      T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = tb_id;
658  
659      /* Delete two parent triangles */
660 <    *del = push_data(*del,t_id);
661 <    if(SM_IS_NTH_T_NEW(sm,t_id))
501 <      SM_CLEAR_NTH_T_NEW(sm,t_id);
660 >    if(remove_from_list(t_id,add_ptr))
661 >       smDelete_tri(sm,t_id);
662      else
663 <      SM_CLEAR_NTH_T_BASE(sm,t_id);
664 <    *del = push_data(*del,t1_id);
665 <    if(SM_IS_NTH_T_NEW(sm,t1_id))
666 <      SM_CLEAR_NTH_T_NEW(sm,t1_id);
663 >       insertelem(del_set,t_id);
664 >
665 >    if(remove_from_list(t1_id,add_ptr))
666 >       smDelete_tri(sm,t1_id);
667      else
668 <      SM_CLEAR_NTH_T_BASE(sm,t1_id);
668 >       insertelem(del_set,t1_id);
669 >
670      *tn_id = ta_id;
671      *tn1_id = tb_id;
672   }
673  
674 < smUpdate_locator(sm,add_list,del_list)
674 > smUpdate_locator(sm,add_list,del_set)
675   SM *sm;
676 < LIST *add_list,*del_list;
676 > LIST *add_list;
677 > OBJECT *del_set;
678   {
679 <  int t_id;
679 >  int t_id,i;
680    TRI *t;
681 +  OBJECT *optr;
682 +  
683    while(add_list)
684    {
685      t_id = pop_list(&add_list);
522    if(!SM_IS_NTH_T_NEW(sm,t_id) && !SM_IS_NTH_T_BASE(sm,t_id))
523    {
524      SM_SET_NTH_T_NEW(sm,t_id);
525      smNew_tri_cnt--;
526      continue;
527    }
686      t = SM_NTH_TRI(sm,t_id);
687 <    smLocator_add_tri(sm,t_id,T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2));
687 >    smLocator_add_tri(sm,t_id,T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2),del_set);
688    }
689 <  
690 <  while(del_list)
689 >
690 >  optr = QT_SET_PTR(del_set);
691 >  for(i = QT_SET_CNT(del_set); i > 0; i--)
692    {
693 <    t_id = pop_list(&del_list);
535 <    if(SM_IS_NTH_T_NEW(sm,t_id))
536 <    {
693 >      t_id = QT_SET_NEXT_ELEM(optr);
694        smDelete_tri(sm,t_id);
538      continue;
539    }
540    smLocator_remove_tri(sm,t_id);
541    smDelete_tri(sm,t_id);
695    }
696   }
697   /* MUST add check for constrained edges */
698   int
699 < smFix_tris(sm,id,tlist)
699 > smFix_tris(sm,id,tlist,add_list,del_set)
700   SM *sm;
701   int id;
702   LIST *tlist;
703 + LIST *add_list;
704 + OBJECT *del_set;
705   {
706      TRI *t,*t_opp;
707      FVECT p,p1,p2,p3;
708      int e,e1,swapped = 0;
709      int t_id,t_opp_id;
555    LIST *add_list,*del_list;
710  
711  
558    add_list = del_list = NULL;
712      VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
713      while(tlist)
714      {
# Line 564 | Line 717 | LIST *tlist;
717          e = (T_WHICH_V(t,id)+1)%3;
718          t_opp_id = T_NTH_NBR(t,e);
719          t_opp = SM_NTH_TRI(sm,t_opp_id);
720 <
721 <        smDir(sm,p1,T_NTH_V(t_opp,0));
722 <        smDir(sm,p2,T_NTH_V(t_opp,1));
723 <        smDir(sm,p3,T_NTH_V(t_opp,2));
720 >        /*
721 >        VSUB(p1,SM_T_NTH_WV(sm,t_opp,0),SM_VIEW_CENTER(sm));
722 >        VSUB(p2,SM_T_NTH_WV(sm,t_opp,1),SM_VIEW_CENTER(sm));
723 >        VSUB(p3,SM_T_NTH_WV(sm,t_opp,2),SM_VIEW_CENTER(sm));
724 >        */
725 >        smDir_in_cone(sm,p1,T_NTH_V(t_opp,0));
726 >        smDir_in_cone(sm,p2,T_NTH_V(t_opp,1));
727 >        smDir_in_cone(sm,p3,T_NTH_V(t_opp,2));
728          if(point_in_cone(p,p1,p2,p3))
729          {
730              swapped = 1;
# Line 575 | Line 732 | LIST *tlist;
732              /* check list for t_opp and Remove if there */
733              remove_from_list(t_opp_id,&tlist);
734              smTris_swap_edge(sm,t_id,t_opp_id,e,e1,&t_id,&t_opp_id,
735 <                             &add_list,&del_list);
735 >                             &add_list,del_set);
736              tlist = push_data(tlist,t_id);
737              tlist = push_data(tlist,t_opp_id);
738          }
739      }
740 <    smUpdate_locator(sm,add_list,del_list);
584 <
740 >    smUpdate_locator(sm,add_list,del_set);
741      return(swapped);
742   }
743  
# Line 614 | Line 770 | int id,nid;
770    
771    T_NTH_V(tri,T_WHICH_V(tri,id)) = nid;
772  
773 <  t_id = smTri_next_ccw_nbr(sm,t,nid);
774 <  while((t= SM_NTH_TRI(sm,t_id)) != tri)
773 >  t_id = smTri_next_ccw_nbr(sm,tri,nid);
774 >  while((t = SM_NTH_TRI(sm,t_id)) != tri)
775    {
776        T_NTH_V(t,T_WHICH_V(t,id)) = nid;
777        t_id = smTri_next_ccw_nbr(sm,t,nid);
# Line 641 | Line 797 | smReplace_vertex(sm,c,dir,p,tri_id,snew_id,type,which)
797     COLR c;
798     FVECT dir,p;
799     int tri_id,snew_id;
800 <   char type,which;
800 >   int type,which;
801   {
802      int n_id,s_id;
803      TRI *tri;
# Line 690 | Line 846 | smInsert_point_in_tri(sm,c,dir,p,s_id,tri_id)
846      TRI *tri,*t0,*t1,*t2,*nbr;
847      int v0_id,v1_id,v2_id,n_id;
848      int t0_id,t1_id,t2_id;
849 <    LIST *tlist;
849 >    LIST *tlist,*add_list;
850 >    OBJECT del_set[QT_MAXSET+1];
851      FVECT npt;
852  
853 +    add_list = NULL;
854 +    QT_CLEAR_SET(del_set);
855      if(s_id == SM_INVALID)
856         s_id = smAdd_sample_point(sm,c,dir,p);
857      
# Line 713 | Line 872 | smInsert_point_in_tri(sm,c,dir,p,s_id,tri_id)
872      }
873      t0_id = smAdd_tri(sm,s_id,v0_id,v1_id,&t0);
874      /* Add triangle to the locator */
875 <    smLocator_add_tri(sm,t0_id,s_id,v0_id,v1_id);
875 >    
876 >    add_list = push_data(add_list,t0_id);
877  
878      t1_id = smAdd_tri(sm,s_id,v1_id,v2_id,&t1);
879 <    smLocator_add_tri(sm,t1_id,s_id,v1_id,v2_id);
879 >    add_list = push_data(add_list,t1_id);
880 >
881      t2_id = smAdd_tri(sm,s_id,v2_id,v0_id,&t2);
882 <    smLocator_add_tri(sm,t2_id,s_id,v2_id,v0_id);      
882 >    add_list = push_data(add_list,t2_id);
883  
884      /* Set the neighbor pointers for the new tris */
885      T_NTH_NBR(t0,0) = t2_id;
# Line 739 | Line 900 | smInsert_point_in_tri(sm,c,dir,p,s_id,tri_id)
900      nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2));
901      T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id;
902          
903 <    smLocator_remove_tri(sm,tri_id);
904 <    smDelete_tri(sm,tri_id);
744 <        
903 >    insertelem(del_set,tri_id);
904 >
905      /* Fix up the new triangles*/
906      tlist = push_data(NULL,t0_id);
907      tlist = push_data(tlist,t1_id);
908      tlist = push_data(tlist,t2_id);
909  
910 <    smFix_tris(sm,s_id,tlist);
910 >    smFix_tris(sm,s_id,tlist,add_list,del_set);
911  
912      if(n_id != -1)
913         smDelete_point(sm,n_id);
# Line 757 | Line 917 | smInsert_point_in_tri(sm,c,dir,p,s_id,tri_id)
917      
918  
919   int
920 < smPointLocate(sm,pt,type,which,norm)
920 > smPointLocate(sm,pt,norm)
921   SM *sm;
922   FVECT pt;
923 < char *type,*which;
764 < char norm;
923 > int norm;
924   {
925    STREE *st;
926    int tri;
# Line 770 | Line 929 | char norm;
929    st = SM_LOCATOR(sm);
930    if(norm)
931    {
932 <      point_on_sphere(npt,pt,SM_VIEW_CENTER(sm));
933 <      tri = stPoint_locate(st,npt,type,which);
932 >      VSUB(npt,pt,SM_VIEW_CENTER(sm));
933 >      tri = stPoint_locate(st,npt);
934    }
935    else
936 <     tri = stPoint_locate(st,pt,type,which);
936 >     tri = stPoint_locate(st,pt);
937    return(tri);
938   }
939  
# Line 782 | Line 941 | QUADTREE
941   smPointLocateCell(sm,pt,norm,v0,v1,v2)
942   SM *sm;
943   FVECT pt;
944 < char norm;
944 > int norm;
945   FVECT v0,v1,v2;
946   {
947    STREE *st;
# Line 792 | Line 951 | FVECT v0,v1,v2;
951    st = SM_LOCATOR(sm);
952    if(norm)
953    {
954 <      point_on_sphere(npt,pt,SM_VIEW_CENTER(sm));
954 >      VSUB(npt,pt,SM_VIEW_CENTER(sm));
955    
956        qtptr = stPoint_locate_cell(st,npt,v0,v1,v2);
957    }
# Line 813 | Line 972 | smAdd_sample_to_mesh(sm,c,dir,pt,s_id)
972     int s_id;
973   {
974      int t_id;
816    char type,which;
975      double d;
976      FVECT p;
977      
# Line 824 | Line 982 | smAdd_sample_to_mesh(sm,c,dir,pt,s_id)
982          d = DIST(pt,SM_VIEW_CENTER(smMesh));
983          smDist_sum += 1.0/d;
984          /************************************/
985 <        t_id = smPointLocate(smMesh,pt,&type,&which,TRUE);
986 <        if(type==GT_FACE)
985 >        t_id = smPointLocate(smMesh,pt,TRUE);
986 >        if(t_id >= 0)
987             s_id = smInsert_point_in_tri(smMesh,c,dir,pt,s_id,t_id);
830        else
831           if(type==GT_VERTEX)
832              s_id = smReplace_vertex(smMesh,c,dir,pt,t_id,s_id,type,which);
988   #ifdef DEBUG
989             else
990 <              eputs("smAdd_sample_to_mesh(): unrecognized type\n");
990 >             {
991 >               c[0] = 255;c[1]=0;c[2]=0;
992 >               s_id = smAdd_sample_point(sm,c,dir,pt);        
993 >               eputs("smAdd_sample_to_mesh(): not found fg\n");
994 >             }
995   #endif
996      }
997      else if(s_id != -1)
# Line 845 | Line 1004 | smAdd_sample_to_mesh(sm,c,dir,pt,s_id)
1004              smDist_sum += 1.0/d;
1005              /************************************/
1006          }
1007 <        t_id = smPointLocate(smMesh,p,&type,&which,TRUE);
1008 <        if(type==GT_FACE)
1007 >        t_id = smPointLocate(smMesh,p,TRUE);
1008 >        if(t_id != -1)
1009             s_id = smInsert_point_in_tri(smMesh,c,dir,p,s_id,t_id);
851        else
852           if(type==GT_VERTEX)
853              s_id = smReplace_vertex(smMesh,c,dir,p,t_id,s_id,type,which);
1010   #ifdef DEBUG
1011             else
1012 <              eputs("smAdd_sample_to_mesh(): unrecognized type\n");
1012 >              eputs("smAdd_sample_to_mesh():not found reinsert\n");
1013   #endif
1014      }
1015      /* Is a BG(sky point) */
1016      else
1017         {
1018 <           t_id = smPointLocate(smMesh,dir,&type,&which,FALSE);
1019 <           if(type==GT_FACE)
1018 >           t_id = smPointLocate(smMesh,dir,FALSE);
1019 >           if(t_id != -1)
1020                s_id = smInsert_point_in_tri(smMesh,c,dir,NULL,s_id,t_id);
1021 <           else
866 <              if(type==GT_VERTEX)
867 <                 s_id = smReplace_vertex(smMesh,c,dir,NULL,t_id,s_id,type,which);
1021 >
1022   #ifdef DEBUG
1023                else
1024 <                 eputs("smAdd_sample_to_mesh(): unrecognized type\n");
1024 >                 eputs("smAdd_sample_to_mesh(): not found bg\n");
1025   #endif
1026         }
1027      return(s_id);
# Line 892 | Line 1046 | FVECT p;
1046  
1047   {
1048      int s_id;
1049 +    int debug=0;
1050      
1051      /* First check if this the first sample: if so initialize mesh */
1052      if(SM_NUM_SAMP(smMesh) == 0)
898 #ifdef TEST_DRIVER
899      smInit_mesh(smMesh,View.vp);
900 #else
1053        smInit_mesh(smMesh,odev.v.vp);
1054 < #endif
1055 <    s_id = smAdd_sample_to_mesh(smMesh,c,dir,p,-1);
904 < #if 0
905 < {
906 <  char buff[100];
907 <  sprintf(buff,"Added sample %d\n",s_id);
908 <    eputs(buff);
909 < }
910 < #endif
1054 >    if(!debug)
1055 >       s_id = smAdd_sample_to_mesh(smMesh,c,dir,p,-1);
1056      return(s_id);
1057      
1058   }    
# Line 981 | Line 1126 | smCreate_base_mesh(sm,type)
1126   SM *sm;
1127   int type;
1128   {
1129 <  int i,id;
1129 >  int i,id,tri_id,nbr_id;
1130    int p[4],ids[4];
1131    int v0_id,v1_id,v2_id;
1132    TRI *tris[4];
# Line 991 | Line 1136 | int type;
1136  
1137    for(i=0; i < 4; i++)
1138    {
1139 <      VADD(cntr,stDefault_base[i],SM_VIEW_CENTER(sm));
1140 <      point_on_sphere(d,cntr,SM_VIEW_CENTER(sm));
1141 <      id = smAdd_base_vertex(sm,cntr,d);
1139 >    VCOPY(cntr,stDefault_base[i]);
1140 >    cntr[0] += .01;
1141 >    cntr[1] += .02;
1142 >    cntr[2] += .03;
1143 >    VADD(cntr,cntr,SM_VIEW_CENTER(sm));
1144 >    d[0] = -1;
1145 >    id = smAdd_base_vertex(sm,cntr,d);
1146      /* test to make sure vertex allocated */
1147      if(id != -1)
1148        p[i] = id;
# Line 1008 | Line 1157 | int type;
1157      v2_id = p[stTri_verts[i][2]];
1158      if((ids[i] = smAdd_tri(sm, v0_id,v1_id,v2_id,&(tris[i])))== -1)
1159       return(0);
1160 <    smLocator_add_tri(sm,ids[i],v0_id,v1_id,v2_id);
1160 >    smLocator_add_tri(sm,ids[i],v0_id,v1_id,v2_id,NULL);
1161    }
1162    /* Set neighbors */
1163  
1164 <  T_NTH_NBR(tris[0],0) = ids[3];
1165 <  T_NTH_NBR(tris[0],1) = ids[2];
1166 <  T_NTH_NBR(tris[0],2) = ids[1];
1164 >  for(tri_id=0;tri_id < 4; tri_id++)
1165 >     for(nbr_id=0; nbr_id < 3; nbr_id++)
1166 >        T_NTH_NBR(tris[tri_id],nbr_id) = smBase_nbrs[tri_id][nbr_id];
1167  
1019  T_NTH_NBR(tris[1],0) = ids[3];
1020  T_NTH_NBR(tris[1],1) = ids[0];
1021  T_NTH_NBR(tris[1],2) = ids[2];
1022
1023  T_NTH_NBR(tris[2],0) = ids[3];
1024  T_NTH_NBR(tris[2],1) = ids[1];
1025  T_NTH_NBR(tris[2],2) = ids[0];
1026
1027  T_NTH_NBR(tris[3],0) = ids[1];
1028  T_NTH_NBR(tris[3],1) = ids[2];
1029  T_NTH_NBR(tris[3],2) = ids[0];
1168    return(1);
1169  
1170   }
# Line 1036 | Line 1174 | int
1174   smNext_tri_flag_set(sm,i,which,b)
1175       SM *sm;
1176       int i,which;
1177 <     char b;
1177 >     int b;
1178   {
1179  
1180    for(; i < SM_TRI_CNT(sm);i++)
1181    {
1044    if(!SM_IS_NTH_T_FLAG(sm,i,which))
1045      continue;
1182  
1183 +      if(!SM_IS_NTH_T_FLAG(sm,i,which))
1184 +         continue;
1185      if(!b)
1186        break;
1187      if((b==1) && !SM_BG_TRI(sm,i))
# Line 1070 | Line 1208 | smNext_valid_tri(sm,i)
1208  
1209  
1210  
1211 < qtTri_verts_from_id(t_id,v0,v1,v2)
1211 > qtTri_from_id(t_id,v0,v1,v2,n0,n1,n2,v0_idp,v1_idp,v2_idp)
1212   int t_id;
1213   FVECT v0,v1,v2;
1214 + FVECT n0,n1,n2;
1215 + int *v0_idp,*v1_idp,*v2_idp;
1216   {
1217    TRI *t;
1218    int v0_id,v1_id,v2_id;
# Line 1082 | Line 1222 | FVECT v0,v1,v2;
1222    v1_id = T_NTH_V(t,1);
1223    v2_id = T_NTH_V(t,2);
1224  
1225 <  smDir(smMesh,v0,v0_id);
1226 <  smDir(smMesh,v1,v1_id);
1227 <  smDir(smMesh,v2,v2_id);
1225 >  if(v0)
1226 >  {
1227 >      VSUB(v0,SM_NTH_WV(smMesh,v0_id),SM_VIEW_CENTER(smMesh));
1228 >      VSUB(v1,SM_NTH_WV(smMesh,v1_id),SM_VIEW_CENTER(smMesh));
1229 >      VSUB(v2,SM_NTH_WV(smMesh,v2_id),SM_VIEW_CENTER(smMesh));
1230 >  }
1231 >  if(n0)
1232 >  {
1233 >      smDir(smMesh,n0,v0_id);
1234 >      smDir(smMesh,n1,v1_id);
1235 >      smDir(smMesh,n2,v2_id);
1236  
1237 < }
1237 >  }
1238 >  if(v0_idp)
1239 >     {
1240 >         *v0_idp = v0_id;
1241 >         *v1_idp = v1_id;
1242 >         *v2_idp = v2_id;
1243 >     }
1244 > }
1245  
1246  
1247 < int
1248 < smIntersectTriSet(sm,t_set,orig,dir,pt)
1247 > /*
1248 > * int
1249 > * smFindSamp(FVECT orig, FVECT dir)
1250 > *
1251 > * Find the closest sample to the given ray.  Returns sample id, -1 on failure.
1252 > * "dir" is assumed to be normalized
1253 > */
1254 >
1255 >  
1256 >
1257 > smRebuild_mesh(sm,vp)
1258     SM *sm;
1259 +   FVECT vp;
1260 + {
1261 +    int i;
1262 +    FVECT dir;
1263 +    COLR c;
1264 +    FVECT p,ov;
1265 +
1266 +    /* Clear the mesh- and rebuild using the current sample array */
1267 +
1268 +    VSUB(ov,vp,SM_VIEW_CENTER(sm));
1269 +    smInit_mesh(sm,vp);
1270 +    
1271 +    SM_FOR_ALL_SAMPLES(sm,i)
1272 +    {
1273 +        if(SM_NTH_W_DIR(sm,i)==-1)
1274 +           VADD(SM_NTH_WV(sm,i),SM_NTH_WV(sm,i),ov);        
1275 +        smAdd_sample_to_mesh(sm,NULL,NULL,NULL,i);      
1276 +    }
1277 + }
1278 +
1279 + int
1280 + intersect_tri_set(t_set,orig,dir,pt)
1281     OBJECT *t_set;
1282     FVECT orig,dir,pt;
1283   {
1284      OBJECT *optr;
1285 <    int i,t_id,v_id;
1286 <    TRI *tri;
1287 <    FVECT p0,p1,p2;
1288 <    char type,which;
1103 <    int p0_id,p1_id,p2_id;
1285 >    int i,t_id,id;
1286 >    int pid0,pid1,pid2;
1287 >    FVECT p0,p1,p2,p;
1288 >    TRI *t;
1289      
1290 <    for(optr = QT_SET_PTR(t_set),i = QT_SET_CNT(t_set); i > 0; i--)
1290 >    optr = QT_SET_PTR(t_set);
1291 >    for(i = QT_SET_CNT(t_set); i > 0; i--)
1292      {
1293          t_id = QT_SET_NEXT_ELEM(optr);
1294 <        tri = SM_NTH_TRI(sm,t_id);
1295 <        p0_id = T_NTH_V(tri,0);
1296 <        p1_id = T_NTH_V(tri,1);
1297 <        p2_id = T_NTH_V(tri,2);
1298 <        VCOPY(p0,SM_NTH_WV(sm,p0_id));
1299 <        VCOPY(p1,SM_NTH_WV(sm,p1_id));
1300 <        VCOPY(p2,SM_NTH_WV(sm,p2_id));
1301 <        if(type = ray_intersect_tri(orig,dir,p0,p1,p2,pt,&which))
1294 >
1295 >        t = SM_NTH_TRI(smMesh,t_id);
1296 >        pid0 = T_NTH_V(t,0);
1297 >        pid1 = T_NTH_V(t,1);
1298 >        pid2 = T_NTH_V(t,2);
1299 >        VCOPY(p0,SM_NTH_WV(smMesh,pid0));
1300 >        VCOPY(p1,SM_NTH_WV(smMesh,pid1));
1301 >        VCOPY(p2,SM_NTH_WV(smMesh,pid2));
1302 >        if(ray_intersect_tri(orig,dir,p0,p1,p2,p))
1303          {
1304 <          if(type==GT_VERTEX)
1305 <            return(T_NTH_V(tri,which));
1306 <          v_id = smClosest_vertex_in_w_tri(sm,p0_id,p1_id,p2_id,pt);
1307 <          return(v_id);
1304 >          id = closest_point_in_tri(p0,p1,p2,p,pid0,pid1,pid2);
1305 >
1306 >          if(pt)
1307 >             VCOPY(pt,p);
1308 > #ifdef DEBUG_TEST_DRIVER
1309 >          Pick_tri = t_id;
1310 >          Pick_samp = id;
1311 >          VCOPY(Pick_point[0],p);
1312 > #endif
1313 >          return(id);
1314          }
1315      }
1316      return(-1);
1317   }
1318  
1319 + int
1320 + ray_trace_check_set(qtptr,orig,dir,tptr,os)
1321 +   QUADTREE *qtptr;
1322 +   FVECT orig,dir;
1323 +   int *tptr;
1324 +   OBJECT *os;
1325 + {
1326 +    OBJECT tset[QT_MAXSET+1];  
1327 +    double dt,t;
1328 +    int found;
1329 +    FVECT o;
1330 +    
1331 +
1332 +    if(!QT_IS_EMPTY(*qtptr))
1333 +     {
1334 +         VADD(o,orig,SM_VIEW_CENTER(smMesh));
1335 +         qtgetset(tset,*qtptr);
1336 +         /* Check triangles in set against those seen so far(os):only
1337 +            check new triangles for intersection (t_set')
1338 +            */
1339 +         check_set(tset,os);
1340 +         if((found = intersect_tri_set(tset,o,dir,NULL))!= -1)
1341 +         {
1342 +             *tptr = found;
1343 +             return(QT_DONE);
1344 +         }
1345 +       }
1346 +    return(FALSE);
1347 + }
1348  
1127 /*
1128 * int
1129 * smFindSamp(FVECT orig, FVECT dir)
1130 *
1131 * Find the closest sample to the given ray.  Returns sample id, -1 on failure.
1132 * "dir" is assumed to be normalized
1133 */
1349   int
1350   smFindSamp(orig,dir)
1351   FVECT orig,dir;
1352   {
1353 <  FVECT r,v0,v1,v2,a,b,p;
1354 <  OBJECT os[MAXCSET+1],t_set[MAXSET+1];
1353 >  FVECT b,p,o;
1354 >  OBJECT *ts;
1355    QUADTREE qt;
1356    int s_id;
1357    double d;
# Line 1156 | Line 1371 | FVECT orig,dir;
1371       either case, do a single test against the cell containing the
1372       intersection of "dir" and the sphere
1373     */
1374 +  /* orig will be updated-so preserve original value */
1375 +  if(!smMesh)
1376 +     return;
1377    point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh));
1378    d = -DOT(b,dir);
1379    if(EQUAL_VEC3(orig,SM_VIEW_CENTER(smMesh)) || EQUAL(fabs(d),1.0))
# Line 1164 | Line 1382 | FVECT orig,dir;
1382        /* Test triangles in the set for intersection with Ray:returns
1383           first found
1384        */
1385 <      qtgetset(t_set,qt);
1386 <      s_id = smIntersectTriSet(smMesh,t_set,orig,dir,p);
1387 < #ifdef TEST_DRIVER
1385 >      ts = qtqueryset(qt);
1386 >      s_id = intersect_tri_set(ts,orig,dir,p);
1387 > #ifdef DEBUG_TEST_DRIVER
1388        VCOPY(Pick_point[0],p);
1389   #endif
1172      return(s_id);
1390    }
1391    else
1392    {
1393 <      /* Starting with orig, Walk along projection of ray onto sphere */
1394 <      point_on_sphere(r,orig,SM_VIEW_CENTER(smMesh));
1395 <      qt = smPointLocateCell(smMesh,r,FALSE,v0,v1,v2);
1396 <      qtgetset(t_set,qt);
1397 <      /* os will contain all triangles seen thus far */
1398 <      setcopy(os,t_set);
1399 <
1400 <      /* Calculate ray perpendicular to dir: when projection ray is // to dir,
1184 <         the dot product will become negative.
1185 <       */
1186 <      VSUM(a,b,dir,d);
1187 <      d = DOT(a,b);
1188 <      while(d > 0)
1189 <      {
1190 <          s_id = smIntersectTriSet(smMesh,t_set,orig,dir,p);
1191 < #ifdef TEST_DRIVER
1192 <          VCOPY(Pick_point[0],p);
1193 < #endif    
1194 <          if(s_id != EMPTY)
1195 <               return(s_id);
1196 <          /* Find next cell that projection of ray intersects */
1197 <          traceRay(r,dir,v0,v1,v2,r);
1198 <          qt = smPointLocateCell(smMesh,r,FALSE,v0,v1,v2);
1199 <          qtgetset(t_set,qt);
1200 <          /* Check triangles in set against those seen so far(os):only
1201 <             check new triangles for intersection (t_set')
1202 <          */
1203 <          check_set(t_set,os);
1204 <          d = DOT(a,r);
1205 <      }
1206 <    }
1207 < #ifdef DEBUG  
1208 <  eputs("smFindSamp():Pick Ray did not intersect mesh");
1209 < #endif
1210 <  return(EMPTY);
1393 >    OBJECT t_set[QT_MAXCSET+1];
1394 >    /* Test each of the root triangles against point id */
1395 >    QT_CLEAR_SET(t_set);
1396 >    VSUB(o,orig,SM_VIEW_CENTER(smMesh));
1397 >    ST_CLEAR_FLAGS(SM_LOCATOR(smMesh));
1398 >    s_id=stTrace_ray(SM_LOCATOR(smMesh),o,dir,ray_trace_check_set,&s_id,t_set);
1399 > }    
1400 >  return(s_id);
1401   }
1212  
1402  
1214 smRebuild_mesh(sm,vptr)
1215   SM *sm;
1216   VIEW *vptr;
1217 {
1218    int i;
1219    FVECT dir;
1220    COLR c;
1221    FVECT p,ov;
1403  
1223    /* Clear the mesh- and rebuild using the current sample array */
1224 #ifdef TEST_DRIVER
1225    View = *vptr;
1226 #endif    
1404  
1405 <    VSUB(ov,vptr->vp,SM_VIEW_CENTER(sm));
1406 <    smInit_mesh(sm,vptr->vp);
1407 <    
1408 <    SM_FOR_ALL_SAMPLES(sm,i)
1409 <    {
1410 <        if(SM_NTH_W_DIR(sm,i)==-1)
1411 <           VADD(SM_NTH_WV(sm,i),SM_NTH_WV(sm,i),ov);        
1235 <        smAdd_sample_to_mesh(sm,NULL,NULL,NULL,i);      
1236 <    }
1237 < }
1405 >
1406 >
1407 >
1408 >
1409 >
1410 >
1411 >
1412  
1413  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines