#ifndef __PVS_H #define __PVS_H #include class KdNode; class BspNode; class Ray; class Intersectable; class ViewCellKdNode; template struct LtSample { bool operator()(const T a, const T b) const { return a < b; } }; //typedef std::map, LtSample> PvsMap; template struct PvsData { int mVisibleSamples; PvsData() {} PvsData(const int samples): mVisibleSamples(samples) {} }; template class Pvs { public: Pvs(): mSamples(0), mEntries() {} int mSamples; int Compress() {return 0;} int GetSize() const {return (int)mEntries.size();} bool Empty() const {return mEntries.size() == 0;} /** Merges pvs of a and pvs of b into this pvs. */ void Merge(const Pvs &a, const Pvs &b); /** Difference of pvs to pvs b. @returns number of different entries. */ int Diff(const Pvs &b); PvsData *Find(T sample); int AddSample(T sample); void GetData(const int index, T &entry, PvsData &data); std::map, LtSample > mEntries; }; template int Pvs::Diff(const Pvs &b) { int dif = 0; std::map, LtSample >::const_iterator it; for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it) { PvsData *data = Find((*it).first); if (!data) ++ dif; } return dif; } template void Pvs::Merge(const Pvs &a, const Pvs &b) { std::map, LtSample >::const_iterator it; // todo: copy all elements instead of inserting for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it) { mEntries.insert(*it); } for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it) { PvsData *data = Find((*it).first); if (data) data->mVisibleSamples += (*it).second.mVisibleSamples; else mEntries.insert(*it); } } template PvsData *Pvs::Find(T sample) { std::map, LtSample >::iterator i = mEntries.find(sample); if (i != mEntries.end()) { return &(*i).second; } else return NULL; } template void Pvs::GetData(const int index, T &entry, PvsData &data) { std::map, LtSample >::iterator i = mEntries.begin(); for (int k = 0; k != index && i != mEntries.end(); i++, k++); entry = (*i).first; data = (*i).second; } template int Pvs::AddSample(T sample) { int result; PvsData *data = Find(sample); if (data) { data->mVisibleSamples ++; result = 0; } else { mEntries[sample] = PvsData(1); result = 1; } return result; } /** Class instantiating the Pvs template for kd tree nodes. */ class KdPvs: public Pvs { int Compress(); }; typedef std::map, LtSample > KdPvsMap; typedef std::map, LtSample > ViewCellKdPvsMap; typedef std::map, LtSample > ViewCellPvsMap; typedef PvsData ViewCellPvsData; typedef PvsData KdPvsData; typedef Pvs ViewCellKdPvs; typedef Pvs ViewCellPvs; #endif