source: GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h @ 2019

Revision 2019, 21.2 KB checked in by bittner, 17 years ago (diff)

merge

RevLine 
[177]1#ifndef __PVS_H
2#define __PVS_H
3
4#include <map>
[469]5#include <vector>
[1189]6#include "common.h"
[2019]7#include <math.h>
8using namespace std;
[177]9
[860]10namespace GtpVisibilityPreprocessor {
11
[177]12class KdNode;
[240]13class BspNode;
[191]14class Ray;
[308]15class Intersectable;
[1077]16class ViewCell;
[177]17
[1077]18
[1740]19/** Information stored with a PVS entry. Consists of the number
20        the object was seen from the view cell.
21*/
22template<typename T, typename S>
[1998]23struct PvsEntry
[1189]24{
[1740]25public:
26
[1741]27        PvsEntry() {}
28
[1740]29        PvsEntry(T sample, const S &data): mObject(sample), mData(data) {}
30
31        T mObject;
32        S mData;
33
34        template<typename T, typename S>
35        friend int operator< (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b);
[1789]36        template<typename T, typename S>
37        friend int operator== (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b);
[1740]38};
39
40
41template<typename T, typename S>
42int operator< (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b)
43{
44        return a.mObject < b.mObject;
45}
46
[1789]47template<typename T, typename S>
48int operator== (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b)
49{
50        return a.mObject == b.mObject;
51}
[1740]52
[1789]53
[1740]54template<typename T, typename S>
55struct LtSample
56{
57    bool operator()(const PvsEntry<T, S> &a, const PvsEntry<T, S> &b) const
[310]58    {
[1740]59                return a.mObject < b.mObject;
[310]60        }
61};
62
[1789]63template<typename T, typename S>
64int equalSample (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b)
65{
66        return a.mObject == b.mObject;
67}
[1740]68
[469]69/** Information stored with a PVS entry. Consists of the number
70        the object was seen from the view cell.
71*/
[1998]72struct PvsData {
[1189]73public:
[1706]74        PvsData() {}
75        PvsData(const float sumPdf):
[1189]76        mSumPdf(sumPdf) {}
[1740]77       
[1706]78        // $$JB in order to return meaningfull values
79        // it assumes that the sum pdf has been normalized somehow!!!
[1740]80        inline float GetVisibility()
[1706]81        {
82                return mSumPdf;
83        }
[1740]84
85        /// sum of probability density of visible sample rays
86        float mSumPdf;
[1189]87};
88
89
90class MailablePvsData
91{
[1740]92public:
93        // sum of probability density of visible sample rays
94        float mSumPdf;
95        int mCounter;
96
97        MailablePvsData() {}
98        MailablePvsData(const float sumPdf):
99        mSumPdf(sumPdf) {}
100
101        // $$JB in order to return meaningfull values
102        // it assumes that the sum pdf has been normalized somehow!!!
103        float GetVisibility()
104        {
105                return mSumPdf;
106        }
107
[1706]108        ////////////////////////////
109        //  Mailing stuff
[1184]110
[1706]111        // last mail id -> warning not thread safe!
112        // both mailId and mailbox should be unique for each thread!!!
113        static int sMailId;
114        static int sReservedMailboxes;
115
[1184]116        static void NewMail(const int reserve = 1) {
117                sMailId += sReservedMailboxes;
118                sReservedMailboxes = reserve;
119        }
[1706]120
[1184]121        void Mail() { mMailbox = sMailId; }
122        bool Mailed() const { return mMailbox == sMailId; }
123
124        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
125        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
126
127        int IncMail() { return ++ mMailbox - sMailId; }
[1740]128       
[1706]129        //////////////////////////////////////////
[1184]130
[1740]131protected:
[1184]132
[1740]133        int mMailbox;
[556]134
[310]135};
[1740]136
137
[1742]138template<typename T, typename S>
139class PvsIterator
140{
141public:
142PvsIterator<T, S>(){}
143        PvsIterator<T, S>(const typename vector<PvsEntry<T, S> >::const_iterator &itCurrent,
144                                          const typename vector<PvsEntry<T, S> >::const_iterator &itEnd):
145        mItCurrent(itCurrent), mItEnd(itEnd)
146        {
147        }
148
149        bool HasMoreEntries() const
150        {
151                return (mItCurrent != mItEnd);
152        }
153
[1744]154        const PvsEntry<T, S> &Next()
[1742]155        {
156                return *(mItCurrent ++);
157        }
158       
159private:
160        typename vector<PvsEntry<T, S> >::const_iterator mItCurrent;
161        typename vector<PvsEntry<T, S> >::const_iterator mItEnd;
[1740]162};
163
164
[469]165/** Template class representing the Potentially Visible Set (PVS)
166        mainly from a view cell, but also e.g., from objects.
167*/
[1189]168template<typename T, typename S>
[311]169class Pvs
[310]170{
[1740]171        template<typename T, typename S>
172        friend class PvsIterator;
173
[310]174public:
[2019]175 
176        Pvs(): mSamples(0), mEntries(), mLastSorted(0), mQueriesSinceSort(0) {}
[1738]177
[1742]178        /** creates pvs and initializes it with the given entries.
179                Assumes that entries are sorted-
180        */
[1740]181        Pvs(const vector<PvsEntry<T, S> > &samples);
[1742]182        virtual ~Pvs() {};
[492]183
[1706]184        /** Compresses PVS lossless or lossy.
185        */
186        int Compress() {return 0;}
187        int GetSize() const {return (int)mEntries.size();}
[1925]188        bool Empty() const {return mEntries.empty();}
[469]189
[1925]190        void Reserve(const int n) { mEntries.reserve(n); }
191
[1740]192        /** Normalize the visibility of entries in order to get
193                comparable results.
[1706]194        */
195        void NormalizeMaximum();
[1184]196
[1706]197        /** Merges pvs of a into this pvs.
[1740]198                Warning: very slow!
[1706]199        */
[1740]200        void MergeInPlace(const Pvs<T, S> &a);
[752]201
[1706]202        /** Difference of pvs to pvs b.
203                @returns number of different entries.
204        */
205        int Diff(const Pvs<T, S> &b);
[469]206
[1706]207        /** Finds sample in PVS.
[1789]208                @param checkDirty if dirty part of the pvs should be checked for entry
209                        (warning: linear runtime in dirty part)
[1740]210                @returns iterator on the sample.
[1706]211        */
[1790]212        bool Find(T sample,
213                          typename vector<PvsEntry<T, S> >::iterator &it,
214                          const bool checkDirty = true);
[469]215
[1706]216        bool GetSampleContribution(T sample, const float pdf, float &contribution);
[485]217
[1706]218        /** Adds sample to PVS.
219                @returns contribution of sample (0 or 1)
220        */
221        float AddSample(T sample, const float pdf);
[1757]222
[1789]223        /** Adds sample to PVS without checking for presence of the sample
224                pvs remains unsorted!
225        */
226        void AddSampleDirty(T sample, const float pdf);
[1757]227
[1789]228        /** Adds sample dirty (on the end of the vector) but
229                first checks if sample is already in clean part of the pvs.
230        */
231        bool AddSampleDirtyCheck(T sample, const float pdf);//, float &contribution);
232
233        /** Sort pvs entries - this should always be called after a
234                sequence of AddSampleDirty calls
235        */
236        void Sort();
237
[1877]238  /** Sort pvs entries assume that the pvs contains unique entries
239   */
240  void SimpleSort();
241
[1742]242        /** Adds sample to PVS. Assumes that the pvs is sorted
[1740]243                @returns contribution of sample (0 or 1)
244        */
[1844]245        //float AddSamples(const vector<PvsEntry<T, S> > &samples);
[752]246
[1706]247        /** Adds sample to PVS.
248                @returns PvsData
249        */
[1740]250        typename std::vector<PvsEntry<T, S> >::iterator AddSample2(T sample, const float pdf);
[1667]251
[1706]252        /** Subtracts one pvs from another one.
253                WARNING: could contains bugs
254                @returns new pvs size
255        */
256        int SubtractPvs(const Pvs<T, S> &pvs);
[1740]257
[1706]258        /** Returns PVS data, i.e., how often it was seen from the view cell,
259                and the object itsef.
260        */
261        void GetData(const int index, T &entry, S &data);
262
263        /** Collects the PVS entries and returns them in the vector.
264        */
265        void CollectEntries(std::vector<T> &entries);
266
267        /** Removes sample from PVS if reference count is zero.
268                @param visibleSamples number of references to be removed
269        */
270        bool RemoveSample(T sample, const float pdf);
271
272        /** Compute continuous PVS difference
273        */
[1740]274        void ComputeContinuousPvsDifference(Pvs<T, S> &pvs,
275                                                                                float &pvsReduction,
276                                                                                float &pvsEnlargement);
[1706]277
278        /** Clears the pvs.
279        */
[1750]280        void Clear(const bool trim = true);
[1706]281
[1750]282        void Trim();
283
[1706]284        static int GetEntrySizeByte();
285        static float GetEntrySize();
286
[1740]287        /** Compute continuous PVS difference
288        */
289        float GetPvsHomogenity(Pvs<T, S> &pvs);
[1706]290
[1740]291        static void Merge(Pvs<T, S> &mergedPvs, const Pvs<T, S> &a, const Pvs<T, S> &b);
[1706]292
[1789]293        static void Merge(Pvs<T, S> &mergedPvs,
294                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aBegin,
295                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aEnd,
296                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bBegin,
297                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bEnd,
298                                          const int aSamples,
299                                          const int bSamples);
300
[1742]301        int GetSamples() const
302        {
303                return mSamples;
304        }
[1738]305
[1789]306
307        bool IsDirty() const
308        {
309                return mLastSorted < mEntries.size();
310        }
311
312        bool RequiresResort() const
313        {
[2015]314          // the last part should not be more than log of the sorted part. this
315          // way we can achieve logarithmic behaviour for insertion and find
[2019]316          const int n = mEntries.size();
317          const int dirtySize = n - mLastSorted;
318
319#define LOG2E 1.442695040f
320         
321          const float logN = log((float)max(1, n))/LOG2E;
322          const float logS = log((float)max(1, mLastSorted))/LOG2E;
323          const float logD = log((float)max(1, dirtySize))/LOG2E;
324         
325          if (8*(n + 2*dirtySize*logD) <
326                  mQueriesSinceSort*((mLastSorted*logS + dirtySize*dirtySize/2)/n - logN)) {
327                //              cout<<"Q="<<mQueriesSinceSort<<" N="<<n<<" D="<<dirtySize<<endl;
328                return true;
329          }
330          return false;
[1789]331        }
332
[2015]333  bool RequiresResortLog() const
334  {
335        // the last part should not be more than log of the sorted part. this
336        // way we can achieve logarithmic behaviour for insertion and find
337        const int dirtySize = (int)mEntries.size() - mLastSorted;
338        return dirtySize > 4*(int)(log((double)mEntries.size()) / log(2.0));
339  }
340 
341 
[1789]342        int GetLastSorted() const
343        {
344                return mLastSorted;
345        }
346
[1742]347        typename PvsIterator<T, S> GetIterator() const;
348
349protected:
350
[1738]351        /// vector of PVS entries
[1740]352        vector<PvsEntry<T, S> > mEntries;
[1736]353       
354        /// Number of samples used to create the PVS
355        int mSamples;
[1757]356 
[1789]357        /// Last sorted entry in the pvs (important for find and merge)
[2019]358        int mLastSorted;
359
360  int mQueriesSinceSort;
[310]361};
362
[581]363
[1740]364template <typename T, typename S>
365Pvs<T, S>::Pvs(const vector<PvsEntry<T, S> > &samples)
366{
367        mEntries.reserve(samples.size());
368        mEntries = samples;
[1757]369        mLastSorted = 0;
[1789]370        mSamples = samples.size();
[1740]371}
[677]372
[1789]373
[1757]374template <typename T, typename S>
375void Pvs<T, S>::Sort()
376{
[1789]377        std::vector<PvsEntry<T, S> >::iterator it = mEntries.begin() + mLastSorted;
378        //std::vector<PvsEntry<T, S> >::const_iterator it = mEntries.begin() + mLastSorted;
379        std::vector<PvsEntry<T, S> >::iterator it_end = mEntries.end();
380
381        // throw out double entries
382        std::vector<PvsEntry<T, S> >::iterator newEnd = unique(it, it_end);
383        sort(it, newEnd);
384        //sort(mEntries.begin(), mEntries.end());
[2019]385       
[1789]386        // now merge sorted ranges
387        ObjectPvs newPvs;
388        Merge(newPvs,
[2019]389                  mEntries.begin(),
390                  it,
391                  it,
392                  newEnd,
393                  mSamples,
394                  0);
[1789]395       
396        mEntries = newPvs.mEntries;
397        mLastSorted = (int)mEntries.size();
[2019]398        mQueriesSinceSort = 0;
[1757]399}
[1740]400
[1877]401template <typename T, typename S>
402void Pvs<T, S>::SimpleSort()
403{
[2019]404  //  sort(mEntries.begin(), mEntries.end());
405  std::vector<PvsEntry<T, S> >::iterator it = mEntries.begin() + mLastSorted;
406 
407  sort(it, mEntries.end());
408  inplace_merge(mEntries.begin(), it, mEntries.end());
409 
[1877]410  mLastSorted = (int)mEntries.size();
[2019]411  mQueriesSinceSort = 0;
[1877]412}
[1789]413
[1877]414
[695]415/**
416   Compute continuous PVS difference of 'b' with respect to the base PVS (*this).
417   Provides separatelly PVS reduction from PVS enlargement.
418
419*/
[1189]420template <typename T, typename S>
[677]421void
[1189]422Pvs<T, S>::ComputeContinuousPvsDifference(Pvs<T, S> &b,
[1740]423                                                                                  float &pvsReduction,
424                                                                                  float &pvsEnlargement)
[677]425{
[705]426        pvsReduction = 0.0f;
427        pvsEnlargement = 0.0f;
[1740]428
[1738]429        // Uses sum of log differences, which corresponds to entropy
[1740]430        std::vector<PvsEntry<T, S> >::iterator it;
[1738]431
432        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
[1189]433        {
[1740]434                float bSumPdf = (*it).mData.mSumPdf;
[1738]435                float aSumPdf = 0.0f;
[713]436
[1790]437                vector<PvsEntry<T, S> >::iterator oit;
438                const bool entryFound = Find((*it).mObject, oit);               
[1740]439
440                if (entryFound)
[1738]441                {
[1740]442                        aSumPdf = (*it).mData.mSumPdf;
443
[1738]444                        // mark this entry as processed to avoid double counting
[1740]445                        (*it).mData.mSumPdf = -aSumPdf;
[1738]446                }
447
[713]448#if 0
[1740]449                const float diff = bSumPdf - aSumPdf;
[1738]450
451                if (diff > 0.0f) {
452                        pvsEnlargement += diff;
453                } else {
454                        pvsReduction += -diff;
455                }
[713]456#else
[1740]457                if (!entryFound)
[1738]458                        pvsEnlargement += 1.0f;
[713]459#endif
[1738]460        }
461
[1740]462        for (it = mEntries.begin(); it != mEntries.end(); ++ it)
463        {
464                float aSumPdf = (*it).mData.mSumPdf;
[1738]465                float bSumPdf = 0.0f;
466                if (aSumPdf < 0.0f) {
[1740]467               
[1738]468                        // this entry was already accounted for!
469                        // just revert it back
[1740]470                        (*it).mData.mSumPdf = -aSumPdf;
[1738]471                } else {
[1790]472                        vector<PvsEntry<T, S> >::iterator oit;
473               
474                        const bool entryFound = b.Find((*it).mObject, oit);
475                                               
[1740]476                        if (entryFound) {
477                                bSumPdf = (*oit).mData.mSumPdf;
[1738]478                        }
[713]479#if 0
[1740]480                        const float diff = bSumPdf - aSumPdf;
[713]481
[1738]482                        if (diff > 0.0f) {
483                                pvsEnlargement += diff;
484                        } else {
485                                pvsReduction += -diff;
486                        }
487
[713]488#else
[1740]489                        if (!entryFound)
[1738]490                                pvsReduction += 1.0f;
[713]491#endif
[1738]492                }
[695]493        }
[677]494}
495
[1738]496
[1189]497template <typename T, typename S>
498int Pvs<T, S>::Diff(const Pvs<T, S> &b)
[362]499{
500        int dif = 0;
501
[1740]502        std::vector<PvsEntry<T, S> >::const_iterator it;
[362]503
504        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
505        {
[1790]506                vector<PvsEntry<T, S> >::iterator bit;
507                const bool entryFound = Find((*it).first, bit);
508
509                if (!entryFound) ++ dif;
[362]510        }
511
512        return dif;
513}
514
[1740]515
516template <typename T, typename S>
517void Pvs<T, S>::MergeInPlace(const Pvs<T, S> &a)
[341]518{
[1786]519        // early exit
520        if (a.Empty())
521        {
522                return;
523        }
524        else if (Empty())
525        {
526                mEntries.reserve(a.GetSize());
527                mEntries = a.mEntries;
528                mSamples = a.mSamples;
529                return;
530        }
531
[1740]532        ObjectPvs interPvs;
533       
534        Merge(interPvs, *this, a);
535       
536        mEntries.reserve(interPvs.GetSize());
537        mEntries = interPvs.mEntries;
[1751]538        mSamples = interPvs.mSamples;
[1740]539}
540
541
542template <typename T, typename S>
543void Pvs<T, S>::Merge(Pvs<T, S> &mergedPvs, const Pvs<T, S> &a, const Pvs<T, S> &b)
544{
545        std::vector<PvsEntry<T, S> >::const_iterator ait = a.mEntries.begin(), ait_end = a.mEntries.end();
546        std::vector<PvsEntry<T, S> >::const_iterator bit = b.mEntries.begin(), bit_end = b.mEntries.end();
[1741]547       
[1789]548        Merge(mergedPvs,
549                  ait, ait_end,
550                  bit, bit_end,
551                  a.mSamples,
552                  b.mSamples);
553}
554
555
556template <typename T, typename S>
557void Pvs<T, S>::Merge(Pvs<T, S> &mergedPvs,
558                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aBegin,
559                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aEnd,
560                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bBegin,
561                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bEnd,
562                                          const int aSamples,
563                                          const int bSamples)
564{
565        std::vector<PvsEntry<T, S> >::const_iterator ait = aBegin;
566        std::vector<PvsEntry<T, S> >::const_iterator bit = bBegin;
567       
568        for (; (ait != aEnd); ++ ait)
[1741]569        {
570                Intersectable *aObj = (*ait).mObject;
571                Intersectable *bObj = NULL;
[1789]572                //Intersectable *bObjOld = NULL;
573       
574                const PvsEntry<T, S> &aEntry = (*ait);
[1740]575
[1789]576                for (; (bit != bEnd) && ((*bit).mObject <= (*ait).mObject); ++ bit)
[1741]577                {
578                        bObj = (*bit).mObject;
579
580                        // object found => add up probabilities
[1742]581                        if (bObj == aEntry.mObject)
[1741]582                        {
583                                PvsData newData(aEntry.mData.mSumPdf + (*bit).mData.mSumPdf);
584                                PvsEntry<T, S> entry(bObj, newData);
585                                mergedPvs.mEntries.push_back(entry);
586                        }
587                        else
588                        {
589                                mergedPvs.mEntries.push_back(*bit);
590                        }
[1789]591                       
592                        //bObjOld = bObj;
[1741]593                }
594
595                // only push back if objects different
596                // (equal case is handled by second loop)
597                if (aObj != bObj)
598                {
599                        mergedPvs.mEntries.push_back(*ait);
600                }
601        }
602
603        // add the rest
[1789]604        for (; (bit != bEnd); ++ bit)
[1740]605        {
[1741]606                mergedPvs.mEntries.push_back(*bit);
607        }
[1789]608
609        mergedPvs.mSamples = aSamples + bSamples;
[1740]610}
611
612
[1750]613template <typename T, typename S> void Pvs<T, S>::Clear(const bool trim = true)
[752]614{
615        mEntries.clear();
[1750]616        mSamples = 0;
[1789]617        mLastSorted = 0;
[1786]618
619        if (trim)
620        {
621                vector<PvsEntry<T,S> >().swap(mEntries);
622        }
[752]623}
624
625
[1750]626template <typename T, typename S> void Pvs<T, S>::Trim()
627{
[1786]628        vector<PvsEntry<T,S> >(mEntries).swap(mEntries);
[1750]629}
630
631
[1189]632template <typename T, typename S>
[1790]633bool Pvs<T, S>::Find(T sample,
634                                         typename vector<PvsEntry<T, S> >::iterator &it,
635                                         const bool checkDirty)
[310]636{
[1877]637  PvsEntry<T, S> dummy(sample, PvsData());
[2019]638  mQueriesSinceSort++;
[1877]639 
640  // only check clean part
641  vector<PvsEntry<T, S> >::iterator sorted_end = mEntries.begin() + mLastSorted;
642 
643  // binary search
644  it = lower_bound(mEntries.begin(), sorted_end, dummy);
645 
646  if ((it != mEntries.end()) && ((*it).mObject == sample))
[2015]647        //  if (it != sorted_end)
648        return true;
[1877]649 
650  // sample not found yet => search further in the unsorted part
[2015]651  if (checkDirty) {
[1790]652       
[1942]653        for (it = sorted_end; (it != mEntries.end()) && ((*it).mObject != sample); ++ it) ;
[1877]654       
[1942]655        if (it != mEntries.end())
[2015]656          return true;
[1877]657  }
658 
[2015]659  return false;
[310]660}
661
[1740]662
[1189]663template <typename T, typename S>
[1740]664void Pvs<T, S>::GetData(const int index, T &entry, S &data)
[310]665{
[1740]666        std::vector<PvsEntry<T, S> >::iterator i = mEntries.begin();
[1738]667        for (int k = 0; k != index && i != mEntries.end(); ++ i, ++ k);
[310]668
[1738]669        entry = (*i).first;
670        data = (*i).second;
[310]671}
672
[1738]673
[1189]674template <typename T, typename S>
[1740]675float Pvs<T, S>::AddSample(T sample, const float pdf)
[177]676{
[1738]677        ++ mSamples;
[1790]678       
679        vector<PvsEntry<T, S> >::iterator it;
680        const bool entryFound = Find(sample, it);               
[1738]681
[1790]682        if (entryFound)
683        {       
[1740]684                S &data = (*it).mData;
685                data.mSumPdf += pdf;
686                return data.mSumPdf;
[1189]687        }
[1738]688        else
[1942]689          {
[1740]690                PvsEntry<T, S> entry(sample, pdf);
691                mEntries.insert(it, entry);
[1789]692                ++ mLastSorted;
[1738]693                return pdf;
[1942]694          }
[466]695}
[177]696
[1189]697
698template <typename T, typename S>
[1757]699void Pvs<T, S>::AddSampleDirty(T sample, const float pdf)
700{
[1789]701        ++ mSamples;
702        mEntries.push_back(PvsEntry<T, S>(sample, pdf));
[1757]703}
704                                         
705
706template <typename T, typename S>
[1790]707typename vector< PvsEntry<T, S> >::iterator Pvs<T, S>::AddSample2(T sample,
708                                                                                                                                  const float pdf)
[1184]709{
[1740]710        ++ mSamples;
[1789]711       
[1790]712        vector<PvsEntry<T, S> >::iterator it;
713        const bool entryFound == Find(sample, it);
[1740]714
[1790]715        if (entryFound)
[1189]716        {
[1740]717                S &data = (*it).second;
718                data->mSumPdf += pdf;
[1189]719        }
[1740]720        else
[1189]721        {
[1740]722                PvsEntry<T, S> entry(sample, pdf);
723                mEntries.insert(it, entry);
[1789]724                ++ mLastSorted;
[1189]725        }
[1740]726
727        return it;
[1184]728}
729
[1740]730
[1789]731/** Adds sample dirty (on the end of the vector) but
732        first checks if sample is already in clean part of the pvs.
733*/
734template <typename T, typename S>
735bool Pvs<T, S>::AddSampleDirtyCheck(T sample,
736                                                                        const float pdf)
737                                                                        //,float &contribution)
738{
739        ++ mSamples;
740
[1790]741        vector<PvsEntry<T, S> >::iterator it;
[1942]742        bool entryFound = Find(sample, it);
[1789]743
[1877]744        if (entryFound) {
745          S &data = (*it).mData;
746         
747          data.mSumPdf += pdf;
748          //contribution = pdf / data.mSumPdf;
749         
750          return false;
[1789]751        }
[1877]752        else {
753          AddSampleDirty(sample, pdf);
754          //contribution = 1.0f;
755          return true;
[1789]756        }
[311]757}
[308]758
[492]759
[1189]760template <typename T, typename S>
[1740]761bool Pvs<T, S>::GetSampleContribution(T sample,
762                                                                          const float pdf,
763                                                                          float &contribution)
[485]764{
[1790]765        vector<PvsEntry<T, S> >::iterator it;
766        const bool entryFound = Find(sample, it);
[1189]767
[1790]768        if (entryFound) 
[1740]769        {
770                S &data = (*it).mData;
771                contribution = pdf / (data.mSumPdf + pdf);
772                return false;
773        }
774        else
775        {
776                contribution = 1.0f;
777                return true;
778        }
[485]779}
780
[1740]781
[1189]782template <typename T, typename S>
[1740]783bool Pvs<T, S>::RemoveSample(T sample, const float pdf)
[485]784{
[1740]785        -- mSamples;
[1789]786       
[1790]787        vector<PvsEntry<T, S> >::iterator it;
788        const bool entryFound = Find(sample, it);
[1737]789
[1790]790        if (!entryFound)
[1740]791                return false;
792
793        S &data = (*it).mData;
794
795        data.mSumPdf -= pdf;
796
797        if (data.mSumPdf <= 0.0f)
798        {
799                mEntries.erase(it);
[1789]800                -- mLastSorted; // wrong if sample was in tail!!
[1740]801        }
802
803        return true;
[485]804}
[1740]805
806
[1189]807template <typename T, typename S>
808int Pvs<T, S>::SubtractPvs(const Pvs<T, S> &pvs)
[485]809{
[1738]810        const int samples = mSamples - pvs.mSamples;
[1740]811
812        std::vector<PvsEntry<T, S> >::
[1738]813                const_iterator it, it_end = pvs.mEntries.end();
[1737]814
[1738]815        // output PVS of view cell
816        for (it = pvs.mEntries.begin(); it != it_end; ++ it)
[1740]817                RemoveSample((*it).mObject, (*it).mData.mSumPdf);
[1738]818
819        mSamples = samples;
[1740]820
[1738]821        return GetSize();
[485]822}
823
[1740]824
[1189]825template <typename T, typename S>
826void Pvs<T, S>::CollectEntries(std::vector<T> &entries)
[469]827{
[1740]828        std::vector<PvsEntry<T, S> >::
[485]829                const_iterator it, it_end = mEntries.end();
[469]830
831        // output PVS of view cell
832        for (it = mEntries.begin(); it != it_end; ++ it)
833                entries.push_back((*it)->first);
834}
835
[1740]836
[1189]837template <typename T, typename S>
838void Pvs<T, S>::NormalizeMaximum()
[556]839{
[1740]840        std::vector<PvsEntry<T, S> >::
841                const_iterator it, it_end = mEntries.end();
[556]842
[1740]843        float maxPdfSum = -1.0f;
[556]844
[1740]845        // output PVS of view cell
846        for (it = mEntries.begin(); it != it_end; ++ it) {
847                float sum = (*it)->second.sumPdf;
848                if (sum > maxSum)
849                        maxSum = sum;
850        }
[556]851
[1740]852        maxSum = 1.0f / maxSum;
[556]853
[1740]854        for (it = mEntries.begin(); it != it_end; ++ it) {
855                (*it)->second.sumPdf *= maxSum;
856        }
857
[556]858}
859
860
[1667]861template <typename T, typename S>
862float Pvs<T, S>::GetEntrySize()
863{
[1673]864        return (float)(sizeof(T) + sizeof(S)) / float(1024 * 1024);
[1667]865}
866
867
868template <typename T, typename S>
869int Pvs<T, S>::GetEntrySizeByte()
870{
871        return sizeof(T) + sizeof(S);
872}
873
874
[1740]875template <typename T, typename S>
876float Pvs<T, S>::GetPvsHomogenity(Pvs<T, S> &pvs)
877{
878        float pvsReduction, pvsEnlargement;
879
880        ComputeContinuousPvsDifference(pvs,     pvsReduction, pvsEnlargement);
881
882        return pvsReduction + pvsEnlargement;
883}
884
885
[1742]886template <typename T, typename S>
887typename PvsIterator<T, S> Pvs<T, S>::GetIterator() const
888{
889        PvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
890
891        return pit;
892}
893
894
[1667]895///////////////////////////////////////
896
[311]897/** Class instantiating the Pvs template for kd tree nodes.
898*/
[1189]899class KdPvs: public Pvs<KdNode *, PvsData>
[308]900{
[1141]901public:
[311]902        int Compress();
[308]903};
904
[1077]905
[1842]906////////////
907//-- typedefs
908
909typedef PvsEntry<Intersectable *, PvsData> ObjectPvsEntry;
910typedef std::vector<ObjectPvsEntry> ObjectPvsEntries;
911typedef Pvs<ViewCell *, MailablePvsData> ViewCellPvs;
912typedef PvsIterator<Intersectable *, PvsData> ObjectPvsIterator;
913
914
[1189]915class ObjectPvs: public Pvs<Intersectable *, PvsData>
[1141]916{
917public:
[1586]918        /** Counts object int the pvs. Different to method "GetSize", not
[1141]919                only the raw container size is returned,
920                but the individual contributions of the entries are summed up.
921        */
[1707]922        float EvalPvsCost() const;
[1842]923
924        friend ostream &operator<<(ostream &s, const ObjectPvs &p)
925        {
926                ObjectPvsIterator pit = p.GetIterator();
927
928                while (pit.HasMoreEntries())
929                {               
930                        const ObjectPvsEntry &entry = pit.Next();
931                        Intersectable *obj = entry.mObject;
932
[1845]933                        cout << obj << " ";
[1842]934                }
935               
936                return s;
937        }
[1141]938};
939
[1586]940
[1077]941
[860]942}
[469]943
[177]944#endif
945
Note: See TracBrowser for help on using the repository browser.