| 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); |