voxelTerrain
 All Classes Functions Variables Typedefs Enumerations Pages
base.hpp
1 #ifndef BLUB_PROCEDURAL_VOXEL_EDIT_BASE_HPP
2 #define BLUB_PROCEDURAL_VOXEL_EDIT_BASE_HPP
3 
4 
5 #include "blub/core/enableSharedFromThis.hpp"
6 #include "blub/core/globals.hpp"
7 #include "blub/core/noncopyable.hpp"
8 #include "blub/math/axisAlignedBox.hpp"
9 #include "blub/math/plane.hpp"
10 #include "blub/math/transform.hpp"
11 #include "blub/math/vector3int.hpp"
12 #include "blub/procedural/predecl.hpp"
13 #include "blub/procedural/voxel/simple/container/base.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 
32 template <class configType>
33 class base : public enableSharedFromThis<base<configType> >, public blub::noncopyable
34 {
35 public:
36  typedef configType t_config;
37  typedef enableSharedFromThis<base<t_config> > t_base;
38  typedef sharedPointer<base<t_config> > pointer;
39  typedef typename t_config::t_container::t_simple t_voxelContainerSimple;
40  typedef typename t_config::t_container::t_tile t_voxelContainerTile;
41  typedef typename t_config::t_data t_voxel;
42 
46  virtual ~base()
47  {
48  }
49 
55  void calculateVoxel(const transform &trans) const
56  {
57  BASSERT(m_voxelContainer != nullptr);
58 
59  m_voxelContainer->editVoxel(t_base::getSharedThisPtr(), trans);
60  }
61 
70  virtual void calculateVoxel(t_voxelContainerTile* voxelContainer,
71  const vector3int32& voxelContainerOffset,
72  const transform &trans) const
73  {
74 #ifdef BLUB_LOG_VOXEL
75  BLUB_PROCEDURAL_LOG_OUT() << "calculateVoxel trans:" << trans;
76 #endif
77 
79 
80  const int32 voxelsPerTile(t_config::voxelsPerTile);
81  const vector3int32 posContainerAbsolut(voxelContainerOffset*voxelsPerTile);
82  for (int32 indX = 0; indX < t_config::voxelsPerTile; ++indX)
83  {
84  for (int32 indY = 0; indY < t_config::voxelsPerTile; ++indY)
85  {
86  for (int32 indZ = 0; indZ < t_config::voxelsPerTile; ++indZ)
87  {
88  const vector3int32 posVoxel(indX, indY, indZ);
89  vector3 posAbsolut(posContainerAbsolut + posVoxel);
90 
91  if (!aabb.contains(posAbsolut))
92  {
93  continue;
94  }
95 
96  posAbsolut -= trans.position;
97  posAbsolut /= trans.scale;
98 
99  t_voxel voxelResult;
100  const bool changeVoxel(calculateOneVoxel(posAbsolut, &voxelResult));
101 
102  if (!changeVoxel)
103  {
104  continue;
105  }
106  if (!m_cut)
107  {
108  voxelContainer->setVoxelIfInterpolationHigher(posVoxel, voxelResult);
109  }
110  else
111  {
112  voxelResult.getInterpolation() *= -1;
113  voxelContainer->setVoxelIfInterpolationLower(posVoxel, voxelResult);
114  }
115  }
116  }
117  }
118  }
119 
124  void setCut(const bool& cut)
125  {
126  m_cut = cut;
127  }
132  const bool &getCut() const
133  {
134  return m_cut;
135  }
136 
141  void setVoxelContainer(t_voxelContainerSimple* toSet)
142  {
143  m_voxelContainer = toSet;
144  }
148  t_voxelContainerSimple* getVoxelContainer() const
149  {
150  return m_voxelContainer;
151  }
152 
158  virtual blub::axisAlignedBox getAxisAlignedBoundingBox(const transform& trans) const = 0;
159 
160 protected:
161  base()
162  : m_voxelContainer(nullptr)
163  , m_cut(false)
164  {
165  }
166 
173  virtual bool calculateOneVoxel(const vector3& pos, t_voxel* resultVoxel) const
174  {
175  return false;
176  }
177 
181  enum class axis
182  {
183  x,
184  y,
185  z
186  };
187 
198  virtual void createLine(t_voxelContainerTile *voxelContainer,
199  const vector3int32 &posVoxel,
200  const real &from,
201  const real &len,
202  const axis &ax,
203  const blub::plane &planeA,
204  const blub::plane &planeB) const
205  {
206  const real &pointA(from);
207  real pointB;
208  vector3int32 lineAxis;
209  switch (ax)
210  {
211  case axis::x:
212  pointB = pointA+len;
213  lineAxis = vector3int32(1, 0, 0);
214  break;
215  case axis::y:
216  pointB = pointA+len;
217  lineAxis = vector3int32(0, 1, 0);
218  break;
219  case axis::z:
220  pointB = pointA+len;
221  lineAxis = vector3int32(0, 0, 1);
222  break;
223  default:
224  BASSERT(false);
225  }
226 
227  t_voxel bufferVoxel;
228 
229  int32 voxelStartRel(0);
230  int32 voxelEndRel(0);
231  const real level(0.5); // cos(60 Degree)
232  {
233  {
234  real roundedDown(blub::math::floor(pointA));
235  if (roundedDown >= 0 && roundedDown < t_config::voxelsPerTile)
236  {
237  if (vector3(lineAxis).dotProduct(planeA.normal) <= -level)
238  {
239  real valueDown(roundedDown-pointA);
240  real zResultDown(127.*valueDown);
241  BASSERT(zResultDown <= 0.);
242  BASSERT(zResultDown >= -127.);
243  bufferVoxel.setInterpolation(zResultDown);
244  setVoxel(voxelContainer, posVoxel + vector3int32(roundedDown)*lineAxis, bufferVoxel);
245  }
246  ++voxelStartRel;
247  }
248  }
249  {
250  real roundedUp(blub::math::ceil(pointA));
251  if (roundedUp >= 0. && roundedUp < t_config::voxelsPerTile)
252  {
253  if (vector3(lineAxis).dotProduct(planeA.normal) <= -level)
254  {
255  real valueUp(roundedUp-pointA);
256  real zResultUp(127.*valueUp);
257  BASSERT(zResultUp >= 0.);
258  BASSERT(zResultUp <= 127.);
259  bufferVoxel.setInterpolation(zResultUp);
260  setVoxel(voxelContainer, posVoxel + vector3int32(roundedUp)*lineAxis, bufferVoxel);
261  }
262  ++voxelStartRel;
263  }
264  }
265  }
266  {
267  {
268  real roundedDown(blub::math::floor(pointB));
269  if (roundedDown >= 0 && roundedDown < t_config::voxelsPerTile)
270  {
271  if (vector3(lineAxis).dotProduct(planeB.normal) >= level)
272  {
273  real valueDown(roundedDown-pointB);
274  real zResultDown(127.*valueDown);
275  BASSERT(zResultDown <= 0.);
276  BASSERT(zResultDown >= -127.);
277  bufferVoxel.setInterpolation(-zResultDown);
278  setVoxel(voxelContainer, posVoxel + vector3int32(roundedDown)*lineAxis, bufferVoxel);
279  }
280  ++voxelEndRel;
281  }
282  }
283  {
284  real roundedUp(blub::math::ceil(pointB));
285  if (roundedUp >= 0. && roundedUp < t_config::voxelsPerTile)
286  {
287  if (vector3(lineAxis).dotProduct(planeB.normal) >= level)
288  {
289  real valueUp(roundedUp-pointB);
290  real zResultUp(127.*valueUp);
291  BASSERT(zResultUp >= 0.);
292  BASSERT(zResultUp <= 127.);
293  bufferVoxel.setInterpolation(-zResultUp);
294  setVoxel(voxelContainer, posVoxel + vector3int32(roundedUp)*lineAxis, bufferVoxel);
295  }
296  ++voxelEndRel;
297  }
298  }
299  }
300  {
301  real cutPointVoxelDown = blub::math::floor(pointA);
302  real cutPointVoxelUp = blub::math::ceil(pointB+1);
303 
304  int32 voxelClampedStart = math::clamp<real>(cutPointVoxelDown, 0., t_config::voxelsPerTile);
305  int32 voxelClampedEnd = math::clamp<real>(cutPointVoxelUp, 0., t_config::voxelsPerTile);
306 
307  for (int32 ind = voxelClampedStart + voxelStartRel; ind < voxelClampedEnd - voxelEndRel; ++ind)
308  {
309  bufferVoxel.setInterpolation(0);
310  setVoxel(voxelContainer, posVoxel + vector3int32(ind)*lineAxis, bufferVoxel);
311  }
312  }
313  }
314 
315 
316 private:
317  virtual void setVoxel(t_voxelContainerTile *voxelContainer, const vector3int32 &posVoxel, t_voxel &toSet) const
318  {
319  voxelContainer->setVoxelIfInterpolationHigher(posVoxel, toSet);
320  }
321 
322 protected:
323  t_voxelContainerSimple* m_voxelContainer;
324 
325  bool m_cut;
326 
327 };
328 
329 
330 }
331 }
332 }
333 }
334 
335 
336 #endif // BLUB_PROCEDURAL_VOXEL_EDIT_BASE_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: customVertexInformation.cpp:193
Definition: transform.hpp:20
base class of all edits. Has various features you may wanna overwrite. If you want to write your own ...
Definition: predecl.hpp:71
virtual ~base()
destructor
Definition: base.hpp:46
void setCut(const bool &cut)
Enable or disable cut. Don't change the value while active calculation.
Definition: base.hpp:124
virtual blub::axisAlignedBox getAxisAlignedBoundingBox(const transform &trans) const =0
getAxisAlignedBoundingBox returns the transformed blub::axisAlignedBox in which the voxel have to get...
virtual void calculateVoxel(t_voxelContainerTile *voxelContainer, const vector3int32 &voxelContainerOffset, const transform &trans) const
calculates all voxel in getAxisAlignedBoundingBox() and inserts them into voxelContainer. Method gets called once per tile from various threads. Voxel only will get set if the interpolation is higher than the inerpoaltion before calculation.
Definition: base.hpp:70
axis
The axis enum is used by createLine() for describing the direction.
Definition: base.hpp:181
bool contains(const vector3 &v) const
Definition: axisAlignedBox.hpp:496
void setInterpolation(const int8 &toSet)
setInterpolation sets interpolation
Definition: data.hpp:61
Definition: noncopyable.hpp:10
Definition: vector3.hpp:26
const bool & getCut() const
Returns if cutting is enabled.
Definition: base.hpp:132
Definition: axisAlignedBox.hpp:20
Definition: plane.hpp:16
The data class is the default voxel. Contains an 8-bit interpolation value. Replace/derive it and set...
Definition: data.hpp:27
t_voxelContainerSimple * getVoxelContainer() const
Definition: base.hpp:148
int8 & getInterpolation()
getInterpolation returns reference to interpolation.
Definition: data.hpp:70
Definition: deadlineTimer.hpp:10
virtual bool calculateOneVoxel(const vector3 &pos, t_voxel *resultVoxel) const
Implement this method for your own edit.
Definition: base.hpp:173
void calculateVoxel(const transform &trans) const
calculates voxel in the container u have to set by setVoxelContainer() before. If setVoxelContainer()...
Definition: base.hpp:55
void setVoxelContainer(t_voxelContainerSimple *toSet)
Sets the voxelcontainer used by calculateVoxel().
Definition: base.hpp:141
Definition: customVertexInformation.cpp:177