| 1 |
|
/* |
| 2 |
< |
================================================================== |
| 2 |
> |
====================================================================== |
| 3 |
|
Photon map interface to out-of-core octree |
| 4 |
|
|
| 5 |
|
Roland Schregle (roland.schregle@{hslu.ch, gmail.com}) |
| 6 |
|
(c) Lucerne University of Applied Sciences and Arts, |
| 7 |
< |
supported by the Swiss National Science Foundation (SNSF, #147053) |
| 8 |
< |
================================================================== |
| 7 |
> |
supported by the Swiss National Science Foundation (SNSF, #147053) |
| 8 |
> |
====================================================================== |
| 9 |
|
|
| 10 |
|
$Id$ |
| 11 |
|
*/ |
| 12 |
|
|
| 13 |
|
|
| 14 |
< |
#ifndef PMAP_OOC |
| 15 |
< |
/* Checked in pmapdata.h */ |
| 16 |
< |
#define PMAP_OOC |
| 17 |
< |
#endif |
| 14 |
> |
|
| 15 |
|
#include "pmapdata.h" /* Includes pmapooc.h */ |
| 16 |
|
#include "source.h" |
| 17 |
+ |
#include "otspecial.h" |
| 18 |
|
#include "oocsort.h" |
| 19 |
|
#include "oocbuild.h" |
| 20 |
|
|
| 152 |
|
|
| 153 |
|
if (OOC_LoadOctree(&pmap -> store, nodeFile, OOC_PhotonKey, leafFile)) |
| 154 |
|
return -1; |
| 155 |
< |
|
| 155 |
> |
|
| 156 |
> |
#ifdef DEBUG_OOC |
| 157 |
> |
/* Check octree for consistency */ |
| 158 |
> |
if (OOC_Check( |
| 159 |
> |
&pmap -> store, OOC_ROOT(&pmap -> store), |
| 160 |
> |
pmap -> store.org, pmap -> store.size, 0 |
| 161 |
> |
)) |
| 162 |
> |
return -1; |
| 163 |
> |
#endif |
| 164 |
> |
|
| 165 |
|
return 0; |
| 166 |
|
} |
| 167 |
|
|
| 224 |
|
DOT(filtData->norm, photon->norm) <= PMAP_NORM_TOL * 127 * frandom()) |
| 225 |
|
return 0; |
| 226 |
|
|
| 227 |
< |
if (isContribPmap(pmap) && pmap -> srcContrib) { |
| 228 |
< |
/* Lookup in contribution photon map */ |
| 229 |
< |
OBJREC *srcMod; |
| 230 |
< |
const int srcIdx = photonSrcIdx(pmap, photon); |
| 227 |
> |
if (isContribPmap(pmap)) { |
| 228 |
> |
/* Lookup in contribution photon map; filter according to emitting |
| 229 |
> |
* light source if contrib list set, else accept all */ |
| 230 |
> |
|
| 231 |
> |
if (pmap -> srcContrib) { |
| 232 |
> |
OBJREC *srcMod; |
| 233 |
> |
const int srcIdx = photonSrcIdx(pmap, photon); |
| 234 |
|
|
| 235 |
< |
if (srcIdx < 0 || srcIdx >= nsources) |
| 236 |
< |
error(INTERNAL, "invalid light source index in photon map"); |
| 235 |
> |
if (srcIdx < 0 || srcIdx >= nsources) |
| 236 |
> |
error(INTERNAL, "invalid light source index in photon map"); |
| 237 |
|
|
| 238 |
< |
srcMod = findmaterial(source [srcIdx].so); |
| 238 |
> |
srcMod = findmaterial(source [srcIdx].so); |
| 239 |
|
|
| 240 |
< |
/* Reject photon if contributions from light source which emitted it |
| 241 |
< |
* are not sought */ |
| 242 |
< |
if (!lu_find(pmap -> srcContrib, srcMod -> oname) -> data) |
| 243 |
< |
return 0; |
| 240 |
> |
/* Reject photon if contributions from light source which emitted |
| 241 |
> |
* it are not sought */ |
| 242 |
> |
if (!lu_find(pmap -> srcContrib, srcMod -> oname) -> data) |
| 243 |
> |
return 0; |
| 244 |
> |
} |
| 245 |
|
|
| 246 |
|
/* Reject non-caustic photon if lookup for caustic contribs */ |
| 247 |
|
if (pmap -> lookupCaustic && !photon -> caustic) |
| 254 |
|
|
| 255 |
|
|
| 256 |
|
|
| 257 |
< |
void OOC_FindPhotons (struct PhotonMap *pmap, const FVECT pos, const FVECT norm) |
| 257 |
> |
int OOC_FindPhotons (struct PhotonMap *pmap, const FVECT pos, const FVECT norm) |
| 258 |
|
{ |
| 259 |
|
OOC_SearchFilter filt; |
| 260 |
|
OOC_FilterData filtData; |
| 266 |
|
|
| 267 |
|
/* Set up filter callback */ |
| 268 |
|
filtData.pmap = pmap; |
| 269 |
< |
VCOPY(n, norm); |
| 270 |
< |
filtData.norm = n; |
| 269 |
> |
if (norm) |
| 270 |
> |
VCOPY(n, norm); |
| 271 |
> |
filtData.norm = norm ? n : NULL; |
| 272 |
|
filt.data = &filtData; |
| 273 |
|
filt.func = OOC_FilterPhoton; |
| 274 |
|
|
| 280 |
|
|
| 281 |
|
if (pmap -> maxDist2 < 0) |
| 282 |
|
error(INTERNAL, "failed k-NN photon lookup in OOC_FindPhotons"); |
| 283 |
+ |
|
| 284 |
+ |
/* Return success or failure (empty queue => none found) */ |
| 285 |
+ |
return pmap -> squeue.tail ? 0 : -1; |
| 286 |
|
} |
| 287 |
|
|
| 288 |
|
|
| 289 |
|
|
| 290 |
< |
void OOC_Find1Photon (struct PhotonMap* pmap, const FVECT pos, |
| 291 |
< |
const FVECT norm, Photon *photon) |
| 290 |
> |
int OOC_Find1Photon (struct PhotonMap* pmap, const FVECT pos, |
| 291 |
> |
const FVECT norm, Photon *photon) |
| 292 |
|
{ |
| 293 |
|
OOC_SearchFilter filt; |
| 294 |
|
OOC_FilterData filtData; |
| 295 |
< |
float n [3]; |
| 295 |
> |
float n [3], maxDist2; |
| 296 |
|
|
| 297 |
|
/* Lazily init OOC cache */ |
| 298 |
|
if (!pmap -> store.cache) |
| 300 |
|
|
| 301 |
|
/* Set up filter callback */ |
| 302 |
|
filtData.pmap = pmap; |
| 303 |
< |
VCOPY(n, norm); |
| 304 |
< |
filtData.norm = n; |
| 303 |
> |
if (norm) |
| 304 |
> |
VCOPY(n, norm); |
| 305 |
> |
filtData.norm = norm ? n : NULL; |
| 306 |
|
filt.data = &filtData; |
| 307 |
|
filt.func = OOC_FilterPhoton; |
| 308 |
|
|
| 309 |
< |
pmap -> maxDist2 = OOC_Find1Nearest(&pmap -> store, |
| 310 |
< |
OOC_ROOT(&pmap -> store), 0, |
| 311 |
< |
pmap -> store.org, pmap -> store.size, |
| 312 |
< |
pos, &filt, photon, pmap -> maxDist2); |
| 313 |
< |
|
| 314 |
< |
if (pmap -> maxDist2 < 0) |
| 315 |
< |
error(INTERNAL, "failed 1-NN photon lookup in OOC_Find1Photon"); |
| 309 |
> |
maxDist2 = OOC_Find1Nearest(&pmap -> store, |
| 310 |
> |
OOC_ROOT(&pmap -> store), 0, |
| 311 |
> |
pmap -> store.org, pmap -> store.size, |
| 312 |
> |
pos, &filt, photon, pmap -> maxDist2); |
| 313 |
> |
|
| 314 |
> |
if (maxDist2 < 0) |
| 315 |
> |
error(INTERNAL, "failed 1-NN photon lookup in OOC_Find1Photon"); |
| 316 |
> |
|
| 317 |
> |
if (maxDist2 >= pmap -> maxDist2) |
| 318 |
> |
/* No photon found => failed */ |
| 319 |
> |
return -1; |
| 320 |
> |
else { |
| 321 |
> |
/* Set photon distance => success */ |
| 322 |
> |
pmap -> maxDist2 = maxDist2; |
| 323 |
> |
return 0; |
| 324 |
> |
} |
| 325 |
|
} |
| 326 |
|
|
| 327 |
|
|