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.1 by greg, Tue Mar 11 17:08:55 2003 UTC vs.
Revision 2.10 by schorsch, Tue Mar 30 16:13:01 2004 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         109     /* length of mesh edge cache */
32 > #define  EDGE_CACHE_SIZ         251     /* length of mesh edge cache */
33  
34   #define  curmi                  (edge_cache.mi)
35   #define  curmsh                 (curmi->msh)
# 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 */
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) % EDGE_CACHE_SIZ];
72 >        ecp = &edge_cache.cache[((v2<<11 ^ v1) & 0x7fffffff) % EDGE_CACHE_SIZ];
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) ||
78 <                                !getmeshvert(&tv2, edge_cache.mi->msh, v2, 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 signed_volume");
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] -
87 <                                  (tv2.v[1] - r->rorg[1])*r->rdir[0] );
87 >                                (v2d[0]*r->rdir[1] - v2d[1]*r->rdir[0]);
88                  if (vol > .0)
89                          ecp->signum = 1;
90                  else if (vol < .0)
# Line 103 | Line 103 | mesh_hit(oset, r)              /* intersect ray with mesh triangle
103   OBJECT  *oset;
104   RAY     *r;
105   {
106 <        int4            tvi[3];
106 >        int32           tvi[3];
107          int             sv1, sv2, sv3;
108          MESHVERT        tv[3];
109 +        OBJECT          tmod;
110          FVECT           va, vb, nrm;
111          double          d;
112          int             i;
113                                          /* check each triangle */
114          for (i = oset[0]; i > 0; i--) {
115 <                if (!getmeshtrivid(tvi, curmsh, oset[i]))
115 >                if (!getmeshtrivid(tvi, &tmod, curmsh, oset[i]))
116                          objerror(edge_cache.o, INTERNAL,
117 <                                        "missing triangle vertices in mesh_hit");
117 >                                "missing triangle vertices in mesh_hit");
118                  sv1 = signed_volume(r, tvi[0], tvi[1]);
119                  sv2 = signed_volume(r, tvi[1], tvi[2]);
120                  sv3 = signed_volume(r, tvi[2], tvi[0]);
# Line 139 | Line 140 | RAY    *r;
140                  r->rot = d;
141                  VSUM(r->rop, r->rorg, r->rdir, d);
142                  VCOPY(r->ron, nrm);
143 <                /* normalize(r->ron) called in o_mesh() & rod set */
143 >                /* normalize(r->ron) called & r->rod set in o_mesh() */
144          }
145   }
146  
147  
148 < int
149 < o_mesh(o, r)                    /* compute ray intersection with a mesh */
150 < OBJREC          *o;
151 < register RAY    *r;
148 > extern int
149 > o_mesh(                 /* compute ray intersection with a mesh */
150 >        OBJREC          *o,
151 >        register RAY    *r
152 > )
153   {
154          RAY             rcont;
155          int             flags;
156          MESHVERT        tv[3];
157 <        FLOAT           wt[3];
157 >        OBJECT          tmod;
158 >        RREAL           wt[3];
159          int             i;
160                                          /* get the mesh instance */
161          prep_edge_cache(o);
162                                          /* copy and transform ray */
163 <        copystruct(&rcont, r);
163 >        rcont = *r;
164          multp3(rcont.rorg, r->rorg, curmi->x.b.xfm);
165          multv3(rcont.rdir, r->rdir, curmi->x.b.xfm);
166          for (i = 0; i < 3; i++)
# Line 170 | Line 173 | register RAY   *r;
173                  return(0);                      /* missed */
174          if (rcont.rot * curmi->x.f.sca >= r->rot)
175                  return(0);                      /* not close enough */
173
174        r->robj = objndx(o);            /* record new hit */
175        r->ro = o;
176                                          /* transform ray back */
177          r->rot = rcont.rot * curmi->x.f.sca;
178          multp3(r->rop, rcont.rop, curmi->x.f.xfm);
179          multv3(r->ron, rcont.ron, curmi->x.f.xfm);
180          normalize(r->ron);
181          r->rod = -DOT(r->rdir, r->ron);
182 <                                        /* compute barycentric weights */
183 <        flags = getmeshtri(tv, curmsh, rcont.robj, MT_ALL);
182 >                                        /* get triangle */
183 >        flags = getmeshtri(tv, &tmod, curmsh, rcont.robj, MT_ALL);
184          if (!(flags & MT_V))
185                  objerror(o, INTERNAL, "missing mesh vertices in o_mesh");
186 +        r->robj = objndx(o);            /* set object and material */
187 +        if (o->omod == OVOID && tmod != OVOID) {
188 +                r->ro = getmeshpseudo(curmsh, tmod);
189 +                r->rox = &curmi->x;
190 +        } else
191 +                r->ro = o;
192 +                                        /* compute barycentric weights */
193          if (flags & (MT_N|MT_UV))
194                  if (get_baryc(wt, rcont.rop, tv[0].v, tv[1].v, tv[2].v) < 0) {
195                          objerror(o, WARNING, "bad triangle in o_mesh");
# Line 197 | Line 204 | register RAY   *r;
204                  if (normalize(r->pert) != 0.0)
205                          for (i = 0; i < 3; i++)
206                                  r->pert[i] -= r->ron[i];
207 <        }
207 >        } else
208 >                r->pert[0] = r->pert[1] = r->pert[2] = .0;
209 >
210          if (flags & MT_UV)              /* interpolate uv coordinates */
211                  for (i = 0; i < 2; i++)
212                          r->uv[i] = wt[0]*tv[0].uv[i] +
213                                          wt[1]*tv[1].uv[i] +
214                                          wt[2]*tv[2].uv[i];
215 +        else
216 +                r->uv[0] = r->uv[1] = .0;
217  
218                                          /* return hit */
219          return(1);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines