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

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