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

Revision 605, 11.5 KB checked in by mattausch, 18 years ago (diff)
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
132        /** if this view cell is the root of a view cell hierarchy
133        */
134        bool IsRoot() const;
135
136        /** Returns parent view cell.
137        */
138        ViewCellInterior *GetParent() const;
139
140       
141        /** Sets the mesh for this view cell.
142        */
143        void SetMesh(Mesh *mesh);
144
145        void SetValid(const bool valid);
146        bool GetValid() const;
147
148
149
150
151        /// parent view cell in the view cell hierarchy
152        ViewCellInterior *mParent;
153
154        /// Rays piercing this view cell.
155        RayContainer mPiercingRays;
156
157
158        /** if this is a view cell correspending to a leaf in a hierarchy.
159        */
160        virtual bool IsLeaf() const = 0;
161
162  static bool SmallerPvs(const ViewCell *a,
163                                                 const ViewCell *b) {
164        return a->GetPvs().GetSize() < b->GetPvs().GetSize();
165  }
166
167
168        void SetMergeCost(const float mergeCost);
169        float GetMergeCost() const;
170        static void NewMail(const int reserve = 1) {
171                sMailId += sReservedMailboxes;
172                sReservedMailboxes = reserve;
173        }
174        void Mail() { mMailbox = sMailId; }
175        bool Mailed() const { return mMailbox == sMailId; }
176
177        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
178        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
179
180        int IncMail() { return ++mMailbox - sMailId; }
181
182
183                                                 
184        // last mail id -> warning not thread safe!
185        // both mailId and mailbox should be unique for each thread!!!
186        static int sMailId;
187        static int sReservedMailboxes;
188       
189        bool mIsActive;
190
191protected:
192
193
194        /// the potentially visible objects
195        ObjectPvs mPvs;
196
197        float mVolume;
198        float mArea;
199
200        float mMergeCost;
201
202        bool mValid;
203};
204
205
206class ViewCellInterior: public ViewCell
207{
208public:
209        ViewCellInterior();
210        ~ViewCellInterior();
211
212        ViewCellInterior(Mesh *mesh);
213       
214
215        /** Sets pointer from parent to child and vice versa.
216        */
217        void SetupChildLink(ViewCell *l);
218        void RemoveChildLink(ViewCell *l);
219        bool IsLeaf() const;
220
221        ViewCellContainer mChildren;
222
223};
224
225/**
226        View cell belonging to a hierarchy.
227*/
228template<typename T>
229class ViewCellLeaf: public ViewCell
230{
231public:
232
233        ViewCellLeaf<T>(): mLeaf(NULL) {}
234        ViewCellLeaf<T>(Mesh *mesh):
235                ViewCell(mesh), mLeaf(NULL) {}
236
237       
238
239        bool IsLeaf() const
240        {
241                return true;
242        }
243
244        /// Leaf of some hierarchy which is part of this view cell.
245        T mLeaf;
246};
247
248
249typedef ViewCellLeaf<BspLeaf *> BspViewCell;
250typedef ViewCellLeaf<KdLeaf *> KdViewCell;
251typedef ViewCellLeaf<VspKdLeaf *> VspKdViewCell;
252
253
254
255class ViewCellsTree
256{
257        friend class ViewCellsManager;
258public:
259        ViewCellsTree(ViewCellsManager *vcm);
260        ~ViewCellsTree();
261
262        /** Returns number of leaves this view cell consists of.
263        */
264        int GetSize(ViewCell *vc) const;
265
266        /** Collects leaves corresponding to a view cell.
267        */
268        void CollectLeaves(ViewCell *vc, ViewCellContainer &leaves) const;
269
270        /** Merges view cells according to some cost heuristics.
271        */
272        int ConstructMergeTree(const VssRayContainer &rays, const ObjectContainer &objects);
273       
274        /** Refines view cells using shuffling, i.e., border leaves
275                of two view cells are exchanged if the resulting view cells
276                are tested to be "better" than the old ones.
277                @returns number of refined view cells
278        */
279        int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
280
281        /** Updates view cell stats for this particular view cell
282        */
283        void UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat);
284       
285
286        /** Returns optimal set of view cells for a given number of view cells.
287        */
288        void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
289
290        /** Root of view cells tree.
291        */
292        ViewCell *GetRoot() const;
293
294        /** Returns pvs of view cell.
295                @note pvs is returned per reference if tree is not compressed,
296                per copy else.
297        */
298        void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
299
300        /** Returns pvs size of view cell.
301        */
302        int GetPvsSize(ViewCell *vc) const;
303
304        /** Returns actual number of object in this pvs and the children.
305        */
306        int GetNumPvsEntries(ViewCell *vc) const;
307
308        /** Returns memory cost of this view cell.
309        */
310        float GetMemoryCost(ViewCell *vc) const;
311
312        /** Compresses the pvs of the view cells from the root.
313        */
314        void CompressViewCellsPvs();
315
316        /** If view cells in this tree have compressed pvs.
317        */
318        bool IsCompressed() const;
319
320        ViewCell *GetActiveViewCell(ViewCell *vc) const;
321
322protected:
323
324
325        //////////////////////////////////////////////////////////////
326        //                 merge options                            //
327        //////////////////////////////////////////////////////////////
328       
329
330        /** Returns cost of this leaf according to current heuristics.
331        */
332        float GetCostHeuristics(ViewCell *vc) const;
333
334        /** Returns cost of leaf.
335        */
336        float GetRenderCost(ViewCell *vc) const;
337
338        /** Evaluates the merge cost of this merge candidate pair.
339        */
340        void EvalMergeCost(MergeCandidate &mc) const;
341
342        /** Variance of leaf.
343        */
344        float GetVariance(ViewCell *vc) const;
345
346        /** Standard deviation of leaf.
347        */
348        float GetDeviation(ViewCell *vc) const;
349
350        /** Tries to set this merge candidate to valid.
351                @returns false if both view cells are the same
352        */
353        bool ValidateMergeCandidate(MergeCandidate &mc) const;
354
355        /** Merge view cells of leaves l1 and l2.
356                @returns difference in pvs size
357        */
358        ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, int &pvsDiff); //const;
359
360        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
361                to view cell 2.
362        */
363        void ShuffleLeaf(ViewCell *leaf, ViewCellInterior *vc1, ViewCellInterior *vc2) const;   
364               
365        /** Shuffles the leaves, i.e., tests if exchanging
366                the leaves helps in improving the view cells.
367        */
368        bool ShuffleLeaves(MergeCandidate &mc) const;
369
370        /** Calculates cost for merge of view cell 1 and 2.
371        */
372        float EvalShuffleCost(ViewCell *leaf,
373                                                  ViewCellInterior *vc1,
374                                                  ViewCellInterior *vc2) const;
375
376        /** Exports a snapshot of the merged view cells to disc.
377        */
378        void ExportMergedViewCells(ViewCellContainer &viewCells,
379                                                           const ObjectContainer &objects,
380                                                           const int numNewViewCells);
381
382        /** merge queue must be reset after some time because expected value
383                may not be valid.
384        */
385        void ResetMergeQueue();
386
387        /** Updates the current top level of view cells.
388                @returns number of newly merged view cells
389        */
390        int UpdateActiveViewCells(ViewCellContainer &viewCells);
391
392        void PropagateUpVisibility(ViewCellInterior *interior);
393
394        void CompressViewCellsPvs(ViewCell *root);
395
396        /** Returns memory usage of view cells.
397        */
398        float GetMemUsage() const;
399
400
401        /// if the view cell tree hold compressed pvs
402        bool mIsCompressed;
403
404        ViewCellsManager *mViewCellsManager;
405        ViewCell *mRoot;
406
407        /// if merge visualization should be shown
408        bool mExportMergedViewCells;
409
410       
411               
412        ViewCellContainer mMergedViewCells;
413       
414
415        bool mRefineViewCells;
416
417        /// weights between variance and render cost increase (must be between zero and one)
418        float mRenderCostWeight;
419
420        /// overall cost used to normalize cost ratio
421        float mOverallCost;
422        float mExpectedCost;
423    float mDeviation;
424        float mAvgRenderCost;
425
426        int mUseAreaForPvs;
427
428        int mNumActiveViewCells;
429
430        /// minimal number of view cells
431        int mMergeMinViewCells;
432        /// maximal cost ratio for the merge
433        float mMergeMaxCostRatio;
434
435        ofstream mStats;
436
437        typedef priority_queue<MergeCandidate> MergeQueue;
438
439        MergeQueue mMergeQueue;
440
441        float mMaxMemory;
442
443};
444
445
446/**
447        Candidate for leaf merging based on priority.
448*/
449class MergeCandidate
450
451        friend class ViewCellsTree;
452
453public:
454
455        MergeCandidate(ViewCell *l, ViewCell *r);
456
457        /** If this merge pair is still valid.
458        */
459        bool IsValid() const;
460
461       
462        friend bool operator<(const MergeCandidate &leafa, const MergeCandidate &leafb)
463        {
464                return leafb.GetMergeCost() < leafa.GetMergeCost();
465        }
466
467        void SetLeftViewCell(ViewCell *l);
468        void SetRightViewCell(ViewCell *l);
469
470        ViewCell *GetLeftViewCell() const;
471        ViewCell *GetRightViewCell() const;
472
473        ViewCell *GetInitialLeftViewCell() const;
474        ViewCell *GetInitialRightViewCell() const;
475
476        /** Returns the increase of the standard deviation of this merge candidate.
477        */
478        float GetDeviationIncr() const;
479
480        /** Merge cost of this candidate pair.
481        */
482        float GetMergeCost() const;
483
484        /** Render cost of this candidate.
485        */
486        float GetRenderCost() const;
487       
488        static float sRenderCostWeight;
489
490protected:
491
492        /// render cost increase by this merge
493        float mRenderCost;
494        /// increase / decrease of standard deviation
495        float mDeviationIncr;
496
497        ViewCell *mLeftViewCell;
498        ViewCell *mRightViewCell;
499
500        ViewCell *mInitialLeftViewCell;
501        ViewCell *mInitialRightViewCell;
502};
503
504
505class MergeStatistics: public StatisticsBase
506{
507public:
508       
509        int merged;
510        int siblings;
511        int candidates;
512        int nodes;
513
514        int accTreeDist;
515        int maxTreeDist;
516       
517        Real collectTime;
518        Real mergeTime;
519
520        Real overallCost;
521
522        Real expectedRenderCost;
523        Real deviation;
524        Real heuristics;
525
526        // Constructor
527        MergeStatistics()
528        {
529                Reset();
530        }
531       
532        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
533
534        void Reset()
535        {
536                nodes = 0;
537                merged = 0;
538                siblings = 0;
539                candidates = 0;
540       
541                accTreeDist = 0;
542                maxTreeDist = 0;
543
544                collectTime = 0;
545                mergeTime = 0;
546                overallCost = 0;
547
548                expectedRenderCost = 0;
549                deviation = 0;
550                heuristics = 0;
551
552        }
553
554        void Print(ostream &app) const;
555
556        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
557        {
558                stat.Print(s);
559                return s;
560        }
561};
562
563#endif
Note: See TracBrowser for help on using the repository browser.