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