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

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