00001 #ifndef LIGHTSAMPLETREE_H_
00002 #define LIGHTSAMPLETREE_H_
00003
00004 #include "../../math/Point2D.h"
00005 #include "../AreaLight.h"
00006 #include "LightSampler.h"
00007
00008 namespace rcrt
00009 {
00010
00011
00012 enum ShadowType
00013 {
00014 NONE,
00015 PENUMBRA,
00016 FULL,
00017 };
00018
00019 class LSTreeNode;
00020 class LSTreeLeaf;
00021 class AreaLightSampler;
00022
00023 class LSTree
00024 {
00025 friend class AreaLightSampler;
00026
00027 protected:
00028 ShadowType type;
00029 int size;
00030 LSTreeNode* parent;
00031
00032 public:
00033
00034 LSTree(LSTreeNode* p=0):type(PENUMBRA), size(-1),parent(p)
00035 {}
00036
00037 LSTree(const ShadowType& t, const int& s, LSTreeNode* p=0)
00038 :type(t),size(s), parent(p)
00039 {}
00040
00041 virtual ~LSTree()
00042 {}
00043
00044 virtual const RGBColor& getMean() const =0;
00045 virtual const RGBColor& getVariance() const =0;
00046 virtual const float& getWeight() const =0;
00047 virtual void setWeight(const float& w) =0;
00048 virtual void getSamples(std::vector<LightSample>& samples) const =0;
00049
00050 inline const int& getSize() const
00051 {
00052 return size;
00053 }
00054
00055 inline const ShadowType& getType() const
00056 {
00057 return type;
00058 }
00059
00060 LSTreeNode* getParent()
00061 {
00062 return parent;
00063 }
00064
00065 virtual bool isLeaf()
00066 {
00067 return false;
00068 }
00069
00070 virtual LSTreeLeaf* refine() =0;
00071 };
00072
00073 class LSTreeLeaf : public LSTree
00074 {
00075 friend class AreaLightSampler;
00076
00077 protected:
00078 LightSample sample;
00079 Point2D uvMin;
00080 Point2D uvMax;
00081 Point2D uvs;
00082
00083 public:
00084 LSTreeLeaf(LightSample sa, const Point2D& uvMi, const Point2D& uvMa, const Point2D& uv
00085 , LSTreeNode* p);
00086
00087 ~LSTreeLeaf()
00088 {}
00089
00090 const RGBColor& getMean() const;
00091 const RGBColor& getVariance() const;
00092 const float& getWeight() const;
00093 void setWeight(const float& w);
00094 virtual void getSamples(std::vector<LightSample>& samples) const;
00095
00096 bool isLeaf();
00097
00098 LSTreeLeaf* refine();
00099 };
00100
00101 class LSTreeNode : public LSTree
00102 {
00103 friend class LSTreeLeaf;
00104 friend class AreaLightSampler;
00105
00106 protected:
00107 LSTree* lc;
00108 LSTree* rc;
00109 RGBColor mean;
00110 RGBColor variance;
00111 float weight;
00112 Point2D uvMin;
00113 Point2D uvMax;
00114
00115 public:
00116 LSTreeNode(const Point2D& uvMi, const Point2D& uvMa, LSTreeNode* p=0);
00117 LSTreeNode(LSTree* l, LSTree* r, LSTreeNode* p, const Point2D& uvMi, const Point2D& uvMa);
00118 ~LSTreeNode()
00119 {
00120
00121
00122 if(lc != 0)delete lc;
00123
00124 if(rc)delete rc;
00125 }
00126
00127 void setLeft(LSTree* l);
00128
00129 void setRight(LSTree* r);
00130
00131 void update();
00132
00135 LSTreeLeaf* refine();
00136 LSTree* getOtherChild(LSTree* c);
00137 const RGBColor& getMean() const;
00138 const float& getWeight() const;
00139 void setWeight(const float& w);
00140 virtual void getSamples(std::vector<LightSample>& samples) const;
00141 const RGBColor& getVariance() const;
00142
00143 };
00144
00145 class AreaLightSampler : public LightSampler
00146 {
00147 private:
00148 AreaLight* light;
00149 LSTreeNode* root;
00150
00151
00152
00153 void subdivide(LSTreeLeaf* leaf, std::vector<LightSample>& samples,
00154 const Point3D& p, const Vec3D& no, Scene* scene);
00155
00156 public:
00157 AreaLightSampler(AreaLight* l);
00158 ~AreaLightSampler()
00159 {
00160 if(root != 0)delete root;
00161 }
00162
00163 void sample(const Point3D& p, const Vec3D& no,
00164 std::vector<LightSample>& samples, const int& maxSamples, Scene* scene);
00165 };
00166
00167
00168
00169 }
00170
00171 #endif