00001 #include "PhotonKDTree.h"
00002 #include <algorithm>
00003 #include <boost/bind.hpp>
00004
00005 using namespace std;
00006
00007 namespace rcrt
00008 {
00009
00010
00011 PhotonKDTree::PhotonKDTree(const float& maxRad):
00012 photons(0), maxSqrRadius(maxRad), root(0), empty(true)
00013 {
00014 }
00015
00016 PhotonKDTree::~PhotonKDTree()
00017 {
00018 if(root) delete root;
00019 }
00020
00021 bool PhotonKDTree::splitPlaneCompare(PKDSplitPlane* a, PKDSplitPlane* b)
00022 {
00023 return a->p->getPos()[a->axis] <= b->p->getPos()[b->axis];
00024 }
00025
00026 void PhotonKDTree::buildTree(vector<Photon*>* phots)
00027 {
00028 if(phots->size() > 0)
00029 empty = false;
00030 else
00031 return;
00032 photons = phots;
00033 std::list<PKDSplitPlane*>* splitPlanes = new std::list<PKDSplitPlane*>();
00034
00035 Point3D minP(numeric_limits<float>::infinity());
00036 Point3D maxP(-numeric_limits<float>::infinity());
00037 unsigned int i = 0;
00038 if(photons->size() % 2 != 0){
00039 splitPlanes->push_back(new PKDSplitPlane(photons->at(i), X_AXIS));
00040 splitPlanes->push_back(new PKDSplitPlane(photons->at(i), Y_AXIS));
00041 splitPlanes->push_back(new PKDSplitPlane(photons->at(i), Z_AXIS));
00042 minP = photons->at(i)->getPos();
00043 maxP = photons->at(i)->getPos();
00044 i++;
00045 }
00046 for(; i < photons->size(); i += 2){
00047 splitPlanes->push_back(new PKDSplitPlane(photons->at(i), X_AXIS));
00048 splitPlanes->push_back(new PKDSplitPlane(photons->at(i), Y_AXIS));
00049 splitPlanes->push_back(new PKDSplitPlane(photons->at(i), Z_AXIS));
00050 splitPlanes->push_back(new PKDSplitPlane(photons->at(i+1), X_AXIS));
00051 splitPlanes->push_back(new PKDSplitPlane(photons->at(i+1), Y_AXIS));
00052 splitPlanes->push_back(new PKDSplitPlane(photons->at(i+1), Z_AXIS));
00053 Point3D tmpMin(photons->at(i)->getPos());
00054 Point3D tmpMax(photons->at(i+1)->getPos());
00055 for(int k = 0; k < 3; k++){
00056 if(tmpMin[k] > tmpMax[k]){
00057 std::swap(tmpMin[k], tmpMax[k]);
00058 }
00059 if(tmpMin[k] < minP[k])
00060 minP[k] = tmpMin[k];
00061 if(tmpMax[k] > maxP[k])
00062 maxP[k] = tmpMax[k];
00063 }
00064 }
00065 AABB bbox(minP, maxP);
00066
00067 splitPlanes->sort(splitPlaneCompare);
00068 root = new PKDNode(splitPlanes, maxSqrRadius, bbox);
00069 cout << "built tree" << endl;
00070 }
00071
00072
00073 void PhotonKDTree::getKNearest(std::vector<PKDSearchP>* result, const unsigned int& k,
00074 const Point3D& pos, const Vec3D& normal, const float& radiusSqr,
00075 const float& flat) const
00076 {
00077 if(empty)
00078 return;
00079 root->getKNearest(result, k, pos, normal, radiusSqr, flat);
00080 }
00081
00082 }