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.19 by schorsch, Mon Jun 30 14:59:12 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   */
7 +
8 + #include <string.h>
9 +
10   #include "standard.h"
11   #include "sm_flag.h"
12   #include "sm_list.h"
13   #include "sm_geom.h"
14   #include "sm.h"
15  
16
17
16   SM *smMesh = NULL;
17   double smDist_sum=0;
18  
# Line 243 | Line 241 | tempbuf(len,resize)                    /* get a temporary buffer */
241   unsigned  len;
242   int resize;
243   {
246  extern char  *malloc(), *realloc();
244    static char  *tempbuf = NULL;
245    static unsigned  tempbuflen = 0;
246  
# Line 263 | Line 260 | int resize;
260   #endif
261          if (len > tempbuflen) {
262                  if (tempbuflen > 0)
263 <                        tempbuf = realloc(tempbuf, len);
263 >                        tempbuf = realloc((void *)tempbuf, len);
264                  else
265                          tempbuf = malloc(len);
266                  tempbuflen = tempbuf==NULL ? 0 : len;
# Line 277 | Line 274 | int resize;
274   smDir(sm,ps,id)
275     SM *sm;
276     FVECT ps;
277 <   int id;
277 >   S_ID id;
278   {
279      VSUB(ps,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
280      normalize(ps);
# Line 291 | Line 288 | int which;
288  
289    if(which== -1)
290      for(i=0; i < T_FLAGS;i++)
291 <      bzero(SM_NTH_FLAGS(sm,i),FLAG_BYTES(SM_MAX_TRIS(sm)));
291 >      memset(SM_NTH_FLAGS(sm,i), '\0', FLAG_BYTES(SM_MAX_TRIS(sm)));
292    else
293 <    bzero(SM_NTH_FLAGS(sm,which),FLAG_BYTES(SM_MAX_TRIS(sm)));
293 >    memset(SM_NTH_FLAGS(sm,which), '\0', FLAG_BYTES(SM_MAX_TRIS(sm)));
294   }
295  
296   /* Given an allocated mesh- initialize */
# Line 333 | Line 330 | int max_verts,max_tris;
330        goto memerr;
331  
332      for(i=0; i< T_FLAGS; i++)
333 <      if(!(SM_NTH_FLAGS(sm,i)=(int4 *)malloc(fbytes)))
333 >      if(!(SM_NTH_FLAGS(sm,i)=(int32 *)malloc(fbytes)))
334          goto memerr;
335  
336      SM_MAX_VERTS(sm) = max_verts;
# Line 347 | Line 344 | memerr:
344   }
345  
346  
347 + /*
348 + * smAlloc_tri(sm) : Allocate a new mesh triangle
349 + * SM *sm;                    : mesh
350 + *
351 + *  Returns ptr to next available tri
352 + */
353   int
354   smAlloc_tri(sm)
355   SM *sm;
# Line 367 | Line 370 | SM *sm;
370    return(INVALID);
371   }
372  
373 +
374   smFree_mesh(sm)
375   SM *sm;
376   {
# Line 379 | Line 383 | SM *sm;
383        free(SM_NTH_FLAGS(sm,i));
384   }
385  
386 <  
387 < /* Initialize/clear global smL sample list for at least n samples */
386 >
387 > /*
388 > * smAlloc(max_samples) : Initialize/clear global sample list for at least
389 > *                       max_samples
390 > * int max_samples;    
391 > *
392 > */
393   smAlloc(max_samples)
394     register int max_samples;
395   {
# Line 395 | Line 404 | smAlloc(max_samples)
404    {
405      if(!(smMesh = (SM *)malloc(sizeof(SM))))
406         error(SYSTEM,"smAlloc():Unable to allocate memory\n");
407 <    bzero(smMesh,sizeof(SM));
407 >    memset(smMesh, '\0', sizeof(SM));
408    }
409    else
410    {   /* If existing structure: first deallocate */
# Line 429 | Line 438 | smInit_sm(sm,vp)
438   SM *sm;
439   FVECT vp;
440   {
432
441    VCOPY(SM_VIEW_CENTER(sm),vp);
442    smClear(sm);
443    smCreate_base_mesh(sm,SM_DEFAULT);
# Line 445 | Line 453 | FVECT vp;
453   * If n is <= 0, then clear data structures.  Returns number samples
454   * actually allocated.
455   */
448
456   int
457   smInit(n)
458     register int n;
459   {
460    int max_vertices;
461 <
461 >  sleep(5);
462    /* If n <=0, Just clear the existing structures */
463    if(n <= 0)
464    {
# Line 505 | Line 512 | smLocator_apply(sm,v0,v1,v2,func,n)
512  
513   }
514  
515 + /*
516 + * QUADTREE
517 + * insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,rev,f,n,doneptr)
518 + *     Callback function called from quadtree traversal when leaf is reached
519 + *   int *argptr;                 :ptr to sample id number
520 + *   int root;                    :quadtree root from which traversal started
521 + *   QUADTREE qt,parent;          :current quadtree node and its parent
522 + *   BCOORD q0[3],q1[3],q2[3],bc[3]; :barycentric coordinates of the current
523 + *                                 quadtree node (q0,q1,q2) and sample (bc)
524 + *   unsigned int scale,rev;      :scale factor relative to which level at in
525 + *                                 tree, rev indicates if traversed of child 3
526 + *   FUNC f;                      :function structure so can recurse
527 + *   int n,*doneptr;              :n indicates which level at in quadtree, and
528 + *                                 doneptr can be set to indicate whether nbr
529 + *                                 sample has been found
530 + */
531   QUADTREE
532   insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,rev,f,n,doneptr)
533       int *argptr;
# Line 515 | Line 538 | insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,re
538       FUNC f;
539       int n,*doneptr;
540   {
541 <  OBJECT *optr,*sptr,s_set[QT_MAXSET+1];
542 <  int i,s_id;
520 <  FVECT p;
521 <  BCOORD bp[3];
522 <  FUNC sfunc;
523 <  S_ARGS args;
541 >  S_ID s_id;
542 >  S_ID *optr;
543  
544    s_id = ((S_ARGS *)argptr)->s_id;
545    /* If the set is empty - just add */
# Line 557 | Line 576 | insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,re
576    /* otherwise: expand node- and insert sample, and reinsert existing samples
577       in set to children of new node
578    */
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--)
579    {
580 <    s_id = QT_SET_NEXT_ELEM(optr);
581 <    args.s_id = s_id;
582 <    VSUB(p,SM_NTH_WV(smMesh,s_id),SM_VIEW_CENTER(smMesh));
583 <    normalize(p);
584 <    vert_to_qt_frame(i,p,bp);    
585 <    if(rev)
586 <      qt= qtInsert_point_rev(root,qt,parent,q0,q1,q2,bp,scale,sfunc,n,doneptr);
587 <    else
588 <      qt= qtInsert_point(root,qt,parent,q0,q1,q2,bp,scale,sfunc,n,doneptr);
589 <  }
590 <  /* Add current sample: have all of the information */
591 <  if(rev)
592 <    qt =qtInsert_point_rev(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
593 <  else
593 <    qt = qtInsert_point(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
594 <  
595 <  /* If we allocated memory: free it */
580 >      OBJECT *sptr,s_set[QT_MAXSET+1];
581 >      FUNC sfunc;
582 >      S_ARGS args;
583 >      FVECT p;
584 >      BCOORD bp[3];
585 >      int i;
586 >      
587 >      if(QT_SET_CNT(optr) > QT_MAXSET)
588 >      {
589 >          if(!(sptr = (OBJECT *)malloc((QT_SET_CNT(optr)+1)*sizeof(OBJECT))))
590 >             goto memerr;
591 >      }
592 >      else
593 >         sptr = s_set;
594  
595 <  if( sptr != s_set)
596 <    free(sptr);
595 >      qtgetset(sptr,qt);
596 >      
597 >      /* subdivide node */
598 >      qtfreeleaf(qt);
599 >      qtSubdivide(qt);
600 >      
601 >      /* Now add in all of the rest; */
602 >      F_FUNC(sfunc) = F_FUNC(f);
603 >      F_ARGS(sfunc) = (int *) (&args);
604 >      args.n_id = 0;
605 >      for(optr = sptr,i=QT_SET_CNT(sptr); i > 0; i--)
606 >      {
607 >          s_id = QT_SET_NEXT_ELEM(optr);
608 >          args.s_id = s_id;
609 >          VSUB(p,SM_NTH_WV(smMesh,s_id),SM_VIEW_CENTER(smMesh));
610 >          normalize(p);
611 >          vert_to_qt_frame(i,p,bp);    
612 >          if(rev)
613 >             qt= qtInsert_point_rev(root,qt,parent,q0,q1,q2,bp,
614 >                                    scale,sfunc,n,doneptr);
615 >          else
616 >             qt= qtInsert_point(root,qt,parent,q0,q1,q2,bp,
617 >                                scale,sfunc,n,doneptr);
618 >      }
619 >      /* Add current sample: have all of the information */
620 >      if(rev)
621 >         qt =qtInsert_point_rev(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
622 >      else
623 >         qt = qtInsert_point(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr);
624 >      
625 >      /* If we allocated memory: free it */
626  
627 <  return(qt);
627 >      if( sptr != s_set)
628 >         free(sptr);
629 >
630 >      return(qt);
631 >  }
632   memerr:
633      error(SYSTEM,"expand_node():Unable to allocate memory");
634  
635   }
636  
637  
638 < double
639 < triangle_normal(n,a,b,c)
640 < double n[3];
641 < double a[3],b[3],c[3];
642 < {
643 <  double ab[3],ac[3];
644 <
645 <  VSUB(ab,b,a);
646 <  normalize(ab);
647 <  VSUB(ac,c,a);
648 <  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 */
638 > /*
639 > * int
640 > * smAdd_tri(sm,v0_id,v1_id,v2_id,tptr)
641 > *             : Add a triangle to the base array with vertices v0-v1-v2,
642 > *               returns ptr to triangle in tptr
643 > * SM *sm;                   : mesh
644 > * S_ID v0_id,v1_id,v2_id;    : sample ids of triangle vertices
645 > * TRI **tptr;               : ptr to set to triangle
646 > *
647 > *  Allocates and initializes mesh triangle with vertices specified.
648 > */
649   int
650   smAdd_tri(sm, v0_id,v1_id,v2_id,tptr)
651   SM *sm;
652 < int v0_id,v1_id,v2_id;
652 > S_ID v0_id,v1_id,v2_id;
653   TRI **tptr;
654   {
655      int t_id;
656      TRI *t;
657 +
658   #ifdef DEBUG
659      if(v0_id==v1_id || v0_id==v2_id || v1_id==v2_id)
660        error(CONSISTENCY,"smAdd_tri: invalid vertex ids\n");
# Line 639 | Line 666 | TRI **tptr;
666      {
667        double v0[3],v1[3],v2[3],n[3];
668        double area,dp;
669 <
669 >      double ab[3],ac[3];
670        VSUB(v0,SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm));
671        VSUB(v1,SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm));
672        VSUB(v2,SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm));
673        normalize(v0);
674        normalize(v1);
675        normalize(v2);
676 <      area = triangle_normal(n,v2,v1,v0);
676 >
677 >      VSUB(ab,v1,v2);
678 >      normalize(ab);
679 >      VSUB(ac,v0,v2);
680 >      normalize(ac);
681 >      VCROSS(n,ab,ac);
682 >      area = normalize(n);
683        if((dp=DOT(v0,n)) < 0.0)
684        {
652        fprintf(stderr,"dp = %.10f on0=%.10f on1=%.10f on2=%.10f\n", dp,
653                on0,on1,on2);
685          eputs("backwards tri\n");
686        }
687      }
688   #endif
689   #endif
690  
660
691      t = SM_NTH_TRI(sm,t_id);
692 <
692 > #ifdef DEBUG
693      T_CLEAR_NBRS(t);
694 + #endif
695      /* set the triangle vertex ids */
696      T_NTH_V(t,0) = v0_id;
697      T_NTH_V(t,1) = v1_id;
# Line 685 | Line 716 | TRI **tptr;
716      SM_SET_NTH_T_ACTIVE(sm,t_id);
717      SM_SET_NTH_T_NEW(sm,t_id);
718  
688
719      *tptr = t;
720      /* return initialized triangle */
721      return(t_id);
722   }
723  
724  
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) */
725  
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
726   smRestore_Delaunay(sm,a,b,c,t,t_id,a_id,b_id,c_id)
727   SM *sm;
728   FVECT a,b,c;
729   TRI *t;
730   int t_id,a_id,b_id,c_id;
731   {
732 <  int e1,topp_id,p_id;
732 >  int e1,topp_id;
733 >  S_ID p_id;
734    TRI *topp;
735    FVECT p;
736  
# Line 883 | Line 874 | int
874   smTri_next_ccw_nbr(sm,t,id)
875   SM *sm;
876   TRI *t;
877 < int id;
877 > S_ID id;
878   {
879    int which;
880    int nbr_id;
# Line 912 | Line 903 | int id;
903   int
904   smInsert_samp_mesh(sm,s_id,tri_id,a,b,c,d,on,which)
905     SM *sm;
906 <   int s_id,tri_id;
906 >   S_ID s_id;
907 >   int tri_id;
908     FVECT a,b,c,d;
909     int on,which;
910   {
911 <    int v_id[3],topp_id,i;
911 >    S_ID v_id[3],opp_id;
912 >    int topp_id,i;
913      int t0_id,t1_id,t2_id,t3_id;
914 <    int e0,e1,e2,opp_id,opp0,opp1,opp2;
914 >    int e0,e1,e2,opp0,opp1,opp2;
915      TRI *tri,*nbr,*topp,*t0,*t1,*t2,*t3;
916      FVECT e;
917  
# Line 1331 | Line 1324 | FVECT a,b;
1324   {
1325    FVECT n,v0,v1,v2;
1326    TRI *tn;
1327 <
1327 >  double on0,on1,on2;
1328    int tn_id;
1329  
1330   #ifdef DEBUG
# Line 1712 | Line 1705 | FVECT a,b;
1705      if(EQUAL_VEC3(v2,p)){ *o = ON_V; *w = 2; return(t_id);}
1706  
1707  
1708 < int
1708 >
1709   find_neighbor(argptr,qt,f,doneptr)
1710   int *argptr;
1711   QUADTREE qt;
1712   FUNC f;
1713   int *doneptr;
1714   {
1715 <  int s_id,i;
1716 <  OBJECT *optr;
1715 >  S_ID s_id;
1716 >  int i;
1717 >  S_ID *optr;
1718    
1719    if(QT_IS_EMPTY(qt))
1720      return;
# Line 1752 | Line 1746 | int *doneptr;
1746  
1747   smInsert_samp(sm,s_id,p,nptr)
1748   SM *sm;
1749 < int s_id;
1749 > S_ID s_id;
1750   FVECT p;
1751 < int *nptr;
1751 > S_ID *nptr;
1752   {
1753    FVECT tpt;
1754    FUNC f;
# Line 1781 | Line 1775 | int
1775   smSample_locate_tri(sm,p,s_id,onptr,whichptr,nptr)
1776   SM *sm;
1777   FVECT p;
1778 < int s_id;
1779 < int *onptr,*whichptr,*nptr;
1778 > S_ID s_id;
1779 > int *onptr,*whichptr;
1780 > S_ID *nptr;
1781   {
1782    int tri_id;
1783    FVECT tpt;
# Line 1853 | Line 1848 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
1848     SM *sm;
1849     int tri_id;
1850     FVECT dir,p;
1851 <   int *rptr;
1851 >   S_ID *rptr;
1852     FVECT ns,n0,n1,n2;
1853     double ds,d0;
1854     int on,which;
# Line 1861 | Line 1856 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
1856      TRI *tri;
1857      double d,d2,dnear,dspt,d01,d12,d20,s0,s1,s2;
1858      double dp,dp1;
1859 <    int vid[3],i,nearid,norm,dcnt,bcnt;
1859 >    S_ID vid[3];
1860 >    int i,norm,dcnt,bcnt;
1861      FVECT diff[3],spt,npt,n;
1862      FVECT nearpt;
1863  
# Line 1880 | Line 1876 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
1876          if(SM_DIR_ID(sm,vid[i]))
1877            dcnt++;
1878      }
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    }
1879      if(on == ON_P)
1900      nearid = which;
1901    if(on == ON_P || dnear < VERT_EPS*VERT_EPS)
1880      {
1881        FVECT edir;
1882 <      /* Pick the point with dir closest to that of the canonical view
1883 <         if it is the new sample: mark existing point for deletion
1884 <         */
1907 <      if(SM_BASE_ID(sm,vid[nearid]))
1908 <        return(FALSE);
1882 >     /* Pick the point with dir closest to that of the canonical view
1883 >         if it is the new sample: mark existing point for deletion
1884 >         */
1885        if(!dir)
1886 <        return(FALSE);
1887 <      if(SM_DIR_ID(sm,vid[nearid]))
1886 >        return(FALSE);
1887 >      if(SM_BASE_ID(sm,vid[which]))
1888 >        return(FALSE);
1889 >      if(SM_DIR_ID(sm,vid[which]))
1890        {
1891 <        *rptr = vid[nearid];
1892 <        return(TRUE);
1891 >        *rptr = vid[which];
1892 >        return(TRUE);
1893        }
1894 <      decodedir(edir,SM_NTH_W_DIR(sm,vid[nearid]));
1895 <      if(nearid == 0)
1894 >  decodedir(edir,SM_NTH_W_DIR(sm,vid[which]));
1895 >      if(which == 0)
1896          d = DOT(edir,n0);
1897        else
1898 <        if(nearid == 1)
1898 >        if(which == 1)
1899            d = DOT(edir,n1);
1900          else
1901            d = DOT(edir,n2);
# Line 1928 | Line 1906 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
1906        else
1907        {
1908          /* The new sample is better: mark existing one for deletion*/
1909 <        *rptr = vid[nearid];
1909 >        *rptr = vid[which];
1910          return(TRUE);
1911        }
1912      }  
# Line 2026 | Line 2004 | smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,
2004              
2005      return(FALSE);
2006   }
2007 < int
2007 > S_ID
2008   smReplace_samp(sm,c,dir,p,np,s_id,t_id,o_id,on,which)
2009       SM *sm;
2010       COLR c;
2011       FVECT dir,p,np;
2012 <     int s_id,t_id,o_id,on,which;
2012 >     S_ID s_id;
2013 >     int t_id;
2014 >     S_ID o_id;
2015 >     int on,which;
2016   {
2017 <  int v_id,tri_id;
2017 >  S_ID v_id;
2018 >  int tri_id;
2019    TRI *t,*tri;
2020  
2021    tri = SM_NTH_TRI(sm,t_id);
# Line 2082 | Line 2064 | smReplace_samp(sm,c,dir,p,np,s_id,t_id,o_id,on,which)
2064  
2065   }
2066  
2067 < int
2067 > S_ID
2068   smAlloc_samp(sm)
2069   SM *sm;
2070   {
2071 <  int s_id,replaced,cnt;
2071 >  S_ID s_id;
2072 >  int replaced,cnt;
2073    SAMP *s;
2074    FVECT p;
2075  
# Line 2114 | Line 2097 | SM *sm;
2097          b) coincide with existing edge
2098          c) Fall in existing triangle
2099   */
2100 < int
2100 > S_ID
2101   smAdd_samp(sm,c,dir,p,o_id)
2102     SM *sm;
2103     COLR c;
2104     FVECT dir,p;
2105 <   int o_id;
2105 >   S_ID o_id;
2106   {
2107 <  int t_id,s_id,r_id,on,which,n_id,nbr_id;
2107 >  int t_id,on,which,n_id;
2108 >  S_ID s_id,r_id,nbr_id;
2109    double ds,d0;
2110    FVECT wpt,ns,n0,n1,n2;
2111    QUADTREE qt,parent;
# Line 2131 | Line 2115 | smAdd_samp(sm,c,dir,p,o_id)
2115    nbr_id = INVALID;
2116    /* Must do this first-as may change mesh */
2117    s_id = smAlloc_samp(sm);
2134
2118    SM_S_NTH_QT(sm,s_id)= EMPTY;
2119    /* If sample is a world space point */
2120    if(p)
# Line 2196 | Line 2179 | smAdd_samp(sm,c,dir,p,o_id)
2179      /* If sample is being added in the middle of the sample array: tone
2180         map individually
2181         */
2199    /* Initialize sample */
2200    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id);
2182      /* If not base or sky point, add distance from center to average*/  
2183      smDist_sum += 1.0/ds;
2184 +    /* Initialize sample */
2185 +    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id);
2186      smInsert_samp_mesh(sm,s_id,t_id,ns,n0,n1,n2,on,which);
2187    }
2188      /* If sample is a direction vector */
2189      else
2190      {
2191        VADD(wpt,dir,SM_VIEW_CENTER(sm));
2192 +      /* Allocate space for a sample and initialize */
2193        while(1)
2194        {
2195          t_id = smSample_locate_tri(sm,dir,s_id,&on,&which,&nbr_id);
# Line 2250 | Line 2234 | smAdd_samp(sm,c,dir,p,o_id)
2234          else
2235            break;
2236        }
2253      /* Allocate space for a sample and initialize */
2237        sInit_samp(SM_SAMP(sm),s_id,c,NULL,wpt,o_id);
2238        smInsert_samp_mesh(sm,s_id,t_id,dir,n0,n1,n2,on,which);
2239      }
# Line 2268 | Line 2251 | smAdd_samp(sm,c,dir,p,o_id)
2251   * New sample representation will be output in next call to smUpdate().
2252   * If the point is a sky point: then v=NULL
2253   */
2254 + #define FVECT_TO_SFLOAT(p) \
2255 +        (p[0]=(SFLOAT)p[0],p[1]=(SFLOAT)p[1],p[2]=(SFLOAT)p[2])
2256   int
2257   smNewSamp(c,dir,p)
2258   COLR c;
2259   FVECT dir;
2260   FVECT p;
2261   {
2262 <    int s_id;
2262 >    S_ID s_id;
2263 >
2264      /* First check if this the first sample: if so initialize mesh */
2265      if(SM_NUM_SAMP(smMesh) == 0)
2266      {
2267        smInit_sm(smMesh,odev.v.vp);
2268        sClear_all_flags(SM_SAMP(smMesh));
2269      }
2270 +    FVECT_TO_SFLOAT(p);
2271 +    FVECT_TO_SFLOAT(dir);
2272      /* Add the sample to the mesh */
2273      s_id = smAdd_samp(smMesh,c,dir,p,INVALID);
2274  
2275 < #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);
2275 >    return((int)s_id);
2276      
2277   }    
2278 < int
2278 > S_ID
2279   smAdd_base_vertex(sm,v)
2280     SM *sm;
2281     FVECT v;
2282   {
2283 <  int id;
2283 >  S_ID id;
2284  
2285    /* First add coordinate to the sample array */
2286    id = sAdd_base_point(SM_SAMP(sm),v);
# Line 2333 | Line 2304 | SM *sm;
2304   int type;
2305   {
2306    int i,s_id,tri_id,nbr_id;
2307 <  int p[SM_BASE_POINTS],ids[SM_BASE_TRIS];
2308 <  int v0_id,v1_id,v2_id;
2307 >  S_ID p[SM_BASE_POINTS];
2308 >  int ids[SM_BASE_TRIS];
2309 >  S_ID v0_id,v1_id,v2_id;
2310    FVECT d,pt,cntr,v0,v1,v2;
2311    TRI *t;
2312  
2313    /* First insert the base vertices into the sample point array */
2342
2314    for(i=0; i < SM_BASE_POINTS; i++)
2315    {
2316      VADD(cntr,icosa_verts[i],SM_VIEW_CENTER(sm));
# Line 2366 | Line 2337 | smRebuild(sm,v)
2337     SM *sm;
2338     VIEW *v;
2339   {
2340 <    int i,j,cnt;
2340 >    S_ID s_id;
2341 >    int j,cnt;
2342      FVECT p,ov,dir;
2343      double d;
2344  
# Line 2386 | Line 2358 | smRebuild(sm,v)
2358      /* Go through all samples and add in if in the new view frustum, and
2359         the dir is <= 30 degrees from new view
2360       */
2361 <    for(i=0; i < cnt; i++)
2361 >    for(s_id=0; s_id < cnt; s_id++)
2362      {
2363        /* First check if sample visible(conservative approx: if one of tris
2364           attached to sample is in frustum)       */
2365 <      if(!S_IS_FLAG(i))
2365 >      if(!S_IS_FLAG(s_id))
2366          continue;
2367        
2368        /* Next test if direction > 30 degrees from current direction */
2369 <        if(SM_NTH_W_DIR(sm,i)!=-1)
2369 >        if(SM_NTH_W_DIR(sm,s_id)!=-1)
2370          {
2371 <            VSUB(p,SM_NTH_WV(sm,i),v->vp);
2372 <            decodedir(dir,SM_NTH_W_DIR(sm,i));
2371 >            VSUB(p,SM_NTH_WV(sm,s_id),v->vp);
2372 >            decodedir(dir,SM_NTH_W_DIR(sm,s_id));
2373              d = DOT(dir,p);
2374              if (d*d < MAXDIFF2*DOT(p,p))
2375                continue;
2376 <            VCOPY(p,SM_NTH_WV(sm,i));
2377 <            smAdd_samp(sm,NULL,dir,p,i);
2376 >            VCOPY(p,SM_NTH_WV(sm,s_id));
2377 >            smAdd_samp(sm,NULL,dir,p,s_id);
2378          }
2379          else
2380          {
2381            /* If the direction is > 45 degrees from current view direction:
2382               throw out
2383             */
2384 <          VSUB(dir,SM_NTH_WV(sm,i),ov);
2384 >          VSUB(dir,SM_NTH_WV(sm,s_id),ov);
2385            if(DOT(dir,v->vdir) < MAXDIR)
2386              continue;
2387  
2388 <          VADD(SM_NTH_WV(sm,i),dir,SM_VIEW_CENTER(sm));
2389 <          smAdd_samp(sm,NULL,dir,NULL,i);
2388 >          VADD(SM_NTH_WV(sm,s_id),dir,SM_VIEW_CENTER(sm));
2389 >          smAdd_samp(sm,NULL,dir,NULL,s_id);
2390          }
2391  
2392      }
# Line 2423 | Line 2395 | smRebuild(sm,v)
2395   #endif
2396   }
2397  
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
2398   /* OS is constrained to be <= QT_MAXCSET : if the set exceeds this, the
2399   results of check_set are conservative
2400   */
2401   int
2402   compare_ids(id1,id2)
2403 < OBJECT *id1,*id2;
2403 > S_ID *id1,*id2;
2404   {
2405    int d;
2406  
# Line 2495 | Line 2414 | OBJECT *id1,*id2;
2414    return(0);
2415   }
2416  
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);
2417  
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
2418   null_func(argptr,root,qt,n)
2419       int *argptr;
2420       int root;
# Line 2672 | Line 2430 | mark_active_samples(argptr,root,qt,n)
2430       QUADTREE qt;
2431       int n;
2432   {
2433 <  OBJECT *os;
2434 <  register int i,s_id,t_id,tri_id;
2433 >  S_ID *os,s_id;
2434 >  register int i,t_id,tri_id;
2435    TRI *tri;
2436  
2437    if(QT_IS_EMPTY(qt) || QT_LEAF_IS_FLAG(qt))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines