#ifndef __VERBOSEPVS_H #define __VERBOSEPVS_H #include #include "common.h" #include #include "PvsBase.h" // namespace GtpVisibilityPreprocessor { template class PvsIterator { public: PvsIterator(){} PvsIterator(const typename vector >::const_iterator &itCurrent, const typename vector >::const_iterator &itEnd): mItCurrent(itCurrent), mItEnd(itEnd) { } bool HasMoreEntries() const { return (mItCurrent != mItEnd); } T Next(S &pdf) { pdf = (*mItCurrent).mData; return (*(mItCurrent ++)).mObject; } T Next() { return (*(mItCurrent ++)).mObject; } private: typename vector >::const_iterator mItCurrent; typename vector >::const_iterator mItEnd; }; /** Template class representing the Potentially Visible Set (PVS) mainly from a view cell, but also e.g., from objects. */ template class VerbosePvs { template friend class PvsIterator; public: VerbosePvs(): mSamples(0), mEntries(), mLastSorted(0), mQueriesSinceSort(0) {} /** creates pvs and initializes it with the given entries. Assumes that entries are sorted- */ VerbosePvs(const vector > &samples); virtual ~VerbosePvs() {}; /** Compresses PVS lossless or lossy. */ int Compress() { return 0; } int GetSize() const { return (int)mEntries.size(); } bool Empty() const { return mEntries.empty(); } void Reserve(const int n) { mEntries.reserve(n); } /** Normalize the visibility of entries in order to get comparable results. */ void NormalizeMaximum(); /** Merges pvs of a into this pvs. Warning: very slow! */ void MergeInPlace(const VerbosePvs &a); /** Difference of pvs to pvs b. @returns number of different entries. */ int Diff(const VerbosePvs &b); /** Finds sample in PVS. @param checkDirty if dirty part of the pvs should be checked for entry (warning: linear runtime in dirty part) @returns iterator on the sample if found, else the place where it would be added in the sorted vector. */ bool Find(T sample, typename vector >::iterator &it, const bool checkDirty = true); bool GetSampleContribution(T sample, const float pdf, float &contribution); /** Adds sample to PVS. @returns contribution of sample (0 or 1) */ float AddSample(T sample, const float pdf); /** Adds sample to PVS without checking for presence of the sample warning: pvs remains unsorted! */ void AddSampleDirty(T sample, const float pdf); /** Adds sample dirty (on the end of the vector) but first checks if sample is already in clean part of the pvs. */ bool AddSampleDirtyCheck(T sample, const float pdf); /** Sort pvs entries - this should always be called after a sequence of AddSampleDirty calls */ void Sort(); /** Sort pvs entries assume that the pvs contains unique entries */ void SimpleSort(); /** Adds sample to PVS. @returns PvsData */ typename std::vector >::iterator AddSample2(T sample, const float pdf); /** Subtracts one pvs from another one. WARNING: could contains bugs @returns new pvs size */ int SubtractPvs(const VerbosePvs &pvs); /** Returns PVS data, i.e., how often it was seen from the view cell, and the object itsef. */ void GetData(const int index, T &entry, S &data); /** Collects the PVS entries and returns them in the vector. */ void CollectEntries(std::vector &entries); /** Removes sample from PVS if reference count is zero. @param visibleSamples number of references to be removed */ bool RemoveSample(T sample, const float pdf); /** Compute continuous PVS difference */ void ComputeContinuousPvsDifference(VerbosePvs &pvs, float &pvsReduction, float &pvsEnlargement); /** Clears the pvs. */ void Clear(const bool trim = true); void Trim(); static int GetEntrySizeByte(); static float GetEntrySize(); /** Compute continuous PVS difference */ float GetPvsHomogenity(VerbosePvs &pvs); static void Merge(VerbosePvs &mergedPvs, const VerbosePvs &a, const VerbosePvs &b); int GetSamples() const { return mSamples; } bool IsDirty() const { return mLastSorted < mEntries.size(); } bool RequiresResort() const { // the last part should not be more than log of the sorted part. this // way we can achieve logarithmic behaviour for insertion and find const int n = mEntries.size(); const int dirtySize = n - mLastSorted; const double LOG2E = 1.442695040f; const float logN = log((float)max(1, n))/LOG2E; const float logS = log((float)max(1, mLastSorted))/LOG2E; const float logD = log((float)max(1, dirtySize))/LOG2E; if (8*(n + 2*dirtySize*logD) < mQueriesSinceSort*((mLastSorted*logS + dirtySize*dirtySize/2)/n - logN)) { // cout<<"Q="<