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

Revision 1842, 20.2 KB checked in by mattausch, 18 years ago (diff)

fixed compress

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