src/rcrt/gi/PhotonKDTree.cpp

Go to the documentation of this file.
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         //calculate BoundingBox and generate list of potential splits
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         //sort list of potential splitting planes
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 }

Generated on Thu Jan 31 19:26:19 2008 for RenderingCompetitionRayTracer by  doxygen 1.5.3