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

Revision 2015, 20.5 KB checked in by bittner, 17 years ago (diff)

pvs efficiency tuning

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