[2116] | 1 | #ifndef __PVSBASE_H
|
---|
| 2 | #define __PVSBASE_H
|
---|
| 3 |
|
---|
| 4 | #include "common.h"
|
---|
| 5 | #include "Containers.h"
|
---|
| 6 |
|
---|
| 7 |
|
---|
| 8 | namespace GtpVisibilityPreprocessor {
|
---|
| 9 |
|
---|
[2582] | 10 | /** Information stored with a PVS entry. Consists of the number
|
---|
| 11 | the object was seen from the view cell.
|
---|
| 12 | */
|
---|
| 13 | struct PvsData
|
---|
| 14 | {
|
---|
| 15 | public:
|
---|
| 16 | PvsData() {}
|
---|
| 17 | PvsData(const float sumPdf):
|
---|
| 18 | mSumPdf(sumPdf) {}
|
---|
| 19 |
|
---|
| 20 | // $$JB in order to return meaningfull values
|
---|
| 21 | // it assumes that the sum pdf has been normalized somehow!!!
|
---|
| 22 | inline float GetVisibility() { return mSumPdf; }
|
---|
[2116] | 23 |
|
---|
[2582] | 24 | /// sum of probability density of visible sample rays
|
---|
| 25 | float mSumPdf;
|
---|
| 26 | };
|
---|
| 27 |
|
---|
| 28 |
|
---|
| 29 | class MailablePvsData
|
---|
| 30 | {
|
---|
| 31 | public:
|
---|
| 32 | // sum of probability density of visible sample rays
|
---|
| 33 | float mSumPdf;
|
---|
| 34 | int mCounter;
|
---|
| 35 |
|
---|
| 36 | MailablePvsData() {}
|
---|
| 37 | MailablePvsData(const float sumPdf):
|
---|
| 38 | mSumPdf(sumPdf) {}
|
---|
| 39 |
|
---|
| 40 | // $$JB in order to return meaningfull values
|
---|
| 41 | // it assumes that the sum pdf has been normalized somehow!!!
|
---|
| 42 | inline float GetVisibility() { return mSumPdf; }
|
---|
| 43 |
|
---|
| 44 |
|
---|
| 45 | ///////////////
|
---|
| 46 | // Mailing stuff
|
---|
| 47 |
|
---|
| 48 | // last mail id -> warning not thread safe!
|
---|
| 49 | // both mailId and mailbox should be unique for each thread!!!
|
---|
| 50 | static int sMailId;
|
---|
| 51 | static int sReservedMailboxes;
|
---|
| 52 |
|
---|
| 53 | static void NewMail(const int reserve = 1)
|
---|
| 54 | {
|
---|
| 55 | sMailId += sReservedMailboxes;
|
---|
| 56 | sReservedMailboxes = reserve;
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | void Mail() { mMailbox = sMailId; }
|
---|
| 60 | bool Mailed() const { return mMailbox == sMailId; }
|
---|
| 61 |
|
---|
| 62 | void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
|
---|
| 63 | bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
|
---|
| 64 |
|
---|
| 65 | int IncMail() { return ++ mMailbox - sMailId; }
|
---|
| 66 |
|
---|
| 67 | //////////////////////////////////////////
|
---|
| 68 |
|
---|
| 69 | protected:
|
---|
| 70 |
|
---|
| 71 | int mMailbox;
|
---|
| 72 |
|
---|
| 73 | };
|
---|
| 74 |
|
---|
| 75 |
|
---|
[2116] | 76 | /** Information stored with a PVS entry. Consists of the number
|
---|
| 77 | the object was seen from the view cell.
|
---|
| 78 | */
|
---|
| 79 | template<typename T, typename S>
|
---|
| 80 | struct PvsEntry
|
---|
| 81 | {
|
---|
| 82 | public:
|
---|
| 83 |
|
---|
[2117] | 84 | PvsEntry(): mObject(NULL), mData(0) {}
|
---|
| 85 | PvsEntry(T sample): mObject(sample), mData(0) {}
|
---|
[2116] | 86 | PvsEntry(T sample, const S &data): mObject(sample), mData(data) {}
|
---|
| 87 |
|
---|
| 88 | T mObject;
|
---|
| 89 | S mData;
|
---|
| 90 |
|
---|
[2582] | 91 | //template<typename T, typename S>
|
---|
| 92 | friend int operator< (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b);
|
---|
| 93 | //template<typename T, typename S>
|
---|
| 94 | friend int operator== (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b);
|
---|
[2116] | 95 | };
|
---|
| 96 |
|
---|
| 97 |
|
---|
| 98 | template<typename T, typename S>
|
---|
| 99 | int operator< (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b)
|
---|
| 100 | {
|
---|
| 101 | return a.mObject < b.mObject;
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 | template<typename T, typename S>
|
---|
| 105 | int operator== (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b)
|
---|
| 106 | {
|
---|
| 107 | return a.mObject == b.mObject;
|
---|
| 108 | }
|
---|
| 109 |
|
---|
| 110 |
|
---|
| 111 | template<typename T, typename S>
|
---|
| 112 | struct LtSample
|
---|
| 113 | {
|
---|
| 114 | bool operator()(const PvsEntry<T, S> &a, const PvsEntry<T, S> &b) const
|
---|
| 115 | {
|
---|
| 116 | return a.mObject < b.mObject;
|
---|
| 117 | }
|
---|
| 118 | };
|
---|
| 119 |
|
---|
| 120 | template<typename T, typename S>
|
---|
| 121 | int equalSample (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b)
|
---|
| 122 | {
|
---|
| 123 | return a.mObject == b.mObject;
|
---|
| 124 | }
|
---|
| 125 |
|
---|
[2582] | 126 |
|
---|
| 127 | /** Iterator over the pvs.
|
---|
[2116] | 128 | */
|
---|
[2582] | 129 | template<typename T, typename S>
|
---|
| 130 | class PvsIterator
|
---|
[2116] | 131 | {
|
---|
| 132 | public:
|
---|
[2582] | 133 | PvsIterator<T, S>(){}
|
---|
| 134 | PvsIterator<T, S>(const typename vector<PvsEntry<T, S> >::const_iterator &itCurrent,
|
---|
| 135 | const typename vector<PvsEntry<T, S> >::const_iterator &itEnd):
|
---|
| 136 | mItCurrent(itCurrent), mItEnd(itEnd)
|
---|
| 137 | {
|
---|
| 138 | }
|
---|
| 139 |
|
---|
| 140 | inline bool HasMoreEntries() const { return (mItCurrent != mItEnd); }
|
---|
| 141 |
|
---|
| 142 | inline T Next(S &pdf) {
|
---|
| 143 | pdf = (*mItCurrent).mData;
|
---|
| 144 | return (*(mItCurrent ++)).mObject;
|
---|
| 145 | }
|
---|
| 146 |
|
---|
| 147 | inline T Next() { return (*(mItCurrent ++)).mObject; }
|
---|
| 148 |
|
---|
| 149 |
|
---|
| 150 | private:
|
---|
[2116] | 151 |
|
---|
[2582] | 152 | typename vector<PvsEntry<T, S> >::const_iterator mItCurrent;
|
---|
| 153 | typename vector<PvsEntry<T, S> >::const_iterator mItEnd;
|
---|
| 154 | };
|
---|
[2116] | 155 |
|
---|
[2582] | 156 |
|
---|
| 157 |
|
---|
| 158 |
|
---|
| 159 | struct VerbosePvsStats
|
---|
| 160 | {
|
---|
| 161 | VerbosePvsStats(): mDistanceWeightedTriangles(0), mDistanceWeightedPvs(0), mWeightedTriangles(0)
|
---|
| 162 | {}
|
---|
| 163 |
|
---|
| 164 | float mDistanceWeightedTriangles;
|
---|
| 165 | float mDistanceWeightedPvs;
|
---|
| 166 | float mWeightedTriangles;
|
---|
[2116] | 167 | };
|
---|
| 168 |
|
---|
| 169 |
|
---|
[2582] | 170 | /** Template class representing the Potentially Visible Set (PVS)
|
---|
| 171 | mainly from a view cell, but also e.g., from objects.
|
---|
| 172 | */
|
---|
| 173 | template<typename T, typename S>
|
---|
| 174 | class VerbosePvs
|
---|
[2116] | 175 | {
|
---|
[2582] | 176 | template<typename T1, typename S1> friend class PvsIterator;
|
---|
| 177 |
|
---|
[2116] | 178 | public:
|
---|
| 179 |
|
---|
[2582] | 180 | VerbosePvs(): mSamples(0), mEntries(), mLastSorted(0), mQueriesSinceSort(0)
|
---|
| 181 | {}
|
---|
[2116] | 182 |
|
---|
[2582] | 183 | /** creates pvs and initializes it with the given entries.
|
---|
| 184 | Assumes that entries are sorted.
|
---|
| 185 | */
|
---|
| 186 | VerbosePvs(const vector<PvsEntry<T, S> > &samples);
|
---|
| 187 | virtual ~VerbosePvs() {};
|
---|
[2116] | 188 |
|
---|
[2582] | 189 | /** Compresses PVS lossless or lossy.
|
---|
| 190 | */
|
---|
| 191 | int Compress() { return 0; }
|
---|
| 192 |
|
---|
| 193 | inline int GetSize() const { return (int)mEntries.size(); }
|
---|
| 194 |
|
---|
| 195 | inline bool Empty() const { return mEntries.empty(); }
|
---|
[2529] | 196 |
|
---|
[2582] | 197 | inline void Reserve(const int n) { mEntries.reserve(n); }
|
---|
| 198 | /** Normalize the visibility of entries in order to get
|
---|
| 199 | comparable results.
|
---|
| 200 | */
|
---|
| 201 | void NormalizeMaximum();
|
---|
| 202 | /** Merges pvs of a into this pvs.
|
---|
| 203 | Warning: very slow!
|
---|
| 204 | */
|
---|
| 205 | void MergeInPlace(const VerbosePvs<T, S> &a);
|
---|
| 206 | /** Difference of pvs to pvs b.
|
---|
| 207 | @returns number of different entries.
|
---|
| 208 | */
|
---|
| 209 | int Diff(const VerbosePvs<T, S> &b);
|
---|
| 210 | /** Finds sample in PVS.
|
---|
| 211 | @param checkDirty if dirty part of the pvs should be checked for entry
|
---|
| 212 | (warning: linear runtime in dirty part)
|
---|
| 213 | @returns iterator on the sample if found, else the place where
|
---|
| 214 | it would be added in the sorted vector.
|
---|
| 215 | */
|
---|
| 216 | bool Find(T sample,
|
---|
| 217 | typename vector<PvsEntry<T, S> >::iterator &it,
|
---|
| 218 | const bool checkDirty = true);
|
---|
[2116] | 219 |
|
---|
[2582] | 220 | bool GetSampleContribution(T sample, const float pdf, float &contribution);
|
---|
| 221 | /** Adds sample to PVS.
|
---|
| 222 | @returns contribution of sample (0 or 1)
|
---|
| 223 | */
|
---|
| 224 | float AddSample(T sample, const float pdf);
|
---|
| 225 | /** Adds sample to PVS without checking for presence of the sample
|
---|
| 226 | warning: pvs remains unsorted!
|
---|
| 227 | */
|
---|
| 228 | void AddSampleDirty(T sample, const float pdf);
|
---|
| 229 | /** Adds sample dirty (on the end of the vector) but
|
---|
| 230 | first checks if sample is already in clean part of the pvs.
|
---|
| 231 | */
|
---|
| 232 | bool AddSampleDirtyCheck(T sample, const float pdf);
|
---|
| 233 | /** Sort pvs entries. This should always be called after a
|
---|
| 234 | sequence of AddSampleDirty calls
|
---|
| 235 | */
|
---|
| 236 | void Sort();
|
---|
| 237 | /** Sort pvs entries assume that the pvs contains unique entries
|
---|
| 238 | */
|
---|
| 239 | void SimpleSort();
|
---|
| 240 | /** Adds sample to PVS.
|
---|
| 241 | @returns PvsData
|
---|
| 242 | */
|
---|
| 243 | typename std::vector<PvsEntry<T, S> >::iterator
|
---|
| 244 | AddSample2(T sample, const float pdf);
|
---|
| 245 | /** Subtracts one pvs from another one.
|
---|
| 246 | WARNING: could contains bugs
|
---|
| 247 | @returns new pvs size
|
---|
| 248 | */
|
---|
| 249 | int SubtractPvs(const VerbosePvs<T, S> &pvs);
|
---|
[2116] | 250 |
|
---|
[2582] | 251 | /** Returns PVS data, i.e., how often it was seen from the view cell,
|
---|
| 252 | and the object itsef.
|
---|
| 253 | */
|
---|
| 254 | void GetData(const int index, T &entry, S &data);
|
---|
| 255 |
|
---|
| 256 | /** Collects the PVS entries and returns them in the vector.
|
---|
| 257 | */
|
---|
| 258 | void CollectEntries(std::vector<T> &entries);
|
---|
| 259 |
|
---|
| 260 | /** Removes sample from PVS if reference count is zero.
|
---|
| 261 | @param visibleSamples number of references to be removed
|
---|
| 262 | */
|
---|
| 263 | bool RemoveSample(T sample, const float pdf);
|
---|
| 264 |
|
---|
| 265 | /** Compute continuous PVS difference
|
---|
| 266 | */
|
---|
| 267 | void ComputeContinuousPvsDifference(VerbosePvs<T, S> &pvs,
|
---|
| 268 | float &pvsReduction,
|
---|
| 269 | float &pvsEnlargement);
|
---|
| 270 |
|
---|
| 271 | /** Clears the pvs.
|
---|
| 272 | */
|
---|
| 273 | void Clear(const bool trim = true);
|
---|
| 274 | /** Trim the vector containing the pvs.
|
---|
| 275 | */
|
---|
| 276 | void Trim();
|
---|
| 277 |
|
---|
| 278 | static int GetEntrySizeByte();
|
---|
| 279 | static float GetEntrySize();
|
---|
| 280 |
|
---|
| 281 | /** Compute continuous PVS difference
|
---|
| 282 | */
|
---|
| 283 | float GetPvsHomogenity(VerbosePvs<T, S> &pvs);
|
---|
| 284 |
|
---|
| 285 | static void Merge(VerbosePvs<T, S> &mergedPvs,
|
---|
| 286 | const VerbosePvs<T, S> &a,
|
---|
| 287 | const VerbosePvs<T, S> &b);
|
---|
| 288 |
|
---|
| 289 | inline int GetSamples() const { return mSamples; }
|
---|
| 290 |
|
---|
| 291 | /** If there is an unsorted part in the pvs.
|
---|
| 292 | */
|
---|
| 293 | bool IsDirty() const { return mLastSorted < mEntries.size(); }
|
---|
| 294 |
|
---|
| 295 | /** If this pvs requires a resort to stay efficient.
|
---|
| 296 | */
|
---|
| 297 | bool RequiresResort() const
|
---|
[2116] | 298 | {
|
---|
[2582] | 299 | // the last part should not be more than log of the sorted part. this
|
---|
| 300 | // way we can achieve logarithmic behaviour for insertion and find
|
---|
| 301 | const int n = mEntries.size();
|
---|
| 302 | const int dirtySize = n - mLastSorted;
|
---|
| 303 |
|
---|
| 304 | const double LOG2E = 1.442695040f;
|
---|
| 305 |
|
---|
| 306 | const float logN = log((float) Max(1, n))/LOG2E;
|
---|
| 307 | const float logS = log((float) Max(1, mLastSorted))/LOG2E;
|
---|
| 308 | const float logD = log((float) Max(1, dirtySize))/LOG2E;
|
---|
| 309 |
|
---|
| 310 | if (8*(n + 2*dirtySize*logD) <
|
---|
| 311 | mQueriesSinceSort*((mLastSorted*logS + dirtySize*dirtySize/2)/n - logN))
|
---|
| 312 | {
|
---|
| 313 | // cout<<"Q="<<mQueriesSinceSort<<" N="<<n<<" D="<<dirtySize<<endl;
|
---|
| 314 | return true;
|
---|
| 315 | }
|
---|
| 316 |
|
---|
| 317 | return false;
|
---|
[2116] | 318 | }
|
---|
| 319 |
|
---|
[2582] | 320 | /** If this pvs requires a resort to stay efficient.
|
---|
| 321 | */
|
---|
| 322 | bool RequiresResortLog() const
|
---|
| 323 | {
|
---|
| 324 | // the last part should not be more than log of the sorted part. this
|
---|
| 325 | // way we can achieve logarithmic behaviour for insertion and find
|
---|
| 326 | const int dirtySize = (int)mEntries.size() - mLastSorted;
|
---|
| 327 | return dirtySize > 4 * (int)(log((double)mEntries.size()) / log(2.0));
|
---|
| 328 | }
|
---|
[2116] | 329 |
|
---|
[2582] | 330 | inline int GetLastSorted() const { return mLastSorted; }
|
---|
[2116] | 331 |
|
---|
[2582] | 332 | PvsIterator<T, S> GetIterator() const;
|
---|
[2116] | 333 |
|
---|
[2582] | 334 | VerbosePvsStats mStats;
|
---|
| 335 |
|
---|
[2116] | 336 | protected:
|
---|
| 337 |
|
---|
[2582] | 338 | /** Merge pvs 1 from begin iterator to end iterator with
|
---|
| 339 | pvs 2 from begin iterator to end iterator.
|
---|
| 340 | */
|
---|
| 341 | static void Merge(VerbosePvs<T, S> &mergedPvs,
|
---|
| 342 | const typename std::vector<PvsEntry<T, S> >::const_iterator &aBegin,
|
---|
| 343 | const typename std::vector<PvsEntry<T, S> >::const_iterator &aEnd,
|
---|
| 344 | const typename std::vector<PvsEntry<T, S> >::const_iterator &bBegin,
|
---|
| 345 | const typename std::vector<PvsEntry<T, S> >::const_iterator &bEnd,
|
---|
| 346 | const int aSamples,
|
---|
| 347 | const int bSamples);
|
---|
[2116] | 348 |
|
---|
[2582] | 349 |
|
---|
| 350 | //////////////////////////////
|
---|
| 351 |
|
---|
| 352 | /// vector of PVS entries
|
---|
| 353 | vector<PvsEntry<T, S> > mEntries;
|
---|
| 354 |
|
---|
| 355 | /// Number of samples used to create the PVS
|
---|
| 356 | int mSamples;
|
---|
| 357 |
|
---|
| 358 | /// Last sorted entry in the pvs (important for find and merge)
|
---|
| 359 | int mLastSorted;
|
---|
| 360 |
|
---|
| 361 | int mQueriesSinceSort;
|
---|
[2116] | 362 | };
|
---|
| 363 |
|
---|
[2582] | 364 |
|
---|
[2116] | 365 | }
|
---|
| 366 |
|
---|
[2582] | 367 | #endif
|
---|