19 |
|
#include "pmap.h" |
20 |
|
#include "pmaprand.h" |
21 |
|
#include "otypes.h" |
22 |
+ |
#include "otspecial.h" |
23 |
|
|
24 |
< |
|
25 |
< |
|
26 |
< |
SRCREC *photonPorts = NULL; /* Photon port list */ |
24 |
> |
/* List of photon port modifier names */ |
25 |
> |
char *photonPortList [MAXSET + 1] = {NULL}; |
26 |
> |
/* Photon port objects (with modifiers in photonPortMods) */ |
27 |
> |
SRCREC *photonPorts = NULL; |
28 |
|
unsigned numPhotonPorts = 0; |
29 |
|
|
30 |
|
void (*photonPartition [NUMOTYPE]) (EmissionMap*); |
31 |
|
void (*photonOrigin [NUMOTYPE]) (EmissionMap*); |
32 |
|
|
31 |
– |
extern OBJECT ambset []; |
32 |
– |
|
33 |
|
|
34 |
|
|
35 |
|
static int flatPhotonPartition2 (EmissionMap* emap, unsigned long mp, |
521 |
|
|
522 |
|
|
523 |
|
|
524 |
< |
void getPhotonPorts () |
525 |
< |
/* Find geometry declared as photon ports */ |
524 |
> |
void getPhotonPorts (char **portList) |
525 |
> |
/* Find geometry declared as photon ports from modifiers in portList */ |
526 |
|
{ |
527 |
|
OBJECT i; |
528 |
|
OBJREC *obj, *mat; |
529 |
+ |
char **lp; |
530 |
|
|
531 |
< |
/* Check for missing port modifiers */ |
532 |
< |
if (!ambset [0]) |
532 |
< |
error(USER, "no photon ports"); |
531 |
> |
/* Init photon port objects */ |
532 |
> |
photonPorts = NULL; |
533 |
|
|
534 |
+ |
if (!portList [0]) |
535 |
+ |
return; |
536 |
+ |
|
537 |
|
for (i = 0; i < nobjects; i++) { |
538 |
|
obj = objptr(i); |
539 |
|
mat = findmaterial(obj); |
540 |
|
|
541 |
|
/* Check if object is a surface and NOT a light source (duh) and |
542 |
|
* resolve its material via any aliases, then check for inclusion in |
543 |
< |
* port modifier list */ |
544 |
< |
if (issurface(obj -> otype) && mat && !islight(mat -> otype) && |
545 |
< |
inset(ambset, objndx(mat))) { |
543 |
< |
/* Add photon port */ |
544 |
< |
photonPorts = (SRCREC*)realloc(photonPorts, |
545 |
< |
(numPhotonPorts + 1) * |
546 |
< |
sizeof(SRCREC)); |
547 |
< |
if (!photonPorts) |
548 |
< |
error(USER, "can't allocate photon ports"); |
549 |
< |
|
550 |
< |
photonPorts [numPhotonPorts].so = obj; |
551 |
< |
photonPorts [numPhotonPorts].sflags = 0; |
543 |
> |
* modifier list */ |
544 |
> |
if (issurface(obj -> otype) && mat && !islight(mat -> otype)) { |
545 |
> |
for (lp = portList; *lp && strcmp(mat -> oname, *lp); lp++); |
546 |
|
|
547 |
< |
if (!sfun [obj -> otype].of || !sfun[obj -> otype].of -> setsrc) |
548 |
< |
objerror(obj, USER, "illegal photon port"); |
547 |
> |
if (*lp) { |
548 |
> |
/* Add photon port */ |
549 |
> |
photonPorts = (SRCREC*)realloc(photonPorts, |
550 |
> |
(numPhotonPorts + 1) * |
551 |
> |
sizeof(SRCREC)); |
552 |
> |
if (!photonPorts) |
553 |
> |
error(USER, "can't allocate photon ports"); |
554 |
|
|
555 |
< |
setsource(photonPorts + numPhotonPorts, obj); |
556 |
< |
numPhotonPorts++; |
555 |
> |
photonPorts [numPhotonPorts].so = obj; |
556 |
> |
photonPorts [numPhotonPorts].sflags = 0; |
557 |
> |
|
558 |
> |
if (!sfun [obj -> otype].of || !sfun[obj -> otype].of -> setsrc) |
559 |
> |
objerror(obj, USER, "illegal photon port"); |
560 |
> |
|
561 |
> |
setsource(photonPorts + numPhotonPorts, obj); |
562 |
> |
numPhotonPorts++; |
563 |
> |
} |
564 |
|
} |
565 |
|
} |
566 |
|
|
763 |
|
emitted photon to break up clustering artifacts */ |
764 |
|
photonOrigin [emap -> src -> so -> otype] ((EmissionMap*)emap); |
765 |
|
/* If we have a local glow source with a maximum radius, then |
766 |
< |
restrict our photon to the specified distance (otherwise no limit) */ |
766 |
> |
restrict our photon to the specified distance, otherwise we set |
767 |
> |
the limit imposed by photonMaxDist (or no limit if 0) */ |
768 |
|
if (mod -> otype == MAT_GLOW && !(emap -> src -> sflags & SDISTANT) |
769 |
|
&& mod -> oargs.farg[3] > FTINY) |
770 |
|
ray -> rmax = mod -> oargs.farg[3]; |
771 |
|
else |
772 |
< |
ray -> rmax = 0; |
772 |
> |
ray -> rmax = photonMaxDist; |
773 |
|
rayorigin(ray, PRIMARY, NULL, NULL); |
774 |
|
|
775 |
|
if (!emap -> numSamples) { |