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

Comparing ray/src/rt/o_mesh.c (file contents):
Revision 2.3 by greg, Wed Mar 12 04:59:05 2003 UTC vs.
Revision 2.11 by greg, Sat Feb 25 19:49:16 2006 UTC

# Line 21 | Line 21 | static const char RCSid[] = "$Id$";
21  
22   #include  "copyright.h"
23  
24 < #include  "ray.h"
24 > #include <string.h>
25  
26 + #include  "ray.h"
27   #include  "mesh.h"
27
28   #include  "tmesh.h"
29 + #include  "rtotypes.h"
30  
31  
32   #define  EDGE_CACHE_SIZ         251     /* length of mesh edge cache */
# Line 39 | Line 40 | struct EdgeCache {
40          OBJREC          *o;     /* mesh object */
41          MESHINST        *mi;    /* current mesh instance */
42          struct EdgeSide {
43 <                int4    v1i, v2i;       /* vertex indices (lowest first) */
43 >                int32   v1i, v2i;       /* vertex indices (lowest first) */
44                  short   signum;         /* signed volume */
45          }               cache[EDGE_CACHE_SIZ];
46   }       edge_cache;
# Line 52 | Line 53 | OBJREC *o;
53                                          /* get mesh instance */
54          edge_cache.mi = getmeshinst(edge_cache.o = o, IO_ALL);
55                                          /* clear edge cache */
56 <        bzero((void *)edge_cache.cache, sizeof(edge_cache.cache));
56 >        memset((void *)edge_cache.cache, '\0', sizeof(edge_cache.cache));
57   }
58  
59  
60   static int
61 < signed_volume(r, v1, v2)        /* get signed volume for ray and edge */
61 > volume_sign(r, v1, v2)  /* get signed volume for ray and edge */
62   register RAY    *r;
63 < int4            v1, v2;
63 > int32           v1, v2;
64   {
65          int                             reversed = 0;
66          register struct EdgeSide        *ecp;
67          
68          if (v1 > v2) {
69 <                int4    t = v2; v2 = v1; v1 = t;
69 >                int32   t = v2; v2 = v1; v1 = t;
70                  reversed = 1;
71          }
72          ecp = &edge_cache.cache[((v2<<11 ^ v1) & 0x7fffffff) % EDGE_CACHE_SIZ];
73 <        if (ecp->v1i != v1 || ecp->v2i != v2) {
73 >        if ((ecp->v1i != v1) | (ecp->v2i != v2)) {
74                  MESHVERT        tv1, tv2;       /* compute signed volume */
75 +                FVECT           v2d;
76                  double          vol;
77 <                if (!getmeshvert(&tv1, edge_cache.mi->msh, v1, MT_V) ||
77 >                if (!getmeshvert(&tv1, edge_cache.mi->msh, v1, MT_V) |
78                              !getmeshvert(&tv2, edge_cache.mi->msh, v2, MT_V))
79                          objerror(edge_cache.o, INTERNAL,
80 <                                "missing mesh vertex in signed_volume");
80 >                                "missing mesh vertex in volume_sign");
81 >                VSUB(v2d, tv2.v, r->rorg);
82                  vol = (tv1.v[0] - r->rorg[0]) *
83 <                                ( (tv2.v[1] - r->rorg[1])*r->rdir[2] -
81 <                                  (tv2.v[2] - r->rorg[2])*r->rdir[1] );
83 >                                (v2d[1]*r->rdir[2] - v2d[2]*r->rdir[1]);
84                  vol += (tv1.v[1] - r->rorg[1]) *
85 <                                ( (tv2.v[2] - r->rorg[2])*r->rdir[0] -
84 <                                  (tv2.v[0] - r->rorg[0])*r->rdir[2] );
85 >                                (v2d[2]*r->rdir[0] - v2d[0]*r->rdir[2]);
86                  vol += (tv1.v[2] - r->rorg[2]) *
87 <                                ( (tv2.v[0] - r->rorg[0])*r->rdir[1] -
88 <                                  (tv2.v[1] - r->rorg[1])*r->rdir[0] );
89 <                if (vol > .0)
89 <                        ecp->signum = 1;
90 <                else if (vol < .0)
91 <                        ecp->signum = -1;
92 <                else
93 <                        ecp->signum = 0;
87 >                                (v2d[0]*r->rdir[1] - v2d[1]*r->rdir[0]);
88 >                                                /* don't generate 0 */
89 >                ecp->signum = vol > .0 ? 1 : -1;
90                  ecp->v1i = v1;
91                  ecp->v2i = v2;
92          }
# Line 103 | Line 99 | mesh_hit(oset, r)              /* intersect ray with mesh triangle
99   OBJECT  *oset;
100   RAY     *r;
101   {
102 <        int4            tvi[3];
102 >        int32           tvi[3];
103          int             sv1, sv2, sv3;
104          MESHVERT        tv[3];
105 +        OBJECT          tmod;
106          FVECT           va, vb, nrm;
107          double          d;
108          int             i;
109                                          /* check each triangle */
110          for (i = oset[0]; i > 0; i--) {
111 <                if (!getmeshtrivid(tvi, curmsh, oset[i]))
111 >                if (!getmeshtrivid(tvi, &tmod, curmsh, oset[i]))
112                          objerror(edge_cache.o, INTERNAL,
113                                  "missing triangle vertices in mesh_hit");
114 <                sv1 = signed_volume(r, tvi[0], tvi[1]);
115 <                sv2 = signed_volume(r, tvi[1], tvi[2]);
116 <                sv3 = signed_volume(r, tvi[2], tvi[0]);
117 <                if (sv1 != sv2 || sv2 != sv3)   /* compare volume signs */
118 <                        if (sv1 && sv2 && sv3)
119 <                                continue;
114 >                sv1 = volume_sign(r, tvi[0], tvi[1]);
115 >                sv2 = volume_sign(r, tvi[1], tvi[2]);
116 >                sv3 = volume_sign(r, tvi[2], tvi[0]);
117 >                                                /* compare volume signs */
118 >                if ((sv1 != sv2) | (sv2 != sv3))
119 >                        continue;
120                                                  /* compute intersection */
121                  getmeshvert(&tv[0], curmsh, tvi[0], MT_V);
122                  getmeshvert(&tv[1], curmsh, tvi[1], MT_V);
# Line 144 | Line 141 | RAY    *r;
141   }
142  
143  
144 < int
145 < o_mesh(o, r)                    /* compute ray intersection with a mesh */
146 < OBJREC          *o;
147 < register RAY    *r;
144 > extern int
145 > o_mesh(                 /* compute ray intersection with a mesh */
146 >        OBJREC          *o,
147 >        register RAY    *r
148 > )
149   {
150          RAY             rcont;
151          int             flags;
152          MESHVERT        tv[3];
153 <        FLOAT           wt[3];
153 >        OBJECT          tmod;
154 >        RREAL           wt[3];
155          int             i;
156                                          /* get the mesh instance */
157          prep_edge_cache(o);
158                                          /* copy and transform ray */
159 <        copystruct(&rcont, r);
159 >        rcont = *r;
160          multp3(rcont.rorg, r->rorg, curmi->x.b.xfm);
161          multv3(rcont.rdir, r->rdir, curmi->x.b.xfm);
162          for (i = 0; i < 3; i++)
# Line 170 | Line 169 | register RAY   *r;
169                  return(0);                      /* missed */
170          if (rcont.rot * curmi->x.f.sca >= r->rot)
171                  return(0);                      /* not close enough */
173
174        r->robj = objndx(o);            /* record new hit */
175        r->ro = o;
172                                          /* transform ray back */
173          r->rot = rcont.rot * curmi->x.f.sca;
174          multp3(r->rop, rcont.rop, curmi->x.f.xfm);
175          multv3(r->ron, rcont.ron, curmi->x.f.xfm);
176          normalize(r->ron);
177          r->rod = -DOT(r->rdir, r->ron);
178 <                                        /* compute barycentric weights */
179 <        flags = getmeshtri(tv, curmsh, rcont.robj, MT_ALL);
178 >                                        /* get triangle */
179 >        flags = getmeshtri(tv, &tmod, curmsh, rcont.robj, MT_ALL);
180          if (!(flags & MT_V))
181                  objerror(o, INTERNAL, "missing mesh vertices in o_mesh");
182 +        r->robj = objndx(o);            /* set object and material */
183 +        if (o->omod == OVOID && tmod != OVOID) {
184 +                r->ro = getmeshpseudo(curmsh, tmod);
185 +                r->rox = &curmi->x;
186 +        } else
187 +                r->ro = o;
188 +                                        /* compute barycentric weights */
189          if (flags & (MT_N|MT_UV))
190                  if (get_baryc(wt, rcont.rop, tv[0].v, tv[1].v, tv[2].v) < 0) {
191                          objerror(o, WARNING, "bad triangle in o_mesh");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines