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

Revision 2066, 22.1 KB checked in by mattausch, 17 years ago (diff)

worked on integration manual

Line 
1#ifndef __PVS_H
2#define __PVS_H
3
4#include <map>
5#include <vector>
6#include "common.h"
7#include <math.h>
8using namespace std;
9
10namespace GtpVisibilityPreprocessor {
11
12class KdNode;
13class BspNode;
14class Ray;
15class Intersectable;
16class ViewCell;
17
18
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>
23struct PvsEntry
24{
25public:
26
27        PvsEntry() {}
28
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);
36        template<typename T, typename S>
37        friend int operator== (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b);
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
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}
52
53
54template<typename T, typename S>
55struct LtSample
56{
57    bool operator()(const PvsEntry<T, S> &a, const PvsEntry<T, S> &b) const
58    {
59                return a.mObject < b.mObject;
60        }
61};
62
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}
68
69/** Information stored with a PVS entry. Consists of the number
70        the object was seen from the view cell.
71*/
72struct PvsData {
73public:
74        PvsData() {}
75        PvsData(const float sumPdf):
76        mSumPdf(sumPdf) {}
77       
78        // $$JB in order to return meaningfull values
79        // it assumes that the sum pdf has been normalized somehow!!!
80        inline float GetVisibility()
81        {
82                return mSumPdf;
83        }
84
85        /// sum of probability density of visible sample rays
86        float mSumPdf;
87};
88
89
90class MailablePvsData
91{
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
108        ////////////////////////////
109        //  Mailing stuff
110
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
116        static void NewMail(const int reserve = 1) {
117                sMailId += sReservedMailboxes;
118                sReservedMailboxes = reserve;
119        }
120
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; }
128       
129        //////////////////////////////////////////
130
131protected:
132
133        int mMailbox;
134
135};
136
137
138template<typename T, typename S>
139class PvsIterator
140{
141public:
142       
143        PvsIterator<T, S>() {}
144
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
156        const PvsEntry<T, S> &Next()
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;
164};
165
166
167/** Template class representing the Potentially Visible Set (PVS)
168        mainly from a view cell, but also e.g., from objects.
169*/
170template<typename T, typename S>
171class Pvs
172{
173        template<typename T, typename S>
174        friend class PvsIterator;
175
176public:
177 
178        Pvs(): mSamples(0), mEntries(), mLastSorted(0), mQueriesSinceSort(0) {}
179
180        /** creates pvs and initializes it with the given entries.
181                Assumes that entries are sorted-
182        */
183        Pvs(const vector<PvsEntry<T, S> > &samples);
184        virtual ~Pvs() {};
185
186        /** Compresses PVS lossless or lossy.
187        */
188        int Compress() {return 0;}
189        int GetSize() const {return (int)mEntries.size();}
190        bool Empty() const {return mEntries.empty();}
191
192        void Reserve(const int n) { mEntries.reserve(n); }
193
194        /** Normalize the visibility of entries in order to get
195                comparable results.
196        */
197        void NormalizeMaximum();
198
199        /** Merges pvs of a into this pvs.
200                Warning: very slow!
201        */
202        void MergeInPlace(const Pvs<T, S> &a);
203
204        /** Difference of pvs to pvs b.
205                @returns number of different entries.
206        */
207        int Diff(const Pvs<T, S> &b);
208
209        /** Finds sample in PVS.
210                @param checkDirty if dirty part of the pvs should be checked for entry
211                        (warning: linear runtime in dirty part)
212                @returns iterator on the sample if found, else the place where
213                        it would be added in the sorted vector.
214        */
215        bool Find(T sample,
216                          typename vector<PvsEntry<T, S> >::iterator &it,
217                          const bool checkDirty = true);
218
219        bool GetSampleContribution(T sample, const float pdf, float &contribution);
220
221        /** Adds sample to PVS.
222                @returns contribution of sample (0 or 1)
223        */
224        float AddSample(T sample, const float pdf);
225
226        /** Adds sample to PVS without checking for presence of the sample
227                warning: pvs remains unsorted!
228        */
229        void AddSampleDirty(T sample, const float pdf);
230
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
241  /** Sort pvs entries assume that the pvs contains unique entries
242   */
243  void SimpleSort();
244
245        /** Adds sample to PVS. Assumes that the pvs is sorted
246                @returns contribution of sample (0 or 1)
247        */
248        //float AddSamples(const vector<PvsEntry<T, S> > &samples);
249
250        /** Adds sample to PVS.
251                @returns PvsData
252        */
253        typename std::vector<PvsEntry<T, S> >::iterator AddSample2(T sample, const float pdf);
254
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);
260
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        */
277        void ComputeContinuousPvsDifference(Pvs<T, S> &pvs,
278                                                                                float &pvsReduction,
279                                                                                float &pvsEnlargement);
280
281        /** Clears the pvs.
282        */
283        void Clear(const bool trim = true);
284
285        void Trim();
286
287        static int GetEntrySizeByte();
288        static float GetEntrySize();
289
290        /** Compute continuous PVS difference
291        */
292        float GetPvsHomogenity(Pvs<T, S> &pvs);
293
294        static void Merge(Pvs<T, S> &mergedPvs, const Pvs<T, S> &a, const Pvs<T, S> &b);
295
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
304        int GetSamples() const
305        {
306                return mSamples;
307        }
308
309
310        bool IsDirty() const
311        {
312                return mLastSorted < mEntries.size();
313        }
314
315        bool RequiresResort() const
316        {
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
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;
334        }
335
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 
345        int GetLastSorted() const
346        {
347                return mLastSorted;
348        }
349
350        typename PvsIterator<T, S> GetIterator() const;
351
352protected:
353
354        /// vector of PVS entries
355        vector<PvsEntry<T, S> > mEntries;
356       
357        /// Number of samples used to create the PVS
358        int mSamples;
359 
360        /// Last sorted entry in the pvs (important for find and merge)
361        int mLastSorted;
362
363  int mQueriesSinceSort;
364};
365
366
367template <typename T, typename S>
368Pvs<T, S>::Pvs(const vector<PvsEntry<T, S> > &samples)
369{
370        mEntries.reserve(samples.size());
371        mEntries = samples;
372        mLastSorted = 0;
373        mSamples = samples.size();
374}
375
376
377template <typename T, typename S>
378void Pvs<T, S>::Sort()
379{
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());
388       
389        // now merge sorted ranges
390        ObjectPvs newPvs;
391        Merge(newPvs,
392                  mEntries.begin(),
393                  it,
394                  it,
395                  newEnd,
396                  mSamples,
397                  0);
398       
399        mEntries = newPvs.mEntries;
400        mLastSorted = (int)mEntries.size();
401        mQueriesSinceSort = 0;
402}
403
404template <typename T, typename S>
405void Pvs<T, S>::SimpleSort()
406{
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());
412 
413        mLastSorted = (int)mEntries.size();
414        mQueriesSinceSort = 0;
415}
416
417
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*/
423template <typename T, typename S>
424void
425Pvs<T, S>::ComputeContinuousPvsDifference(Pvs<T, S> &b,
426                                                                                  float &pvsReduction,
427                                                                                  float &pvsEnlargement)
428{
429        pvsReduction = 0.0f;
430        pvsEnlargement = 0.0f;
431
432        // Uses sum of log differences, which corresponds to entropy
433        std::vector<PvsEntry<T, S> >::iterator it;
434
435        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
436        {
437                float bSumPdf = (*it).mData.mSumPdf;
438                float aSumPdf = 0.0f;
439
440                vector<PvsEntry<T, S> >::iterator oit;
441                const bool entryFound = Find((*it).mObject, oit);               
442
443                if (entryFound)
444                {
445                        aSumPdf = (*it).mData.mSumPdf;
446
447                        // mark this entry as processed to avoid double counting
448                        (*it).mData.mSumPdf = -aSumPdf;
449                }
450
451#if 0
452                const float diff = bSumPdf - aSumPdf;
453
454                if (diff > 0.0f) {
455                        pvsEnlargement += diff;
456                } else {
457                        pvsReduction += -diff;
458                }
459#else
460                if (!entryFound)
461                        pvsEnlargement += 1.0f;
462#endif
463        }
464
465        for (it = mEntries.begin(); it != mEntries.end(); ++ it)
466        {
467                float aSumPdf = (*it).mData.mSumPdf;
468                float bSumPdf = 0.0f;
469                if (aSumPdf < 0.0f) {
470               
471                        // this entry was already accounted for!
472                        // just revert it back
473                        (*it).mData.mSumPdf = -aSumPdf;
474                } else {
475                        vector<PvsEntry<T, S> >::iterator oit;
476               
477                        const bool entryFound = b.Find((*it).mObject, oit);
478                                               
479                        if (entryFound) {
480                                bSumPdf = (*oit).mData.mSumPdf;
481                        }
482#if 0
483                        const float diff = bSumPdf - aSumPdf;
484
485                        if (diff > 0.0f) {
486                                pvsEnlargement += diff;
487                        } else {
488                                pvsReduction += -diff;
489                        }
490
491#else
492                        if (!entryFound)
493                                pvsReduction += 1.0f;
494#endif
495                }
496        }
497}
498
499
500template <typename T, typename S>
501int Pvs<T, S>::Diff(const Pvs<T, S> &b)
502{
503        int dif = 0;
504
505        std::vector<PvsEntry<T, S> >::const_iterator it;
506
507        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
508        {
509                vector<PvsEntry<T, S> >::iterator bit;
510                const bool entryFound = Find((*it).first, bit);
511
512                if (!entryFound) ++ dif;
513        }
514
515        return dif;
516}
517
518
519template <typename T, typename S>
520void Pvs<T, S>::MergeInPlace(const Pvs<T, S> &a)
521{
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
535        ObjectPvs interPvs;
536       
537        Merge(interPvs, *this, a);
538       
539        mEntries.reserve(interPvs.GetSize());
540        mEntries = interPvs.mEntries;
541        mSamples = interPvs.mSamples;
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();
550       
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)
572        {
573                Intersectable *aObj = (*ait).mObject;
574                Intersectable *bObj = NULL;
575                //Intersectable *bObjOld = NULL;
576       
577                const PvsEntry<T, S> &aEntry = (*ait);
578
579                for (; (bit != bEnd) && ((*bit).mObject <= (*ait).mObject); ++ bit)
580                {
581                        bObj = (*bit).mObject;
582
583                        // object found => add up probabilities
584                        if (bObj == aEntry.mObject)
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                        }
594                       
595                        //bObjOld = bObj;
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
607        for (; (bit != bEnd); ++ bit)
608        {
609                mergedPvs.mEntries.push_back(*bit);
610        }
611
612        mergedPvs.mSamples = aSamples + bSamples;
613}
614
615
616template <typename T, typename S> void Pvs<T, S>::Clear(const bool trim = true)
617{
618        mEntries.clear();
619        mSamples = 0;
620        mLastSorted = 0;
621
622        if (trim)
623        {
624                vector<PvsEntry<T,S> >().swap(mEntries);
625        }
626}
627
628
629template <typename T, typename S> void Pvs<T, S>::Trim()
630{
631        vector<PvsEntry<T,S> >(mEntries).swap(mEntries);
632}
633
634
635template <typename T, typename S>
636bool Pvs<T, S>::Find(T sample,
637                                         typename vector<PvsEntry<T, S> >::iterator &it,
638                                         const bool checkDirty)
639{
640        bool found = false;
641
642        PvsEntry<T, S> dummy(sample, PvsData());
643
644        // only check clean part
645        vector<PvsEntry<T, S> >::iterator sorted_end = mEntries.begin() + mLastSorted;
646
647        // binary search
648        it = lower_bound(mEntries.begin(), sorted_end, dummy);
649
650        if ((it != mEntries.end()) && ((*it).mObject == sample))
651                found = true;
652
653        // sample not found yet => search further in the unsorted part
654        if (!found && checkDirty)
655        {
656                vector<PvsEntry<T, S> >::iterator dit, dit_end = mEntries.end();
657
658        for (dit = sorted_end; (dit != dit_end) && ((*dit).mObject != sample); ++ dit);
659       
660                if (dit != dit_end)
661                {
662                        found = true;
663                        it = dit;
664                }
665        }
666
667        return found;
668}
669
670/*
671template <typename T, typename S>
672bool Pvs<T, S>::Find(T sample,
673                                         typename vector<PvsEntry<T, S> >::iterator &it,
674                                         const bool checkDirty)
675{
676        PvsEntry<T, S> dummy(sample, PvsData());
677        mQueriesSinceSort++;
678
679        // only check clean part
680        vector<PvsEntry<T, S> >::iterator sorted_end = mEntries.begin() + mLastSorted;
681
682        // binary search
683        it = lower_bound(mEntries.begin(), sorted_end, dummy);
684
685        if ((it != mEntries.end()) && ((*it).mObject == sample))
686                return true;
687
688        // sample not found yet => search further in the unsorted part
689        if (checkDirty)
690        {
691                for (it = sorted_end; (it != mEntries.end()) && ((*it).mObject != sample); ++ it);
692
693                if (it != mEntries.end())
694                        return true;
695        }
696
697        return false;
698}
699*/
700
701template <typename T, typename S>
702void Pvs<T, S>::GetData(const int index, T &entry, S &data)
703{
704        std::vector<PvsEntry<T, S> >::iterator i = mEntries.begin();
705        for (int k = 0; k != index && i != mEntries.end(); ++ i, ++ k);
706
707        entry = (*i).first;
708        data = (*i).second;
709}
710
711
712template <typename T, typename S>
713float Pvs<T, S>::AddSample(T sample, const float pdf)
714{cout << "t";
715        ++ mSamples;
716       
717        vector<PvsEntry<T, S> >::iterator it;
718        const bool entryFound = Find(sample, it);               
719
720        if (entryFound)
721        {       
722                S &data = (*it).mData;
723                data.mSumPdf += pdf;
724                return data.mSumPdf;
725        }
726        else
727        {
728                PvsEntry<T, S> entry(sample, pdf);
729                mEntries.insert(it, entry);
730                ++ mLastSorted;
731                return pdf;
732        }
733}
734
735
736template <typename T, typename S>
737void Pvs<T, S>::AddSampleDirty(T sample, const float pdf)
738{
739        ++ mSamples;
740        mEntries.push_back(PvsEntry<T, S>(sample, pdf));
741}
742                                         
743
744template <typename T, typename S>
745typename vector< PvsEntry<T, S> >::iterator Pvs<T, S>::AddSample2(T sample,
746                                                                                                                                  const float pdf)
747{
748        ++ mSamples;
749       
750        vector<PvsEntry<T, S> >::iterator it;
751        const bool entryFound = Find(sample, it);
752
753        if (entryFound)
754        {
755                S &data = (*it).second;
756                data->mSumPdf += pdf;
757        }
758        else
759        {
760                PvsEntry<T, S> entry(sample, pdf);
761                mEntries.insert(it, entry);
762                ++ mLastSorted;
763        }
764
765        return it;
766}
767
768
769/** Adds sample dirty (on the end of the vector) but
770        first checks if sample is already in clean part of the pvs.
771*/
772template <typename T, typename S>
773bool Pvs<T, S>::AddSampleDirtyCheck(T sample,
774                                                                        const float pdf)
775                                                                        //,float &contribution)
776{
777        ++ mSamples;
778
779        vector<PvsEntry<T, S> >::iterator it;
780        const bool entryFound = Find(sample, it);
781
782        if (entryFound)
783        {
784                S &data = (*it).mData;
785         
786                data.mSumPdf += pdf;
787                //contribution = pdf / data.mSumPdf;
788
789        return false;
790        }
791        else
792        {
793                AddSampleDirty(sample, pdf);
794                //contribution = 1.0f;
795               
796                return true;
797        }
798}
799
800
801template <typename T, typename S>
802bool Pvs<T, S>::GetSampleContribution(T sample,
803                                                                          const float pdf,
804                                                                          float &contribution)
805{
806        vector<PvsEntry<T, S> >::iterator it;
807        const bool entryFound = Find(sample, it);
808
809        if (entryFound) 
810        {
811                S &data = (*it).mData;
812                contribution = pdf / (data.mSumPdf + pdf);
813                return false;
814        }
815        else
816        {
817                contribution = 1.0f;
818                return true;
819        }
820}
821
822
823template <typename T, typename S>
824bool Pvs<T, S>::RemoveSample(T sample, const float pdf)
825{
826        -- mSamples;
827       
828        vector<PvsEntry<T, S> >::iterator it;
829        const bool entryFound = Find(sample, it);
830
831        if (!entryFound)
832                return false;
833
834        S &data = (*it).mData;
835
836        data.mSumPdf -= pdf;
837
838        if (data.mSumPdf <= 0.0f)
839        {
840                mEntries.erase(it);
841                -- mLastSorted; // wrong if sample was in tail!!
842        }
843
844        return true;
845}
846
847
848template <typename T, typename S>
849int Pvs<T, S>::SubtractPvs(const Pvs<T, S> &pvs)
850{
851        const int samples = mSamples - pvs.mSamples;
852
853        std::vector<PvsEntry<T, S> >::
854                const_iterator it, it_end = pvs.mEntries.end();
855
856        // output PVS of view cell
857        for (it = pvs.mEntries.begin(); it != it_end; ++ it)
858                RemoveSample((*it).mObject, (*it).mData.mSumPdf);
859
860        mSamples = samples;
861
862        return GetSize();
863}
864
865
866template <typename T, typename S>
867void Pvs<T, S>::CollectEntries(std::vector<T> &entries)
868{
869        std::vector<PvsEntry<T, S> >::
870                const_iterator it, it_end = mEntries.end();
871
872        // output PVS of view cell
873        for (it = mEntries.begin(); it != it_end; ++ it)
874                entries.push_back((*it)->first);
875}
876
877
878template <typename T, typename S>
879void Pvs<T, S>::NormalizeMaximum()
880{
881        std::vector<PvsEntry<T, S> >::
882                const_iterator it, it_end = mEntries.end();
883
884        float maxPdfSum = -1.0f;
885
886        // output PVS of view cell
887        for (it = mEntries.begin(); it != it_end; ++ it) {
888                float sum = (*it)->second.sumPdf;
889                if (sum > maxSum)
890                        maxSum = sum;
891        }
892
893        maxSum = 1.0f / maxSum;
894
895        for (it = mEntries.begin(); it != it_end; ++ it) {
896                (*it)->second.sumPdf *= maxSum;
897        }
898
899}
900
901
902template <typename T, typename S>
903float Pvs<T, S>::GetEntrySize()
904{
905        return (float)(sizeof(T) + sizeof(S)) / float(1024 * 1024);
906}
907
908
909template <typename T, typename S>
910int Pvs<T, S>::GetEntrySizeByte()
911{
912        return sizeof(T) + sizeof(S);
913}
914
915
916template <typename T, typename S>
917float Pvs<T, S>::GetPvsHomogenity(Pvs<T, S> &pvs)
918{
919        float pvsReduction, pvsEnlargement;
920
921        ComputeContinuousPvsDifference(pvs,     pvsReduction, pvsEnlargement);
922
923        return pvsReduction + pvsEnlargement;
924}
925
926
927template <typename T, typename S>
928typename PvsIterator<T, S> Pvs<T, S>::GetIterator() const
929{
930        PvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
931
932        return pit;
933}
934
935
936///////////////////////////////////////
937
938/** Class instantiating the Pvs template for kd tree nodes.
939*/
940class KdPvs: public Pvs<KdNode *, PvsData>
941{
942public:
943        int Compress();
944};
945
946
947////////////
948//-- typedefs
949
950typedef PvsEntry<Intersectable *, PvsData> ObjectPvsEntry;
951typedef std::vector<ObjectPvsEntry> ObjectPvsEntries;
952typedef Pvs<ViewCell *, MailablePvsData> ViewCellPvs;
953typedef PvsIterator<Intersectable *, PvsData> ObjectPvsIterator;
954
955
956class ObjectPvs: public Pvs<Intersectable *, PvsData>
957{
958public:
959        /** Counts object int the pvs. Different to method "GetSize", not
960                only the raw container size is returned,
961                but the individual contributions of the entries are summed up.
962        */
963        float EvalPvsCost() const;
964
965        friend ostream &operator<<(ostream &s, const ObjectPvs &p)
966        {
967                ObjectPvsIterator pit = p.GetIterator();
968
969                while (pit.HasMoreEntries())
970                {               
971                        const ObjectPvsEntry &entry = pit.Next();
972                        Intersectable *obj = entry.mObject;
973
974                        cout << obj << " ";
975                }
976               
977                return s;
978        }
979};
980
981
982
983}
984
985#endif
986
Note: See TracBrowser for help on using the repository browser.