15 |
|
|
16 |
|
#include "random.h" |
17 |
|
|
18 |
+ |
#ifdef SSKIPOPT |
19 |
+ |
/* The following table is used for skipping sources */ |
20 |
+ |
static uby8 *srcskipflags = NULL; /* source inclusion lookup */ |
21 |
+ |
static int ssf_count = 0; /* number of flag entries */ |
22 |
+ |
static int ssf_max = 0; /* current array size */ |
23 |
+ |
static uby8 *ssf_noskip = NULL; /* set of zero flags */ |
24 |
|
|
25 |
< |
static int |
26 |
< |
srcskip( /* pre-emptive test for out-of-range glow */ |
27 |
< |
SRCREC *sp, |
28 |
< |
FVECT orig |
25 |
> |
uby8 *ssf_select = NULL; /* sources we may skip */ |
26 |
> |
|
27 |
> |
/* Find/allocate source skip flag entry (free all if NULL) */ |
28 |
> |
int |
29 |
> |
sskip_rsi(uby8 *flags) |
30 |
> |
{ |
31 |
> |
uby8 *flp; |
32 |
> |
int i; |
33 |
> |
|
34 |
> |
if (flags == NULL) { /* means clear all */ |
35 |
> |
efree(srcskipflags); srcskipflags = NULL; |
36 |
> |
ssf_count = ssf_max = 0; |
37 |
> |
sskip_free(ssf_noskip); |
38 |
> |
sskip_free(ssf_select); |
39 |
> |
return(0); |
40 |
> |
} |
41 |
> |
if (ssf_noskip == NULL) /* first call? */ |
42 |
> |
ssf_noskip = sskip_new(); |
43 |
> |
|
44 |
> |
if (sskip_eq(flags, ssf_noskip)) |
45 |
> |
return(-1); /* nothing to skip */ |
46 |
> |
/* search recent entries */ |
47 |
> |
flp = srcskipflags + ssf_count*SSKIPFLSIZ; |
48 |
> |
for (i = ssf_count; i-- > 0; ) |
49 |
> |
if (sskip_eq(flp -= SSKIPFLSIZ, flags)) |
50 |
> |
return(-2-i); /* found it! */ |
51 |
> |
/* else tack on new entry */ |
52 |
> |
if (ssf_count >= ssf_max) { /* need more space? */ |
53 |
> |
fprintf(stderr, "DEBUG: skip flag array > %d entries (%.2f MBytes)\n", |
54 |
> |
ssf_count, SSKIPFLSIZ/1024./1024.*ssf_count); |
55 |
> |
ssf_max = ssf_count + (ssf_count>>2) + 64; |
56 |
> |
if (ssf_max <= ssf_count && |
57 |
> |
(ssf_max = ssf_count+1024) <= ssf_count) |
58 |
> |
error(SYSTEM, "out of space in sskip_rsi()"); |
59 |
> |
|
60 |
> |
srcskipflags = (uby8 *)erealloc(srcskipflags, |
61 |
> |
ssf_max*SSKIPFLSIZ); |
62 |
> |
} |
63 |
> |
sskip_cpy(srcskipflags + ssf_count*SSKIPFLSIZ, flags); |
64 |
> |
|
65 |
> |
return(-2 - ssf_count++); /* return index (< -1) */ |
66 |
> |
} |
67 |
> |
|
68 |
> |
/* Get skip flags associated with RAY rsrc index (or NULL) */ |
69 |
> |
uby8 * |
70 |
> |
sskip_flags(int rsi) |
71 |
> |
{ |
72 |
> |
if (rsi >= -1) |
73 |
> |
return(ssf_noskip); |
74 |
> |
|
75 |
> |
if ((rsi = -2 - rsi) >= ssf_count) |
76 |
> |
error(CONSISTENCY, "bad index to sskip_flags()"); |
77 |
> |
|
78 |
> |
return(srcskipflags + rsi*SSKIPFLSIZ); |
79 |
> |
} |
80 |
> |
|
81 |
> |
/* OR in a second set of flags into a first */ |
82 |
> |
void |
83 |
> |
sskip_addflags(uby8 *dfl, const uby8 *sfl) |
84 |
> |
{ |
85 |
> |
int nb = SSKIPFLSIZ; |
86 |
> |
|
87 |
> |
while (nb--) |
88 |
> |
*dfl++ |= *sfl++; |
89 |
> |
} |
90 |
> |
#endif |
91 |
> |
|
92 |
> |
int |
93 |
> |
srcskip( /* pre-emptive test for source to skip */ |
94 |
> |
int sn, |
95 |
> |
RAY *r |
96 |
|
) |
97 |
|
{ |
98 |
+ |
SRCREC *sp = source + sn; |
99 |
+ |
|
100 |
|
if (sp->sflags & SSKIP) |
101 |
|
return(1); |
102 |
< |
|
102 |
> |
#ifdef SSKIPOPT |
103 |
> |
if (r->rsrc < -1 && /* ray has custom skip flags? */ |
104 |
> |
sskip_chk(sskip_flags(r->rsrc), sn)) |
105 |
> |
return(1); |
106 |
> |
#endif |
107 |
|
if ((sp->sflags & (SPROX|SDISTANT)) != SPROX) |
108 |
|
return(0); |
109 |
|
|
110 |
< |
return(dist2(orig, sp->sloc) > |
110 |
> |
return(dist2(r->rorg, sp->sloc) > |
111 |
|
(sp->sl.prox + sp->srad)*(sp->sl.prox + sp->srad)); |
112 |
|
} |
113 |
|
|
114 |
|
double |
115 |
|
nextssamp( /* compute sample for source, rtn. distance */ |
116 |
|
RAY *r, /* origin is read, direction is set */ |
117 |
< |
SRCINDEX *si /* source index (modified to current) */\ |
117 |
> |
SRCINDEX *si /* source index (modified to current) */ |
118 |
|
) |
119 |
|
{ |
120 |
|
int cent[3], size[3], parr[2]; |
126 |
|
while (++si->sp >= si->np) { /* get next sample */ |
127 |
|
if (++si->sn >= nsources) |
128 |
|
return(0.0); /* no more */ |
129 |
< |
if (srcskip(source+si->sn, r->rorg)) |
129 |
> |
if (srcskip(si->sn, r)) |
130 |
|
si->np = 0; |
131 |
|
else if (srcsizerat <= FTINY) |
132 |
|
nopart(si, r); |
163 |
|
|
164 |
|
VSUM(vpos, vpos, cent, 1.0/MAXSPART); |
165 |
|
/* avoid circular aiming failures */ |
166 |
< |
if ((srcp->sflags & SCIR) && (si->np > 1 || dstrsrc > 0.7)) { |
166 |
> |
if ((srcp->sflags & SCIR) && (si->np > 1) | (dstrsrc > 0.7)) { |
167 |
|
FVECT trim; |
168 |
|
if (srcp->sflags & (SFLAT|SDISTANT)) { |
169 |
|
d = 1.12837917; /* correct setflatss() */ |