source: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h @ 497

Revision 497, 21.6 KB checked in by mattausch, 19 years ago (diff)

beware: bug in view cells merging

Line 
1#ifndef _VspBspTree_H__
2#define _VspBspTree_H__
3
4#include "Mesh.h"
5#include "Containers.h"
6#include "Polygon3.h"
7#include <stack>
8#include "Statistics.h"
9#include "VssRay.h"
10#include "RayInfo.h"
11#include "ViewCellBsp.h"
12
13class ViewCell;
14//class BspViewCell;
15class Plane3;
16class VspBspTree; 
17class BspInterior;
18class BspNode;
19class AxisAlignedBox3;
20class Ray;
21class ViewCellsStatistics;
22class ViewCellsManager;
23class BspMergeCandidate;
24struct BspRay;
25
26
27/**
28        This is a view space partitioning specialised BSPtree. 
29        There are no polygon splits, but we split the sample rays.
30        The candidates for the next split plane are evaluated only
31        by checking the sampled visibility information.
32        The polygons are employed merely as candidates for the next split planes.
33*/
34class VspBspTree
35{
36public:
37       
38        /** Additional data which is passed down the BSP tree during traversal.
39        */
40        struct VspBspTraversalData
41        { 
42                /// the current node
43                BspNode *mNode;
44                /// polygonal data for splitting
45                PolygonContainer *mPolygons;
46                /// current depth
47                int mDepth;
48                /// rays piercing this node
49                RayInfoContainer *mRays;
50                /// area of current node
51                float mArea;
52                /// geometry of node as induced by planes
53                BspNodeGeometry *mGeometry;
54                /// pvs size
55                int mPvs;
56                /// how often this branch has missed the max-cost ratio
57                int mMaxCostMisses;
58
59
60                /** Returns average ray contribution.
61                */
62                float GetAvgRayContribution() const
63                {
64                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
65                }
66
67
68                VspBspTraversalData():
69                mNode(NULL),
70                mPolygons(NULL),
71                mDepth(0),
72                mRays(NULL),
73                mPvs(0),
74                mArea(0.0),
75                mGeometry(NULL),
76                mMaxCostMisses(0)
77                {}
78               
79                VspBspTraversalData(BspNode *node,
80                                                        PolygonContainer *polys,
81                                                        const int depth,
82                                                        RayInfoContainer *rays,
83                                                        int pvs,
84                                                        float area,
85                                                        BspNodeGeometry *geom):
86                mNode(node),
87                mPolygons(polys),
88                mDepth(depth),
89                mRays(rays),
90                mPvs(pvs),
91                mArea(area),
92                mGeometry(geom),
93                mMaxCostMisses(0)
94                {}
95
96                VspBspTraversalData(PolygonContainer *polys,
97                                                        const int depth,
98                                                        RayInfoContainer *rays,
99                                                        BspNodeGeometry *geom):
100                mNode(NULL),
101                mPolygons(polys),
102                mDepth(depth),
103                mRays(rays),
104                mPvs(0),
105                mArea(0),
106                mGeometry(geom),
107                mMaxCostMisses(0)
108                {}
109
110                /** Returns cost of the traversal data.
111                */
112                float GetCost() const
113                {
114#if 1
115                        return mPvs * mArea;
116#endif
117#if 0
118                        return (float)(mPvs * (int)mRays->size());
119#endif
120#if 0
121                        return (float)mPvs;
122#endif
123#if 0
124                        return mArea * (float)mRays->size();
125#endif
126                }
127
128                // deletes contents and sets them to NULL
129                void Clear()
130                {
131                        DEL_PTR(mPolygons);
132                        DEL_PTR(mRays);
133                        DEL_PTR(mGeometry);
134                }
135
136                friend bool operator<(const VspBspTraversalData &a, const VspBspTraversalData &b)
137                {
138                        return a.GetCost() < b.GetCost();
139                }
140    };
141       
142        typedef std::priority_queue<VspBspTraversalData> VspBspTraversalStack;
143        //typedef std::stack<VspBspTraversalData> VspBspTraversalStack;
144
145        /** Default constructor creating an empty tree.
146        */
147        VspBspTree();
148
149        /** Default destructor.
150        */
151        ~VspBspTree();
152
153        /** Returns BSP Tree statistics.
154        */
155        const BspTreeStatistics &GetStatistics() const;
156 
157
158        /** Constructs the tree from a given set of rays.
159                @param sampleRays the set of sample rays the construction is based on
160                @param viewCells if not NULL, new view cells are
161                created in the leafs and stored in the container
162        */
163        void Construct(const VssRayContainer &sampleRays,
164                                   AxisAlignedBox3 *forcedBoundingBox);
165
166        /** Returns list of BSP leaves.
167        */
168        void CollectLeaves(vector<BspLeaf *> &leaves) const;
169
170        /** Returns box which bounds the whole tree.
171        */
172        AxisAlignedBox3 GetBoundingBox()const;
173
174        /** Returns root of BSP tree.
175        */
176        BspNode *GetRoot() const;
177
178        /** Exports VspBsp tree to file.
179        */
180        bool Export(const string filename);
181
182        /** Collects the leaf view cells of the tree
183                @param viewCells returns the view cells
184        */
185        void CollectViewCells(ViewCellContainer &viewCells) const;
186
187        /** A ray is cast possible intersecting the tree.
188                @param the ray that is cast.
189                @returns the number of intersections with objects stored in the tree.
190        */
191        int CastRay(Ray &ray);
192
193        /// bsp tree construction types
194        enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_SAMPLES};
195
196        /** finds neighbouring leaves of this tree node.
197        */
198        int FindNeighbors(BspNode *n,
199                                          vector<BspLeaf *> &neighbors,
200                                          const bool onlyUnmailed) const;
201
202        /** Constructs geometry associated with the half space intersections
203                leading to this node.
204        */
205        void ConstructGeometry(BspNode *n, PolygonContainer &cell) const;
206
207        /** Constructs geometry associated with the half space intersections
208                leading to this node.
209        */
210        void ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const;
211
212        /** Construct geometry and stores it in a geometry node container.
213        */
214        void ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const;
215
216        /** Returns random leaf of BSP tree.
217                @param halfspace defines the halfspace from which the leaf is taken.
218        */
219        BspLeaf *GetRandomLeaf(const Plane3 &halfspace);
220
221        /** Returns random leaf of BSP tree.
222                @param onlyUnmailed if only unmailed leaves should be returned.
223        */
224        BspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
225
226        /** Returns epsilon of this tree.
227        */
228        float GetEpsilon() const;
229
230        /** Casts line segment into the tree.
231                @param origin the origin of the line segment
232                @param termination the end point of the line segment
233                @returns view cells intersecting the line segment.
234        */
235    int CastLineSegment(const Vector3 &origin,
236                                                const Vector3 &termination,
237                                                ViewCellContainer &viewcells);
238
239               
240        /** Sets pointer to view cells manager.
241        */
242        void SetViewCellsManager(ViewCellsManager *vcm);
243
244        /** Returns distance from node 1 to node 2.
245        */
246        int TreeDistance(BspNode *n1, BspNode *n2) const;
247
248        /** Merges view cells according to some cost heuristics.
249        */
250        int MergeViewCells(const VssRayContainer &rays);
251       
252        /** Refines view cells using shuffling, i.e., border leaves
253                of two view cells are exchanged if the resulting view cells
254                are tested to be "better" than the old ones.
255                @returns number of refined view cells
256        */
257        int RefineViewCells(const VssRayContainer &rays);
258
259        /** Collapses the tree with respect to the view cell partition.
260        */
261        void CollapseTree();
262
263  ViewCell *
264  GetViewCell(const Vector3 &point);
265
266        /** Constructs bsp rays for post processing and visualization.
267        */
268        void ConstructBspRays(vector<BspRay *> &bspRays,
269                                                  const VssRayContainer &rays);
270       
271        /** Merge view cells of leaves l1 and l2.
272        */
273        bool MergeViewCells(BspLeaf *l1, BspLeaf *l2) const;
274
275        /** Returns true if this view point is in a valid view space,
276                false otherwise.
277        */
278        bool ViewPointValid(const Vector3 &viewPoint) const;
279
280        /** Returns the view cell corresponding to
281                the space outside the valid view space.
282        */
283        BspViewCell *GetOutOfBoundsCell() const;
284
285protected:
286
287        // --------------------------------------------------------------
288        // For sorting objects
289        // --------------------------------------------------------------
290        struct SortableEntry
291        {
292                enum EType
293                {
294                        ERayMin,
295                        ERayMax
296                };
297
298                int type;
299                float value;
300                VssRay *ray;
301 
302                SortableEntry() {}
303                SortableEntry(const int t, const float v, VssRay *r):type(t),
304                                          value(v), ray(r)
305                {
306                }
307               
308                friend bool operator<(const SortableEntry &a, const SortableEntry &b)
309                {
310                        return a.value < b.value;
311                }
312        };
313
314        /** Collapses the tree with respect to the view cell partition,
315                i.e. leaves having the same view cell are collapsed.
316                @returns node of type leaf if the node could be collapsed,
317                this node otherwise
318        */
319        BspNode *CollapseTree(BspNode *node);
320        /** Shuffles the leaves, i.e., tests if exchanging
321                the leaves helps in improving the view cells.
322        */
323        bool ShuffleLeaves(BspLeaf *leaf1, BspLeaf *leaf2) const;
324
325        /** Helper function revalidating the view cell leaf list after merge.
326        */
327        void RepairVcLeafLists();
328
329        /** Evaluates tree stats in the BSP tree leafs.
330        */
331        void EvaluateLeafStats(const VspBspTraversalData &data);
332
333        /** Subdivides node with respect to the traversal data.
334            @param tStack current traversal stack
335                @param tData traversal data also holding node to be subdivided
336                @returns new root of the subtree
337        */
338        BspNode *Subdivide(VspBspTraversalStack &tStack,
339                                           VspBspTraversalData &tData);
340
341        /** Constructs the tree from the given traversal data.
342                @param polys stores set of polygons on which subdivision may be based
343                @param rays storesset of rays on which subdivision may be based
344        */
345        void Construct(const PolygonContainer &polys, RayInfoContainer *rays);
346
347        /** Selects the best possible splitting plane.
348                @param plane returns the split plane
349                @param leaf the leaf to be split
350                @param polys the polygon list on which the split decition is based
351                @param rays ray container on which selection may be based
352                @note the polygons can be reordered in the process
353                @returns true if the cost of the split is under maxCostRatio
354
355        */
356        bool SelectPlane(Plane3 &plane,
357                                         BspLeaf *leaf,
358                                         VspBspTraversalData &data);
359       
360        /** Strategies where the effect of the split plane is tested
361            on all input rays.
362
363                @returns the cost of the candidate split plane
364        */
365        float SplitPlaneCost(const Plane3 &candidatePlane,
366                                                 const VspBspTraversalData &data) const;
367
368
369        /** Subdivide leaf.
370                @param leaf the leaf to be subdivided
371               
372                @param polys the polygons to be split
373                @param frontPolys returns the polygons in front of the split plane
374                @param backPolys returns the polygons in the back of the split plane
375               
376                @param rays the polygons to be filtered
377                @param frontRays returns the polygons in front of the split plane
378                @param backRays returns the polygons in the back of the split plane
379
380                @returns the root of the subdivision
381        */
382
383        BspNode *SubdivideNode(VspBspTraversalData &tData,
384                                                   VspBspTraversalData &frontData,
385                                                   VspBspTraversalData &backData,
386                                                   PolygonContainer &coincident);
387
388        /** Selects the split plane in order to construct a tree with
389                certain characteristics (e.g., balanced tree, least splits,
390                2.5d aligned)
391                @param bestPlane returns the split plane
392                @param polygons container of polygons
393                @param rays bundle of rays on which the split can be based
394
395                @returns true if the overall cost is under maxCostRatio
396        */
397        bool SelectPlaneHeuristics(Plane3 &bestPlane,
398                                                           BspLeaf *leaf,
399                                                           VspBspTraversalData &data);
400
401        /** Extracts the meshes of the objects and adds them to polygons.
402                Adds object aabb to the aabb of the tree.
403                @param maxPolys the maximal number of objects to be stored as polygons
404                @returns the number of polygons
405        */
406        int AddToPolygonSoup(const ObjectContainer &objects,
407                                                 PolygonContainer &polys,
408                                                 int maxObjects = 0);
409
410        /** Extracts the meshes of the view cells and and adds them to polygons.
411                Adds view cell aabb to the aabb of the tree.
412                @param maxPolys the maximal number of objects to be stored as polygons
413                @returns the number of polygons
414        */
415        int AddToPolygonSoup(const ViewCellContainer &viewCells,
416                                                 PolygonContainer &polys,
417                                                 int maxObjects = 0);
418
419        /** Extract polygons of this mesh and add to polygon container.
420                @param mesh the mesh that drives the polygon construction
421                @param parent the parent intersectable this polygon is constructed from
422                @returns number of polygons
423        */
424        int AddMeshToPolygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent);
425
426        /** Selects an axis aligned for the next split.
427                @returns cost for this split
428        */
429        float SelectAxisAlignedPlane(Plane3 &plane,
430                                                                 const VspBspTraversalData &tData,
431                                                                 int &axis,
432                                                                 float &position,
433                                                                 int &raysBack,
434                                                                 int &raysFront,
435                                                                 int &pvsBack,
436                                                                 int &pvsFront);
437
438        /** Sorts split candidates for surface area heuristics for axis aligned splits.
439                @param polys the input for choosing split candidates
440                @param axis the current split axis
441                @param splitCandidates returns sorted list of split candidates
442        */
443        void SortSplitCandidates(const RayInfoContainer &rays, const int axis);
444
445        /** Computes best cost for axis aligned planes.
446        */
447        float BestCostRatioHeuristics(const RayInfoContainer &rays,
448                                                                  const AxisAlignedBox3 &box,
449                                                                  const int pvsSize,
450                                                                  const int &axis,
451                                                                  float &position);
452
453        /** Evaluates cost ratio for axis aligned splits.
454        */
455        float EvalCostRatio(const VspBspTraversalData &tData,
456                                                const AxisAlignedBox3 &box,
457                                                const int axis,
458                                                const float position,
459                                                int &raysBack,
460                                                int &raysFront,
461                                                int &pvsBack,
462                                                int &pvsFront);
463
464        /** Selects an axis aligned split plane.
465                @Returns true if split is valied
466        */
467        bool SelectAxisAlignedPlane(Plane3 &plane, const PolygonContainer &polys) const;
468
469        /** Subdivides the rays into front and back rays according to the split plane.
470               
471                @param plane the split plane
472                @param rays contains the rays to be split. The rays are
473                           distributed into front and back rays.
474                @param frontRays returns rays on the front side of the plane
475                @param backRays returns rays on the back side of the plane
476               
477                @returns the number of splits
478        */
479        int SplitRays(const Plane3 &plane,
480                                  RayInfoContainer &rays,
481                              RayInfoContainer &frontRays,
482                                  RayInfoContainer &backRays);
483
484
485        /** Extracts the split planes representing the space bounded by node n.
486        */
487        void ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const;
488
489        /** Adds the object to the pvs of the front and back leaf with a given classification.
490
491                @param obj the object to be added
492                @param cf the ray classification regarding the split plane
493                @param frontPvs returns the PVS of the front partition
494                @param backPvs returns the PVS of the back partition
495       
496        */
497        void AddObjToPvs(Intersectable *obj, const int cf, int &frontPvs, int &backPvs) const;
498       
499        /** Computes PVS size induced by the rays.
500        */
501        int ComputePvsSize(const RayInfoContainer &rays) const;
502
503        /** Returns true if tree can be terminated.
504        */
505        inline bool TerminationCriteriaMet(const VspBspTraversalData &data) const;
506
507        /** Computes accumulated ray lenght of this rays.
508        */
509        float AccumulatedRayLength(const RayInfoContainer &rays) const;
510
511        /** Splits polygons with respect to the split plane.
512
513                @param plane the split plane
514                @param polys the polygons to be split. the polygons are consumed and
515                           distributed to the containers frontPolys, backPolys, coincident.
516                @param frontPolys returns the polygons in the front of the split plane
517                @param backPolys returns the polygons in the back of the split plane
518                @param coincident returns the polygons coincident to the split plane
519
520                @returns the number of splits   
521        */
522        int SplitPolygons(const Plane3 &plane,
523                                          PolygonContainer &polys,
524                                          PolygonContainer &frontPolys,
525                                          PolygonContainer &backPolys,
526                                          PolygonContainer &coincident) const;
527
528        /** Adds ray sample contributions to the PVS.
529                @param sampleContributions the number contributions of the samples
530                @param contributingSampels the number of contributing rays
531               
532        */
533        void AddToPvs(BspLeaf *leaf,
534                                  const RayInfoContainer &rays,
535                                  int &sampleContributions,
536                                  int &contributingSamples);
537
538
539        /** Collects candidates for the merge in the merge queue.
540                @returns number of leaves in queue
541        */
542        int CollectMergeCandidates();
543        /** Collects candidates for the merge in the merge queue.
544                @returns number of leaves in queue
545        */
546        int CollectMergeCandidates(const VssRayContainer &rays);
547
548        /** Take 3 ray endpoints, where two are minimum and one a maximum
549                point or the other way round.
550        */
551        Plane3 ChooseCandidatePlane(const RayInfoContainer &rays) const;
552
553        /** Take plane normal as plane normal and the midpoint of the ray.
554                PROBLEM: does not resemble any point where visibility is
555                likely to change
556        */
557        Plane3 ChooseCandidatePlane2(const RayInfoContainer &rays) const;
558
559        /** Fit the plane between the two lines so that the plane
560                has equal shortest distance to both lines.
561        */
562        Plane3 ChooseCandidatePlane3(const RayInfoContainer &rays) const;
563 
564        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
565                to view cell 2.
566        */
567        void ShuffleLeaf(BspLeaf *leaf,
568                                         BspViewCell *vc1,
569                                         BspViewCell *vc2) const;
570
571        /**
572                Checks if this traversal data corresponds to
573                a valid view space region.
574        */
575        bool CheckValid(const VspBspTraversalData &data) const;
576
577        /** Propagates valid flag up the tree.
578        */
579        void PropagateUpValidity(BspNode *node);
580
581        /** Creates or returns view cell corresponding to
582                the space outside the valid view space.
583        */
584        BspViewCell *GetOrCreateOutOfBoundsCell();
585
586        /// Pointer to the root of the tree
587        BspNode *mRoot;
588               
589        BspTreeStatistics mStat;
590
591        /// Strategies for choosing next split plane.
592        enum {NO_STRATEGY = 0,
593                  RANDOM_POLYGON = 1,
594                  AXIS_ALIGNED = 2,
595                  LEAST_RAY_SPLITS = 256,
596                  BALANCED_RAYS = 512,
597                  PVS = 1024
598                };
599
600        /// box around the whole view domain
601        AxisAlignedBox3 mBox;
602
603        /// minimal number of rays before subdivision termination
604        int mTermMinRays;
605        /// maximal possible depth
606        int mTermMaxDepth;
607        /// mininum area
608        float mTermMinArea;
609        /// mininum PVS
610        int mTermMinPvs;
611
612        /// minimal number of rays for axis aligned split
613        int mTermMinRaysForAxisAligned;
614        /// minimal number of objects for axis aligned split
615        int mTermMinObjectsForAxisAligned;
616        /// maximal contribution per ray
617        float mTermMaxRayContribution;
618        /// minimal accumulated ray length
619        float mTermMinAccRayLength;
620
621        /// strategy to get the best split plane
622        int mSplitPlaneStrategy;
623        /// number of candidates evaluated for the next split plane
624        int mMaxPolyCandidates;
625        /// number of candidates for split planes evaluated using the rays
626        int mMaxRayCandidates;
627        /// balancing factor for PVS criterium
628        float mCtDivCi;
629
630        //-- axis aligned split criteria
631        float mAxisAlignedCtDivCi;
632        /// spezifies the split border of the axis aligned split
633        float mAxisAlignedSplitBorder;
634
635        /// maximal acceptable cost ratio
636        float mTermMaxCostRatio;
637        /// tolerance value indicating how often the max cost ratio can be failed
638        int mTermMissTolerance;
639
640        //-- factors guiding the split plane heuristics
641        float mLeastRaySplitsFactor;
642        float mBalancedRaysFactor;
643        float mPvsFactor;
644
645        /// if area or accumulated ray lenght should be used for PVS heuristics
646        bool mPvsUseArea;
647        /// tolerance for polygon split
648        float mEpsilon;
649        /// maximal number of test rays used to evaluate candidate split plane
650        int mMaxTests;
651        /// normalizes different bsp split plane criteria
652        float mCostNormalizer;
653        /// maximal number of view cells
654        int mMaxViewCells;
655        /// minimal number of view cells
656        int mMergeMinViewCells;
657        /// maximal cost ratio for the merge
658        float mMergeMaxCostRatio;
659
660        // if rays should be stored in leaves
661        bool mStoreRays;
662       
663        /// if only driving axis should be used for split
664        bool mOnlyDrivingAxis;
665
666        ViewCellsManager *mViewCellsManager;
667
668        vector<SortableEntry> *mSplitCandidates;
669
670
671        typedef priority_queue<BspMergeCandidate> MergeQueue;
672
673        MergeQueue mMergeQueue;
674        /// if rays should be used to collect merge candidates
675        bool mUseRaysForMerge;
676        /// maximal allowed pvs so that view cell is valid
677        int mMaxPvs;
678
679        /// View cell corresponding to the space outside the valid view space
680        BspViewCell *mOutOfBoundsCell;
681
682        /// if invalid space should be shown
683        bool mShowInvalidSpace;
684
685private:
686       
687        static const float sLeastRaySplitsTable[5];
688        /** Evaluates split plane classification with respect to the plane's
689                contribution for balanced rays.
690        */
691        static const float sBalancedRaysTable[5];
692
693        /// Generates unique ids for PVS criterium
694        static void GenerateUniqueIdsForPvs();
695
696        //-- unique ids for PVS criterium
697        static int sFrontId;
698        static int sBackId;
699        static int sFrontAndBackId;
700};
701
702/**
703        Candidate for leaf merging based on priority.
704*/
705class BspMergeCandidate
706
707public:
708
709        BspMergeCandidate(BspLeaf *l1, BspLeaf *l2);
710
711        /** If this merge pair is still valid.
712        */
713        bool Valid() const;
714
715        /** Sets this merge candidate to be valid.
716        */
717        void SetValid();
718
719        friend bool operator<(const BspMergeCandidate &leafa, const BspMergeCandidate &leafb)
720        {
721                return leafb.GetMergeCost() < leafa.GetMergeCost();
722        }
723
724        void SetLeaf1(BspLeaf *l);
725        void SetLeaf2(BspLeaf *l);
726
727        BspLeaf *GetLeaf1();
728        BspLeaf *GetLeaf2();
729
730        /** Merge cost of this candidate pair.
731        */
732        float GetMergeCost() const;
733
734        /** Returns cost of leaf 1.
735        */
736        float GetLeaf1Cost() const;
737        /** Returns cost of leaf 2.
738        */
739        float GetLeaf2Cost() const;
740
741        /// maximal pvs size
742        static int sMaxPvsSize;
743        /// overall cost used to normalize cost ratio
744        static float sOverallCost;
745
746protected:
747
748        /** Cost of a view cell.
749        */
750        float GetCost(ViewCell *vc) const;
751        /** Evaluates the merge costs of the leaves.
752        */
753        void EvalMergeCost();
754
755        int mLeaf1Id;
756        int mLeaf2Id;
757
758        float mMergeCost;
759       
760        BspLeaf *mLeaf1;
761        BspLeaf *mLeaf2;
762};
763
764
765class MergeStatistics: public StatisticsBase
766{
767public:
768       
769        int merged;
770        int siblings;
771        int candidates;
772        int nodes;
773
774        int accTreeDist;
775        int maxTreeDist;
776       
777        Real collectTime;
778        Real mergeTime;
779
780        // Constructor
781        MergeStatistics()
782        {
783                Reset();
784        }
785       
786        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
787
788        void Reset()
789        {
790                nodes = 0;
791                merged = 0;
792                siblings = 0;
793                candidates = 0;
794       
795                accTreeDist = 0;
796                maxTreeDist = 0;
797
798                collectTime = 0;
799                mergeTime = 0;
800        }
801
802        void Print(ostream &app) const;
803
804        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
805        {
806                stat.Print(s);
807                return s;
808        }
809};
810
811#endif
Note: See TracBrowser for help on using the repository browser.