source: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h @ 492

Revision 492, 6.3 KB checked in by bittner, 19 years ago (diff)

Large merge - viewcells seem not functional now

RevLine 
[177]1#ifndef __PVS_H
2#define __PVS_H
3
4#include <map>
[469]5#include <vector>
[177]6
7class KdNode;
[240]8class BspNode;
[191]9class Ray;
[308]10class Intersectable;
[406]11class ViewCellKdNode;
[177]12
[310]13template<typename T>
14struct LtSample {
[311]15    bool operator()(const T a, const T b) const
[310]16    {
17                return a < b;
18        }
19};
20
[469]21/** Information stored with a PVS entry. Consists of the number
22        the object was seen from the view cell.
23*/
[310]24
25template<typename T>
26struct PvsData {
27  int mVisibleSamples;
28  PvsData<T>() {}
[311]29  PvsData<T>(const int samples): mVisibleSamples(samples) {}
[310]30};
31
[469]32/** Template class representing the Potentially Visible Set (PVS)
33        mainly from a view cell, but also e.g., from objects.
34*/
[310]35template<typename T>
[311]36class Pvs
[310]37{
38public:
[469]39  Pvs(): /*mSamples(0), */mEntries() {}
[466]40 
[469]41  //int mSamples;
[466]42 
[469]43  /** Compresses PVS lossless or lossy.
44  */
[466]45  int Compress() {return 0;}
46  int GetSize() const {return (int)mEntries.size();}
[469]47  bool Empty() const {return mEntries.empty();}
48 
[466]49  /** Merges pvs of a and pvs of b into this pvs.
50   */
51  void Merge(const Pvs<T> &a, const Pvs<T> &b);
[469]52 
[466]53  /** Difference of pvs to pvs b.
54          @returns number of different entries.
55  */
56  int Diff(const Pvs<T> &b);
57 
[469]58  /** Finds sample in PVS.
59          @returns sample if found, NULL otherwise.
60  */
[466]61  PvsData<T> *Find(T sample);
[492]62
63  bool GetSampleContribution(T sample, float &contribution);
[469]64 
65  /** Adds sample to PVS.
66          @contribution contribution of sample (0 or 1)
67          @returns true if sample was not already in PVS.
68  */
[466]69  bool AddSample(T sample, float &contribution);
[469]70
71  /** Adds sample to PVS.
72          @returns contribution of sample (0 or 1)
73  */
[466]74  int AddSample(T sample);
[492]75 
[485]76  /** Adds one pvs to another one.
77          @returns new pvs size
78  */
79  int AddPvs(const Pvs<T> &pvs);
80  /** Subtracts one pvs from another one.
81          @returns new pvs size
82  */
83  int SubtractPvs(const Pvs<T> &pvs);
[469]84  /** Returns PVS data, i.e., how often it was seen from the view cell,
85          and the object itsef.
86  */
[466]87  void GetData(const int index, T &entry, PvsData<T> &data);
[469]88
89  /** Collects the PVS entries and returns them in the vector.
90  */
91  void CollectEntries(std::vector<T> &entries);
92
[485]93  /** Removes sample from PVS if reference count is zero.
94          @param visibleSampels number of references to be removed
95  */
96  bool RemoveSample(T sample, const int visibleSamples);
97
[469]98  /// Map of PVS entries
[466]99  std::map<T, PvsData<T>, LtSample<T> > mEntries;
[310]100};
101
[341]102template <typename T>
[362]103int Pvs<T>::Diff(const Pvs<T> &b)
104{
105        int dif = 0;
106
107        std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
108
109        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
110        {
111                PvsData<T> *data = Find((*it).first);           
112                if (!data) ++ dif;
113        }
114
115        return dif;
116}
117
118template <typename T>
[350]119void Pvs<T>::Merge(const Pvs<T> &a, const Pvs<T> &b)
[341]120{
[362]121        std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
122
123        // todo: copy all elements instead of inserting
124        for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
125                mEntries.insert(*it);
[485]126       
[362]127        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
128        {
129                PvsData<T> *data = Find((*it).first);
130               
131                if (data)
132                        data->mVisibleSamples += (*it).second.mVisibleSamples;
133                else
134                        mEntries.insert(*it);
135        }
[341]136}
137
[310]138template <typename T>
[311]139PvsData<T> *Pvs<T>::Find(T sample)
[310]140{
[311]141  std::map<T, PvsData<T>, LtSample<T> >::iterator i = mEntries.find(sample);
[310]142  if (i != mEntries.end()) {
143    return &(*i).second;
[311]144  } else
[310]145    return NULL;
146}
147
148template <typename T>
[311]149void Pvs<T>::GetData(const int index,
[485]150                                         T &entry,
151                                         PvsData<T> &data)
[310]152{
[311]153  std::map<T, PvsData<T>, LtSample<T> >::iterator i = mEntries.begin();
[310]154  for (int k = 0; k != index && i != mEntries.end(); i++, k++);
155
156  entry = (*i).first;
[311]157  data = (*i).second;
[310]158}
159
[311]160template <typename T>
[492]161int
162Pvs<T>::AddSample(T sample)
[177]163{
[492]164  PvsData<T> *data = Find(sample);
165 
166  if (data)  {
167        return ++data->mVisibleSamples;
168  }
169  else {
170        mEntries[sample] = PvsData<T>(1);
171        return 1;
172  }
[466]173}
[177]174
[466]175template <typename T>
[492]176bool
177Pvs<T>::AddSample(T sample, float &contribution)
[466]178{
179  PvsData<T> *data = Find(sample);
180 
181  if (data)  {
182        data->mVisibleSamples++;
183        contribution = 1.0f/data->mVisibleSamples;
184        return false;
185  }
186  else {
187        mEntries[sample] = PvsData<T>(1);
188        contribution = 1.0f;
189        return true;
190  }
[311]191}
[308]192
[469]193template <typename T>
[492]194bool
195Pvs<T>::GetSampleContribution(T sample, float &contribution)
196{
197  PvsData<T> *data = Find(sample);
198 
199  if (data)  {
200        contribution = 1.0f/(data->mVisibleSamples + 1);
201        return false;
202  }
203  else {
204        contribution = 1.0f;
205        return true;
206  }
207}
208
209template <typename T>
[485]210bool Pvs<T>::RemoveSample(T sample, const int visibleSamples)
211{
212        std::map<T, PvsData<T>, LtSample<T> >::
213                iterator it = mEntries.find(sample);
214
215        if (it == mEntries.end())
216                return false;
217
218        PvsData<T> *data = &(*it).second;
219 
220        data->mVisibleSamples -= visibleSamples;
221        if (data->mVisibleSamples <= 0)
222                mEntries.erase(it);
223
224        return true;
225}
226
227template <typename T>
228int Pvs<T>::AddPvs(const Pvs<T> &pvs)
229{
230        std::map<T, PvsData<T>, LtSample<T> >::
231                const_iterator it, it_end = pvs.mEntries.end();
232
233        float contri;
234        // output PVS of view cell
235        for (it = pvs.mEntries.begin(); it != it_end; ++ it)
236                AddSample((*it).first, contri);
237
238        return GetSize();
239}
240 
241template <typename T>
242int Pvs<T>::SubtractPvs(const Pvs<T> &pvs)
243{
244        std::map<T, PvsData<T>, LtSample<T> >::
245                const_iterator it, it_end = pvs.mEntries.end();
246
247        // output PVS of view cell
248        for (it = pvs.mEntries.begin(); it != it_end; ++ it)
249                RemoveSample((*it).first, (*it).second.mVisibleSamples);
250
251        return GetSize();
252}
253
254template <typename T>
[469]255void Pvs<T>::CollectEntries(std::vector<T> &entries)
256{
[485]257        std::map<T, PvsData<T>, LtSample<T> >::
258                const_iterator it, it_end = mEntries.end();
[469]259
260        // output PVS of view cell
261        for (it = mEntries.begin(); it != it_end; ++ it)
262                entries.push_back((*it)->first);
263}
264
[311]265/** Class instantiating the Pvs template for kd tree nodes.
266*/
267class KdPvs: public Pvs<KdNode *>
[308]268{
[311]269        int Compress();
[308]270};
271
[311]272typedef std::map<KdNode *, PvsData<KdNode *>, LtSample<KdNode *> > KdPvsMap;
[469]273typedef std::map<Intersectable *, PvsData<Intersectable *>, LtSample<Intersectable *> > ObjectPvsMap;
274typedef PvsData<Intersectable *> ObjectPvsData;
[311]275typedef PvsData<KdNode *> KdPvsData;
[308]276
[469]277typedef Pvs<Intersectable *> ObjectPvs;
[366]278
[469]279
[177]280#endif
281
Note: See TracBrowser for help on using the repository browser.