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

Revision 1761, 19.9 KB checked in by bittner, 18 years ago (diff)

filter updates, kd + bvh PVS coexistence

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