| 518 |
|
/* Query BSDF value and sample hypercube for the given vectors */ |
| 519 |
|
static int |
| 520 |
|
SDqueryTre(const SDTre *sdt, float *coef, |
| 521 |
< |
const FVECT outVec, const FVECT inVec, double *hc) |
| 521 |
> |
const FVECT inVec, const FVECT outVec, double *hc) |
| 522 |
|
{ |
| 523 |
|
const RREAL *vtmp; |
| 524 |
|
float yval; |
| 525 |
|
FVECT rOutVec; |
| 526 |
< |
double gridPos[4]; |
| 526 |
> |
RREAL gridPos[4]; |
| 527 |
|
|
| 528 |
|
if (sdt->stc[tt_Y] == NULL) /* paranoia, I hope */ |
| 529 |
|
return 0; |
| 561 |
|
spinvector(rOutVec, outVec, zvec, -atan2(-inVec[1],-inVec[0])); |
| 562 |
|
gridPos[0] = (.5-FTINY) - |
| 563 |
|
.5*sqrt(inVec[0]*inVec[0] + inVec[1]*inVec[1]); |
| 564 |
< |
SDdisk2square(gridPos+1, rOutVec[0], rOutVec[1]); |
| 564 |
> |
disk2square(gridPos+1, rOutVec[0], rOutVec[1]); |
| 565 |
|
} else if (sdt->stc[tt_Y]->ndim == 4) { |
| 566 |
< |
SDdisk2square(gridPos, -inVec[0], -inVec[1]); |
| 567 |
< |
SDdisk2square(gridPos+2, outVec[0], outVec[1]); |
| 566 |
> |
disk2square(gridPos, -inVec[0], -inVec[1]); |
| 567 |
> |
disk2square(gridPos+2, outVec[0], outVec[1]); |
| 568 |
|
} else |
| 569 |
|
return 0; /* should be internal error */ |
| 570 |
|
/* get BSDF value */ |
| 744 |
|
const SDCDst * |
| 745 |
|
SDgetTreCDist(const FVECT inVec, SDComponent *sdc) |
| 746 |
|
{ |
| 747 |
+ |
unsigned long cacheLeft = SDmaxCache; |
| 748 |
|
const SDTre *sdt; |
| 749 |
< |
double inCoord[2]; |
| 749 |
> |
RREAL inCoord[2]; |
| 750 |
|
int i; |
| 751 |
|
int mode; |
| 752 |
< |
SDTreCDst *cd, *cdlast; |
| 752 |
> |
SDTreCDst *cd, *cdlast, *cdlimit; |
| 753 |
|
/* check arguments */ |
| 754 |
|
if ((inVec == NULL) | (sdc == NULL) || |
| 755 |
|
(sdt = (SDTre *)sdc->dist) == NULL) |
| 781 |
|
.5*sqrt(inVec[0]*inVec[0] + inVec[1]*inVec[1]); |
| 782 |
|
} else if (sdt->stc[tt_Y]->ndim == 4) { |
| 783 |
|
if (mode != sdt->sidef) /* use reciprocity? */ |
| 784 |
< |
SDdisk2square(inCoord, inVec[0], inVec[1]); |
| 784 |
> |
disk2square(inCoord, inVec[0], inVec[1]); |
| 785 |
|
else |
| 786 |
< |
SDdisk2square(inCoord, -inVec[0], -inVec[1]); |
| 786 |
> |
disk2square(inCoord, -inVec[0], -inVec[1]); |
| 787 |
|
} else |
| 788 |
|
return NULL; /* should be internal error */ |
| 789 |
|
/* quantize to avoid f.p. errors */ |
| 790 |
|
for (i = sdt->stc[tt_Y]->ndim - 2; i--; ) |
| 791 |
|
inCoord[i] = floor(inCoord[i]/quantum)*quantum + .5*quantum; |
| 792 |
< |
cdlast = NULL; /* check for direction in cache list */ |
| 792 |
> |
cdlast = cdlimit = NULL; /* check for direction in cache list */ |
| 793 |
|
/* PLACE MUTEX LOCK HERE FOR THREAD-SAFE */ |
| 794 |
|
for (cd = (SDTreCDst *)sdc->cdList; cd != NULL; |
| 795 |
|
cdlast = cd, cd = cd->next) { |
| 796 |
+ |
if (cacheLeft) { /* check cache size limit */ |
| 797 |
+ |
long csiz = sizeof(SDTreCDst) + |
| 798 |
+ |
sizeof(cd->carr[0])*cd->calen; |
| 799 |
+ |
if (cacheLeft > csiz) |
| 800 |
+ |
cacheLeft -= csiz; |
| 801 |
+ |
else { |
| 802 |
+ |
cdlimit = cdlast; |
| 803 |
+ |
cacheLeft = 0; |
| 804 |
+ |
} |
| 805 |
+ |
} |
| 806 |
|
if (cd->sidef != mode) |
| 807 |
|
continue; |
| 808 |
|
for (i = sdt->stc[tt_Y]->ndim - 2; i--; ) |
| 812 |
|
if (i < 0) |
| 813 |
|
break; /* means we have a match */ |
| 814 |
|
} |
| 815 |
< |
if (cd == NULL) /* need to create new entry? */ |
| 815 |
> |
if (cd == NULL) { /* need to create new entry? */ |
| 816 |
> |
if (cdlimit != NULL) /* exceeded cache size limit? */ |
| 817 |
> |
while ((cd = cdlimit->next) != NULL) { |
| 818 |
> |
cdlimit->next = cd->next; |
| 819 |
> |
free(cd); |
| 820 |
> |
} |
| 821 |
|
cdlast = cd = make_cdist(sdt, inCoord, mode != sdt->sidef); |
| 822 |
+ |
} |
| 823 |
|
if (cdlast != NULL) { /* move entry to head of cache list */ |
| 824 |
|
cdlast->next = cd->next; |
| 825 |
|
cd->next = (SDTreCDst *)sdc->cdList; |
| 888 |
|
const SDTreCDst *cd = (const SDTreCDst *)cdp; |
| 889 |
|
const unsigned target = randX*cumlmax; |
| 890 |
|
bitmask_t hndx, hcoord[2]; |
| 891 |
< |
double gpos[3], rotangle; |
| 891 |
> |
FVECT gpos; |
| 892 |
> |
double rotangle; |
| 893 |
|
int i, iupper, ilower; |
| 894 |
|
/* check arguments */ |
| 895 |
|
if ((ioVec == NULL) | (cd == NULL)) |
| 919 |
|
for (i = 2; i--; ) |
| 920 |
|
gpos[i] = ((double)hcoord[i] + rand()*(1./(RAND_MAX+.5))) / |
| 921 |
|
(double)((bitmask_t)1 << nBitsC); |
| 922 |
< |
SDsquare2disk(gpos, gpos[0], gpos[1]); |
| 922 |
> |
square2disk(gpos, gpos[0], gpos[1]); |
| 923 |
|
/* compute Z-coordinate */ |
| 924 |
|
gpos[2] = 1. - gpos[0]*gpos[0] - gpos[1]*gpos[1]; |
| 925 |
|
gpos[2] = sqrt(gpos[2]*(gpos[2]>0)); |
| 1379 |
|
dv->cieY = subtract_min_Y(sdt->stc[tt_Y]); |
| 1380 |
|
} |
| 1381 |
|
df->maxHemi -= dv->cieY; /* adjust maximum hemispherical */ |
| 1382 |
< |
/* make sure everything is set */ |
| 1383 |
< |
c_ccvt(&dv->spec, C_CSXY+C_CSSPEC); |
| 1382 |
> |
|
| 1383 |
> |
c_ccvt(&dv->spec, C_CSXY); /* make sure (x,y) is set */ |
| 1384 |
|
} |
| 1385 |
|
|
| 1386 |
|
/* Load a variable-resolution BSDF tree from an open XML file */ |
| 1431 |
|
/* separate diffuse components */ |
| 1432 |
|
extract_diffuse(&sd->rLambFront, sd->rf); |
| 1433 |
|
extract_diffuse(&sd->rLambBack, sd->rb); |
| 1434 |
< |
if (sd->tf != NULL) |
| 1435 |
< |
extract_diffuse(&sd->tLamb, sd->tf); |
| 1436 |
< |
if (sd->tb != NULL) |
| 1437 |
< |
extract_diffuse(&sd->tLamb, sd->tb); |
| 1434 |
> |
extract_diffuse(&sd->tLambFront, sd->tf); |
| 1435 |
> |
if (sd->tb != NULL) { |
| 1436 |
> |
extract_diffuse(&sd->tLambBack, sd->tb); |
| 1437 |
> |
if (sd->tf == NULL) |
| 1438 |
> |
sd->tLambFront = sd->tLambBack; |
| 1439 |
> |
} else if (sd->tf != NULL) |
| 1440 |
> |
sd->tLambBack = sd->tLambFront; |
| 1441 |
|
/* return success */ |
| 1442 |
|
return SDEnone; |
| 1443 |
|
} |