source: GTP/trunk/Lib/Vis/Preprocessing/src/VssTree.h @ 2575

Revision 2575, 19.7 KB checked in by bittner, 17 years ago (diff)

big merge: preparation for havran ray caster, check if everything works

Line 
1// ================================================================
2// $Id$
3// ****************************************************************
4//
5// Initial coding by
6/**
7   @author Jiri Bittner
8*/
9
10#ifndef __VSSTREE_H__
11#define __VSSTREE_H__
12
13// Standard headers
14#include <iomanip>
15#include <vector>
16#include <functional>
17#include <stack>
18
19
20// User headers
21#include "VssRay.h"
22#include "AxisAlignedBox3.h"
23#include "Statistics.h"
24#include "Ray.h"
25
26namespace GtpVisibilityPreprocessor {
27
28#define USE_KDNODE_VECTORS 1
29#define _RSS_STATISTICS
30#define _RSS_TRAVERSAL_STATISTICS
31
32class SimpleRayContainer;
33
34
35// --------------------------------------------------------------
36// Static statistics for kd-tree search
37// --------------------------------------------------------------
38class VssStatistics :
39  public StatisticsBase
40{
41public: 
42  // total number of nodes
43  int nodes;
44  // number of splits along each of the axes
45  int splits[7];
46  // totals number of rays
47  int rays;
48  // initial size of the pvs
49  int initialPvsSize;
50  // total number of query domains
51  int queryDomains;
52  // total number of ray references
53  int rayRefs;
54
55  // max depth nodes
56  int maxDepthNodes;
57  // max depth nodes
58  int minPvsNodes;
59  int minRaysNodes;
60  // max ray contribution nodes
61  int maxRayContribNodes;
62  // max depth nodes
63  int minSizeNodes;
64  int maxCostRatioNodes;
65
66  // max number of rays per node
67  int maxRayRefs;
68  // number of dynamically added ray refs
69  int addedRayRefs;
70  // number of dynamically removed ray refs
71  int removedRayRefs;
72 
73  // Constructor
74  VssStatistics() {
75    Reset();
76  }
77
78  int Nodes() const {return nodes;}
79  int Interior() const { return nodes/2; }
80  int Leaves() const { return (nodes/2) + 1; }
81
82  void Reset() {
83    nodes = 0;
84    for (int i=0; i<7; i++)
85      splits[i] = 0;
86    rays = queryDomains = 0;
87    rayRefs = 0;
88    maxDepthNodes = 0;
89    minPvsNodes = 0;
90    minRaysNodes = 0;
91    maxRayRefs = 0;
92    addedRayRefs = removedRayRefs = 0;
93        initialPvsSize = 0;
94        maxRayContribNodes = 0;
95        minSizeNodes = 0;
96        maxCostRatioNodes = 0;
97  }
98
99 
100  void
101  Print(std::ostream &app) const;
102
103  friend std::ostream &operator<<(std::ostream &s, const VssStatistics &stat) {
104    stat.Print(s);
105    return s;
106  }
107 
108};
109
110
111
112
113class VssTreeInterior;
114
115
116// --------------------------------------------------------------
117// KD-tree node - abstract class
118// --------------------------------------------------------------
119class VssTreeNode
120{
121public:
122
123#define USE_FIXEDPOINT_T 0
124
125  struct RayInfo
126  {
127        // pointer to the actual ray
128        VssRay *mRay;
129       
130        // endpoints  - do we need them?
131#if USE_FIXEDPOINT_T
132        short mMinT, mMaxT;
133#else
134        float mMinT, mMaxT;
135#endif
136       
137        RayInfo():mRay(NULL) {}
138       
139        RayInfo(VssRay *r):mRay(r), mMinT(0),
140#if USE_FIXEDPOINT_T
141#define FIXEDPOINT_ONE 0x7FFE
142                                           //                     mMaxT(0xFFFF)
143                                           mMaxT(FIXEDPOINT_ONE)
144#else
145          mMaxT(1.0f)
146#endif
147        {}
148       
149        RayInfo(VssRay *r,
150                        const float _min,
151                        const float _max
152                        ):mRay(r) {
153          SetMinT(_min);
154          SetMaxT(_max);
155        }
156       
157        RayInfo(VssRay *r,
158                        const short _min,
159                        const float _max
160                        ):mRay(r), mMinT(_min) {
161          SetMaxT(_max);
162        }
163       
164        RayInfo(VssRay *r,
165                        const float _min,
166                        const short _max
167                        ):mRay(r), mMaxT(_max) {
168          SetMinT(_min);
169        }
170
171        enum {
172          SOURCE_RAY = 0,
173          TERMINATION_RAY,
174          PASSING_RAY,
175          CONTAINED_RAY
176        };
177       
178        int GetRayClass() const {
179               
180          bool startsBefore = GetMinT() > 0.0f;
181          bool terminatesAfter = GetMaxT() < 1.0f;
182               
183          if (startsBefore && terminatesAfter)
184                return PASSING_RAY;
185
186          if (!startsBefore && !terminatesAfter)
187                return CONTAINED_RAY;
188               
189          if (!startsBefore)
190                return SOURCE_RAY;
191               
192          return TERMINATION_RAY;
193        }
194       
195        friend bool operator<(const RayInfo &a, const RayInfo &b) {
196          return a.mRay < b.mRay;
197        }
198 
199       
200        float ExtrapOrigin(const int axis) const {
201          return mRay->GetOrigin(axis) + GetMinT()*mRay->GetDir(axis);
202        }
203       
204        float ExtrapTermination(const int axis) const {
205          return mRay->GetOrigin(axis) + GetMaxT()*mRay->GetDir(axis);
206        }
207
208        Vector3 Extrap(const float t) const {
209          return mRay->Extrap(t);
210        }
211       
212#if USE_FIXEDPOINT_T
213        float GetMinT () const { return mMinT/(float)(FIXEDPOINT_ONE); }
214        float GetMaxT () const { return mMaxT/(float)(FIXEDPOINT_ONE); }
215       
216        void SetMinT (const float t) {
217          mMinT = (short) (t*(float)(FIXEDPOINT_ONE));
218        }
219       
220        void SetMaxT (const float t) {
221          mMaxT = (short) (t*(float)(FIXEDPOINT_ONE));
222          mMaxT++;
223          //      if (mMaxT!=0xFFFF)
224          //    mMaxT++;
225        }
226#else
227        float GetMinT () const { return mMinT; }
228        float GetMaxT () const { return mMaxT; }
229       
230        void SetMinT (const float t) { mMinT = t; }
231        void SetMaxT (const float t) { mMaxT = t; }
232#endif
233
234
235        int ComputeRayIntersection(const int axis,
236                                                           const float position,
237                                                           float &t
238                                                           ) const {
239               
240#if 1
241          // intersect the ray with the plane
242          float denom = mRay->GetDir(axis);
243   
244          if (fabs(denom) < 1e-20)
245                //if (denom == 0.0f)
246                return (mRay->GetOrigin(axis) > position) ? 1 : -1;
247   
248          t = (position - mRay->GetOrigin(axis))/denom;
249
250          if (t < GetMinT())
251                return (denom > 0) ? 1 : -1;
252
253          if (t > GetMaxT())
254                return (denom > 0) ? -1 : 1;
255
256          return 0;
257#else
258          // subbdivision based only on the origin
259          t = 0;
260          float rpos = mRay->GetOrigin(axis);
261          return (rpos < position) ? -1 : 1;
262
263#endif
264        }
265
266
267  };
268
269  void GetSampleData(const bool isTerminaton,
270                                  Vector3 &pt,
271                                  Intersectable **obj,
272                                  KdNode **node) const;
273
274  typedef vector<RayInfo> RayInfoContainer;
275       
276  enum { EInterior, ELeaf };
277
278  /////////////////////////////////
279  // The actual data goes here
280 
281  // link to the parent
282  VssTreeInterior *parent;
283
284  enum {SPLIT_X=0, SPLIT_Y, SPLIT_Z, SPLIT_DIRX, SPLIT_DIRY, SPLIT_DIRZ};
285 
286  // splitting axis
287  char axis;
288       
289  // depth
290  unsigned char depth;
291 
292  //  short depth;
293  //
294  /////////////////////////////////
295 
296  inline VssTreeNode(VssTreeInterior *p);
297
298 
299  virtual ~VssTreeNode() {};
300  virtual int Type() const  = 0;
301 
302
303  bool IsLeaf() const { return axis == -1; }
304 
305  virtual void Print(std::ostream &s) const = 0;
306
307  virtual int GetAccessTime() {
308    return 0x7FFFFFF;
309  }
310
311 
312       
313};
314
315// --------------------------------------------------------------
316// KD-tree node - interior node
317// --------------------------------------------------------------
318class VssTreeInterior :
319  public VssTreeNode
320{
321public:
322  // plane in local modelling coordinates
323  float position;
324
325  // pointers to children
326  VssTreeNode *back, *front;
327
328  // the bbox of the node
329  AxisAlignedBox3 bbox;
330
331  // the bbox of the node
332  AxisAlignedBox3 dirBBox;
333 
334  // data for caching
335  long accesses;
336  long lastAccessTime;
337 
338  VssTreeInterior(VssTreeInterior *p):VssTreeNode(p),
339                                                                          back(NULL),
340                                                                          front(NULL),
341                                                                          accesses(0),
342                                                                          lastAccessTime(-1)
343  { }
344
345  virtual int GetAccessTime() {
346    return lastAccessTime;
347  }
348
349  void SetupChildLinks(VssTreeNode *b, VssTreeNode *f) {
350    back = b;
351    front = f;
352    b->parent = f->parent = this;
353  }
354
355  void ReplaceChildLink(VssTreeNode *oldChild, VssTreeNode *newChild) {
356    if (back == oldChild)
357      back = newChild;
358    else
359      front = newChild;
360  }
361
362  virtual int Type() const  { return EInterior; }
363 
364  virtual ~VssTreeInterior() {
365    if (back)
366      delete back;
367    if (front)
368      delete front;
369  }
370 
371  virtual void Print(std::ostream &s) const {
372    if (axis == 0)
373      s<<"x ";
374    else
375      if (axis == 1)
376                s<<"y ";
377      else
378                s<<"z ";
379    s<<position<<" ";
380    back->Print(s);
381    front->Print(s);
382  }
383
384 
385       
386  int ComputeRayIntersection(const RayInfo &rayData,
387                                                         float &t
388                                                         ) {
389        return rayData.ComputeRayIntersection(axis, position, t);
390  }
391
392};
393
394
395// --------------------------------------------------------------
396// KD-tree node - leaf node
397// --------------------------------------------------------------
398class VssTreeLeaf :
399  public VssTreeNode
400{
401private:
402  int mPvsSize;
403public:
404  static int mailID;
405  int mailbox;
406 
407  RayInfoContainer rays;
408  int mPassingRays;
409       
410  bool mValidPvs;
411  float mEntropyImportance;
412 
413       
414  VssTreeLeaf(VssTreeInterior *p,
415                          const int nRays
416                          ):VssTreeNode(p), rays(), mPvsSize(0), mPassingRays(0), mValidPvs(false) {
417    rays.reserve(nRays);
418  }
419 
420  virtual ~VssTreeLeaf() { }
421
422  virtual int Type() const  { return ELeaf; }
423
424  virtual void Print(std::ostream &s) const {
425    s<<std::endl<<"L: r="<<(int)rays.size()<<std::endl;
426  };
427 
428  void AddRay(const RayInfo &data) {
429        mValidPvs = false;
430    rays.push_back(data);
431    data.mRay->Ref();
432        if (data.GetRayClass() == RayInfo::PASSING_RAY)
433          mPassingRays++;
434  }
435       
436  int GetPvsSize() const {
437        return mPvsSize;
438  }
439
440  void SetPvsSize(const int s) {
441        mPvsSize = s;
442        mValidPvs = true;
443  }
444
445  void
446  UpdatePvsSize();
447
448  float
449  ComputePvsEntropy();
450 
451  float
452  ComputeRayLengthEntropy();
453 
454  float
455  ComputeRayTerminationEntropy();
456 
457  void
458  ComputeEntropyImportance();
459
460  void Mail() { mailbox = mailID; }
461  static void NewMail() { mailID++; }
462  bool Mailed() const { return mailbox == mailID; }
463 
464  bool Mailed(const int mail) {
465    return mailbox >= mailID + mail;
466  }
467
468  float GetAvgRayContribution() const {
469        return GetPvsSize()/((float)rays.size() + Limits::Small);
470  }
471
472  float GetImportance() const;
473 
474  float GetSqrRayContribution() const {
475        return sqr(GetPvsSize()/((float)rays.size() + Limits::Small));
476  }
477 
478  // comparator for the
479  struct less_contribution : public
480  std::binary_function<const VssTreeLeaf *, const VssTreeLeaf *, bool> {
481       
482        bool operator()(const VssTreeLeaf * a, const VssTreeLeaf *b) {
483          return a->GetAvgRayContribution() < b->GetAvgRayContribution();
484        }
485  };
486 
487  struct greater_contribution : public
488  std::binary_function<const VssTreeLeaf *, const VssTreeLeaf *, bool> {
489       
490        bool operator()(const VssTreeLeaf * a, const VssTreeLeaf *b) {
491          return a->GetAvgRayContribution() > b->GetAvgRayContribution();
492        }
493  };
494 
495  friend bool GreaterContribution(const VssTreeLeaf * a, const VssTreeLeaf *b);
496 
497};
498
499// Inline functions
500inline
501VssTreeNode::VssTreeNode(VssTreeInterior *p):
502  parent(p), axis(-1), depth(p ? p->depth + 1 : 0) {}
503
504inline bool GreaterContribution(const VssTreeLeaf * a, const VssTreeLeaf *b) {
505  return a->GetAvgRayContribution() > b->GetAvgRayContribution();
506}
507 
508
509// ---------------------------------------------------------------
510// Main LSDS search class
511// ---------------------------------------------------------------
512class VssTree
513{
514  struct TraversalData
515  { 
516    VssTreeNode *node;
517    AxisAlignedBox3 bbox;
518    int depth;
519    float priority;
520   
521    TraversalData() {}
522
523    TraversalData(VssTreeNode *n, const float p):
524      node(n), priority(p)
525    {}
526
527    TraversalData(VssTreeNode *n,
528                                  const AxisAlignedBox3 &b,
529                                  const int d):
530      node(n), bbox(b), depth(d) {}
531   
532               
533    // comparator for the
534    struct less_priority : public
535    std::binary_function<const TraversalData, const TraversalData, bool> {
536                       
537      bool operator()(const TraversalData a, const TraversalData b) {
538                return a.priority < b.priority;
539      }
540     
541    };
542
543    //    ~TraversalData() {}
544    //    TraversalData(const TraversalData &s):node(s.node), bbox(s.bbox), depth(s.depth) {}
545   
546    friend bool operator<(const TraversalData &a,
547                                                  const TraversalData &b) {
548      //      return a.node->queries.size() < b.node->queries.size();
549      VssTreeLeaf *leafa = (VssTreeLeaf *) a.node;
550      VssTreeLeaf *leafb = (VssTreeLeaf *) b.node;
551#if 0
552          return
553                leafa->rays.size()*a.bbox.GetVolume()
554                <
555                leafb->rays.size()*b.bbox.GetVolume();
556#endif
557#if 0
558          return
559                leafa->GetPvsSize()*a.bbox.GetVolume()
560                <
561                leafb->GetPvsSize()*b.bbox.GetVolume();
562#endif
563#if 0
564          return
565                leafa->GetPvsSize()
566                <
567                leafb->GetPvsSize();
568#endif
569#if 0
570          return
571                leafa->GetPvsSize()/(leafa->rays.size()+1)
572                >
573                leafb->GetPvsSize()/(leafb->rays.size()+1);
574#endif
575#if 1
576          return
577                leafa->GetPvsSize()*leafa->rays.size()
578                <
579                leafb->GetPvsSize()*leafb->rays.size();
580#endif
581    }
582  };
583 
584  // simplified data for ray traversal only...
585
586  struct RayTraversalData {
587   
588    VssTreeNode::RayInfo rayData;
589    VssTreeNode *node;
590   
591    RayTraversalData() {}
592    RayTraversalData(VssTreeNode *n,
593                                         const VssTreeNode::RayInfo &data):
594      rayData(data), node(n) {}
595  };
596       
597public:
598  /////////////////////////////
599  // The core pointer
600  VssTreeNode *root;
601 
602  /////////////////////////////
603  // Basic properties
604
605  // total number of nodes of the tree
606  int nodes;
607  // axis aligned bounding box of the scene
608  AxisAlignedBox3 bbox;
609
610  // axis aligned bounding box of directions
611  AxisAlignedBox3 dirBBox;
612 
613  /////////////////////////////
614  // Construction parameters
615
616  // epsilon used for the construction
617  float epsilon;
618
619  // ratio between traversal and intersection costs
620  float ct_div_ci;
621  // max depth of the tree
622  int termMaxDepth;
623  // minimal ratio of the volume of the cell and the query volume
624  float termMinSize;
625
626  // minimal pvs per node to still get subdivided
627  int termMinPvs;
628
629  // minimal ray number per node to still get subdivided
630  int termMinRays;
631       
632  // maximal cost ration to subdivide a node
633  float termMaxCostRatio;
634       
635  // maximal contribution per ray to subdivide the node
636  float termMaxRayContribution;
637
638       
639  // randomized construction
640  bool randomize;
641 
642  // type of the splitting to use fo rthe tree construction
643  enum {ESplitRegular, ESplitHeuristic, ESplitHybrid };
644  int splitType;
645
646  bool mSplitUseOnlyDrivingAxis;
647 
648  // use ray space subdivision instead of view space subdivision
649  bool mUseRss;
650
651  // interleave directional and spatial splits based on their costs
652  // if false directional splits are only performed after spatial splits
653  bool mInterleaveDirSplits;
654
655  // depth at which directional splits are performed if mInterleaveDirSplits is false
656  int mDirSplitDepth;
657 
658  // maximal size of the box on which the refdir splitting can be performed
659  // (relative to the scene bbox
660  float refDirBoxMaxSize;
661 
662  // maximum alovable memory in MB
663  float maxTotalMemory;
664
665  // maximum alovable memory for static kd tree in MB
666  float maxStaticMemory;
667
668  // this is used during the construction depending
669  // on the type of the tree and queries...
670  float maxMemory;
671
672
673  // minimal acess time for collapse
674  int accessTimeThreshold;
675
676  // minimal depth at which to perform collapse
677  int minCollapseDepth;
678
679 
680  // reusable array of split candidates
681  vector<SortableEntry> *splitCandidates;
682  /////////////////////////////
683
684  VssStatistics stat;
685       
686 
687  VssTree();
688  virtual ~VssTree();
689
690  virtual void
691  Construct(
692                        VssRayContainer &rays,
693                        AxisAlignedBox3 *forcedBoundingBox = NULL
694                        );
695       
696  // incemental construction
697  virtual void UpdateRays(VssRayContainer &remove,
698                                                  VssRayContainer &add
699                                                  );
700
701  virtual void AddRays(
702                                           VssRayContainer &add
703                                           )
704  {
705        VssRayContainer remove;
706        UpdateRays(remove, add);
707  }
708
709 
710       
711  VssTreeNode *
712  Locate(const Vector3 &v);
713       
714  VssTreeNode *
715  SubdivideNode(VssTreeLeaf *leaf,
716                                const AxisAlignedBox3 &box,
717                                AxisAlignedBox3 &backBox,
718                                AxisAlignedBox3 &frontBox
719                                );
720       
721  VssTreeNode *
722  Subdivide(const TraversalData &tdata);
723       
724  int
725  SelectPlane(VssTreeLeaf *leaf,
726                          const AxisAlignedBox3 &box,
727                          float &position,
728                          int &raysBack,
729                          int &raysFront,
730                          int &pvsBack,
731                          int &pvsFront
732                          );
733
734  void
735  SortSubdivisionCandidates(
736                                          VssTreeLeaf *node,
737                                          const int axis
738                                          );
739       
740 
741  // return memory usage in MB
742  float GetMemUsage() const {
743    return
744      (sizeof(VssTree) +
745       stat.Leaves()*sizeof(VssTreeLeaf) +
746       stat.Interior()*sizeof(VssTreeInterior) +
747       stat.rayRefs*sizeof(VssTreeNode::RayInfo))/(1024.0f*1024.0f);
748  }
749       
750  float GetRayMemUsage() const {
751    return
752      stat.rays*(sizeof(VssRay))/(1024.0f*1024.0f);
753  }
754 
755
756  float
757  BestCostRatio(
758                                VssTreeLeaf *node,
759                                int &axis,
760                                float &position,
761                                int &raysBack,
762                                int &raysFront,
763                                int &pvsBack,
764                                int &pvsFront
765                                );
766       
767  float
768  EvalCostRatio(
769                                VssTreeLeaf *node,
770                                const int axis,
771                                const float position,
772                                int &raysBack,
773                                int &raysFront,
774                                int &pvsBack,
775                                int &pvsFront
776                                );
777
778  float
779  EvalCostRatioHeuristic(
780                                                 VssTreeLeaf *node,
781                                                 const int axis,
782                                                 float &position,
783                                                 int &raysBack,
784                                                 int &raysFront,
785                                                 int &pvsBack,
786                                                 int &pvsFront
787                                                 );
788
789  float
790  GetCostRatio(
791                           VssTreeLeaf *leaf,
792                           const int axis,
793                           const float position,
794                           const int raysBack,
795                           const int raysFront,
796                           const int pvsBack,
797                           const int pvsFront
798                           );
799
800  AxisAlignedBox3 GetBBox(const VssTreeNode *node) const {
801    if (node->parent == NULL)
802      return bbox;
803
804    if (!node->IsLeaf())
805      return ((VssTreeInterior *)node)->bbox;
806
807    if (node->parent->axis >= 3)
808      return node->parent->bbox;
809     
810    AxisAlignedBox3 box(node->parent->bbox);
811    if (node->parent->front == node)
812      box.SetMin(node->parent->axis, node->parent->position);
813    else
814      box.SetMax(node->parent->axis, node->parent->position);
815    return box;
816  }
817
818  AxisAlignedBox3 GetDirBBox(const VssTreeNode *node) const {
819
820    if (node->parent == NULL)
821      return dirBBox;
822   
823    if (!node->IsLeaf() )
824      return ((VssTreeInterior *)node)->dirBBox;
825
826    if (node->parent->axis < 3)
827      return node->parent->dirBBox;
828   
829    AxisAlignedBox3 dBBox(node->parent->dirBBox);
830
831    if (node->parent->front == node)
832      dBBox.SetMin(node->parent->axis - 3, node->parent->position);
833    else
834      dBBox.SetMax(node->parent->axis - 3, node->parent->position);
835    return dBBox;
836  }
837 
838  int
839  ReleaseMemory(const int time);
840
841  int
842  CollapseSubtree(VssTreeNode *node, const int time);
843
844  void
845  CountAccess(VssTreeInterior *node, const long time) {
846    node->accesses++;
847    node->lastAccessTime = time;
848  }
849
850  VssTreeNode *
851  SubdivideLeaf(
852                                VssTreeLeaf *leaf
853                                );
854
855  void
856  RemoveRay(VssRay *ray,
857                        vector<VssTreeLeaf *> *affectedLeaves,
858                        const bool removeAllScheduledRays
859                        );
860
861  //  void
862  //  AddRay(VssRay *ray);
863  void
864  AddRay(VssTreeNode::RayInfo &info);
865 
866  void
867  TraverseInternalNode(
868                                           RayTraversalData &data,
869                                           std::stack<RayTraversalData> &tstack);
870
871  void
872  EvaluateLeafStats(const TraversalData &data);
873
874
875  int
876  GetRootPvsSize() const {
877        return GetPvsSize(bbox);
878  }
879 
880  int
881  GetPvsSize(const AxisAlignedBox3 &box) const;
882
883  void
884  GetRayContributionStatistics(
885                                                           float &minRayContribution,
886                                                           float &maxRayContribution,
887                                                           float &avgRayContribution
888                                                           );
889
890  int
891  GenerateRays(const float ratioPerLeaf,
892                           SimpleRayContainer &rays);
893
894  int
895  GenerateRays(const int numberOfRays,
896                           const int numberOfLeaves,
897                           SimpleRayContainer &rays);
898               
899  float
900  GetAvgPvsSize();
901
902  int
903  UpdateSubdivision();
904
905  bool
906  TerminationCriteriaSatisfied(VssTreeLeaf *leaf);
907
908  void
909  CollectLeaves(vector<VssTreeLeaf *> &leaves);
910
911  bool
912  ClipRay(
913                  VssTreeNode::RayInfo &rayInfo,
914                  const AxisAlignedBox3 &box
915                  );
916
917  VssTreeNode *GetRoot() const { return root; }
918
919  bool
920  ValidLeaf(VssTreeLeaf *leaf) const;
921
922  void
923  GenerateLeafRays(VssTreeLeaf *leaf,
924                                   const int numberOfRays,
925                                   SimpleRayContainer &rays);
926
927  int
928  CollectRays(VssRayContainer &rays,
929                          const int number);
930
931  int
932  CollectRays(VssRayContainer &rays);
933 
934};
935
936};
937
938#endif // __LSDS_KDTREE_H__
939
Note: See TracBrowser for help on using the repository browser.