source: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h @ 860

Revision 860, 14.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#include "Material.h"
9//namespace GtpVisibilityPreprocessor {
10
11namespace GtpVisibilityPreprocessor {
12
13struct Triangle3;
14
15class BspInterior;
16class BspPvs;
17class BspLeaf;
18class VspKdTree;
19class VspKdLeaf;
20class KdLeaf;
21class ViewCellInterior;
22class MergeCandidate;
23class ViewCellsManager;
24
25/** Statistics for a view cell partition.
26*/
27
28class ViewCellsStatistics: public StatisticsBase
29{
30public:
31
32        /// number of view cells
33        int viewCells;
34
35        /// size of the PVS
36        int pvsSize;
37
38        /// largest PVS of all view cells
39        int maxPvs;
40
41        /// smallest PVS of all view cells
42        int minPvs;
43
44        /// view cells with empty PVS
45        int emptyPvs;
46
47        /// number of leaves covering the view space
48        int leaves;
49
50        /// largest number of leaves covered by one view cell
51        int maxLeaves;
52
53        int invalid;
54
55    // Constructor
56        ViewCellsStatistics()
57        {
58                Reset();
59        }
60
61        double AvgLeaves() const {return (double)leaves / (double)viewCells;};
62        double AvgPvs() const {return (double)pvsSize / (double)viewCells;};
63
64        void Reset()
65        {
66                viewCells = 0;
67                pvsSize = 0;
68                maxPvs = 0;
69
70                minPvs = 999999;
71                emptyPvs = 0;
72                leaves = 0;
73                maxLeaves = 0;
74                invalid = 0;
75        }
76
77        void Print(ostream &app) const;
78
79        friend ostream &operator<<(ostream &s, const ViewCellsStatistics &stat)
80        {
81                stat.Print(s);
82                return s;
83        }
84};
85
86
87/**
88        View cell with an optional mesh representation
89*/
90
91
92class ViewCell: public MeshInstance
93{
94        friend class ViewCellsTree;
95        friend class ViewCellsManager;
96        friend class VspBspViewCellsManager;
97        friend class BspViewCellsManager;
98        friend class VspBspTree;
99        friend class FromPointVisibilityTree;
100        friend class BspTree;
101
102
103public:
104        ViewCell();
105
106        /** Constructor taking a mesh representing the shape of the viewcell.
107        */
108        ViewCell(Mesh *mesh);
109
110        /** Default destructor.
111        */
112        virtual ~ViewCell() {}
113
114        /** Returns Pvs.
115        */
116        const ObjectPvs &GetPvs() const;
117
118        ObjectPvs &GetPvs();
119
120        /** Type of view cells.
121        */
122        int Type() const;
123
124        void SetParent(ViewCellInterior *parent);
125
126        /** Adds a passing ray to the passing ray container.
127        */
128        void AddPassingRay(const Ray &ray, const int contributions);
129
130        /** Returns volume of the view cell.
131        */
132        float GetVolume() const;
133
134        /** Returns area of the view cell.
135        */
136        float GetArea() const;
137
138        /** Sets the volume of the view cell.
139        */
140        void SetVolume(float volume);
141       
142        /** Sets the area of the view cell.
143        */
144        void SetArea(float area);
145
146
147        /** if this view cell is the root of a view cell hierarchy
148        */
149        bool IsRoot() const;
150
151        /** Returns parent view cell.
152        */
153        ViewCellInterior *GetParent() const;
154
155       
156        /** Sets the mesh for this view cell.
157        */
158        void SetMesh(Mesh *mesh);
159
160        void SetValid(const bool valid);
161        bool GetValid() const;
162
163        /** Returns estimated render cost of this view cell.
164        */
165        float GetRenderCost() const;
166
167        /** set color for visiualizations.
168        */
169        void SetColor(const RgbColor &color);
170
171        /** get color for visualuzations.
172        */
173    RgbColor GetColor() const;
174
175 
176        /// parent view cell in the view cell hierarchy
177        ViewCellInterior *mParent;
178
179        /// Rays piercing this view cell.
180        RayContainer mPiercingRays;
181
182
183        /** if this is a view cell correspending to a leaf in a hierarchy.
184        */
185        virtual bool IsLeaf() const = 0;
186
187        static bool SmallerPvs(const ViewCell *a, const ViewCell *b)
188        {
189        return a->GetPvs().GetSize() < b->GetPvs().GetSize();
190  }
191
192 static bool SmallerRenderCost(const ViewCell *a, const ViewCell *b)
193 {
194         return a->GetRenderCost() < b->GetRenderCost();
195 }
196
197 static bool LargerRenderCost(const ViewCell *a, const ViewCell *b)
198 {
199         return a->GetRenderCost() > b->GetRenderCost();
200 }
201
202        void SetMergeCost(const float mergeCost);
203        float GetMergeCost() const;
204        static void NewMail(const int reserve = 1) {
205                sMailId += sReservedMailboxes;
206                sReservedMailboxes = reserve;
207        }
208        void Mail() { mMailbox = sMailId; }
209        bool Mailed() const { return mMailbox == sMailId; }
210
211        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
212        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
213
214        int IncMail() { return ++mMailbox - sMailId; }
215
216
217        /** Sets this view cell to be an active view cell.
218        */
219        void SetActive();
220        /** Returns if this view cell is active.
221        */
222        bool IsActive() const;
223
224
225        // last mail id -> warning not thread safe!
226        // both mailId and mailbox should be unique for each thread!!!
227        static int sMailId;
228        static int sReservedMailboxes;
229
230        static int sLastUpdated;
231       
232protected:
233
234        /// the potentially visible objects
235        ObjectPvs mPvs;
236
237        float mVolume;
238        float mArea;
239
240        float mMergeCost;
241
242        bool mValid;
243
244        int mLastUpdated;
245        bool mIsActive;
246        /** color used for consistent visualization */
247        RgbColor mColor;
248
249       
250        /// pvs size, used for lazy pvs computation
251        int mPvsSize;
252        bool mPvsSizeValid;
253
254};
255
256
257class ViewCellInterior: public ViewCell
258{
259        friend class ViewCellsManager;
260public:
261        ViewCellInterior();
262        ~ViewCellInterior();
263
264        ViewCellInterior(Mesh *mesh);
265       
266
267        /** Sets pointer from parent to child and vice versa.
268        */
269        void SetupChildLink(ViewCell *l);
270        void RemoveChildLink(ViewCell *l);
271        bool IsLeaf() const;
272
273        ViewCellContainer mChildren;
274
275  void SetCost(const float c) {
276        mCost = c;
277  }
278  float GetCost() const {
279        return mCost;
280  }
281 
282protected:
283  /** overall cost resulting from the merge */
284  float mCost;
285};
286
287/**
288        View cell belonging to a hierarchy.
289*/
290template<typename T>
291class ViewCellLeaf: public ViewCell
292{
293public:
294
295        ViewCellLeaf<T>(): mLeaf(NULL) { SetActive(); }
296        ViewCellLeaf<T>(Mesh *mesh):
297        ViewCell(mesh), mLeaf(NULL) { SetActive(); }
298       
299
300        bool IsLeaf() const
301        {
302                return true;
303        }
304
305        /// Leaf of some hierarchy which is part of this view cell.
306        T mLeaf;
307};
308
309
310typedef ViewCellLeaf<BspLeaf *> BspViewCell;
311typedef ViewCellLeaf<KdLeaf *> KdViewCell;
312typedef ViewCellLeaf<VspKdLeaf *> VspKdViewCell;
313
314
315
316class ViewCellsTree
317{
318        friend class ViewCellsManager;
319
320
321public:
322        ViewCellsTree(ViewCellsManager *vcm);
323        ~ViewCellsTree();
324
325        /** Returns number of leaves this view cell consists of.
326        */
327        int GetNumInitialViewCells(ViewCell *vc) const;
328
329        /** Collects leaves corresponding to a view cell.
330        */
331        void CollectLeaves(ViewCell *vc, ViewCellContainer &leaves) const;
332
333        /** Merges view cells according to some cost heuristics.
334        */
335        int ConstructMergeTree(const VssRayContainer &rays, const ObjectContainer &objects);
336       
337        /** Refines view cells using shuffling, i.e., border leaves
338                of two view cells are exchanged if the resulting view cells
339                are tested to be "better" than the old ones.
340                @returns number of refined view cells
341        */
342        int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
343       
344        /** Assign colors to the viewcells so that they can be renderered interactively without
345          color flickering.
346          */
347        void AssignRandomColors();
348
349        /** Updates view cell stats for this particular view cell
350        */
351        void UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat);
352
353
354        /** Get costs resulting from each merge step. */
355        void GetCostFunction(vector<float> &costFunction);
356
357 
358        /** Returns optimal set of view cells for a given number of view cells.
359        */
360        void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
361
362        /** Root of view cells tree.
363        */
364        ViewCell *GetRoot() const;
365
366        /** Returns pvs of view cell.
367                @note pvs is returned per reference if tree is not compressed,
368                per copy else.
369        */
370        void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
371
372        /** Returns pvs size of view cell.
373        */
374        int GetPvsSize(ViewCell *vc) const;
375
376        /** Returns actual number of object in this pvs and the children.
377        */
378        int GetNumPvsEntries(ViewCell *vc) const;
379
380        /** Returns memory cost of this view cell.
381        */
382        float GetMemoryCost(ViewCell *vc) const;
383
384        /** Sets method of storage for view cells.
385        */
386        void SetViewCellsStorage(int type);
387
388        /** pvs storage methods
389        */
390        enum {PVS_IN_INTERIORS, COMPRESSED, PVS_IN_LEAVES};
391
392       
393        /** If view cells in this tree have compressed pvs.
394        */
395        int ViewCellsStorage() const;
396
397        /** Returns active view cell that is in the path of this view cell.
398        */
399        ViewCell *GetActiveViewCell(ViewCell *vc) const;
400
401        /** Sets the leaves to be the currently active view cells.
402        */
403    void SetActiveSetToLeaves();
404
405        /** Propagates pvs up the tree to the root and downwards the tree.
406        */
407        void PropagatePvs(ViewCell *vc);
408
409        /** Exports view cells to file.
410        */
411    bool Export(ofstream &stream, const bool exportPvs = false);
412
413        /** Export statistics of this view cell tree.
414        */
415        void ExportStats(const string &mergeStats);
416
417        /** Sets root of hierarchy.
418        */
419        void SetRoot(ViewCell *root);
420
421        //float ComputeVolume(ViewCell *vc);
422
423        /** Assignes unique ids to view cells.
424        */
425        void CreateUniqueViewCellsIds();
426
427        /** Resets pvs of whole tree.
428        */
429        void ResetPvs();
430
431protected:
432
433
434        //////////////////////////////////////////////////////////////
435        //                 merge related stuff                      //
436        //////////////////////////////////////////////////////////////
437
438        /** Computes render cost of the merged pvs.
439        */
440        float ComputeMergedPvsCost(const ObjectPvs &pvs1, const ObjectPvs &pvs2) const;
441
442        /** Returns cost of this leaf according to current heuristics.
443        */
444        float GetCostHeuristics(ViewCell *vc) const;
445
446        /** Returns cost of leaf.
447        */
448        float GetRenderCost(ViewCell *vc) const;
449
450        /** Evaluates the merge cost of this merge candidate pair.
451        */
452        void EvalMergeCost(MergeCandidate &mc) const;
453
454        /** Variance of leaf.
455        */
456        float GetVariance(ViewCell *vc) const;
457
458        /** Standard deviation of leaf.
459        */
460        float GetDeviation(ViewCell *vc) const;
461
462        /** Tries to set this merge candidate to valid.
463                @returns false if both view cells are the same
464        */
465        bool ValidateMergeCandidate(MergeCandidate &mc) const;
466
467        /** Merge view cells of leaves l1 and l2.
468                @returns difference in pvs size
469        */
470        ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, int &pvsDiff); //const;
471
472        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
473                to view cell 2.
474        */
475        void ShuffleLeaf(ViewCell *leaf, ViewCellInterior *vc1, ViewCellInterior *vc2) const;   
476               
477        /** Shuffles the leaves, i.e., tests if exchanging
478                the leaves helps in improving the view cells.
479        */
480        bool ShuffleLeaves(MergeCandidate &mc) const;
481
482        /** Calculates cost for merge of view cell 1 and 2.
483        */
484        float EvalShuffleCost(ViewCell *leaf,
485                                                  ViewCellInterior *vc1,
486                                                  ViewCellInterior *vc2) const;
487
488        /** Exports a snapshot of the merged view cells to disc.
489        */
490        void ExportMergedViewCells(ViewCellContainer &viewCells,
491                                                           const ObjectContainer &objects,
492                                                           const int numNewViewCells);
493
494        /** merge queue must be reset after some time because expected value
495                may not be valid.
496        */
497        void ResetMergeQueue();
498
499        /** Updates the current top level of view cells.
500                @returns number of newly merged view cells
501        */
502        int UpdateActiveViewCells(ViewCellContainer &viewCells);
503
504        void PullUpVisibility(ViewCellInterior *interior);
505
506        void CompressViewCellsPvs(ViewCell *root);
507
508        /** Returns memory usage of view cells.
509        */
510        float GetMemUsage() const;
511
512        /**     Exports single view cell.
513                NOTE: should be in exporter!!
514        */
515        void ExportViewCell(ViewCell *viewCell, ofstream &stream, const bool exportPvs);
516
517        /** Exports pvs of a view cell.
518        */
519        void ExportPvs(ViewCell *viewCell, ofstream &stream);
520
521
522
523        /// if the view cell tree hold compressed pvs
524        int mViewCellsStorage;
525
526        ViewCellsManager *mViewCellsManager;
527        ViewCell *mRoot;
528
529        /// if merge visualization should be shown
530        bool mExportMergedViewCells;
531
532       
533        /// intermediate container of merged view cells.
534        ViewCellContainer mMergedViewCells;
535       
536
537        /// if merged view cells are refined.
538        bool mRefineViewCells;
539
540        /// weights between variance and render cost increase (must be between zero and one)
541        float mRenderCostWeight;
542
543        /// overall cost used to normalize cost ratio
544        float mOverallCost;
545        float mExpectedCost;
546    float mDeviation;
547        float mAvgRenderCost;
548        /// the area is used for pvs heuristics
549        int mUseAreaForPvs;
550
551        int mNumActiveViewCells;
552
553        /// minimal number of view cells
554        int mMergeMinViewCells;
555        /// maximal cost ratio for the merge
556        float mMergeMaxCostRatio;
557
558        typedef priority_queue<MergeCandidate> MergeQueue;
559
560        MergeQueue mMergeQueue;
561
562        float mMaxMemory;
563
564};
565
566
567/**
568        Candidate for leaf merging based on priority.
569*/
570class MergeCandidate
571
572        friend class ViewCellsTree;
573
574public:
575
576        MergeCandidate(ViewCell *l, ViewCell *r);
577
578        /** If this merge pair is still valid.
579        */
580        bool IsValid() const;
581
582       
583        friend bool operator<(const MergeCandidate &leafa, const MergeCandidate &leafb)
584        {
585                return leafb.GetMergeCost() < leafa.GetMergeCost();
586        }
587
588        void SetLeftViewCell(ViewCell *l);
589        void SetRightViewCell(ViewCell *l);
590
591        ViewCell *GetLeftViewCell() const;
592        ViewCell *GetRightViewCell() const;
593
594        /** Returns leaf view cell initially associated with this merge candidate.
595        */
596        ViewCell *GetInitialLeftViewCell() const;
597        ViewCell *GetInitialRightViewCell() const;
598
599        /** Returns the increase of the standard deviation of this merge candidate.
600        */
601        float GetDeviationIncr() const;
602
603        /** Merge cost of this candidate pair.
604        */
605        float GetMergeCost() const;
606
607        /** Render cost of this candidate.
608        */
609        float GetRenderCost() const;
610       
611        static float sRenderCostWeight;
612
613protected:
614
615        /// render cost increase by this merge
616        float mRenderCost;
617        /// increase / decrease of standard deviation
618        float mDeviationIncr;
619
620        ViewCell *mLeftViewCell;
621        ViewCell *mRightViewCell;
622
623        ViewCell *mInitialLeftViewCell;
624        ViewCell *mInitialRightViewCell;
625};
626
627
628class MergeStatistics: public StatisticsBase
629{
630public:
631       
632        int merged;
633        int siblings;
634        int candidates;
635        int nodes;
636
637        int accTreeDist;
638        int maxTreeDist;
639       
640        Real collectTime;
641        Real mergeTime;
642
643        Real overallCost;
644
645        Real expectedRenderCost;
646        Real deviation;
647        Real heuristics;
648
649        // Constructor
650        MergeStatistics()
651        {
652                Reset();
653        }
654       
655        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
656
657        void Reset()
658        {
659                nodes = 0;
660                merged = 0;
661                siblings = 0;
662                candidates = 0;
663       
664                accTreeDist = 0;
665                maxTreeDist = 0;
666
667                collectTime = 0;
668                mergeTime = 0;
669                overallCost = 0;
670
671                expectedRenderCost = 0;
672                deviation = 0;
673                heuristics = 0;
674
675        }
676
677        void Print(ostream &app) const;
678
679        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
680        {
681                stat.Print(s);
682                return s;
683        }
684};
685
686}
687
688#endif
Note: See TracBrowser for help on using the repository browser.