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.15 by gwlarson, Thu Jun 10 15:22:21 1999 UTC vs.
Revision 3.16 by greg, Sat Feb 22 02:07:25 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ SGI";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  sm.c
6   */
# Line 13 | Line 10 | static char SCCSid[] = "$SunId$ SGI";
10   #include "sm_geom.h"
11   #include "sm.h"
12  
16
17
13   SM *smMesh = NULL;
14   double smDist_sum=0;
15  
# Line 243 | Line 238 | tempbuf(len,resize)                    /* get a temporary buffer */
238   unsigned  len;
239   int resize;
240   {
246  extern char  *malloc(), *realloc();
241    static char  *tempbuf = NULL;
242    static unsigned  tempbuflen = 0;
243  
# Line 277 | Line 271 | int resize;
271   smDir(sm,ps,id)
272     SM *sm;
273     FVECT ps;
274 <   int id;
274 >   S_ID id;
275   {
276      VSUB(ps,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
277      normalize(ps);
# Line 347 | Line 341 | memerr:
341   }
342  
343  
344 + /*
345 + * smAlloc_tri(sm) : Allocate a new mesh triangle
346 + * SM *sm;                    : mesh
347 + *
348 + *  Returns ptr to next available tri
349 + */
350   int
351   smAlloc_tri(sm)
352   SM *sm;
# Line 367 | Line 367 | SM *sm;
367    return(INVALID);
368   }
369  
370 +
371   smFree_mesh(sm)
372   SM *sm;
373   {
# Line 379 | Line 380 | SM *sm;
380        free(SM_NTH_FLAGS(sm,i));
381   }
382  
383 <  
384 < /* Initialize/clear global smL sample list for at least n samples */
383 >
384 > /*
385 > * smAlloc(max_samples) : Initialize/clear global sample list for at least
386 > *                       max_samples
387 > * int max_samples;    
388 > *
389 > */
390   smAlloc(max_samples)
391     register int max_samples;
392   {
# Line 429 | Line 435 | smInit_sm(sm,vp)
435   SM *sm;
436   FVECT vp;
437   {
432
438    VCOPY(SM_VIEW_CENTER(sm),vp);
439    smClear(sm);
440    smCreate_base_mesh(sm,SM_DEFAULT);
# Line 445 | Line 450 | FVECT vp;
450   * If n is <= 0, then clear data structures.  Returns number samples
451   * actually allocated.
452   */
448
453   int
454   smInit(n)
455     register int n;
456   {
457    int max_vertices;
458 <
458 >  sleep(5);
459    /* If n <=0, Just clear the existing structures */
460    if(n <= 0)
461    {
# Line 505 | Line 509 | smLocator_apply(sm,v0,v1,v2,func,n)
509  
510   }
511  
512 + /*
513 + * QUADTREE
514 + * insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,rev,f,n,doneptr)
515 + *     Callback function called from quadtree traversal when leaf is reached
516 + *   int *argptr;                 :ptr to sample id number
517 + *   int root;                    :quadtree root from which traversal started
518 + *   QUADTREE qt,parent;          :current quadtree node and its parent
519 + *   BCOORD q0[3],q1[3],q2[3],bc[3]; :barycentric coordinates of the current
520 + *                                 quadtree node (q0,q1,q2) and sample (bc)
521 + *   unsigned int scale,rev;      :scale factor relative to which level at in
522 + *                                 tree, rev indicates if traversed of child 3
523 + *   FUNC f;                      :function structure so can recurse
524 + *   int n,*doneptr;              :n indicates which level at in quadtree, and
525 + *                                 doneptr can be set to indicate whether nbr
526 + *                                 sample has been found
527 + */
528   QUADTREE
529   insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,rev,f,n,doneptr)
530       int *argptr;
# Line 515 | Line 535 | insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,re
535       FUNC f;
536       int n,*doneptr;
537   {
538 <  OBJECT *optr,*sptr,s_set[QT_MAXSET+1];
539 <  int i,s_id;
520 <  FVECT p;
521 <  BCOORD bp[3];
522 <  FUNC sfunc;
523 <  S_ARGS args;
538 >  S_ID s_id;
539 >  S_ID *optr;
540  
541    s_id = ((S_ARGS *)argptr)->s_id;
542    /* If the set is empty - just add */
# Line 557 | Line 573 | insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,re
573    /* otherwise: expand node- and insert sample, and reinsert existing samples
574       in set to children of new node
575    */
560  if(QT_SET_CNT(optr) > QT_MAXSET)
561  {
562    if(!(sptr = (OBJECT *)malloc((QT_SET_CNT(optr)+1)*sizeof(OBJECT))))
563      goto memerr;
564  }
565  else
566    sptr = s_set;
567  qtgetset(sptr,qt);
568
569  /* subdivide node */
570  qtfreeleaf(qt);
571  qtSubdivide(qt);
572
573  /* Now add in all of the rest; */
574  F_FUNC(sfunc) = F_FUNC(f);
575  F_ARGS(sfunc) = (int *) (&args);
576  args.n_id = 0;
577  for(optr = sptr,i=QT_SET_CNT(sptr); i > 0; i--)
576    {
577 <    s_id = QT_SET_NEXT_ELEM(optr);
578 <    args.s_id = s_id;
579 <    VSUB(p,SM_NTH_WV(smMesh,s_id),SM_VIEW_CENTER(smMesh));
580 <    normalize(p);
581 <    vert_to_qt_frame(i,p,bp);    
582 <    if(rev)
583 <      qt= qtInsert_point_rev(root,qt,parent,q0,q1,q2,bp,scale,sfunc,n,doneptr);
584 <    else
585 <      qt= qtInsert_point(root,qt,parent,q0,q1,q2,bp,scale,sfunc,n,doneptr);
586 <  }
587 <  /* Add current sample: have all of the information */
588 <  if(rev)
589 <    qt =qtInsert_point_rev(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
590 <  else
593 <    qt = qtInsert_point(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
594 <  
595 <  /* If we allocated memory: free it */
577 >      OBJECT *sptr,s_set[QT_MAXSET+1];
578 >      FUNC sfunc;
579 >      S_ARGS args;
580 >      FVECT p;
581 >      BCOORD bp[3];
582 >      int i;
583 >      
584 >      if(QT_SET_CNT(optr) > QT_MAXSET)
585 >      {
586 >          if(!(sptr = (OBJECT *)malloc((QT_SET_CNT(optr)+1)*sizeof(OBJECT))))
587 >             goto memerr;
588 >      }
589 >      else
590 >         sptr = s_set;
591  
592 <  if( sptr != s_set)
593 <    free(sptr);
592 >      qtgetset(sptr,qt);
593 >      
594 >      /* subdivide node */
595 >      qtfreeleaf(qt);
596 >      qtSubdivide(qt);
597 >      
598 >      /* Now add in all of the rest; */
599 >      F_FUNC(sfunc) = F_FUNC(f);
600 >      F_ARGS(sfunc) = (int *) (&args);
601 >      args.n_id = 0;
602 >      for(optr = sptr,i=QT_SET_CNT(sptr); i > 0; i--)
603 >      {
604 >          s_id = QT_SET_NEXT_ELEM(optr);
605 >          args.s_id = s_id;
606 >          VSUB(p,SM_NTH_WV(smMesh,s_id),SM_VIEW_CENTER(smMesh));
607 >          normalize(p);
608 >          vert_to_qt_frame(i,p,bp);    
609 >          if(rev)
610 >             qt= qtInsert_point_rev(root,qt,parent,q0,q1,q2,bp,
611 >                                    scale,sfunc,n,doneptr);
612 >          else
613 >             qt= qtInsert_point(root,qt,parent,q0,q1,q2,bp,
614 >                                scale,sfunc,n,doneptr);
615 >      }
616 >      /* Add current sample: have all of the information */
617 >      if(rev)
618 >         qt =qtInsert_point_rev(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
619 >      else
620 >         qt = qtInsert_point(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
621 >      
622 >      /* If we allocated memory: free it */
623  
624 <  return(qt);
624 >      if( sptr != s_set)
625 >         free(sptr);
626 >
627 >      return(qt);
628 >  }
629   memerr:
630      error(SYSTEM,"expand_node():Unable to allocate memory");
631  
632   }
633  
634  
635 < double
636 < triangle_normal(n,a,b,c)
637 < double n[3];
638 < double a[3],b[3],c[3];
639 < {
640 <  double ab[3],ac[3];
641 <
642 <  VSUB(ab,b,a);
643 <  normalize(ab);
644 <  VSUB(ac,c,a);
645 <  normalize(ac);
618 <  VCROSS(n,ab,ac);
619 <  return(normalize(n));
620 < }
621 < double on0,on1,on2;
622 < /* Add a triangle to the base array with vertices v1-v2-v3 */
635 > /*
636 > * int
637 > * smAdd_tri(sm,v0_id,v1_id,v2_id,tptr)
638 > *             : Add a triangle to the base array with vertices v0-v1-v2,
639 > *               returns ptr to triangle in tptr
640 > * SM *sm;                   : mesh
641 > * S_ID v0_id,v1_id,v2_id;    : sample ids of triangle vertices
642 > * TRI **tptr;               : ptr to set to triangle
643 > *
644 > *  Allocates and initializes mesh triangle with vertices specified.
645 > */
646   int
647   smAdd_tri(sm, v0_id,v1_id,v2_id,tptr)
648   SM *sm;
649 < int v0_id,v1_id,v2_id;
649 > S_ID v0_id,v1_id,v2_id;
650   TRI **tptr;
651   {
652      int t_id;
653      TRI *t;
654 +
655   #ifdef DEBUG
656      if(v0_id==v1_id || v0_id==v2_id || v1_id==v2_id)
657        error(CONSISTENCY,"smAdd_tri: invalid vertex ids\n");
# Line 639 | Line 663 | TRI **tptr;
663      {
664        double v0[3],v1[3],v2[3],n[3];
665        double area,dp;
666 <
666 >      double ab[3],ac[3];
667        VSUB(v0,SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm));
668        VSUB(v1,SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm));
669        VSUB(v2,SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm));
670        normalize(v0);
671        normalize(v1);
672        normalize(v2);
673 <      area = triangle_normal(n,v2,v1,v0);
673 >
674 >      VSUB(ab,v1,v2);
675 >      normalize(ab);
676 >      VSUB(ac,v0,v2);
677 >      normalize(ac);
678 >      VCROSS(n,ab,ac);
679 >      area = normalize(n);
680        if((dp=DOT(v0,n)) < 0.0)
681        {
652        fprintf(stderr,"dp = %.10f on0=%.10f on1=%.10f on2=%.10f\n", dp,
653                on0,on1,on2);
682          eputs("backwards tri\n");
683        }
684      }
685   #endif
686   #endif
687  
660
688      t = SM_NTH_TRI(sm,t_id);
689 <
689 > #ifdef DEBUG
690      T_CLEAR_NBRS(t);
691 + #endif
692      /* set the triangle vertex ids */
693      T_NTH_V(t,0) = v0_id;
694      T_NTH_V(t,1) = v1_id;
# Line 685 | Line 713 | TRI **tptr;
713      SM_SET_NTH_T_ACTIVE(sm,t_id);
714      SM_SET_NTH_T_NEW(sm,t_id);
715  
688
716      *tptr = t;
717      /* return initialized triangle */
718      return(t_id);
719   }
720  
721  
695 /* pt_in_cone: assumed apex at origin, a,b,c are unit vectors defining the
696   triangle which the cone circumscribes. Assumed p is not normalized
697 */
698 int
699 pt_in_cone(p,a,b,c)
700 double p[3],a[3],b[3],c[3];
701 {
702  double r[3];
703  double pr,ar;
704  double ab[3],ac[3];
705  /* r =  (B-A)X(C-A) */
706  /* in = (p.r) > (a.r) */
722  
708 #ifdef DEBUG
709 #if DEBUG > 1
710 {
711  double l;
712  l = triangle_normal(r,a,b,c);
713  /* l = sin@ between ab,ac - if 0 vectors are colinear */
714  if( l <= COLINEAR_EPS)
715  {
716    eputs("pt in cone: null triangle:returning FALSE\n");
717    return(FALSE);
718  }
719 }
720 #endif
721 #endif
722
723  VSUB(ab,b,a);
724  VSUB(ac,c,a);
725  VCROSS(r,ab,ac);
726
727  pr = DOT(p,r);        
728  ar = DOT(a,r);
729  /* Need to check for equality for degeneracy of 4 points on circle */
730  if( pr > ar *( 1.0 + EQUALITY_EPS))
731    return(TRUE);
732  else
733    return(FALSE);
734 }
735
723   smRestore_Delaunay(sm,a,b,c,t,t_id,a_id,b_id,c_id)
724   SM *sm;
725   FVECT a,b,c;
726   TRI *t;
727   int t_id,a_id,b_id,c_id;
728   {
729 <  int e1,topp_id,p_id;
729 >  int e1,topp_id;
730 >  S_ID p_id;
731    TRI *topp;
732    FVECT p;
733  
# Line 883 | Line 871 | int
871   smTri_next_ccw_nbr(sm,t,id)
872   SM *sm;
873   TRI *t;
874 < int id;
874 > S_ID id;
875   {
876    int which;
877    int nbr_id;
# Line 912 | Line 900 | int id;
900   int
901   smInsert_samp_mesh(sm,s_id,tri_id,a,b,c,d,on,which)
902     SM *sm;
903 <   int s_id,tri_id;
903 >   S_ID s_id;
904 >   int tri_id;
905     FVECT a,b,c,d;
906     int on,which;
907   {
908 <    int v_id[3],topp_id,i;
908 >    S_ID v_id[3],opp_id;
909 >    int topp_id,i;
910      int t0_id,t1_id,t2_id,t3_id;
911 <    int e0,e1,e2,opp_id,opp0,opp1,opp2;
911 >    int e0,e1,e2,opp0,opp1,opp2;
912      TRI *tri,*nbr,*topp,*t0,*t1,*t2,*t3;
913      FVECT e;
914  
# Line 1331 | Line 1321 | FVECT a,b;
1321   {
1322    FVECT n,v0,v1,v2;
1323    TRI *tn;
1324 <
1324 >  double on0,on1,on2;
1325    int tn_id;
1326  
1327   #ifdef DEBUG
# Line 1712 | Line 1702 | FVECT a,b;
1702      if(EQUAL_VEC3(v2,p)){ *o = ON_V; *w = 2; return(t_id);}
1703  
1704  
1705 < int
1705 >
1706   find_neighbor(argptr,qt,f,doneptr)
1707   int *argptr;
1708   QUADTREE qt;
1709   FUNC f;
1710   int *doneptr;
1711   {
1712 <  int s_id,i;
1713 <  OBJECT *optr;
1712 >  S_ID s_id;
1713 >  int i;
1714 >  S_ID *optr;
1715    
1716    if(QT_IS_EMPTY(qt))
1717      return;
# Line 1752 | Line 1743 | int *doneptr;
1743  
1744   smInsert_samp(sm,s_id,p,nptr)
1745   SM *sm;
1746 < int s_id;
1746 > S_ID s_id;
1747   FVECT p;
1748 < int *nptr;
1748 > S_ID *nptr;
1749   {
1750    FVECT tpt;
1751    FUNC f;
# Line 1781 | Line 1772 | int
1772   smSample_locate_tri(sm,p,s_id,onptr,whichptr,nptr)
1773   SM *sm;
1774   FVECT p;
1775 < int s_id;
1776 < int *onptr,*whichptr,*nptr;
1775 > S_ID s_id;
1776 > int *onptr,*whichptr;
1777 > S_ID *nptr;
1778   {
1779    int tri_id;
1780    FVECT tpt;
# Line 1853 | Line 1845 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
1845     SM *sm;
1846     int tri_id;
1847     FVECT dir,p;
1848 <   int *rptr;
1848 >   S_ID *rptr;
1849     FVECT ns,n0,n1,n2;
1850     double ds,d0;
1851     int on,which;
# Line 1861 | Line 1853 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
1853      TRI *tri;
1854      double d,d2,dnear,dspt,d01,d12,d20,s0,s1,s2;
1855      double dp,dp1;
1856 <    int vid[3],i,nearid,norm,dcnt,bcnt;
1856 >    S_ID vid[3];
1857 >    int i,norm,dcnt,bcnt;
1858      FVECT diff[3],spt,npt,n;
1859      FVECT nearpt;
1860  
# Line 1880 | Line 1873 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
1873          if(SM_DIR_ID(sm,vid[i]))
1874            dcnt++;
1875      }
1883    if( on == IN_T)
1884    {
1885      d = DIST_SQ(n0,ns);
1886      dnear = d;
1887      nearid = 0;
1888      d = DIST_SQ(n1,ns);
1889      if(d < dnear)
1890      {
1891        dnear = d; nearid = 1;
1892      }
1893      d = DIST_SQ(n2,ns);
1894      if(d < dnear)
1895      {
1896        dnear = d; nearid = 2;
1897      }
1898    }
1876      if(on == ON_P)
1900      nearid = which;
1901    if(on == ON_P || dnear < VERT_EPS*VERT_EPS)
1877      {
1878        FVECT edir;
1879 <      /* Pick the point with dir closest to that of the canonical view
1880 <         if it is the new sample: mark existing point for deletion
1881 <         */
1907 <      if(SM_BASE_ID(sm,vid[nearid]))
1908 <        return(FALSE);
1879 >     /* Pick the point with dir closest to that of the canonical view
1880 >         if it is the new sample: mark existing point for deletion
1881 >         */
1882        if(!dir)
1883 <        return(FALSE);
1884 <      if(SM_DIR_ID(sm,vid[nearid]))
1883 >        return(FALSE);
1884 >      if(SM_BASE_ID(sm,vid[which]))
1885 >        return(FALSE);
1886 >      if(SM_DIR_ID(sm,vid[which]))
1887        {
1888 <        *rptr = vid[nearid];
1889 <        return(TRUE);
1888 >        *rptr = vid[which];
1889 >        return(TRUE);
1890        }
1891 <      decodedir(edir,SM_NTH_W_DIR(sm,vid[nearid]));
1892 <      if(nearid == 0)
1891 >  decodedir(edir,SM_NTH_W_DIR(sm,vid[which]));
1892 >      if(which == 0)
1893          d = DOT(edir,n0);
1894        else
1895 <        if(nearid == 1)
1895 >        if(which == 1)
1896            d = DOT(edir,n1);
1897          else
1898            d = DOT(edir,n2);
# Line 1928 | Line 1903 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
1903        else
1904        {
1905          /* The new sample is better: mark existing one for deletion*/
1906 <        *rptr = vid[nearid];
1906 >        *rptr = vid[which];
1907          return(TRUE);
1908        }
1909      }  
# Line 2026 | Line 2001 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
2001              
2002      return(FALSE);
2003   }
2004 < int
2004 > S_ID
2005   smReplace_samp(sm,c,dir,p,np,s_id,t_id,o_id,on,which)
2006       SM *sm;
2007       COLR c;
2008       FVECT dir,p,np;
2009 <     int s_id,t_id,o_id,on,which;
2009 >     S_ID s_id;
2010 >     int t_id;
2011 >     S_ID o_id;
2012 >     int on,which;
2013   {
2014 <  int v_id,tri_id;
2014 >  S_ID v_id;
2015 >  int tri_id;
2016    TRI *t,*tri;
2017  
2018    tri = SM_NTH_TRI(sm,t_id);
# Line 2082 | Line 2061 | smReplace_samp(sm,c,dir,p,np,s_id,t_id,o_id,on,which)
2061  
2062   }
2063  
2064 < int
2064 > S_ID
2065   smAlloc_samp(sm)
2066   SM *sm;
2067   {
2068 <  int s_id,replaced,cnt;
2068 >  S_ID s_id;
2069 >  int replaced,cnt;
2070    SAMP *s;
2071    FVECT p;
2072  
# Line 2114 | Line 2094 | SM *sm;
2094          b) coincide with existing edge
2095          c) Fall in existing triangle
2096   */
2097 < int
2097 > S_ID
2098   smAdd_samp(sm,c,dir,p,o_id)
2099     SM *sm;
2100     COLR c;
2101     FVECT dir,p;
2102 <   int o_id;
2102 >   S_ID o_id;
2103   {
2104 <  int t_id,s_id,r_id,on,which,n_id,nbr_id;
2104 >  int t_id,on,which,n_id;
2105 >  S_ID s_id,r_id,nbr_id;
2106    double ds,d0;
2107    FVECT wpt,ns,n0,n1,n2;
2108    QUADTREE qt,parent;
# Line 2131 | Line 2112 | smAdd_samp(sm,c,dir,p,o_id)
2112    nbr_id = INVALID;
2113    /* Must do this first-as may change mesh */
2114    s_id = smAlloc_samp(sm);
2134
2115    SM_S_NTH_QT(sm,s_id)= EMPTY;
2116    /* If sample is a world space point */
2117    if(p)
# Line 2196 | Line 2176 | smAdd_samp(sm,c,dir,p,o_id)
2176      /* If sample is being added in the middle of the sample array: tone
2177         map individually
2178         */
2199    /* Initialize sample */
2200    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id);
2179      /* If not base or sky point, add distance from center to average*/  
2180      smDist_sum += 1.0/ds;
2181 +    /* Initialize sample */
2182 +    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id);
2183      smInsert_samp_mesh(sm,s_id,t_id,ns,n0,n1,n2,on,which);
2184    }
2185      /* If sample is a direction vector */
2186      else
2187      {
2188        VADD(wpt,dir,SM_VIEW_CENTER(sm));
2189 +      /* Allocate space for a sample and initialize */
2190        while(1)
2191        {
2192          t_id = smSample_locate_tri(sm,dir,s_id,&on,&which,&nbr_id);
# Line 2250 | Line 2231 | smAdd_samp(sm,c,dir,p,o_id)
2231          else
2232            break;
2233        }
2253      /* Allocate space for a sample and initialize */
2234        sInit_samp(SM_SAMP(sm),s_id,c,NULL,wpt,o_id);
2235        smInsert_samp_mesh(sm,s_id,t_id,dir,n0,n1,n2,on,which);
2236      }
# Line 2268 | Line 2248 | smAdd_samp(sm,c,dir,p,o_id)
2248   * New sample representation will be output in next call to smUpdate().
2249   * If the point is a sky point: then v=NULL
2250   */
2251 + #define FVECT_TO_SFLOAT(p) \
2252 +        (p[0]=(SFLOAT)p[0],p[1]=(SFLOAT)p[1],p[2]=(SFLOAT)p[2])
2253   int
2254   smNewSamp(c,dir,p)
2255   COLR c;
2256   FVECT dir;
2257   FVECT p;
2258   {
2259 <    int s_id;
2259 >    S_ID s_id;
2260 >
2261      /* First check if this the first sample: if so initialize mesh */
2262      if(SM_NUM_SAMP(smMesh) == 0)
2263      {
2264        smInit_sm(smMesh,odev.v.vp);
2265        sClear_all_flags(SM_SAMP(smMesh));
2266      }
2267 +    FVECT_TO_SFLOAT(p);
2268 +    FVECT_TO_SFLOAT(dir);
2269      /* Add the sample to the mesh */
2270      s_id = smAdd_samp(smMesh,c,dir,p,INVALID);
2271  
2272 < #if 0
2288 <    {
2289 <      int i;
2290 <      FILE *fp;
2291 <      if(s_id == 10000)
2292 <        {
2293 <          fp = fopen("test.xyz","w");
2294 <          for(i=0; i < s_id; i++)
2295 <            if(!SM_DIR_ID(smMesh,i))
2296 <              fprintf(fp,"%f %f %f %d %d %d \n",SM_NTH_WV(smMesh,i)[0],
2297 <                    SM_NTH_WV(smMesh,i)[1],SM_NTH_WV(smMesh,i)[2],
2298 <                    SM_NTH_RGB(smMesh,i)[0],SM_NTH_RGB(smMesh,i)[1],
2299 <                    SM_NTH_RGB(smMesh,i)[2]);
2300 <          fclose(fp);
2301 <        }
2302 <    }
2303 < #endif    
2304 <    return(s_id);
2272 >    return((int)s_id);
2273      
2274   }    
2275 < int
2275 > S_ID
2276   smAdd_base_vertex(sm,v)
2277     SM *sm;
2278     FVECT v;
2279   {
2280 <  int id;
2280 >  S_ID id;
2281  
2282    /* First add coordinate to the sample array */
2283    id = sAdd_base_point(SM_SAMP(sm),v);
# Line 2333 | Line 2301 | SM *sm;
2301   int type;
2302   {
2303    int i,s_id,tri_id,nbr_id;
2304 <  int p[SM_BASE_POINTS],ids[SM_BASE_TRIS];
2305 <  int v0_id,v1_id,v2_id;
2304 >  S_ID p[SM_BASE_POINTS];
2305 >  int ids[SM_BASE_TRIS];
2306 >  S_ID v0_id,v1_id,v2_id;
2307    FVECT d,pt,cntr,v0,v1,v2;
2308    TRI *t;
2309  
2310    /* First insert the base vertices into the sample point array */
2342
2311    for(i=0; i < SM_BASE_POINTS; i++)
2312    {
2313      VADD(cntr,icosa_verts[i],SM_VIEW_CENTER(sm));
# Line 2366 | Line 2334 | smRebuild(sm,v)
2334     SM *sm;
2335     VIEW *v;
2336   {
2337 <    int i,j,cnt;
2337 >    S_ID s_id;
2338 >    int j,cnt;
2339      FVECT p,ov,dir;
2340      double d;
2341  
# Line 2386 | Line 2355 | smRebuild(sm,v)
2355      /* Go through all samples and add in if in the new view frustum, and
2356         the dir is <= 30 degrees from new view
2357       */
2358 <    for(i=0; i < cnt; i++)
2358 >    for(s_id=0; s_id < cnt; s_id++)
2359      {
2360        /* First check if sample visible(conservative approx: if one of tris
2361           attached to sample is in frustum)       */
2362 <      if(!S_IS_FLAG(i))
2362 >      if(!S_IS_FLAG(s_id))
2363          continue;
2364        
2365        /* Next test if direction > 30 degrees from current direction */
2366 <        if(SM_NTH_W_DIR(sm,i)!=-1)
2366 >        if(SM_NTH_W_DIR(sm,s_id)!=-1)
2367          {
2368 <            VSUB(p,SM_NTH_WV(sm,i),v->vp);
2369 <            decodedir(dir,SM_NTH_W_DIR(sm,i));
2368 >            VSUB(p,SM_NTH_WV(sm,s_id),v->vp);
2369 >            decodedir(dir,SM_NTH_W_DIR(sm,s_id));
2370              d = DOT(dir,p);
2371              if (d*d < MAXDIFF2*DOT(p,p))
2372                continue;
2373 <            VCOPY(p,SM_NTH_WV(sm,i));
2374 <            smAdd_samp(sm,NULL,dir,p,i);
2373 >            VCOPY(p,SM_NTH_WV(sm,s_id));
2374 >            smAdd_samp(sm,NULL,dir,p,s_id);
2375          }
2376          else
2377          {
2378            /* If the direction is > 45 degrees from current view direction:
2379               throw out
2380             */
2381 <          VSUB(dir,SM_NTH_WV(sm,i),ov);
2381 >          VSUB(dir,SM_NTH_WV(sm,s_id),ov);
2382            if(DOT(dir,v->vdir) < MAXDIR)
2383              continue;
2384  
2385 <          VADD(SM_NTH_WV(sm,i),dir,SM_VIEW_CENTER(sm));
2386 <          smAdd_samp(sm,NULL,dir,NULL,i);
2385 >          VADD(SM_NTH_WV(sm,s_id),dir,SM_VIEW_CENTER(sm));
2386 >          smAdd_samp(sm,NULL,dir,NULL,s_id);
2387          }
2388  
2389      }
# Line 2423 | Line 2392 | smRebuild(sm,v)
2392   #endif
2393   }
2394  
2426 int
2427 intersect_tri_set(t_set,orig,dir,pt)
2428   OBJECT *t_set;
2429   FVECT orig,dir,pt;
2430 {
2431    OBJECT *optr;
2432    int i,t_id,id,base;
2433    int pid0,pid1,pid2;
2434    FVECT p0,p1,p2,p;
2435    TRI *t;
2436    double d,d1;
2437    
2438    optr = t_set;
2439    for(i = QT_SET_CNT(t_set); i > 0; i--)
2440    {
2441        t_id = QT_SET_NEXT_ELEM(optr);
2442        t = SM_NTH_TRI(smMesh,t_id);
2443        if(!T_IS_VALID(t) || SM_IS_NTH_T_BASE(smMesh,t_id)||
2444               SM_IS_NTH_T_BG(smMesh,t_id))
2445          continue;
2446        pid0 = T_NTH_V(t,0);
2447        pid1 = T_NTH_V(t,1);
2448        pid2 = T_NTH_V(t,2);
2449        VCOPY(p0,SM_NTH_WV(smMesh,pid0));
2450        VCOPY(p1,SM_NTH_WV(smMesh,pid1));
2451        VCOPY(p2,SM_NTH_WV(smMesh,pid2));
2452        if(ray_intersect_tri(orig,dir,p0,p1,p2,p))
2453        {
2454          d =  DIST_SQ(p,p0);
2455          d1 = DIST_SQ(p,p1);
2456          if(d < d1)
2457           {
2458             d1 = DIST_SQ(p,p2);
2459             id = (d1 < d)?pid2:pid0;
2460           }
2461          else
2462            {
2463              d = DIST_SQ(p,p2);
2464              id = (d < d1)? pid2:pid1;
2465            }
2466          if(pt)
2467            VCOPY(pt,p);
2468 #ifdef TEST_DRIVER
2469          Pick_tri = t_id;
2470          Pick_samp = id;
2471          VCOPY(Pick_point[0],p);
2472 #endif
2473          return(id);
2474        }
2475    }
2476    return(-1);
2477 }
2478
2395   /* OS is constrained to be <= QT_MAXCSET : if the set exceeds this, the
2396   results of check_set are conservative
2397   */
2398   int
2399   compare_ids(id1,id2)
2400 < OBJECT *id1,*id2;
2400 > S_ID *id1,*id2;
2401   {
2402    int d;
2403  
# Line 2495 | Line 2411 | OBJECT *id1,*id2;
2411    return(0);
2412   }
2413  
2498 ray_trace_check_set(qt,argptr,fptr)
2499   QUADTREE qt;
2500   RT_ARGS *argptr;
2501   int *fptr;
2502 {
2503    OBJECT tset[QT_MAXSET+1],*tptr;    
2504    double dt,t;
2505    int found;
2506  if(QT_IS_EMPTY(qt))
2507    return;
2508  if(QT_LEAF_IS_FLAG(qt))
2509  {
2510    QT_FLAG_SET_DONE(*fptr);
2511 #if DEBUG
2512       eputs("ray_trace_check_set():Already visited this node:aborting\n");
2513 #endif
2514       return;
2515  }
2516  else
2517    QT_LEAF_SET_FLAG(qt);
2414  
2519  tptr = qtqueryset(qt);
2520  if(QT_SET_CNT(tptr) > QT_MAXSET)
2521    tptr = (OBJECT *)malloc((QT_SET_CNT(tptr)+1)*sizeof(OBJECT));
2522  else
2523    tptr = tset;
2524  if(!tptr)
2525    goto memerr;
2526    
2527  qtgetset(tptr,qt);
2528  /* Must sort */
2529  qsort((void *)(&(tptr[1])),tptr[0],sizeof(OBJECT),compare_ids);
2530  /* Check triangles in set against those seen so far(os):only
2531     check new triangles for intersection (t_set')  
2532     */
2533  check_set_large(tptr,argptr->os);
2534
2535  if(!QT_SET_CNT(tptr))
2536    return;
2537  found = intersect_tri_set(tptr,argptr->orig,argptr->dir,NULL);
2538  if(tptr != tset)
2539    free(tptr);
2540  if(found != INVALID)
2541  {
2542    argptr->t_id = found;
2543    QT_FLAG_SET_DONE(*fptr);
2544  }
2545  return;
2546 memerr:
2547    error(SYSTEM,"ray_trace_check_set():Unable to allocate memory");
2548 }
2549
2550
2551 /*
2552 * int
2553 * smFindSamp(FVECT orig, FVECT dir)
2554 *
2555 * Find the closest sample to the given ray.  Returns sample id, -1 on failure.
2556 * "dir" is assumed to be normalized
2557 */
2558
2559 int
2560 smFindSamp(orig,dir)
2561 FVECT orig,dir;
2562 {
2563  FVECT b,p,o;
2564  OBJECT *ts;
2565  QUADTREE qt;
2566  int s_id,test;
2567  double d;
2568
2569 /*  r is the normalized vector from the view center to the current
2570  *  ray point ( starting with "orig"). Find the cell that r falls in,
2571  *  and test the ray against all triangles stored in the cell. If
2572  *  the test fails, trace the projection of the ray across to the
2573  *  next cell it intersects: iterate until either an intersection
2574  *  is found, or the projection ray is // to the direction. The sample
2575  *  corresponding to the triangle vertex closest to the intersection
2576  *  point is returned.
2577  */
2578  
2579  /* First test if "orig" coincides with the View_center or if "dir" is
2580     parallel to r formed by projecting "orig" on the sphere. In
2581     either case, do a single test against the cell containing the
2582     intersection of "dir" and the sphere
2583   */
2584  /* orig will be updated-so preserve original value */
2585  if(!smMesh)
2586     return;
2587
2588  if(EQUAL_VEC3(orig,SM_VIEW_CENTER(smMesh)))
2589  {
2590    qt = smPoint_locate_cell(smMesh,dir);
2591    if(QT_IS_EMPTY(qt))
2592      goto Lerror;
2593    ts = qtqueryset(qt);
2594    s_id = intersect_tri_set(ts,orig,dir,p);
2595    return(s_id);
2596  }
2597  d = point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh));
2598  if(EQUAL_VEC3(b,dir))
2599  {
2600    qt = smPoint_locate_cell(smMesh,dir);
2601    if(QT_IS_EMPTY(qt))
2602      goto Lerror;
2603    ts = qtqueryset(qt);
2604    s_id = intersect_tri_set(ts,orig,dir,p);
2605    return(s_id);
2606  }
2607  if(OPP_EQUAL_VEC3(b,dir))
2608  {
2609    qt = smPoint_locate_cell(smMesh,orig);
2610    if(QT_IS_EMPTY(qt))
2611      goto Lerror;
2612    ts = qtqueryset(qt);
2613    s_id = intersect_tri_set(ts,orig,dir,p);
2614    if(s_id != INVALID)
2615     {
2616 #ifdef DEBUG
2617    fprintf(stderr,"Front pick returning %d\n",s_id);
2618 #endif
2619          return(s_id);
2620     }
2621    qt = smPoint_locate_cell(smMesh,dir);
2622    if(QT_IS_EMPTY(qt))
2623      goto Lerror;
2624    ts = qtqueryset(qt);
2625    s_id = intersect_tri_set(ts,orig,dir,p);
2626 #ifdef DEBUG
2627    fprintf(stderr,"Back pick returning %d\n",s_id);
2628 #endif
2629    return(s_id);
2630  }
2631  {
2632    OBJECT t_set[QT_MAXCSET + 1];
2633    RT_ARGS rt;
2634    FUNC func;
2635
2636    /* Test each of the root triangles against point id */
2637    QT_CLEAR_SET(t_set);
2638    VSUB(o,orig,SM_VIEW_CENTER(smMesh));
2639    ST_CLEAR_FLAGS(SM_LOCATOR(smMesh));
2640    rt.t_id = -1;
2641    rt.os = t_set;
2642    VCOPY(rt.orig,orig);
2643    VCOPY(rt.dir,dir);
2644    F_FUNC(func) = ray_trace_check_set;
2645    F_ARGS(func) = (int *)(&rt);
2646    stTrace_ray(SM_LOCATOR(smMesh),o,dir,func);
2647    s_id = rt.t_id;
2648
2649  }    
2650  return(s_id);
2651
2652 Lerror:
2653 #ifdef DEBUG
2654  eputs("smFindSamp(): point not found");
2655 #endif  
2656  return(INVALID);
2657
2658 }
2659
2415   null_func(argptr,root,qt,n)
2416       int *argptr;
2417       int root;
# Line 2672 | Line 2427 | mark_active_samples(argptr,root,qt,n)
2427       QUADTREE qt;
2428       int n;
2429   {
2430 <  OBJECT *os;
2431 <  register int i,s_id,t_id,tri_id;
2430 >  S_ID *os,s_id;
2431 >  register int i,t_id,tri_id;
2432    TRI *tri;
2433  
2434    if(QT_IS_EMPTY(qt) || QT_LEAF_IS_FLAG(qt))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines