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.6 by gwlarson, Mon Sep 14 10:33:46 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 226 | Line 224 | smInit(n)
224   {
225    int max_vertices;
226  
229  sleep(10);
230  
227    /* If n <=0, Just clear the existing structures */
228    if(n <= 0)
229    {
# Line 260 | Line 256 | smLocator_apply_func(sm,v0,v1,v2,func,arg)
256   SM *sm;
257   FVECT v0,v1,v2;
258   int (*func)();
259 < char *arg;
259 > int *arg;
260   {
261    STREE *st;
262 <  char found;
262 >  int found;
263    FVECT p0,p1,p2;
264  
265    st = SM_LOCATOR(sm);
266  
267 <  point_on_sphere(p0,v0,SM_VIEW_CENTER(sm));
268 <  point_on_sphere(p1,v1,SM_VIEW_CENTER(sm));
269 <  point_on_sphere(p2,v2,SM_VIEW_CENTER(sm));
267 >  VSUB(p0,v0,SM_VIEW_CENTER(sm));
268 >  VSUB(p1,v1,SM_VIEW_CENTER(sm));
269 >  VSUB(p2,v2,SM_VIEW_CENTER(sm));
270  
271    found = stApply_to_tri_cells(st,p0,p1,p2,func,arg);
272  
# Line 279 | Line 275 | char *arg;
275  
276  
277   int
278 + add_tri_expand(qtptr,q0,q1,q2,t0,t1,t2,n,arg,t_id)
279 + QUADTREE *qtptr;
280 + FVECT q0,q1,q2;
281 + FVECT t0,t1,t2;
282 + int n;
283 + int *arg;
284 + int t_id;
285 + {
286 +    OBJECT tset[QT_MAXSET+1],*optr;    
287 +    int i,id,found;
288 +    FVECT v0,v1,v2;
289 +    TRI *tri;
290 + #ifdef DEBUG_TEST_DRIVER
291 +    Pick_tri = t_id;
292 +    Picking = TRUE;
293 + #endif    
294 +    
295 +    if(QT_IS_EMPTY(*qtptr))
296 +    {
297 +      *qtptr = qtaddelem(*qtptr,t_id);
298 +      return(TRUE);
299 +    }
300 +    
301 +    optr = qtqueryset(*qtptr);
302 +    if(!inset(optr,t_id))
303 +    {
304 +      if(QT_SET_CNT(optr) < QT_MAXSET)
305 +        *qtptr = qtaddelem(*qtptr,t_id);
306 +      else
307 +        {
308 + #ifdef DEBUG
309 +          eputs("add_tri_expand():no room in set\n");
310 + #endif
311 +          return(FALSE);
312 +        }
313 +    }
314 +    optr = qtqueryset(*qtptr);
315 +    if(QT_SET_CNT(optr) >= QT_SET_THRESHOLD)
316 +      if (n < QT_MAX_LEVELS)
317 +      {
318 +        qtgetset(tset,*qtptr);
319 +        /* If set size exceeds threshold: subdivide cell and reinsert tris*/
320 +        qtfreeleaf(*qtptr);
321 +        qtSubdivide(qtptr);
322 +
323 +        for(optr = QT_SET_PTR(tset),i=QT_SET_CNT(tset); i > 0; i--)
324 +        {
325 +          id = QT_SET_NEXT_ELEM(optr);
326 +          tri = SM_NTH_TRI(smMesh,id);
327 +          VSUB(v0,SM_T_NTH_WV(smMesh,tri,0),SM_VIEW_CENTER(smMesh));
328 +          VSUB(v1,SM_T_NTH_WV(smMesh,tri,1),SM_VIEW_CENTER(smMesh));
329 +          VSUB(v2,SM_T_NTH_WV(smMesh,tri,2),SM_VIEW_CENTER(smMesh));
330 +          found = qtAdd_tri(qtptr,q0,q1,q2,v0,v1,v2,id,n);
331 + #ifdef DEBUG
332 +          if(!found)
333 +            eputs("add_tri_expand():Reinsert\n");
334 + #endif
335 +        }
336 +        return(QT_MODIFIED);
337 +      }
338 +      else
339 +        if(QT_SET_CNT(optr) < QT_MAXSET)
340 +        {
341 + #ifdef DEBUG_TEST_DRIVER              
342 +          eputs("add_tri_expand():too many levels:can't expand\n");
343 + #endif
344 +          return(TRUE);
345 +        }
346 +        else
347 +          {
348 + #ifdef DEBUG          
349 +            eputs("add_tri_expand():too many tris inset:can't add\n");
350 + #endif
351 +            return(FALSE);
352 +          }
353 + }
354 +
355 +
356 + int
357 + add_tri(qtptr,fptr,t_id)
358 +   QUADTREE *qtptr;
359 +   int *fptr;
360 +   int t_id;
361 + {
362 +
363 +  OBJECT *optr;
364 +
365 + #ifdef DEBUG_TEST_DRIVER
366 +    Pick_tri = t_id;
367 +    Picking = TRUE;
368 + #endif    
369 +    if(QT_IS_EMPTY(*qtptr))
370 +    {
371 +        *qtptr = qtaddelem(*qtptr,t_id);
372 +        if(!QT_FLAG_FILL_TRI(*fptr))
373 +          (*fptr)++;
374 +    }
375 +    else
376 +     {
377 +       optr = qtqueryset(*qtptr);
378 +       if(!inset(optr,t_id))
379 +       {
380 +         if(QT_SET_CNT(optr) < QT_MAXSET)
381 +         {
382 +           if(QT_SET_CNT(optr) >= QT_SET_THRESHOLD)
383 +             (*fptr) |= QT_EXPAND;
384 +           if(!QT_FLAG_FILL_TRI(*fptr))
385 +             (*fptr)++;
386 +           *qtptr = qtaddelem(*qtptr,t_id);
387 +         }
388 +         else
389 +           {
390 + #ifdef DEBUG_TESTDRIVER      
391 +             eputs("add_tri():exceeded set size\n");
392 + #endif
393 +             return(FALSE);
394 +           }
395 +       }
396 +     }
397 +    return(TRUE);
398 + }
399 +
400 +
401 + int
402 + stInsert_tri(st,t_id,t0,t1,t2)
403 +   STREE *st;
404 +   int t_id;
405 +   FVECT t0,t1,t2;
406 + {
407 +    int f;
408 +    FVECT dir;
409 +    
410 +  /* First add all of the leaf cells lying on the triangle perimeter:
411 +     mark all cells seen on the way
412 +   */
413 +    ST_CLEAR_FLAGS(st);
414 +    f = 0;
415 +    VSUB(dir,t1,t0);
416 +    stTrace_edge(st,t0,dir,1.0,add_tri,&f,t_id);
417 +    VSUB(dir,t2,t1);
418 +    stTrace_edge(st,t1,dir,1.0,add_tri,&f,t_id);
419 +    VSUB(dir,t0,t2);
420 +    stTrace_edge(st,t2,dir,1.0,add_tri,&f,t_id);
421 +    /* Now visit interior */
422 +    if(QT_FLAG_FILL_TRI(f) || QT_FLAG_UPDATE(f))
423 +       stVisit_tri_interior(st,t0,t1,t2,add_tri_expand,&f,t_id);
424 + }
425 +
426   smLocator_add_tri(sm,t_id,v0_id,v1_id,v2_id)
427   SM *sm;
428   int t_id;
429   int v0_id,v1_id,v2_id;  
430   {
431    STREE *st;
432 <  FVECT p0,p1,p2;
432 >  FVECT v0,v1,v2;
433    
434    st = SM_LOCATOR(sm);
435  
436 <  smDir(sm,p0,v0_id);
437 <  smDir(sm,p1,v1_id);
438 <  smDir(sm,p2,v2_id);
436 >  VSUB(v0,SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm));
437 >  VSUB(v1,SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm));
438 >  VSUB(v2,SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm));
439  
440 <  stAdd_tri(st,t_id,p0,p1,p2);
440 >  stUpdate_tri(st,t_id,v0,v1,v2,add_tri,add_tri_expand);
441  
298  return(1);
442   }
443  
444   /* Add a triangle to the base array with vertices v1-v2-v3 */
# Line 383 | Line 526 | double eps;
526             }
527        }
528        else
529 <        if(d1 < d2)
529 >        if(d1 < d0)
530          {
531            if((eps < 0) ||  d1 < eps)
532            {
# Line 391 | Line 534 | double eps;
534              d = d1;
535            }
536          }
537 <      else
395 <         if((eps < 0) ||  d2 < eps)
396 <          {
397 <            closest = v2_id;
398 <            d = d2;
399 <          }
400 <  }
537 >    }
538      if(v2_id != -1)
539      {
540        smDir(sm,v,v2_id);
541        d2 = DIST(p,v);
542        if((eps < 0) ||  d2 < eps)
543 <         if(closest== -1 ||(d2 < d))
543 >         if(closest == -1 ||(d2 < d))
544               return(v2_id);
545      }
546      return(closest);
# Line 426 | Line 563 | FVECT p;
563      
564      VCOPY(v,SM_NTH_WV(sm,v1_id));
565      d1 = DIST(p,v);
566 <    if(d1 < d2)
566 >    if(d1 < d0)
567      {
568        closest = v1_id;
569        d = d1;
# Line 444 | Line 581 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add,d
581     SM *sm;
582     int t_id,t1_id;
583     int e,e1;
584 <   int **tn_id,**tn1_id;
584 >   int *tn_id,*tn1_id;
585     LIST **add,**del;
586  
587   {
# Line 469 | Line 606 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add,d
606      verts[eprev] = T_NTH_V(t,eprev);
607      ta_id = smAdd_tri(sm,verts[0],verts[1],verts[2],&ta);
608      *add = push_data(*add,ta_id);
472
609      verts[e1] = T_NTH_V(t1,e1);
610      verts[e1next] = T_NTH_V(t,eprev);
611      verts[e1prev] = T_NTH_V(t1,e1prev);
# Line 496 | Line 632 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add,d
632      T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = tb_id;
633  
634      /* Delete two parent triangles */
635 +
636      *del = push_data(*del,t_id);
637 <    if(SM_IS_NTH_T_NEW(sm,t_id))
501 <      SM_CLEAR_NTH_T_NEW(sm,t_id);
502 <    else
503 <      SM_CLEAR_NTH_T_BASE(sm,t_id);
637 >    T_VALID_FLAG(t) = -1;
638      *del = push_data(*del,t1_id);
639 <    if(SM_IS_NTH_T_NEW(sm,t1_id))
506 <      SM_CLEAR_NTH_T_NEW(sm,t1_id);
507 <    else
508 <      SM_CLEAR_NTH_T_BASE(sm,t1_id);
639 >    T_VALID_FLAG(t1) = -1;
640      *tn_id = ta_id;
641      *tn1_id = tb_id;
642   }
# Line 519 | Line 650 | LIST *add_list,*del_list;
650    while(add_list)
651    {
652      t_id = pop_list(&add_list);
653 <    if(!SM_IS_NTH_T_NEW(sm,t_id) && !SM_IS_NTH_T_BASE(sm,t_id))
653 >    t = SM_NTH_TRI(sm,t_id);
654 >    if(!T_IS_VALID(t))
655      {
656 <      SM_SET_NTH_T_NEW(sm,t_id);
525 <      smNew_tri_cnt--;
656 >      T_VALID_FLAG(t) = 1;
657        continue;
658      }
528    t = SM_NTH_TRI(sm,t_id);
659      smLocator_add_tri(sm,t_id,T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2));
660    }
661    
662    while(del_list)
663    {
664      t_id = pop_list(&del_list);
665 <    if(SM_IS_NTH_T_NEW(sm,t_id))
666 <    {
667 <      smDelete_tri(sm,t_id);
668 <      continue;
665 >    t = SM_NTH_TRI(sm,t_id);
666 >    if(!T_IS_VALID(t))
667 >    {
668 >      smLocator_remove_tri(sm,t_id);
669      }
540    smLocator_remove_tri(sm,t_id);
670      smDelete_tri(sm,t_id);
671    }
672   }
673   /* MUST add check for constrained edges */
674   int
675 < smFix_tris(sm,id,tlist)
675 > smFix_tris(sm,id,tlist,add_list,del_list)
676   SM *sm;
677   int id;
678   LIST *tlist;
679 + LIST *add_list,*del_list;
680   {
681      TRI *t,*t_opp;
682      FVECT p,p1,p2,p3;
683      int e,e1,swapped = 0;
684      int t_id,t_opp_id;
555    LIST *add_list,*del_list;
685  
686  
558    add_list = del_list = NULL;
687      VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
688      while(tlist)
689      {
# Line 564 | Line 692 | LIST *tlist;
692          e = (T_WHICH_V(t,id)+1)%3;
693          t_opp_id = T_NTH_NBR(t,e);
694          t_opp = SM_NTH_TRI(sm,t_opp_id);
695 <
695 >        /*
696 >        VSUB(p1,SM_T_NTH_WV(sm,t_opp,0),SM_VIEW_CENTER(sm));
697 >        VSUB(p2,SM_T_NTH_WV(sm,t_opp,1),SM_VIEW_CENTER(sm));
698 >        VSUB(p3,SM_T_NTH_WV(sm,t_opp,2),SM_VIEW_CENTER(sm));
699 >        */
700          smDir(sm,p1,T_NTH_V(t_opp,0));
701          smDir(sm,p2,T_NTH_V(t_opp,1));
702          smDir(sm,p3,T_NTH_V(t_opp,2));
# Line 581 | Line 713 | LIST *tlist;
713          }
714      }
715      smUpdate_locator(sm,add_list,del_list);
584
716      return(swapped);
717   }
718  
# Line 614 | Line 745 | int id,nid;
745    
746    T_NTH_V(tri,T_WHICH_V(tri,id)) = nid;
747  
748 <  t_id = smTri_next_ccw_nbr(sm,t,nid);
749 <  while((t= SM_NTH_TRI(sm,t_id)) != tri)
748 >  t_id = smTri_next_ccw_nbr(sm,tri,nid);
749 >  while((t = SM_NTH_TRI(sm,t_id)) != tri)
750    {
751        T_NTH_V(t,T_WHICH_V(t,id)) = nid;
752        t_id = smTri_next_ccw_nbr(sm,t,nid);
# Line 641 | Line 772 | smReplace_vertex(sm,c,dir,p,tri_id,snew_id,type,which)
772     COLR c;
773     FVECT dir,p;
774     int tri_id,snew_id;
775 <   char type,which;
775 >   int type,which;
776   {
777      int n_id,s_id;
778      TRI *tri;
# Line 690 | Line 821 | smInsert_point_in_tri(sm,c,dir,p,s_id,tri_id)
821      TRI *tri,*t0,*t1,*t2,*nbr;
822      int v0_id,v1_id,v2_id,n_id;
823      int t0_id,t1_id,t2_id;
824 <    LIST *tlist;
824 >    LIST *tlist,*add_list,*del_list;
825      FVECT npt;
826  
827 +    add_list = del_list = NULL;
828      if(s_id == SM_INVALID)
829         s_id = smAdd_sample_point(sm,c,dir,p);
830      
# Line 713 | Line 845 | smInsert_point_in_tri(sm,c,dir,p,s_id,tri_id)
845      }
846      t0_id = smAdd_tri(sm,s_id,v0_id,v1_id,&t0);
847      /* Add triangle to the locator */
848 <    smLocator_add_tri(sm,t0_id,s_id,v0_id,v1_id);
848 >    
849 >    add_list = push_data(add_list,t0_id);
850  
851      t1_id = smAdd_tri(sm,s_id,v1_id,v2_id,&t1);
852 <    smLocator_add_tri(sm,t1_id,s_id,v1_id,v2_id);
852 >    add_list = push_data(add_list,t1_id);
853 >
854      t2_id = smAdd_tri(sm,s_id,v2_id,v0_id,&t2);
855 <    smLocator_add_tri(sm,t2_id,s_id,v2_id,v0_id);      
855 >    add_list = push_data(add_list,t2_id);
856  
857      /* Set the neighbor pointers for the new tris */
858      T_NTH_NBR(t0,0) = t2_id;
# Line 739 | Line 873 | smInsert_point_in_tri(sm,c,dir,p,s_id,tri_id)
873      nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2));
874      T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id;
875          
876 <    smLocator_remove_tri(sm,tri_id);
877 <    smDelete_tri(sm,tri_id);
878 <        
876 >    del_list = push_data(del_list,tri_id);
877 >    T_VALID_FLAG(tri) = -1;
878 >
879      /* Fix up the new triangles*/
880      tlist = push_data(NULL,t0_id);
881      tlist = push_data(tlist,t1_id);
882      tlist = push_data(tlist,t2_id);
883  
884 <    smFix_tris(sm,s_id,tlist);
884 >    smFix_tris(sm,s_id,tlist,add_list,del_list);
885  
886      if(n_id != -1)
887         smDelete_point(sm,n_id);
# Line 757 | Line 891 | smInsert_point_in_tri(sm,c,dir,p,s_id,tri_id)
891      
892  
893   int
894 < smPointLocate(sm,pt,type,which,norm)
894 > smPointLocate(sm,pt,norm)
895   SM *sm;
896   FVECT pt;
897 < char *type,*which;
764 < char norm;
897 > int norm;
898   {
899    STREE *st;
900    int tri;
# Line 770 | Line 903 | char norm;
903    st = SM_LOCATOR(sm);
904    if(norm)
905    {
906 <      point_on_sphere(npt,pt,SM_VIEW_CENTER(sm));
907 <      tri = stPoint_locate(st,npt,type,which);
906 >      VSUB(npt,pt,SM_VIEW_CENTER(sm));
907 >      tri = stPoint_locate(st,npt);
908    }
909    else
910 <     tri = stPoint_locate(st,pt,type,which);
910 >     tri = stPoint_locate(st,pt);
911    return(tri);
912   }
913  
# Line 782 | Line 915 | QUADTREE
915   smPointLocateCell(sm,pt,norm,v0,v1,v2)
916   SM *sm;
917   FVECT pt;
918 < char norm;
918 > int norm;
919   FVECT v0,v1,v2;
920   {
921    STREE *st;
# Line 792 | Line 925 | FVECT v0,v1,v2;
925    st = SM_LOCATOR(sm);
926    if(norm)
927    {
928 <      point_on_sphere(npt,pt,SM_VIEW_CENTER(sm));
928 >      VSUB(npt,pt,SM_VIEW_CENTER(sm));
929    
930        qtptr = stPoint_locate_cell(st,npt,v0,v1,v2);
931    }
# Line 813 | Line 946 | smAdd_sample_to_mesh(sm,c,dir,pt,s_id)
946     int s_id;
947   {
948      int t_id;
816    char type,which;
949      double d;
950      FVECT p;
951      
# Line 824 | Line 956 | smAdd_sample_to_mesh(sm,c,dir,pt,s_id)
956          d = DIST(pt,SM_VIEW_CENTER(smMesh));
957          smDist_sum += 1.0/d;
958          /************************************/
959 <        t_id = smPointLocate(smMesh,pt,&type,&which,TRUE);
960 <        if(type==GT_FACE)
959 >        t_id = smPointLocate(smMesh,pt,TRUE);
960 >        if(t_id >= 0)
961             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);
962   #ifdef DEBUG
963             else
964 <              eputs("smAdd_sample_to_mesh(): unrecognized type\n");
964 >             {
965 >               c[0] = 255;c[1]=0;c[2]=0;
966 >               s_id = smAdd_sample_point(sm,c,dir,pt);        
967 >               eputs("smAdd_sample_to_mesh(): not found fg\n");
968 >             }
969   #endif
970      }
971      else if(s_id != -1)
# Line 845 | Line 978 | smAdd_sample_to_mesh(sm,c,dir,pt,s_id)
978              smDist_sum += 1.0/d;
979              /************************************/
980          }
981 <        t_id = smPointLocate(smMesh,p,&type,&which,TRUE);
982 <        if(type==GT_FACE)
981 >        t_id = smPointLocate(smMesh,p,TRUE);
982 >        if(t_id != -1)
983             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);
984   #ifdef DEBUG
985             else
986 <              eputs("smAdd_sample_to_mesh(): unrecognized type\n");
986 >              eputs("smAdd_sample_to_mesh():not found reinsert\n");
987   #endif
988      }
989      /* Is a BG(sky point) */
990      else
991         {
992 <           t_id = smPointLocate(smMesh,dir,&type,&which,FALSE);
993 <           if(type==GT_FACE)
992 >           t_id = smPointLocate(smMesh,dir,FALSE);
993 >           if(t_id != -1)
994                s_id = smInsert_point_in_tri(smMesh,c,dir,NULL,s_id,t_id);
995 <           else
866 <              if(type==GT_VERTEX)
867 <                 s_id = smReplace_vertex(smMesh,c,dir,NULL,t_id,s_id,type,which);
995 >
996   #ifdef DEBUG
997                else
998 <                 eputs("smAdd_sample_to_mesh(): unrecognized type\n");
998 >                 eputs("smAdd_sample_to_mesh(): not found bg\n");
999   #endif
1000         }
1001      return(s_id);
# Line 892 | Line 1020 | FVECT p;
1020  
1021   {
1022      int s_id;
1023 +    int debug=0;
1024      
1025      /* First check if this the first sample: if so initialize mesh */
1026      if(SM_NUM_SAMP(smMesh) == 0)
898 #ifdef TEST_DRIVER
899      smInit_mesh(smMesh,View.vp);
900 #else
1027        smInit_mesh(smMesh,odev.v.vp);
1028 < #endif
1029 <    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
1028 >    if(!debug)
1029 >       s_id = smAdd_sample_to_mesh(smMesh,c,dir,p,-1);
1030      return(s_id);
1031      
1032   }    
# Line 981 | Line 1100 | smCreate_base_mesh(sm,type)
1100   SM *sm;
1101   int type;
1102   {
1103 <  int i,id;
1103 >  int i,id,tri_id,nbr_id;
1104    int p[4],ids[4];
1105    int v0_id,v1_id,v2_id;
1106    TRI *tris[4];
# Line 991 | Line 1110 | int type;
1110  
1111    for(i=0; i < 4; i++)
1112    {
1113 <      VADD(cntr,stDefault_base[i],SM_VIEW_CENTER(sm));
1114 <      point_on_sphere(d,cntr,SM_VIEW_CENTER(sm));
1115 <      id = smAdd_base_vertex(sm,cntr,d);
1113 >    VCOPY(cntr,stDefault_base[i]);
1114 >    cntr[0] += .01;
1115 >    cntr[1] += .02;
1116 >    cntr[2] += .03;
1117 >    VADD(cntr,cntr,SM_VIEW_CENTER(sm));
1118 >    /* WONT use dir */
1119 >    point_on_sphere(d,cntr,SM_VIEW_CENTER(sm));
1120 >    id = smAdd_base_vertex(sm,cntr,d);
1121      /* test to make sure vertex allocated */
1122      if(id != -1)
1123        p[i] = id;
# Line 1012 | Line 1136 | int type;
1136    }
1137    /* Set neighbors */
1138  
1139 <  T_NTH_NBR(tris[0],0) = ids[3];
1140 <  T_NTH_NBR(tris[0],1) = ids[2];
1141 <  T_NTH_NBR(tris[0],2) = ids[1];
1139 >  for(tri_id=0;tri_id < 4; tri_id++)
1140 >     for(nbr_id=0; nbr_id < 3; nbr_id++)
1141 >        T_NTH_NBR(tris[tri_id],nbr_id) = smBase_nbrs[tri_id][nbr_id];
1142  
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];
1143    return(1);
1144  
1145   }
# Line 1036 | Line 1149 | int
1149   smNext_tri_flag_set(sm,i,which,b)
1150       SM *sm;
1151       int i,which;
1152 <     char b;
1152 >     int b;
1153   {
1154  
1155    for(; i < SM_TRI_CNT(sm);i++)
1156    {
1044    if(!SM_IS_NTH_T_FLAG(sm,i,which))
1045      continue;
1157  
1158 +      if(!SM_IS_NTH_T_FLAG(sm,i,which))
1159 +         continue;
1160      if(!b)
1161        break;
1162      if((b==1) && !SM_BG_TRI(sm,i))
# Line 1070 | Line 1183 | smNext_valid_tri(sm,i)
1183  
1184  
1185  
1186 < qtTri_verts_from_id(t_id,v0,v1,v2)
1186 > qtTri_from_id(t_id,v0,v1,v2,n0,n1,n2,v0_idp,v1_idp,v2_idp)
1187   int t_id;
1188   FVECT v0,v1,v2;
1189 + FVECT n0,n1,n2;
1190 + int *v0_idp,*v1_idp,*v2_idp;
1191   {
1192    TRI *t;
1193    int v0_id,v1_id,v2_id;
# Line 1082 | Line 1197 | FVECT v0,v1,v2;
1197    v1_id = T_NTH_V(t,1);
1198    v2_id = T_NTH_V(t,2);
1199  
1200 <  smDir(smMesh,v0,v0_id);
1201 <  smDir(smMesh,v1,v1_id);
1202 <  smDir(smMesh,v2,v2_id);
1200 >  if(v0)
1201 >  {
1202 >      VCOPY(v0,SM_NTH_WV(smMesh,v0_id));
1203 >      VCOPY(v1,SM_NTH_WV(smMesh,v1_id));
1204 >      VCOPY(v2,SM_NTH_WV(smMesh,v2_id));
1205 >  }
1206 >  if(n0)
1207 >  {
1208 >      smDir(smMesh,n0,v0_id);
1209 >      smDir(smMesh,n1,v1_id);
1210 >      smDir(smMesh,n2,v2_id);
1211  
1212 < }
1212 >  }
1213 >  if(v0_idp)
1214 >     {
1215 >         *v0_idp = v0_id;
1216 >         *v1_idp = v1_id;
1217 >         *v2_idp = v2_id;
1218 >     }
1219 > }
1220  
1221  
1222 < int
1223 < smIntersectTriSet(sm,t_set,orig,dir,pt)
1222 > /*
1223 > * int
1224 > * smFindSamp(FVECT orig, FVECT dir)
1225 > *
1226 > * Find the closest sample to the given ray.  Returns sample id, -1 on failure.
1227 > * "dir" is assumed to be normalized
1228 > */
1229 >
1230 >  
1231 >
1232 > smRebuild_mesh(sm,vp)
1233     SM *sm;
1234 +   FVECT vp;
1235 + {
1236 +    int i;
1237 +    FVECT dir;
1238 +    COLR c;
1239 +    FVECT p,ov;
1240 +
1241 +    /* Clear the mesh- and rebuild using the current sample array */
1242 +
1243 +    VSUB(ov,vp,SM_VIEW_CENTER(sm));
1244 +    smInit_mesh(sm,vp);
1245 +    
1246 +    SM_FOR_ALL_SAMPLES(sm,i)
1247 +    {
1248 +        if(SM_NTH_W_DIR(sm,i)==-1)
1249 +           VADD(SM_NTH_WV(sm,i),SM_NTH_WV(sm,i),ov);        
1250 +        smAdd_sample_to_mesh(sm,NULL,NULL,NULL,i);      
1251 +    }
1252 + }
1253 +
1254 + int
1255 + intersect_tri_set(t_set,orig,dir,pt)
1256     OBJECT *t_set;
1257     FVECT orig,dir,pt;
1258   {
1259      OBJECT *optr;
1260 <    int i,t_id,v_id;
1261 <    TRI *tri;
1262 <    FVECT p0,p1,p2;
1263 <    char type,which;
1103 <    int p0_id,p1_id,p2_id;
1260 >    int i,t_id,id;
1261 >    int pid0,pid1,pid2;
1262 >    FVECT p0,p1,p2,p;
1263 >    TRI *t;
1264      
1265 <    for(optr = QT_SET_PTR(t_set),i = QT_SET_CNT(t_set); i > 0; i--)
1265 >    optr = QT_SET_PTR(t_set);
1266 >    for(i = QT_SET_CNT(t_set); i > 0; i--)
1267      {
1268          t_id = QT_SET_NEXT_ELEM(optr);
1269 <        tri = SM_NTH_TRI(sm,t_id);
1270 <        p0_id = T_NTH_V(tri,0);
1271 <        p1_id = T_NTH_V(tri,1);
1272 <        p2_id = T_NTH_V(tri,2);
1273 <        VCOPY(p0,SM_NTH_WV(sm,p0_id));
1274 <        VCOPY(p1,SM_NTH_WV(sm,p1_id));
1275 <        VCOPY(p2,SM_NTH_WV(sm,p2_id));
1276 <        if(type = ray_intersect_tri(orig,dir,p0,p1,p2,pt,&which))
1269 >
1270 >        t = SM_NTH_TRI(smMesh,t_id);
1271 >        pid0 = T_NTH_V(t,0);
1272 >        pid1 = T_NTH_V(t,1);
1273 >        pid2 = T_NTH_V(t,2);
1274 >        VCOPY(p0,SM_NTH_WV(smMesh,pid0));
1275 >        VCOPY(p1,SM_NTH_WV(smMesh,pid1));
1276 >        VCOPY(p2,SM_NTH_WV(smMesh,pid2));
1277 >        if(ray_intersect_tri(orig,dir,p0,p1,p2,p))
1278          {
1279 <          if(type==GT_VERTEX)
1280 <            return(T_NTH_V(tri,which));
1281 <          v_id = smClosest_vertex_in_w_tri(sm,p0_id,p1_id,p2_id,pt);
1282 <          return(v_id);
1279 >          id = closest_point_in_tri(p0,p1,p2,p,pid0,pid1,pid2);
1280 >
1281 >          if(pt)
1282 >             VCOPY(pt,p);
1283 > #ifdef DEBUG_TEST_DRIVER
1284 >          Pick_tri = t_id;
1285 >          Pick_samp = id;
1286 >          VCOPY(Pick_point[0],p);
1287 > #endif
1288 >          return(id);
1289          }
1290      }
1291      return(-1);
1292   }
1293  
1294 + int
1295 + ray_trace_check_set(qtptr,orig,dir,tptr,os)
1296 +   QUADTREE *qtptr;
1297 +   FVECT orig,dir;
1298 +   int *tptr;
1299 +   OBJECT *os;
1300 + {
1301 +    OBJECT tset[QT_MAXSET+1];  
1302 +    double dt,t;
1303 +    int found;
1304 +    FVECT o;
1305 +    
1306 +
1307 +    if(!QT_IS_EMPTY(*qtptr))
1308 +     {
1309 +         VADD(o,orig,SM_VIEW_CENTER(smMesh));
1310 +         qtgetset(tset,*qtptr);
1311 +         /* Check triangles in set against those seen so far(os):only
1312 +            check new triangles for intersection (t_set')
1313 +            */
1314 +         check_set(tset,os);
1315 +         if((found = intersect_tri_set(tset,o,dir,NULL))!= -1)
1316 +         {
1317 +             *tptr = found;
1318 +             return(QT_DONE);
1319 +         }
1320 +       }
1321 +    return(FALSE);
1322 + }
1323  
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 */
1324   int
1325   smFindSamp(orig,dir)
1326   FVECT orig,dir;
1327   {
1328 <  FVECT r,v0,v1,v2,a,b,p;
1329 <  OBJECT os[MAXCSET+1],t_set[MAXSET+1];
1328 >  FVECT b,p,o;
1329 >  OBJECT *ts;
1330    QUADTREE qt;
1331    int s_id;
1332    double d;
# Line 1156 | Line 1346 | FVECT orig,dir;
1346       either case, do a single test against the cell containing the
1347       intersection of "dir" and the sphere
1348     */
1349 +  /* orig will be updated-so preserve original value */
1350 +  if(!smMesh)
1351 +     return;
1352    point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh));
1353    d = -DOT(b,dir);
1354    if(EQUAL_VEC3(orig,SM_VIEW_CENTER(smMesh)) || EQUAL(fabs(d),1.0))
# Line 1164 | Line 1357 | FVECT orig,dir;
1357        /* Test triangles in the set for intersection with Ray:returns
1358           first found
1359        */
1360 <      qtgetset(t_set,qt);
1361 <      s_id = smIntersectTriSet(smMesh,t_set,orig,dir,p);
1362 < #ifdef TEST_DRIVER
1360 >      ts = qtqueryset(qt);
1361 >      s_id = intersect_tri_set(ts,orig,dir,p);
1362 > #ifdef DEBUG_TEST_DRIVER
1363        VCOPY(Pick_point[0],p);
1364   #endif
1172      return(s_id);
1365    }
1366    else
1367    {
1368 <      /* Starting with orig, Walk along projection of ray onto sphere */
1369 <      point_on_sphere(r,orig,SM_VIEW_CENTER(smMesh));
1370 <      qt = smPointLocateCell(smMesh,r,FALSE,v0,v1,v2);
1371 <      qtgetset(t_set,qt);
1372 <      /* os will contain all triangles seen thus far */
1373 <      setcopy(os,t_set);
1374 <
1375 <      /* 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);
1368 >    OBJECT t_set[QT_MAXCSET+1];
1369 >    /* Test each of the root triangles against point id */
1370 >    QT_CLEAR_SET(t_set);
1371 >    VSUB(o,orig,SM_VIEW_CENTER(smMesh));
1372 >    ST_CLEAR_FLAGS(SM_LOCATOR(smMesh));
1373 >    s_id=stTrace_ray(SM_LOCATOR(smMesh),o,dir,ray_trace_check_set,&s_id,t_set);
1374 > }    
1375 >  return(s_id);
1376   }
1212  
1377  
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;
1378  
1223    /* Clear the mesh- and rebuild using the current sample array */
1224 #ifdef TEST_DRIVER
1225    View = *vptr;
1226 #endif    
1379  
1380 <    VSUB(ov,vptr->vp,SM_VIEW_CENTER(sm));
1381 <    smInit_mesh(sm,vptr->vp);
1382 <    
1383 <    SM_FOR_ALL_SAMPLES(sm,i)
1384 <    {
1385 <        if(SM_NTH_W_DIR(sm,i)==-1)
1386 <           VADD(SM_NTH_WV(sm,i),SM_NTH_WV(sm,i),ov);        
1235 <        smAdd_sample_to_mesh(sm,NULL,NULL,NULL,i);      
1236 <    }
1237 < }
1380 >
1381 >
1382 >
1383 >
1384 >
1385 >
1386 >
1387  
1388  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines