voxelTerrain
 All Classes Functions Variables Typedefs Enumerations Pages
box.hpp
1 #ifndef PROCEDURAL_VOXEL_EDIT_BOX_HPP
2 #define PROCEDURAL_VOXEL_EDIT_BOX_HPP
3 
4 #include "blub/math/axisAlignedBox.hpp"
5 #include "blub/math/quaternion.hpp"
6 #include "blub/math/plane.hpp"
7 #include "blub/math/ray.hpp"
8 #include "blub/procedural/voxel/edit/base.hpp"
9 
10 #include "blub/core/sharedPointer.hpp"
11 #include "blub/math/intersection.hpp"
12 #include "blub/math/ray.hpp"
13 #include "blub/math/transform.hpp"
14 #include "blub/procedural/voxel/tile/container.hpp"
15 
16 
17 namespace blub
18 {
19 namespace procedural
20 {
21 namespace voxel
22 {
23 namespace edit
24 {
25 
26 
30 template <class voxelType>
31 class box : public base<voxelType>
32 {
33 public:
34  typedef base<voxelType> t_base;
35  typedef sharedPointer<box<voxelType> > pointer;
36 
43  static pointer create(const vector3 &size, const quaternion &rotation)
44  {
45  return pointer(new box(size, rotation));
46  }
47 
53  {
54  return blub::axisAlignedBox(m_aabb.getMinimum()*trans.scale + trans.position,
55  m_aabb.getMaximum()*trans.scale + trans.position);
56  }
57 
58 protected:
64  box(const vector3 &size, const quaternion &rotation)
65  : m_size(size)
66  , m_rotation(rotation.getNormalised())
67  , m_aabb(-size.length(), size.length())
68  {
69  BASSERT(size.x > 0.);
70  BASSERT(size.y > 0.);
71  BASSERT(size.z > 0.);
72 
73  {
74  const blub::vector3 rotatedUp(m_rotation*vector3(0., m_size.y, 0.));
75  const blub::vector3 normalUp(rotatedUp.getNormalise());
76  m_planes[0] = blub::plane(rotatedUp, normalUp);
77  m_planes[1] = blub::plane(-rotatedUp, -normalUp);
78  }
79  {
80  const blub::vector3 rotatedRight(m_rotation*vector3(m_size.x, 0., 0.));
81  const blub::vector3 normalRight(rotatedRight.getNormalise());
82  m_planes[2] = blub::plane(rotatedRight, normalRight);
83  m_planes[3] = blub::plane(-rotatedRight, -normalRight);
84  }
85  {
86  const blub::vector3 rotatedFront(m_rotation*vector3(0., 0., m_size.z));
87  const blub::vector3 normalFront(rotatedFront.getNormalise());
88  m_planes[4] = blub::plane(rotatedFront, normalFront);
89  m_planes[5] = blub::plane(-rotatedFront, -normalFront);
90  }
91  }
92 
93 
101  void calculateVoxel(typename t_base::t_voxelContainerTile *voxelContainer, const vector3int32 &voxelContainerOffset, const transform &trans) const override
102  {
103  const vector3int32 posContainerAbsolut(voxelContainerOffset*t_base::t_voxelContainerTile::voxelLength);
104 
105  vector3int32 toLoop[] = {{1, t_base::t_voxelContainerTile::voxelLength, t_base::t_voxelContainerTile::voxelLength},
106  {t_base::t_voxelContainerTile::voxelLength, 1, t_base::t_voxelContainerTile::voxelLength},
107  {t_base::t_voxelContainerTile::voxelLength, t_base::t_voxelContainerTile::voxelLength, 1}
108  };
109  vector3 rayDir[] = {{1., 0., 0.},
110  {0., 1., 0.},
111  {0., 0., 1.}};
112  for (int32 indAxis = 0; indAxis < 3; ++indAxis)
113  {
114  for (int32 indX = 0; indX < toLoop[indAxis].x; ++indX)
115  {
116  for (int32 indY = 0; indY < toLoop[indAxis].y; ++indY)
117  {
118  for (int32 indZ = 0; indZ < toLoop[indAxis].z; ++indZ)
119  {
120  const vector3int32 posVoxel(indX, indY, indZ);
121  vector3 posAbsolut(posContainerAbsolut + posVoxel);
122 
123  posAbsolut -= trans.position;
124  posAbsolut /= trans.scale;
125 
126  const ray test(posAbsolut, rayDir[indAxis]);
127  vector3 cutPoint;
128 
129  real cutPoints[2];
130  blub::plane cutPlanes[2];
131  blub::uint16 numCutPointsFound(0);
132 
133  for (blub::int32 indPlane = 0; indPlane < 6; ++indPlane)
134  {
135  if (test.intersects(m_planes[indPlane], &cutPoint))
136  {
137  bool pointOnBoxSurface(true);
138  for (blub::int32 indPlane2 = 0; indPlane2 < 6; ++indPlane2)
139  {
140  if (indPlane2 == indPlane)
141  {
142  continue;
143  }
144  if (m_planes[indPlane2].getDistance(cutPoint) > 0.0)
145  {
146  pointOnBoxSurface = false;
147  break;
148  }
149  }
150  if (!pointOnBoxSurface)
151  {
152  continue;
153  }
154  cutPoints[numCutPointsFound] = (cutPoint[indAxis]*trans.scale[indAxis] + trans.position[indAxis]) - static_cast<real>(posContainerAbsolut[indAxis]);
155  cutPlanes[numCutPointsFound] = m_planes[indPlane];
156  ++numCutPointsFound;
157  if (numCutPointsFound > 2)
158  {
159  numCutPointsFound = 0;
160  break;
161  }
162  }
163  }
164  if(numCutPointsFound == 0)
165  {
166  continue;
167  }
168  if(numCutPointsFound != 2)
169  {
170  continue;
171  }
172 
173  real cutPointsSorted[2];
174 
175  cutPointsSorted[0] = math::min<real>(cutPoints[0], cutPoints[1]);
176  cutPointsSorted[1] = math::max<real>(cutPoints[0], cutPoints[1]);
177  if (cutPointsSorted[0] != cutPoints[0])
178  {
179  std::swap(cutPlanes[0], cutPlanes[1]);
180  }
181  const real length(cutPointsSorted[1]-cutPointsSorted[0]);
182  if (length < 2.)
183  {
184  continue;
185  }
186  switch (indAxis)
187  {
188  case 0:
189  t_base::createLine(voxelContainer, posVoxel, cutPointsSorted[0], length, t_base::axis::x, cutPlanes[0], cutPlanes[1]);
190  break;
191  case 1:
192  t_base::createLine(voxelContainer, posVoxel, cutPointsSorted[0], length, t_base::axis::y, cutPlanes[0], cutPlanes[1]);
193  break;
194  case 2:
195  t_base::createLine(voxelContainer, posVoxel, cutPointsSorted[0], length, t_base::axis::z, cutPlanes[0], cutPlanes[1]);
196  break;
197  default:
198  BASSERT(false);
199  break;
200  }
201  }
202  }
203  }
204  }
205  }
206 
207 private:
208  const vector3 m_size;
209  const quaternion m_rotation;
210 
211  const blub::axisAlignedBox m_aabb;
212 
213  blub::plane m_planes[6];
214 
215 };
216 
217 
218 }
219 }
220 }
221 }
222 
223 
224 #endif // PROCEDURAL_VOXEL_EDIT_BOX_HPP
virtual void createLine(t_voxelContainerTile *voxelContainer, const vector3int32 &posVoxel, const real &from, const real &len, const axis &ax, const blub::plane &planeA, const blub::plane &planeB) const
createLine creates a voxel-line on one axis with a specific length
Definition: base.hpp:198
Definition: transform.hpp:20
Definition: quaternion.hpp:25
void calculateVoxel(typename t_base::t_voxelContainerTile *voxelContainer, const vector3int32 &voxelContainerOffset, const transform &trans) const override
calculateVoxel cuts the box in voxelLines. Only sets values if voxel is inside box.
Definition: box.hpp:101
box(const vector3 &size, const quaternion &rotation)
constructor. Sets up the cutPlanes of the box
Definition: box.hpp:64
blub::axisAlignedBox getAxisAlignedBoundingBox(const transform &trans) const override
getAxisAlignedBoundingBox returns the scaled, transformed bounding box of the to calculate voxels ...
Definition: box.hpp:52
Definition: ray.hpp:16
Definition: vector3.hpp:26
Definition: axisAlignedBox.hpp:20
Definition: plane.hpp:16
const vector3 & getMinimum(void) const
Definition: axisAlignedBox.hpp:126
const vector3 & getMaximum(void) const
Definition: axisAlignedBox.hpp:141
static pointer create(const vector3 &size, const quaternion &rotation)
create creates an instance of box.
Definition: box.hpp:43
vector3 getNormalise() const
Definition: vector3.hpp:611
Definition: deadlineTimer.hpp:10