38 |
|
/* Additional information on last error (ASCII English) */ |
39 |
|
char SDerrorDetail[256]; |
40 |
|
|
41 |
+ |
/* Empty distribution for getCDist() calls that fail for some reason */ |
42 |
+ |
const SDCDst SDemptyCD; |
43 |
+ |
|
44 |
|
/* Cache of loaded BSDFs */ |
45 |
|
struct SDCache_s *SDcacheList = NULL; |
46 |
|
|
216 |
|
if (sd->tf != NULL && sd->tf->maxHemi <= .001) { |
217 |
|
SDfreeSpectralDF(sd->tf); sd->tf = NULL; |
218 |
|
} |
219 |
+ |
if (sd->tb != NULL && sd->tb->maxHemi <= .001) { |
220 |
+ |
SDfreeSpectralDF(sd->tb); sd->tb = NULL; |
221 |
+ |
} |
222 |
|
/* return success */ |
223 |
|
return SDEnone; |
224 |
|
} |
353 |
|
SDfreeSpectralDF(sd->tf); |
354 |
|
sd->tf = NULL; |
355 |
|
} |
356 |
+ |
if (sd->tb != NULL) { |
357 |
+ |
SDfreeSpectralDF(sd->tb); |
358 |
+ |
sd->tb = NULL; |
359 |
+ |
} |
360 |
|
sd->rLambFront.cieY = .0; |
361 |
|
sd->rLambFront.spec.flags = 0; |
362 |
|
sd->rLambBack.cieY = .0; |
444 |
|
SDfreeCumulativeCache(sd->rf); |
445 |
|
SDfreeCumulativeCache(sd->rb); |
446 |
|
SDfreeCumulativeCache(sd->tf); |
447 |
+ |
SDfreeCumulativeCache(sd->tb); |
448 |
|
return; |
449 |
|
} |
450 |
|
/* remove from list and free */ |
573 |
|
case 0: |
574 |
|
return SDEargument; |
575 |
|
} |
576 |
< |
if (v1[2] > 0) /* front surface query? */ |
576 |
> |
if (v1[2] > 0) { /* front surface query? */ |
577 |
|
rdf = sd->rf; |
578 |
< |
else |
578 |
> |
tdf = (sd->tf != NULL) ? sd->tf : sd->tb; |
579 |
> |
} else { |
580 |
|
rdf = sd->rb; |
581 |
< |
tdf = sd->tf; |
581 |
> |
tdf = (sd->tb != NULL) ? sd->tb : sd->tf; |
582 |
> |
} |
583 |
|
if (v2 != NULL) /* bidirectional? */ |
584 |
|
if (v1[2] > 0 ^ v2[2] > 0) |
585 |
|
rdf = NULL; |
627 |
|
} else if (!(inFront | outFront)) { |
628 |
|
*sv = sd->rLambBack; |
629 |
|
sdf = sd->rb; |
630 |
< |
} else /* inFront ^ outFront */ { |
630 |
> |
} else if (inFront) { |
631 |
|
*sv = sd->tLamb; |
632 |
< |
sdf = sd->tf; |
632 |
> |
sdf = (sd->tf != NULL) ? sd->tf : sd->tb; |
633 |
> |
} else /* inBack */ { |
634 |
> |
*sv = sd->tLamb; |
635 |
> |
sdf = (sd->tb != NULL) ? sd->tb : sd->tf; |
636 |
|
} |
637 |
|
sv->cieY *= 1./M_PI; |
638 |
|
/* add non-diffuse components */ |
656 |
|
SDdirectHemi(const FVECT inVec, int sflags, const SDData *sd) |
657 |
|
{ |
658 |
|
double hsum; |
659 |
< |
SDSpectralDF *rdf; |
659 |
> |
SDSpectralDF *rdf, *tdf; |
660 |
|
const SDCDst *cd; |
661 |
|
int i; |
662 |
|
/* check arguments */ |
666 |
|
if (inVec[2] > 0) { |
667 |
|
hsum = sd->rLambFront.cieY; |
668 |
|
rdf = sd->rf; |
669 |
+ |
tdf = (sd->tf != NULL) ? sd->tf : sd->tb; |
670 |
|
} else /* !inFront */ { |
671 |
|
hsum = sd->rLambBack.cieY; |
672 |
|
rdf = sd->rb; |
673 |
+ |
tdf = (sd->tb != NULL) ? sd->tb : sd->tf; |
674 |
|
} |
675 |
|
if ((sflags & SDsampDf+SDsampR) != SDsampDf+SDsampR) |
676 |
|
hsum = .0; |
677 |
|
if ((sflags & SDsampDf+SDsampT) == SDsampDf+SDsampT) |
678 |
|
hsum += sd->tLamb.cieY; |
679 |
|
/* gather non-diffuse components */ |
680 |
< |
i = ((sflags & SDsampSp+SDsampR) == SDsampSp+SDsampR && |
681 |
< |
rdf != NULL) ? rdf->ncomp : 0; |
680 |
> |
i = (((sflags & SDsampSp+SDsampR) == SDsampSp+SDsampR) & |
681 |
> |
(rdf != NULL)) ? rdf->ncomp : 0; |
682 |
|
while (i-- > 0) { /* non-diffuse reflection */ |
683 |
|
cd = (*rdf->comp[i].func->getCDist)(inVec, &rdf->comp[i]); |
684 |
|
if (cd != NULL) |
685 |
|
hsum += cd->cTotal; |
686 |
|
} |
687 |
< |
i = ((sflags & SDsampSp+SDsampT) == SDsampSp+SDsampT && |
688 |
< |
sd->tf != NULL) ? sd->tf->ncomp : 0; |
687 |
> |
i = (((sflags & SDsampSp+SDsampT) == SDsampSp+SDsampT) & |
688 |
> |
(tdf != NULL)) ? tdf->ncomp : 0; |
689 |
|
while (i-- > 0) { /* non-diffuse transmission */ |
690 |
< |
cd = (*sd->tf->comp[i].func->getCDist)(inVec, &sd->tf->comp[i]); |
690 |
> |
cd = (*tdf->comp[i].func->getCDist)(inVec, &tdf->comp[i]); |
691 |
|
if (cd != NULL) |
692 |
|
hsum += cd->cTotal; |
693 |
|
} |
701 |
|
SDError ec; |
702 |
|
FVECT inVec; |
703 |
|
int inFront; |
704 |
< |
SDSpectralDF *rdf; |
704 |
> |
SDSpectralDF *rdf, *tdf; |
705 |
|
double rdiff; |
706 |
|
float coef[SDmaxCh]; |
707 |
|
int i, j, n, nr; |
718 |
|
if (inFront) { |
719 |
|
*sv = sd->rLambFront; |
720 |
|
rdf = sd->rf; |
721 |
+ |
tdf = (sd->tf != NULL) ? sd->tf : sd->tb; |
722 |
|
} else /* !inFront */ { |
723 |
|
*sv = sd->rLambBack; |
724 |
|
rdf = sd->rb; |
725 |
+ |
tdf = (sd->tb != NULL) ? sd->tb : sd->tf; |
726 |
|
} |
727 |
|
if ((sflags & SDsampDf+SDsampR) != SDsampDf+SDsampR) |
728 |
|
sv->cieY = .0; |
730 |
|
if ((sflags & SDsampDf+SDsampT) == SDsampDf+SDsampT) |
731 |
|
sv->cieY += sd->tLamb.cieY; |
732 |
|
/* gather non-diffuse components */ |
733 |
< |
i = nr = ((sflags & SDsampSp+SDsampR) == SDsampSp+SDsampR && |
734 |
< |
rdf != NULL) ? rdf->ncomp : 0; |
735 |
< |
j = ((sflags & SDsampSp+SDsampT) == SDsampSp+SDsampT && |
736 |
< |
sd->tf != NULL) ? sd->tf->ncomp : 0; |
733 |
> |
i = nr = (((sflags & SDsampSp+SDsampR) == SDsampSp+SDsampR) & |
734 |
> |
(rdf != NULL)) ? rdf->ncomp : 0; |
735 |
> |
j = (((sflags & SDsampSp+SDsampT) == SDsampSp+SDsampT) & |
736 |
> |
(tdf != NULL)) ? tdf->ncomp : 0; |
737 |
|
n = i + j; |
738 |
|
if (n > 0 && (cdarr = (const SDCDst **)malloc(n*sizeof(SDCDst *))) == NULL) |
739 |
|
return SDEmemory; |
740 |
|
while (j-- > 0) { /* non-diffuse transmission */ |
741 |
< |
cdarr[i+j] = (*sd->tf->comp[j].func->getCDist)(inVec, &sd->tf->comp[j]); |
741 |
> |
cdarr[i+j] = (*tdf->comp[j].func->getCDist)(inVec, &tdf->comp[j]); |
742 |
|
if (cdarr[i+j] == NULL) { |
743 |
|
free(cdarr); |
744 |
|
return SDEmemory; |
781 |
|
if (i >= n) |
782 |
|
return SDEinternal; |
783 |
|
/* compute sample direction */ |
784 |
< |
sdc = (i < nr) ? &rdf->comp[i] : &sd->tf->comp[i-nr]; |
784 |
> |
sdc = (i < nr) ? &rdf->comp[i] : &tdf->comp[i-nr]; |
785 |
|
ec = (*sdc->func->sampCDist)(ioVec, randX/cdarr[i]->cTotal, cdarr[i]); |
786 |
|
if (ec) |
787 |
|
return ec; |