source: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h @ 586

Revision 586, 11.6 KB checked in by mattausch, 18 years ago (diff)

changed shuffling (but does not work yet...)

Line 
1#ifndef _ViewCell_H__
2#define _ViewCell_H__
3
4#include "Mesh.h"
5#include "Containers.h"
6#include "Ray.h"
7#include "Statistics.h"
8//namespace GtpVisibilityPreprocessor {
9
10struct Triangle3;
11
12class BspInterior;
13class BspPvs;
14class BspLeaf;
15class VspKdTree;
16class VspKdLeaf;
17class KdLeaf;
18class ViewCellInterior;
19class MergeCandidate;
20class ViewCellsManager;
21
22/** Statistics for a view cell partition.
23*/
24
25class ViewCellsStatistics: public StatisticsBase
26{
27public:
28
29        /// number of view cells
30        int viewCells;
31
32        /// size of the PVS
33        int pvs;
34
35        /// largest PVS of all view cells
36        int maxPvs;
37
38        /// smallest PVS of all view cells
39        int minPvs;
40
41        /// view cells with empty PVS
42        int emptyPvs;
43
44        /// number of leaves covering the view space
45        int leaves;
46
47        /// largest number of leaves covered by one view cell
48        int maxLeaves;
49
50        int invalid;
51
52    // Constructor
53        ViewCellsStatistics()
54        {
55                Reset();
56        }
57
58        double AvgLeaves() const {return (double)leaves / (double)viewCells;};
59        double AvgPvs() const {return (double)pvs / (double)viewCells;};
60
61        void Reset()
62        {
63                viewCells = 0;
64                pvs = 0;
65                maxPvs = 0;
66
67                minPvs = 999999;
68                emptyPvs = 0;
69                leaves = 0;
70                maxLeaves = 0;
71                invalid = 0;
72        }
73
74        void Print(ostream &app) const;
75
76        friend ostream &operator<<(ostream &s, const ViewCellsStatistics &stat)
77        {
78                stat.Print(s);
79                return s;
80        }
81};
82
83
84/**
85        View cell with an optional mesh representation
86*/
87
88
89class ViewCell: public MeshInstance
90{
91public:
92        ViewCell();
93
94        /** Constructor taking a mesh representing the shape of the viewcell.
95        */
96        ViewCell(Mesh *mesh);
97
98        /** Default destructor.
99        */
100        virtual ~ViewCell() {}
101
102        /** Returns Pvs.
103        */
104        const ObjectPvs &GetPvs() const;
105        ObjectPvs &GetPvs();
106
107        int Type() const;
108
109        void SetParent(ViewCellInterior *parent);
110
111        /** Adds a passing ray to the passing ray container.
112        */
113        void AddPassingRay(const Ray &ray, const int contributions);
114
115        /** Returns volume of the view cell.
116        */
117        float GetVolume() const;
118
119        /** Returns area of the view cell.
120        */
121        float GetArea() const;
122
123        /** Sets the volume of the view cell.
124        */
125        void SetVolume(float volume);
126       
127        /** Sets the area of the view cell.
128        */
129        void SetArea(float area);
130
131        /** Updates the view cell statstics for this particular view cell.
132        */
133        virtual void UpdateViewCellsStats(ViewCellsStatistics &vcStat);
134
135        /** if this view cell is the root of a view cell hierarchy
136        */
137        bool IsRoot() const;
138
139        /** Returns parent view cell.
140        */
141        ViewCellInterior *GetParent() const;
142
143       
144        /** Sets the mesh for this view cell.
145        */
146        void SetMesh(Mesh *mesh);
147
148        void SetValid(const bool valid);
149        bool GetValid() const;
150
151
152
153
154        /// parent view cell in the view cell hierarchy
155        ViewCellInterior *mParent;
156
157        /// Rays piercing this view cell.
158        RayContainer mPiercingRays;
159
160
161        /** if this is a view cell correspending to a leaf in a hierarchy.
162        */
163        virtual bool IsLeaf() const = 0;
164
165  static bool SmallerPvs(const ViewCell *a,
166                                                 const ViewCell *b) {
167        return a->GetPvs().GetSize() < b->GetPvs().GetSize();
168  }
169
170
171        void SetTimeStamp(const int timeStamp);
172        int GetTimeStamp() const;
173        static void NewMail(const int reserve = 1) {
174                sMailId += sReservedMailboxes;
175                sReservedMailboxes = reserve;
176        }
177        void Mail() { mMailbox = sMailId; }
178        bool Mailed() const { return mMailbox == sMailId; }
179
180        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
181        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
182
183        int IncMail() { return ++mMailbox - sMailId; }
184
185
186                                                 
187        // last mail id -> warning not thread safe!
188        // both mailId and mailbox should be unique for each thread!!!
189        static int sMailId;
190        static int sReservedMailboxes;
191       
192
193protected:
194
195        /// the potentially visible objects
196        ObjectPvs mPvs;
197
198        float mVolume;
199        float mArea;
200
201        int mTimeStamp;
202
203        bool mValid;
204};
205
206
207class ViewCellInterior: public ViewCell
208{
209public:
210        ViewCellInterior();
211        ~ViewCellInterior();
212
213        ViewCellInterior(Mesh *mesh);
214       
215
216        /** Sets pointer from parent to child and vice versa.
217        */
218        void SetupChildLink(ViewCell *l);
219        void RemoveChildLink(ViewCell *l);
220        bool IsLeaf() const;
221
222        ViewCellContainer mChildren;
223
224};
225
226/**
227        View cell belonging to a hierarchy.
228*/
229template<typename T>
230class ViewCellLeaf: public ViewCell
231{
232public:
233
234        ViewCellLeaf<T>(): mLeaf(NULL) {}
235        ViewCellLeaf<T>(Mesh *mesh):
236                ViewCell(mesh), mLeaf(NULL) {}
237
238        void UpdateViewCellsStats(ViewCellsStatistics &vcStat)
239        {
240                ViewCell::UpdateViewCellsStats(vcStat);
241
242                //if ((int)mLeaves.size() > vcStat.maxLeaves)
243                //      vcStat.maxLeaves = (int)mLeaves.size();
244                //vcStat.leaves += (int)mLeaves.size();
245        }
246
247        bool IsLeaf() const
248        {
249                return true;
250        }
251
252        /// Leaf of some hierarchy which is part of this view cell.
253        T mLeaf;
254};
255
256
257typedef ViewCellLeaf<BspLeaf *> BspViewCell;
258typedef ViewCellLeaf<KdLeaf *> KdViewCell;
259typedef ViewCellLeaf<VspKdLeaf *> VspKdViewCell;
260
261
262
263class ViewCellsTree
264{
265public:
266        ViewCellsTree(ViewCellsManager *vcm);
267        ~ViewCellsTree();
268
269        /** Returns number of leaves this view cell consists of.
270        */
271        int GetSize(ViewCell *vc) const;
272
273        /** Collects leaves corresponding to a view cell.
274        */
275        void CollectLeaves(ViewCell *vc, ViewCellContainer &leaves) const;
276
277        /** Merges view cells according to some cost heuristics.
278        */
279        int ConstructMergeTree(const VssRayContainer &rays, const ObjectContainer &objects);
280       
281        /** Refines view cells using shuffling, i.e., border leaves
282                of two view cells are exchanged if the resulting view cells
283                are tested to be "better" than the old ones.
284                @returns number of refined view cells
285        */
286        int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
287
288       
289
290        /** Returns optimal set of view cells for a given number of view cells.
291        */
292        void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
293
294        /** Root of view cells tree.
295        */
296        ViewCell *GetRoot() const;
297
298        /** Returns pvs of view cell.
299                @note pvs is returned per reference if tree is not compressed,
300                per copy else.
301        */
302        void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
303
304        /** Returns pvs size of view cell.
305        */
306        int GetPvsSize(ViewCell *vc) const;
307
308        /** Returns actual number of object in this pvs and the children.
309        */
310        int GetNumPvsEntries(ViewCell *vc) const;
311
312        /** Returns memory cost of this view cell.
313        */
314        float GetMemoryCost(ViewCell *vc) const;
315
316        /** Compresses the pvs of the view cells from the root.
317        */
318        void CompressViewCellsPvs();
319
320        /** If view cells in this tree have compressed pvs.
321        */
322        bool IsCompressed() const;
323
324protected:
325
326
327        //////////////////////////////////////////////////////////////
328        //                 merge options                            //
329        //////////////////////////////////////////////////////////////
330       
331
332        /** Returns cost of this leaf according to current heuristics.
333        */
334        float GetCostHeuristics(ViewCell *vc) const;
335
336        /** Returns cost of leaf.
337        */
338        float GetRenderCost(ViewCell *vc) const;
339
340        /** Evaluates the merge cost of this merge candidate pair.
341        */
342        void EvalMergeCost(MergeCandidate &mc) const;
343
344        /** Variance of leaf.
345        */
346        float GetVariance(ViewCell *vc) const;
347
348        /** Standard deviation of leaf.
349        */
350        float GetDeviation(ViewCell *vc) const;
351
352        /** Tries to set this merge candidate to valid.
353                @returns false if both view cells are the same
354        */
355        bool ValidateMergeCandidate(MergeCandidate &mc) const;
356
357        /** Merge view cells of leaves l1 and l2.
358                @returns difference in pvs size
359        */
360        ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, int &pvsDiff); //const;
361
362        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
363                to view cell 2.
364        */
365        void ShuffleLeaf(ViewCell *leaf, ViewCellInterior *vc1, ViewCellInterior *vc2) const;   
366               
367        /** Shuffles the leaves, i.e., tests if exchanging
368                the leaves helps in improving the view cells.
369        */
370        bool ShuffleLeaves(MergeCandidate &mc) const;
371
372        /** Calculates cost for merge of view cell 1 and 2.
373        */
374        float EvalShuffleCost(ViewCell *leaf,
375                                                  ViewCellInterior *vc1,
376                                                  ViewCellInterior *vc2) const;
377
378        /** Exports a snapshot of the merged view cells to disc.
379        */
380        void ExportMergedViewCells(ViewCellContainer &viewCells,
381                                                           const ObjectContainer &objects,
382                                                           const int numNewViewCells);
383
384        /** merge queue must be reset after some time because expected value
385                may not be valid.
386        */
387        void ResetMergeQueue();
388
389        /** Updates the current top level of view cells.
390                @returns number of newly merged view cells
391        */
392        int UpdateActiveViewCells(ViewCellContainer &viewCells);
393
394        void PropagateUpVisibility(ViewCellInterior *interior);
395
396        void CompressViewCellsPvs(ViewCell *root);
397
398        /** Returns memory usage of view cells.
399        */
400        float GetMemUsage() const;
401
402
403        /// if the view cell tree hold compressed pvs
404        bool mIsCompressed;
405
406        ViewCellsManager *mViewCellsManager;
407        ViewCell *mRoot;
408
409        /// if merge visualization should be shown
410        bool mExportMergedViewCells;
411
412       
413               
414        ViewCellContainer mMergedViewCells;
415       
416
417        bool mRefineViewCells;
418
419        /// weights between variance and render cost increase (must be between zero and one)
420        float mRenderCostWeight;
421
422        /// overall cost used to normalize cost ratio
423        float mOverallCost;
424        float mExpectedCost;
425    float mDeviation;
426        float mAvgRenderCost;
427
428        int mUseAreaForPvs;
429
430        int mNumActiveViewCells;
431
432        /// minimal number of view cells
433        int mMergeMinViewCells;
434        /// maximal cost ratio for the merge
435        float mMergeMaxCostRatio;
436
437        ofstream mStats;
438
439        typedef priority_queue<MergeCandidate> MergeQueue;
440
441        MergeQueue mMergeQueue;
442
443        float mMaxMemory;
444
445};
446
447
448/**
449        Candidate for leaf merging based on priority.
450*/
451class MergeCandidate
452
453        friend class ViewCellsTree;
454
455public:
456
457        MergeCandidate(ViewCell *l, ViewCell *r);
458
459        /** If this merge pair is still valid.
460        */
461        bool IsValid() const;
462
463       
464        friend bool operator<(const MergeCandidate &leafa, const MergeCandidate &leafb)
465        {
466                return leafb.GetMergeCost() < leafa.GetMergeCost();
467        }
468
469        void SetLeftViewCell(ViewCell *l);
470        void SetRightViewCell(ViewCell *l);
471
472        ViewCell *GetLeftViewCell() const;
473        ViewCell *GetRightViewCell() const;
474
475        ViewCell *GetInitialLeftViewCell() const;
476        ViewCell *GetInitialRightViewCell() const;
477
478        /** Returns the increase of the standard deviation of this merge candidate.
479        */
480        float GetDeviationIncr() const;
481
482        /** Merge cost of this candidate pair.
483        */
484        float GetMergeCost() const;
485
486        /** Render cost of this candidate.
487        */
488        float GetRenderCost() const;
489       
490        static float sRenderCostWeight;
491
492protected:
493
494        /// render cost increase by this merge
495        float mRenderCost;
496        /// increase / decrease of standard deviation
497        float mDeviationIncr;
498
499        ViewCell *mLeftViewCell;
500        ViewCell *mRightViewCell;
501
502        ViewCell *mInitialLeftViewCell;
503        ViewCell *mInitialRightViewCell;
504};
505
506
507class MergeStatistics: public StatisticsBase
508{
509public:
510       
511        int merged;
512        int siblings;
513        int candidates;
514        int nodes;
515
516        int accTreeDist;
517        int maxTreeDist;
518       
519        Real collectTime;
520        Real mergeTime;
521
522        Real overallCost;
523
524        Real expectedRenderCost;
525        Real deviation;
526        Real heuristics;
527
528        // Constructor
529        MergeStatistics()
530        {
531                Reset();
532        }
533       
534        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
535
536        void Reset()
537        {
538                nodes = 0;
539                merged = 0;
540                siblings = 0;
541                candidates = 0;
542       
543                accTreeDist = 0;
544                maxTreeDist = 0;
545
546                collectTime = 0;
547                mergeTime = 0;
548                overallCost = 0;
549
550                expectedRenderCost = 0;
551                deviation = 0;
552                heuristics = 0;
553
554        }
555
556        void Print(ostream &app) const;
557
558        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
559        {
560                stat.Print(s);
561                return s;
562        }
563};
564
565#endif
Note: See TracBrowser for help on using the repository browser.