1
2 #include <yafraycore/photon.h>
3 #include <core_api/file.h>
4
5 __BEGIN_YAFRAY
6
7 YAFRAYCORE_EXPORT dirConverter_t dirconverter;
8
dirConverter_t()9 dirConverter_t::dirConverter_t()
10 {
11 for(int i=0;i<255;++i)
12 {
13 float angle=(float)i * cInv255Ratio;
14 costheta[i]=fCos(angle);
15 sintheta[i]=fSin(angle);
16 }
17 for(int i=0;i<256;++i)
18 {
19 float angle=(float)i * cInv256Ratio;
20 cosphi[i]=fCos(angle);
21 sinphi[i]=fSin(angle);
22 }
23 }
24
photonGather_t(uint32_t mp,const point3d_t & P)25 photonGather_t::photonGather_t(uint32_t mp, const point3d_t &P): p(P)
26 {
27 photons = 0;
28 nLookup = mp;
29 foundPhotons = 0;
30 }
31
operator ()(const photon_t * photon,float dist2,float & maxDistSquared) const32 void photonGather_t::operator()(const photon_t *photon, float dist2, float &maxDistSquared) const
33 {
34 // Do usual photon heap management
35 if (foundPhotons < nLookup) {
36 // Add photon to unordered array of photons
37 photons[foundPhotons++] = foundPhoton_t(photon, dist2);
38 if (foundPhotons == nLookup) {
39 std::make_heap(&photons[0], &photons[nLookup]);
40 maxDistSquared = photons[0].distSquare;
41 }
42 }
43 else {
44 // Remove most distant photon from heap and add new photon
45 std::pop_heap(&photons[0], &photons[nLookup]);
46 photons[nLookup-1] = foundPhoton_t(photon, dist2);
47 std::push_heap(&photons[0], &photons[nLookup]);
48 maxDistSquared = photons[0].distSquare;
49 }
50 }
51
load(const std::string & filename)52 bool photonMap_t::load(const std::string &filename)
53 {
54 clear();
55
56 file_t file(filename);
57 if (!file.open("rb"))
58 {
59 Y_WARNING << "PhotonMap file '" << filename << "' not found, aborting load operation";
60 return false;
61 }
62
63 std::string header;
64 file.read(header);
65 if(header != "YAF_PHOTONMAPv1")
66 {
67 Y_WARNING << "PhotonMap file '" << filename << "' does not contain a valid YafaRay photon map";
68 file.close();
69 return false;
70 }
71 file.read(name);
72 file.read<int>(paths);
73 file.read<float>(searchRadius);
74 file.read<int>(threadsPKDtree);
75 unsigned int photons_size;
76 file.read<unsigned int>(photons_size);
77 photons.resize(photons_size);
78 for(auto &p : photons)
79 {
80 file.read<float>(p.pos.x);
81 file.read<float>(p.pos.y);
82 file.read<float>(p.pos.z);
83 file.read<float>(p.c.R);
84 file.read<float>(p.c.G);
85 file.read<float>(p.c.B);
86 }
87 file.close();
88
89 updateTree();
90 return true;
91 }
92
save(const std::string & filename) const93 bool photonMap_t::save(const std::string &filename) const
94 {
95 file_t file(filename);
96 file.open("wb");
97 file.append(std::string("YAF_PHOTONMAPv1"));
98 file.append(name);
99 file.append<int>(paths);
100 file.append<float>(searchRadius);
101 file.append<int>(threadsPKDtree);
102 file.append<unsigned int>((unsigned int) photons.size());
103 for(const auto &p : photons)
104 {
105 file.append<float>(p.pos.x);
106 file.append<float>(p.pos.y);
107 file.append<float>(p.pos.z);
108 file.append<float>(p.c.R);
109 file.append<float>(p.c.G);
110 file.append<float>(p.c.B);
111 }
112 file.close();
113 return true;
114 }
115
updateTree()116 void photonMap_t::updateTree()
117 {
118 if(tree) delete tree;
119 if(photons.size() > 0)
120 {
121 tree = new kdtree::pointKdTree<photon_t>(photons, name, threadsPKDtree);
122 updated = true;
123 }
124 else tree=0;
125 }
126
gather(const point3d_t & P,foundPhoton_t * found,unsigned int K,float & sqRadius) const127 int photonMap_t::gather(const point3d_t &P, foundPhoton_t *found, unsigned int K, float &sqRadius) const
128 {
129 photonGather_t proc(K, P);
130 proc.photons = found;
131 tree->lookup(P, proc, sqRadius);
132 return proc.foundPhotons;
133 }
134
findNearest(const point3d_t & P,const vector3d_t & n,float dist) const135 const photon_t* photonMap_t::findNearest(const point3d_t &P, const vector3d_t &n, float dist) const
136 {
137 nearestPhoton_t proc(P, n);
138 //float dist=std::numeric_limits<float>::infinity(); //really bad idea...
139 tree->lookup(P, proc, dist);
140 return proc.nearest;
141 }
142
143 __END_YAFRAY
144