19 |
|
#if SHADCACHE /* preemptive shadow checking */ |
20 |
|
|
21 |
|
|
22 |
< |
static void /* cast source ray to first blocker */ |
22 |
> |
static int /* cast source ray to first blocker */ |
23 |
|
castshadow(int sn, FVECT rorg, FVECT rdir) |
24 |
|
{ |
25 |
|
RAY rt; |
28 |
|
VCOPY(rt.rdir, rdir); |
29 |
|
rt.rmax = 0; |
30 |
|
rayorigin(&rt, NULL, PRIMARY, 1.0); |
31 |
< |
if (!localhit(&rt, &thescene)) |
32 |
< |
return; |
33 |
< |
/* pretend we were aimed at source */ |
34 |
< |
rt.crtype |= rt.rtype = SHADOW; |
35 |
< |
rt.rdir[0] = -rt.rdir[0]; |
36 |
< |
rt.rdir[1] = -rt.rdir[1]; |
37 |
< |
rt.rdir[2] = -rt.rdir[2]; |
38 |
< |
rt.rod = -rt.rod; |
39 |
< |
VSUB(rt.rorg, rt.rop, rt.rdir); |
40 |
< |
rt.rot = 1.; |
41 |
< |
rt.rsrc = sn; |
31 |
> |
/* check for intersection */ |
32 |
> |
while (localhit(&rt, &thescene)) { |
33 |
> |
RAY rt1 = rt; /* pretend we were aimed at source */ |
34 |
> |
rt1.crtype |= rt1.rtype = SHADOW; |
35 |
> |
rt1.rdir[0] = -rt.rdir[0]; |
36 |
> |
rt1.rdir[1] = -rt.rdir[1]; |
37 |
> |
rt1.rdir[2] = -rt.rdir[2]; |
38 |
> |
rt1.rod = -rt.rod; |
39 |
> |
VSUB(rt1.rorg, rt.rop, rt.rdir); |
40 |
> |
rt1.rot = 1.; |
41 |
> |
rt1.rsrc = sn; |
42 |
|
/* record blocker */ |
43 |
< |
srcblocker(&rt); |
43 |
> |
if (srcblocker(&rt1)) |
44 |
> |
return(1); |
45 |
> |
/* move past failed blocker */ |
46 |
> |
VSUM(rt.rorg, rt.rop, rt.rdir, FTINY); |
47 |
> |
rayclear(&rt); /* & try again... */ |
48 |
> |
} |
49 |
> |
return(0); /* found no blockers */ |
50 |
|
} |
51 |
|
|
52 |
|
|
53 |
< |
static void /* initialize occlusion cache */ |
53 |
> |
void /* initialize occlusion cache */ |
54 |
|
initobscache(int sn) |
55 |
|
{ |
56 |
|
register SRCREC *srcp = &source[sn]; |
60 |
|
int i, j, k; |
61 |
|
int ax, ax1, ax2; |
62 |
|
|
63 |
+ |
if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL)) |
64 |
+ |
return; /* don't cache these */ |
65 |
|
if (srcp->sflags & SDISTANT) |
66 |
|
cachelen = 4*SHADCACHE*SHADCACHE; |
67 |
|
else if (srcp->sflags & SFLAT) |
69 |
|
else /* spherical distribution */ |
70 |
|
cachelen = SHADCACHE*SHADCACHE*6; |
71 |
|
/* allocate cache */ |
64 |
– |
DCHECK(srcp->obscache != NULL, |
65 |
– |
CONSISTENCY, "initobscache() called twice"); |
72 |
|
srcp->obscache = (OBSCACHE *)malloc(sizeof(OBSCACHE) + |
73 |
|
sizeof(OBJECT)*(cachelen-1)); |
74 |
|
if (srcp->obscache == NULL) |
282 |
|
} |
283 |
|
|
284 |
|
|
285 |
< |
void /* record a source blocker */ |
285 |
> |
int /* record a source blocker */ |
286 |
|
srcblocker(register RAY *r) |
287 |
|
{ |
288 |
|
OBJREC *m; |
289 |
|
|
290 |
|
if (r->robj == OVOID || objptr(r->robj) != r->ro || |
291 |
|
isvolume(r->ro->otype)) |
292 |
< |
return; /* don't record complex blockers */ |
292 |
> |
return(0); /* don't record complex blockers */ |
293 |
|
m = findmaterial(r->ro); |
294 |
|
if (m == NULL) |
295 |
< |
return; /* no material?! */ |
295 |
> |
return(0); /* no material?! */ |
296 |
|
if (!isopaque(m->otype)) |
297 |
< |
return; /* material not a reliable blocker */ |
297 |
> |
return(0); /* material not a reliable blocker */ |
298 |
|
*srcobstructp(r) = r->robj; /* else record obstructor */ |
299 |
+ |
return(1); |
300 |
|
} |
301 |
|
|
302 |
|
|