sKit  0.0.9
BRectBase.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <functional>
4 #include <glm/vec2.hpp>
5 #include <memory>
6 #include <optional>
7 
8 namespace sKit {
9 namespace structure {
10 
12 template <typename Derived>
13 class BRectBase : public std::enable_shared_from_this<Derived> {
14  using SplitFn = std::function<float(unsigned int, glm::vec2)>;
15 
16  public:
17  BRectBase() = default;
18 
19  auto subdivide(
20  unsigned int numLevels,
21  glm::vec2 _id = {0, 0},
23  ) -> void;
24 
27  auto getLeaves() -> std::vector<std::shared_ptr<Derived>>;
28 
29  auto getLeafAt(int x, int y) -> std::optional<std::shared_ptr<Derived>>;
30 
31  std::shared_ptr<Derived> left, right;
32 
33  enum class Orientation { VERTICAL, HORIZONTAL };
34 
35  protected:
38  const static float splitfn(unsigned int _level, glm::vec2 _id) {
39  return 0.5;
40  };
41 
43  float x_, y_, width_, height_;
44  /* vec2 id; */
45  glm::vec2 id;
46  int levels;
47  bool vertical;
48 };
49 
50 template <typename Derived>
52  unsigned int numLevels,
53  glm::vec2 _id,
54  SplitFn splitfn
55 ) -> void {
56  levels = numLevels;
57  id = _id;
58 
59  if (numLevels == 0) {
60  return;
61  }
62 
63  float t = splitfn(levels, id);
64  left = std::make_shared<Derived>();
65  right = std::make_shared<Derived>();
66  if (orientation_ == Orientation::VERTICAL) {
67  float x1 = x_;
68  float x2 = x_ + width_ * t;
69  float w1 = width_ * t;
70  float w2 = width_ - width_ * t;
71  left->setDimensions(x1, y_, w1, height_);
72  left->setOrientation(Orientation::HORIZONTAL);
73  left->subdivide(numLevels - 1, {id.x * 2, id.y}, splitfn);
74  right->setOrientation(Orientation::HORIZONTAL);
75  right->setDimensions(x2, y_, w2, height_);
76  right->subdivide(numLevels - 1, {id.x * 2 + 1, id.y}, splitfn);
77  } else {
78  float y1 = y_;
79  float y2 = y_ + height_ * t;
80  float h1 = height_ * t;
81  float h2 = height_ - height_ * t;
82  left->setDimensions(x_, y1, width_, h1);
83  left->subdivide(numLevels - 1, {id.x, id.y * 2}, splitfn);
84  right->setDimensions(x_, y2, width_, h2);
85  right->subdivide(numLevels - 1, {id.x, id.y * 2 + 1}, splitfn);
86  }
87 }
88 
89 template <typename Derived>
91  -> std::optional<std::shared_ptr<Derived>> {
92  for (auto leaf : getLeaves()) {
93  if (leaf->id.x == x && leaf->id.y == y) {
94  return leaf;
95  }
96  }
97  return std::nullopt;
98 }
99 
100 template <typename Derived>
101 auto BRectBase<Derived>::getLeaves() -> std::vector<std::shared_ptr<Derived>> {
102  std::vector<std::shared_ptr<Derived>> leaves;
103  if (left && right) {
104  for (auto p : left->getLeaves()) {
105  leaves.push_back(p);
106  }
107  for (auto p : right->getLeaves()) {
108  leaves.push_back(p);
109  }
110  } else {
111  leaves.push_back(std::static_pointer_cast<Derived>(this->shared_from_this())
112  );
113  }
114  return leaves;
115 }
116 
117 } // namespace structure
118 
119 } // namespace sKit
sKit::structure::BRectBase::splitfn
const static float splitfn(unsigned int _level, glm::vec2 _id)
Definition: BRectBase.hpp:38
sKit::structure::BRectBase::levels
int levels
Definition: BRectBase.hpp:46
sKit::structure::BRectBase::Orientation
Orientation
Definition: BRectBase.hpp:33
sKit::structure::BRectBase::vertical
bool vertical
Definition: BRectBase.hpp:47
sKit::structure::BRectBase::BRectBase
BRectBase()=default
sKit::structure::BRectBase::getLeaves
auto getLeaves() -> std::vector< std::shared_ptr< Derived >>
Definition: BRectBase.hpp:101
sKit::structure::BRectBase::getLeafAt
auto getLeafAt(int x, int y) -> std::optional< std::shared_ptr< Derived >>
Definition: BRectBase.hpp:90
sKit::structure::BRectBase::Orientation::HORIZONTAL
@ HORIZONTAL
sKit::structure::BRectBase::Orientation::VERTICAL
@ VERTICAL
sKit::structure::BRectBase::x_
float x_
Definition: BRectBase.hpp:43
sKit::structure::BRectBase::width_
float width_
Definition: BRectBase.hpp:43
sKit::structure::BRectBase::subdivide
auto subdivide(unsigned int numLevels, glm::vec2 _id={0, 0}, SplitFn splitfn=BRectBase< Derived >::splitfn) -> void
Definition: BRectBase.hpp:51
sKit::structure::BRectBase::right
std::shared_ptr< Derived > right
Definition: BRectBase.hpp:31
sKit
Definition: camera.hpp:8
sKit::structure::BRectBase::y_
float y_
Definition: BRectBase.hpp:43
sKit::structure::BRectBase::left
std::shared_ptr< Derived > left
Definition: BRectBase.hpp:31
sKit::structure::BRectBase::id
glm::vec2 id
Definition: BRectBase.hpp:45
sKit::structure::BRectBase::height_
float height_
Definition: BRectBase.hpp:43
sKit::structure::BRectBase
The base class of BRect implemented as CRTP. Do not use directly.
Definition: BRectBase.hpp:13
sKit::structure::BRectBase::orientation_
Orientation orientation_
Definition: BRectBase.hpp:42