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 */ |
18 |
|
|
25 |
– |
uby8 *ssf_select = NULL; /* sources we may skip */ |
26 |
– |
|
27 |
– |
/* Find/allocate source skip flag entry (free all if NULL) */ |
19 |
|
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 |
– |
ssf_max = ssf_count + (ssf_count>>2) + 64; |
54 |
– |
if (ssf_max <= ssf_count && |
55 |
– |
(ssf_max = ssf_count+1024) <= ssf_count) |
56 |
– |
error(SYSTEM, "out of space in sskip_rsi()"); |
57 |
– |
|
58 |
– |
srcskipflags = (uby8 *)erealloc(srcskipflags, |
59 |
– |
ssf_max*SSKIPFLSIZ); |
60 |
– |
} |
61 |
– |
sskip_cpy(srcskipflags + ssf_count*SSKIPFLSIZ, flags); |
62 |
– |
|
63 |
– |
return(-2 - ssf_count++); /* return index (< -1) */ |
64 |
– |
} |
65 |
– |
|
66 |
– |
/* Get skip flags associated with RAY rsrc index (or NULL) */ |
67 |
– |
uby8 * |
68 |
– |
sskip_flags(int rsi) |
69 |
– |
{ |
70 |
– |
if (rsi >= -1) |
71 |
– |
return(ssf_noskip); |
72 |
– |
|
73 |
– |
if ((rsi = -2 - rsi) >= ssf_count) |
74 |
– |
error(CONSISTENCY, "bad index to sskip_flags()"); |
75 |
– |
|
76 |
– |
return(srcskipflags + rsi*SSKIPFLSIZ); |
77 |
– |
} |
78 |
– |
|
79 |
– |
/* OR in a second set of flags into a first */ |
80 |
– |
void |
81 |
– |
sskip_addflags(uby8 *dfl, const uby8 *sfl) |
82 |
– |
{ |
83 |
– |
int nb = SSKIPFLSIZ; |
84 |
– |
|
85 |
– |
while (nb--) |
86 |
– |
*dfl++ |= *sfl++; |
87 |
– |
} |
88 |
– |
#endif |
89 |
– |
|
90 |
– |
int |
20 |
|
srcskip( /* pre-emptive test for source to skip */ |
21 |
|
int sn, |
22 |
|
RAY *r |
26 |
|
|
27 |
|
if (sp->sflags & SSKIP) |
28 |
|
return(1); |
100 |
– |
#ifdef SSKIPOPT /* parent ray has custom skip flags? */ |
101 |
– |
if (r->parent != NULL && r->parent->rsrc < -1 && |
102 |
– |
sskip_chk(sskip_flags(r->parent->rsrc), sn)) |
103 |
– |
return(1); |
104 |
– |
#endif |
29 |
|
if ((sp->sflags & (SPROX|SDISTANT)) == SPROX) |
30 |
|
return(dist2(r->rorg, sp->sloc) > |
31 |
|
(sp->sl.prox + sp->srad)*(sp->sl.prox + sp->srad)); |