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

Revision 971, 15.4 KB checked in by mattausch, 18 years ago (diff)

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