source: GTP/trunk/Lib/Vis/Preprocessing/src/HashPvs.h @ 2146

Revision 2146, 7.5 KB checked in by mattausch, 17 years ago (diff)

improved hash pvs timings

Line 
1#ifndef __HASHPVS_H
2#define __HASHPVS_H
3
4//#include <hash_map>
5#include <hash_set>
6#include "common.h"
7#include <math.h>
8#include "PvsBase.h"
9
10
11using namespace std;
12
13namespace GtpVisibilityPreprocessor {
14
15
16template<typename T>
17struct my_hash_compare
18{
19   enum
20   {
21      bucket_size = 1,
22      min_buckets = 16
23   };
24
25   size_t operator()(T a) const
26   {
27      size_t h = (size_t)(a->GetId());// % 2000;
28      //for (; *s; ++s)
29      //   h = 5 * h + *s;
30      return h;
31   }
32
33   bool operator()(T a, T b) const
34   {
35      return a < b;
36   }
37};
38
39/*
40template<typename T>
41struct gt
42{
43        bool operator() (T s1, T s2) const
44        {
45                return s1 > s2;
46        }
47};
48*/
49//#define HASH_SET stdext::hash_set<T, stdext::hash_compare<T, gt<T> > >
50#define HASH_SET stdext::hash_set<T, my_hash_compare<T> >
51
52/** Iterator over a hash pvs.
53*/
54template<typename T, typename S>
55class HashPvsIterator
56{
57public:
58       
59        HashPvsIterator<T, S>() {}
60
61        HashPvsIterator<T, S>(const typename HASH_SET::const_iterator &itCurrent,
62                                                  const typename HASH_SET::const_iterator &itEnd):
63        mItCurrent(itCurrent), mItEnd(itEnd)
64        {
65        }
66
67        bool HasMoreEntries() const
68        {
69                return (mItCurrent != mItEnd);
70        }
71
72        T Next(S &pdf)
73        {
74                // hack: create new pvs entry
75                return *(mItCurrent) ++;
76        }
77
78        T Next()
79        {
80                // hack: create new pvs entry
81                return *(mItCurrent) ++;
82        }
83       
84private:
85        typename HASH_SET::const_iterator mItCurrent;
86        typename HASH_SET::const_iterator mItEnd;
87};
88
89
90/** Template class representing the Potentially Visible Set (PVS)
91        mainly from a view cell, but also e.g., from objects.
92*/
93template<typename T, typename S>
94class HashPvs//: public PvsBase<T>
95{
96        template<typename T, typename S> friend class HashPvsIterator;
97
98public:
99
100        //HashPvs(): mEntries((Intersectable *)100) {};
101        HashPvs() {};
102        //virtual ~HashPvs() {};
103
104        int GetSize() const;
105        bool Empty() const;
106
107        /** Adds sample to PVS.
108                @returns contribution of sample (0 or 1)
109        */
110        float AddSample(T sample, const float pdf);
111
112        /** Adds sample to PVS without checking for presence of the sample
113                warning: pvs remains unsorted!
114        */
115        void AddSampleDirty(T sample, const float pdf);
116
117        /** Adds sample dirty (on the end of the vector) but
118                first checks if sample is already in clean part of the pvs.
119        */
120        bool AddSampleDirtyCheck(T sample, const float pdf);
121
122        /** Sort pvs entries - this should always be called after a
123                sequence of AddSampleDirty calls
124        */
125        void Sort();
126
127        /** Clears the pvs.
128        */
129        void Clear(const bool trim = true);
130
131        bool IsDirty() const;
132
133        bool RequiresResort() const;
134
135        /** Finds sample in PVS.
136                @param checkDirty if dirty part of the pvs should be checked for entry
137                (warning: linear runtime in dirty part)
138                @returns iterator on the sample if found, else the place where
139                it would be added in the sorted vector.
140        */
141        bool Find(T sample, typename HASH_SET::iterator &it);
142
143        typename HashPvsIterator<T, S> GetIterator() const;
144
145        /** Compute continuous PVS difference
146        */
147        float GetPvsHomogenity(HashPvs<T, S> &pvs);
148
149        static void Merge(HashPvs<T, S> &mergedPvs,
150                                          const HashPvs<T, S> &a,
151                                          const HashPvs<T, S> &b);
152
153        static int GetEntrySizeByte();
154        static float GetEntrySize();
155
156        bool GetSampleContribution(T sample,
157                                                   const float pdf,
158                                                           float &contribution);
159
160        int GetSamples() const
161        {
162                return mSamples;
163        }
164
165        void MergeInPlace(const HashPvs<T, S> &a)
166        {
167                cerr << "not implemented yet" << endl;
168        }
169
170        bool RequiresResortLog() const
171        {
172                return false;
173        }
174
175        void Reserve(const int n)
176        {
177                // not necessary
178        }
179
180        /** Sort pvs entries assume that the pvs contains unique entries
181        */
182        void SimpleSort()
183        {
184                // not necessary
185        }
186
187        int SubtractPvs(const HashPvs<T, S> &pvs)
188        {
189                cerr << "not yet implemented" << endl;
190                return 0;
191        }
192
193        /** Compute continuous PVS difference
194        */
195        void ComputeContinuousPvsDifference(HashPvs<T, S> &pvs,
196                                                                                float &pvsReduction,
197                                                                                float &pvsEnlargement)
198        {
199                cerr << "not yet implemented" << endl;
200        }
201protected:
202
203        /// hash table of PVS entries
204        HASH_SET mEntries;
205
206        /// Number of samples used to create the PVS
207        int mSamples;
208};
209
210
211template <typename T, typename S>
212bool HashPvs<T, S>::Find(T sample, typename HASH_SET::iterator &it)
213{
214        it = mEntries.find(sample);
215
216        // already in map
217        return (it != mEntries.end());
218}
219
220
221template <typename T, typename S>
222int HashPvs<T, S>::GetSize() const
223{
224        return (int)mEntries.size();
225}
226
227
228template <typename T, typename S>
229bool HashPvs<T, S>::Empty() const
230{
231        return mEntries.empty();
232}
233
234
235template <typename T, typename S>
236float HashPvs<T, S>::AddSample(T sample, const float pdf)
237{
238        static HASH_SET::iterator it;
239
240        if (Find(sample, it))
241                return 0.0f;
242       
243        mEntries.insert(sample);
244        return 1.0f;
245
246        /*pair<HASH_SET::iterator, bool> p = mEntries.insert(sample);
247
248        if (p.second)
249                return 0.0f;
250        else
251                return 1.0f;*/
252}
253       
254
255template <typename T, typename S>
256void HashPvs<T, S>::AddSampleDirty(T sample, const float pdf)
257{
258        static HASH_SET::iterator it;
259
260        // not yet in map
261        if (!Find(sample, it))
262        {
263                mEntries.insert(sample);       
264        }
265
266        //pair<HASH_SET::iterator, bool> p = mEntries.insert(sample);
267}
268
269
270template <typename T, typename S>
271bool HashPvs<T, S>::AddSampleDirtyCheck(T sample,
272                                                                                const float pdf)
273{
274        /*pair<HASH_SET::iterator, bool> p = mEntries.insert(sample);
275
276        // already in map
277        return p.second;
278*/
279        static HASH_SET::iterator it;
280
281        // already in map
282        if (Find(sample, it))
283                return false;
284       
285        mEntries.insert(sample);
286        return true;
287}
288
289
290template <typename T, typename S>
291void HashPvs<T, S>::Sort()
292{
293}
294
295
296template <typename T, typename S>
297void HashPvs<T, S>::Clear(const bool trim = true)
298{
299        mEntries.clear();
300}
301
302
303template <typename T, typename S>
304bool HashPvs<T, S>::IsDirty() const
305{
306        return false;
307}
308
309
310template <typename T, typename S>
311bool HashPvs<T, S>::RequiresResort() const
312{
313        return false;
314}
315
316
317template <typename T, typename S>
318typename HashPvsIterator<T, S> HashPvs<T, S>::GetIterator() const
319{
320        HashPvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
321
322        return pit;
323}
324
325
326template <typename T, typename S>
327float HashPvs<T, S>::GetEntrySize()
328{
329        return (float)(sizeof(T)) / float(1024 * 1024);
330}
331
332
333template <typename T, typename S>
334int HashPvs<T, S>::GetEntrySizeByte()
335{
336        return sizeof(T);
337}
338
339
340template <typename T, typename S>
341float HashPvs<T, S>::GetPvsHomogenity(HashPvs<T, S> &pvs)
342{
343        float pvsReduction, pvsEnlargement;
344
345        ComputeContinuousPvsDifference(pvs,     pvsReduction, pvsEnlargement);
346
347        return pvsReduction + pvsEnlargement;
348}
349
350
351template <typename T, typename S>
352bool HashPvs<T, S>::GetSampleContribution(T sample,
353                                                                          const float pdf,
354                                                                          float &contribution)
355{
356        HASH_SET::iterator it;
357        const bool entryFound = Find(sample, it);
358
359        if (entryFound) 
360        {
361                contribution = 0.0f;
362                return false;
363        }
364        else
365        {
366                contribution = 1.0f;
367                return true;
368        }
369}
370
371
372template <typename T, typename S>
373void HashPvs<T, S>::Merge(HashPvs<T, S> &mergedPvs,
374                                                  const HashPvs<T, S> &a,
375                                                  const HashPvs<T, S> &b)
376{
377        HASH_SET::const_iterator ait, ait_end = a.mEntries.end();
378
379        for (ait = a.mEntries.begin(); ait != ait_end; ++ ait)
380        {
381                mergedPvs.AddSample(*ait, 1.0f);
382        }
383
384        HASH_SET::const_iterator bit, bit_end = b.mEntries.end();
385
386        for (bit = b.mEntries.begin(); bit != bit_end; ++ bit)
387        {
388                mergedPvs.AddSample(*bit, 1.0f);
389        }
390
391        //cerr << "not implemented" << endl;
392}
393
394}
395
396#endif
397
Note: See TracBrowser for help on using the repository browser.