1 #pragma once 2 3 #ifndef Y_PHOTONMAP_H 4 #define Y_PHOTONMAP_H 5 6 #include <yafray_constants.h> 7 8 #include "pkdtree.h" 9 #include <core_api/color.h> 10 11 __BEGIN_YAFRAY 12 #define c255Ratio 81.16902097686662123083 13 #define c256Ratio 40.74366543152520595687 14 15 16 #define cInv255Ratio 0.01231997119054820878 17 #define cInv256Ratio 0.02454369260617025968 18 19 20 class dirConverter_t 21 { 22 public: 23 dirConverter_t(); 24 convert(unsigned char theta,unsigned char phi)25 vector3d_t convert(unsigned char theta,unsigned char phi) 26 { 27 return vector3d_t(sintheta[theta]*cosphi[phi], 28 sintheta[theta]*sinphi[phi], 29 costheta[theta]); 30 } convert(const vector3d_t & dir)31 std::pair<unsigned char,unsigned char> convert(const vector3d_t &dir) 32 { 33 int t=(int)(fAcos(dir.z)*c255Ratio); 34 int p=(int)(atan2(dir.y,dir.x)*c256Ratio); 35 if(t>254) t=254; 36 else if(t<0) t=0; 37 if(p>255) p=255; 38 else if(p<0) p+=256; 39 return std::pair<unsigned char,unsigned char>(t,p); 40 } 41 42 protected: 43 float cosphi[256]; 44 float sinphi[256]; 45 float costheta[255]; 46 float sintheta[255]; 47 }; 48 49 extern YAFRAYCORE_EXPORT dirConverter_t dirconverter; 50 51 class photon_t 52 { 53 public: photon_t()54 photon_t() {/*theta=255;*/}; photon_t(const vector3d_t & d,const point3d_t & p,const color_t & col)55 photon_t(const vector3d_t &d,const point3d_t &p, const color_t &col) 56 { 57 #ifdef _SMALL_PHOTONS 58 direction(d); 59 #else 60 dir=d; 61 #endif 62 pos=p; 63 c=col; 64 }; 65 // photon_t(const runningPhoton_t &p) 66 // { 67 // pos=p.pos; 68 // c=p.c; 69 // vector3d_t dir=p.lastpos-p.pos; 70 // dir.normalize(); 71 // direction(dir); 72 // }; position()73 const point3d_t & position()const {return pos;}; color()74 const color_t color()const {return c;}; color(const color_t & col)75 void color(const color_t &col) {c=col;}; direction()76 vector3d_t direction()const 77 { 78 #ifdef _SMALL_PHOTONS 79 if(theta==255) return vector3d_t(0,0,0); 80 else return dirconverter.convert(theta,phi); 81 #else //_SMALL_PHOTONS 82 return (vector3d_t)dir; 83 #endif //_SMALL_PHOTONS 84 }; direction(const vector3d_t & d)85 void direction(const vector3d_t &d) 86 { 87 #ifdef _SMALL_PHOTONS 88 if(dir.null()) theta=255; 89 else 90 { 91 std::pair<unsigned char,unsigned char> cd=dirconverter.convert(d); 92 theta=cd.first; 93 phi=cd.second; 94 } 95 #else //_SMALL_PHOTONS 96 dir=d; 97 #endif //_SMALL_PHOTONS 98 } 99 100 point3d_t pos; 101 102 #ifdef _SMALL_PHOTONS 103 rgbe_t c; 104 unsigned char theta,phi; 105 106 #else //_SMALL_PHOTONS 107 color_t c; 108 normal_t dir; 109 #endif //_SMALL_PHOTONS 110 }; 111 112 struct radData_t 113 { radData_tradData_t114 radData_t(point3d_t &p, vector3d_t n): pos(p), normal(n), use(true) {} 115 point3d_t pos; 116 vector3d_t normal; 117 color_t refl; 118 color_t transm; 119 mutable bool use; 120 }; 121 122 struct foundPhoton_t 123 { foundPhoton_tfoundPhoton_t124 foundPhoton_t(){}; foundPhoton_tfoundPhoton_t125 foundPhoton_t(const photon_t *p, float d): photon(p), distSquare(d){} 126 bool operator<(const foundPhoton_t &p2) const { return distSquare < p2.distSquare; } 127 const photon_t *photon; 128 float distSquare; 129 //temp!! 130 float dis; 131 }; 132 133 class YAFRAYCORE_EXPORT photonMap_t 134 { 135 public: photonMap_t()136 photonMap_t(): paths(0), updated(false), searchRadius(1.), tree(nullptr){ } photonMap_t(const std::string & mapname,int threads)137 photonMap_t(const std::string &mapname, int threads): paths(0), updated(false), searchRadius(1.), tree(nullptr), name(mapname),threadsPKDtree(threads) { } ~photonMap_t()138 ~photonMap_t(){ if(tree) delete tree; } setNumPaths(int n)139 void setNumPaths(int n){ paths=n; } setName(const std::string & mapname)140 void setName(const std::string &mapname) { name = mapname; } setNumThreadsPKDtree(int threads)141 void setNumThreadsPKDtree(int threads){ threadsPKDtree = threads; } nPaths()142 int nPaths() const{ return paths; } nPhotons()143 int nPhotons() const{ return photons.size(); } pushPhoton(photon_t & p)144 void pushPhoton(photon_t &p) { photons.push_back(p); updated=false; } swapVector(std::vector<photon_t> & vec)145 void swapVector(std::vector<photon_t> &vec) { photons.swap(vec); updated=false; } appendVector(std::vector<photon_t> & vec,unsigned int curr)146 void appendVector(std::vector<photon_t> &vec, unsigned int curr) { photons.insert(std::end(photons), std::begin(vec), std::end(vec)); updated=false; paths += curr;} reserveMemory(size_t numPhotons)147 void reserveMemory(size_t numPhotons) { photons.reserve(numPhotons); } 148 void updateTree(); clear()149 void clear(){ photons.clear(); delete tree; tree = nullptr; updated=false; } ready()150 bool ready() const { return updated; } 151 // void gather(const point3d_t &P, std::vector< foundPhoton_t > &found, unsigned int K, float &sqRadius) const; 152 int gather(const point3d_t &P, foundPhoton_t *found, unsigned int K, float &sqRadius) const; 153 const photon_t* findNearest(const point3d_t &P, const vector3d_t &n, float dist) const; 154 bool load(const std::string &filename); 155 bool save(const std::string &filename) const; 156 std::mutex mutx; 157 158 protected: 159 std::vector<photon_t> photons; 160 int paths; //!< amount of photon paths that have been traced for generating the map 161 bool updated; 162 float searchRadius; 163 kdtree::pointKdTree<photon_t> *tree; 164 std::string name; 165 int threadsPKDtree = 1; 166 }; 167 168 // photon "processes" for lookup 169 170 struct photonGather_t 171 { 172 photonGather_t(uint32_t mp, const point3d_t &p); 173 void operator()(const photon_t *photon, float dist2, float &maxDistSquared) const; 174 const point3d_t &p; 175 foundPhoton_t *photons; 176 uint32_t nLookup; 177 mutable uint32_t foundPhotons; 178 }; 179 180 struct nearestPhoton_t 181 { nearestPhoton_tnearestPhoton_t182 nearestPhoton_t(const point3d_t &pos, const vector3d_t &norm): p(pos), n(norm), nearest(nullptr) {} operatornearestPhoton_t183 void operator()(const photon_t *photon, float dist2, float &maxDistSquared) const 184 { 185 if ( photon->direction() * n > 0.f) { nearest = photon; maxDistSquared = dist2; } 186 } 187 const point3d_t p; //wth do i need this for actually?? 188 const vector3d_t n; 189 mutable const photon_t *nearest; 190 }; 191 192 /*! "eliminates" photons within lookup radius (sets use=false) */ 193 struct eliminatePhoton_t 194 { eliminatePhoton_teliminatePhoton_t195 eliminatePhoton_t(const vector3d_t &norm): n(norm) {} operatoreliminatePhoton_t196 void operator()(const radData_t *rpoint, float dist2, float &maxDistSquared) const 197 { 198 if ( rpoint->normal * n > 0.f) { rpoint->use = false; } 199 } 200 const vector3d_t n; 201 }; 202 203 __END_YAFRAY 204 205 #endif // Y_PHOTONMAP_H 206