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

Revision 1004, 17.0 KB checked in by mattausch, 18 years ago (diff)

environment as a singleton

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