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

Revision 1667, 19.3 KB checked in by mattausch, 18 years ago (diff)

updated priority meaurement: taking total cost and memory into account

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