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

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