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

Revision 2116, 19.6 KB checked in by mattausch, 17 years ago (diff)

implemented hashpvs

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