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

Revision 2077, 22.1 KB checked in by bittner, 17 years ago (diff)

pvs query count fix

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