405 |
|
|
406 |
|
/* Sample an individual BSDF component */ |
407 |
|
SDError |
408 |
< |
SDsampComponent(SDValue *sv, FVECT outVec, const FVECT inVec, |
409 |
< |
double randX, SDComponent *sdc) |
408 |
> |
SDsampComponent(SDValue *sv, FVECT ioVec, double randX, SDComponent *sdc) |
409 |
|
{ |
410 |
|
float coef[SDmaxCh]; |
411 |
|
SDError ec; |
412 |
+ |
FVECT inVec; |
413 |
|
const SDCDst *cd; |
414 |
|
double d; |
415 |
|
int n; |
416 |
|
/* check arguments */ |
417 |
< |
if ((sv == NULL) | (outVec == NULL) | (inVec == NULL) | (sdc == NULL)) |
417 |
> |
if ((sv == NULL) | (ioVec == NULL) | (sdc == NULL)) |
418 |
|
return SDEargument; |
419 |
|
/* get cumulative distribution */ |
420 |
+ |
VCOPY(inVec, ioVec); |
421 |
|
cd = (*sdc->func->getCDist)(inVec, sdc); |
422 |
|
if (cd == NULL) |
423 |
|
return SDEmemory; |
424 |
|
if (cd->cTotal <= 1e-7) { /* anything to sample? */ |
425 |
|
sv->spec = c_dfcolor; |
426 |
|
sv->cieY = .0; |
427 |
< |
memset(outVec, 0, 3*sizeof(double)); |
427 |
> |
memset(ioVec, 0, 3*sizeof(double)); |
428 |
|
return SDEnone; |
429 |
|
} |
430 |
|
sv->cieY = cd->cTotal; |
431 |
|
/* compute sample direction */ |
432 |
< |
ec = (*sdc->func->sampCDist)(outVec, randX, cd); |
432 |
> |
ec = (*sdc->func->sampCDist)(ioVec, randX, cd); |
433 |
|
if (ec) |
434 |
|
return ec; |
435 |
|
/* get BSDF color */ |
436 |
< |
n = (*sdc->func->getBSDFs)(coef, outVec, inVec, sdc->dist); |
436 |
> |
n = (*sdc->func->getBSDFs)(coef, ioVec, inVec, sdc->dist); |
437 |
|
if (n <= 0) { |
438 |
|
strcpy(SDerrorDetail, "BSDF sample value error"); |
439 |
|
return SDEinternal; |
627 |
|
|
628 |
|
/* Sample BSDF direction based on the given random variable */ |
629 |
|
SDError |
630 |
< |
SDsampBSDF(SDValue *sv, FVECT outVec, const FVECT inVec, |
630 |
< |
double randX, int sflags, const SDData *sd) |
630 |
> |
SDsampBSDF(SDValue *sv, FVECT ioVec, double randX, int sflags, const SDData *sd) |
631 |
|
{ |
632 |
|
SDError ec; |
633 |
+ |
FVECT inVec; |
634 |
|
int inFront; |
635 |
|
SDSpectralDF *rdf; |
636 |
|
double rdiff; |
639 |
|
SDComponent *sdc; |
640 |
|
const SDCDst **cdarr = NULL; |
641 |
|
/* check arguments */ |
642 |
< |
if ((sv == NULL) | (outVec == NULL) | (inVec == NULL) | (sd == NULL) | |
642 |
> |
if ((sv == NULL) | (ioVec == NULL) | (sd == NULL) | |
643 |
|
(randX < 0) | (randX >= 1.)) |
644 |
|
return SDEargument; |
645 |
|
/* whose side are we on? */ |
646 |
+ |
VCOPY(inVec, ioVec); |
647 |
|
inFront = (inVec[2] > 0); |
648 |
|
/* remember diffuse portions */ |
649 |
|
if (inFront) { |
684 |
|
} |
685 |
|
if (sv->cieY <= 1e-7) { /* anything to sample? */ |
686 |
|
sv->cieY = .0; |
687 |
< |
memset(outVec, 0, 3*sizeof(double)); |
687 |
> |
memset(ioVec, 0, 3*sizeof(double)); |
688 |
|
return SDEnone; |
689 |
|
} |
690 |
|
/* scale random variable */ |
691 |
|
randX *= sv->cieY; |
692 |
|
/* diffuse reflection? */ |
693 |
|
if (randX < rdiff) { |
694 |
< |
SDdiffuseSamp(outVec, inFront, randX/rdiff); |
694 |
> |
SDdiffuseSamp(ioVec, inFront, randX/rdiff); |
695 |
|
goto done; |
696 |
|
} |
697 |
|
randX -= rdiff; |
699 |
|
if ((sflags & SDsampDf+SDsampT) == SDsampDf+SDsampT) { |
700 |
|
if (randX < sd->tLamb.cieY) { |
701 |
|
sv->spec = sd->tLamb.spec; |
702 |
< |
SDdiffuseSamp(outVec, !inFront, randX/sd->tLamb.cieY); |
702 |
> |
SDdiffuseSamp(ioVec, !inFront, randX/sd->tLamb.cieY); |
703 |
|
goto done; |
704 |
|
} |
705 |
|
randX -= sd->tLamb.cieY; |
711 |
|
return SDEinternal; |
712 |
|
/* compute sample direction */ |
713 |
|
sdc = (i < nr) ? &rdf->comp[i] : &sd->tf->comp[i-nr]; |
714 |
< |
ec = (*sdc->func->sampCDist)(outVec, randX/cdarr[i]->cTotal, cdarr[i]); |
714 |
> |
ec = (*sdc->func->sampCDist)(ioVec, randX/cdarr[i]->cTotal, cdarr[i]); |
715 |
|
if (ec) |
716 |
|
return ec; |
717 |
|
/* compute color */ |
718 |
< |
j = (*sdc->func->getBSDFs)(coef, outVec, inVec, sdc->dist); |
718 |
> |
j = (*sdc->func->getBSDFs)(coef, ioVec, inVec, sdc->dist); |
719 |
|
if (j <= 0) { |
720 |
|
sprintf(SDerrorDetail, "BSDF \"%s\" sampling value error", |
721 |
|
sd->name); |