File: TestHybridBVH.cpp

package info (click to toggle)
vecgeom 1.2.8%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 24,016 kB
  • sloc: cpp: 88,803; ansic: 6,888; python: 1,035; sh: 582; sql: 538; makefile: 23
file content (110 lines) | stat: -rw-r--r-- 3,519 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "VecGeom/management/HybridManager2.h"
#include "VecGeom/navigation/HybridNavigator2.h"
#include "VecGeom/management/ABBoxManager.h"
#include <memory>
#undef NDEBUG
#include <cassert>

using namespace vecgeom;

using Boxes_t     = ABBoxManager::ABBoxContainer_t;
using BoxCorner_t = ABBoxManager::ABBox_s;

// make a vector of aligned bounding boxes
// boxes are just arranged linearly
Boxes_t MakeABBoxes_linear(int N)
{
  // N boxes ... so 2*N corners
  double boxhalflength{4}; // half length of an aligned box
  BoxCorner_t *boxcorners = new BoxCorner_t[2 * N];
  for (int i = 0; i < N; ++i) {
    double xoffset            = i * (2.5 * boxhalflength);
    boxcorners[2 * i].x()     = xoffset - boxhalflength;
    boxcorners[2 * i].y()     = -boxhalflength;
    boxcorners[2 * i].z()     = -boxhalflength;
    boxcorners[2 * i + 1].x() = xoffset + boxhalflength;
    boxcorners[2 * i + 1].y() = boxhalflength;
    boxcorners[2 * i + 1].z() = boxhalflength;
  }
  return &boxcorners[0];
}

using BVHStructure = HybridManager2::HybridBoxAccelerationStructure;
BVHStructure const *CreateHybridStructure(Boxes_t boxes, size_t N)
{
  return HybridManager2::Instance().BuildStructure(boxes, N);
}

void QueryStructure(BVHStructure const &s)
{
  // testing the looper + correct intersection by calculating
  // the sum of all box ids intersected
  int checkhitsum = 0;
  auto userhook   = [&](HybridManager2::BoxIdDistancePair_t hitbox) {
    checkhitsum += (hitbox.first + 1); // +1 just to detect also hit with the first box (whose id is 0)
    return false;                      // we are never done early here
  };

  int c = 0;
  for (int i = 0; i < (int)s.fNumberOfOriginalBoxes; ++i) {
    c += (i + 1);
  }

  HybridNavigator<> *instance = (HybridNavigator<> *)HybridNavigator<>::Instance();

  {
    // for a ray passing all boxes left to right
    Vector3D<Precision> pos(-1000, 0, 0);
    Vector3D<Precision> dir(1., 0., 0);

    checkhitsum = 0;
    // intersect ray with the BVH structure and use hook
    instance->BVHSortedIntersectionsLooper(s, pos, dir, 1E20, userhook);
    assert(c == checkhitsum); // checks that all boxes have been hit
  }

  { // for a ray passing all boxes right to left
    // define the ray
    Vector3D<Precision> pos(10000, 0, 0);
    Vector3D<Precision> dir(-1., 0., 0);

    checkhitsum = 0;
    // intersect ray with the BVH structure and use hook
    instance->BVHSortedIntersectionsLooper(s, pos, dir, 1E20, userhook);
    assert(c == checkhitsum); // checks that all boxes have been hit
  }

  {
    // for a ray passing none of the boxes
    // define the ray
    Vector3D<Precision> pos(1000., 1000., 0.);
    Vector3D<Precision> dir(-1., 0., 0);

    checkhitsum = 0;
    // intersect ray with the BVH structure and use hook
    instance->BVHSortedIntersectionsLooper(s, pos, dir, 1E20, userhook);
    assert(0 == checkhitsum);
  }

  {
    // for a ray passing exactly one of the boxes
    // define the ray
    Vector3D<Precision> pos(0., -100., 0.);
    Vector3D<Precision> dir(0., 1., 0.);

    // intersect ray with the BVH structure and use hook
    instance->BVHSortedIntersectionsLooper(s, pos, dir, 1E20, userhook);
    assert(1 == checkhitsum); // should hit exactly the first box (index 0 + 1)
  }
}

int main()
{
  // test for various numbers of aligned boxes
  for (int i = 4; i < 100; i += 6) {
    auto structure = CreateHybridStructure(MakeABBoxes_linear(i), i);
    QueryStructure(*structure);
  }
  std::cout << "test passed\n";
  return 0;
}