voxelTerrain
 All Classes Functions Variables Typedefs Enumerations Pages
noise.hpp
1 #ifndef BLUB_PROCEDURAL_VOXEL_EDIT_NOISE_HPP
2 #define BLUB_PROCEDURAL_VOXEL_EDIT_NOISE_HPP
3 
4 #include "blub/core/vector.hpp"
5 #include "blub/math/axisAlignedBox.hpp"
6 #include "blub/procedural/log/global.hpp"
7 #include "blub/procedural/voxel/edit/base.hpp"
8 
9 #include <boost/function/function2.hpp>
10 
11 #include <numeric>
12 
13 
14 namespace blub
15 {
16 namespace procedural
17 {
18 namespace voxel
19 {
20 namespace edit
21 {
22 
23 
28 template <class configType>
29 class noise : public base<configType>
30 {
31 public:
32  typedef boost::function<bool (vector3, real&)> t_callbackInterpolation;
33 
34  typedef configType t_config;
35  typedef base<t_config> t_base;
36  typedef sharedPointer<noise> pointer;
37  typedef typename t_config::t_data t_voxel;
38 
47  static pointer create(const blub::axisAlignedBox& desc,
48  const vector3& scale,
49  const uint32& seed = 0,
50  const t_callbackInterpolation& callbackInterpolation = [] (const vector3&, real& value) {value*=1024;return true;})
51  {
52  return pointer(new noise(desc, scale, seed, callbackInterpolation));
53  }
57  virtual ~noise()
58  {
59  ;
60  }
61 
68  {
69  return blub::axisAlignedBox(m_aab.getMinimum() + trans.position,
70  m_aab.getMaximum() + trans.position);
71  }
72 
73 protected:
74  static real fade(const real &t)
75  {
76  return t * t * t * (t * (t * 6 - 15) + 10);
77  }
78  static real lerp(const real& t, const real& a, const real& b)
79  {
80  return a + t * (b - a);
81  }
82  static real grad(const int32& hash, const real& x, const real& y, const real& z) {
83  const int32 h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
84  const real u = h < 8 ? x : y, // INTO 12 GRADIENT DIRECTIONS.
85  v = h < 4 ? y : h == 12 || h == 14 ? x : z;
86  return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
87  }
88  int32 permutation(const int32 index) const
89  {
90  BASSERT(index >= 0);
91  BASSERT(index < 512);
92  return m_permutation[index%256];
93  }
94 
101  bool calculateOneVoxel(const vector3& pos, t_voxel* resultVoxel) const override
102  {
103  real x(pos.x*m_scale.x);
104  real y(pos.y*m_scale.y);
105  real z(pos.z*m_scale.z);
106 
107  const int32 X = static_cast<int32>(math::floor(x)) & 255; // FIND UNIT CUBE THAT
108  const int32 Y = static_cast<int32>(math::floor(y)) & 255; // CONTAINS POINT.
109  const int32 Z = static_cast<int32>(math::floor(z)) & 255;
110  x -= static_cast<int32>(math::floor(x)); // FIND RELATIVE X,Y,Z
111  y -= static_cast<int32>(math::floor(y)); // OF POINT IN CUBE.
112  z -= static_cast<int32>(math::floor(z));
113  const real u = fade(x); // COMPUTE FADE CURVES
114  const real v = fade(y); // FOR EACH OF X,Y,Z.
115  const real w = fade(z);
116  const int32 A = permutation(X )+Y;
117  const int32 AA = permutation(A)+Z;
118  const int32 AB = permutation(A+1)+Z; // HASH COORDINATES OF
119  const int32 B = permutation(X+1)+Y;
120  const int32 BA = permutation(B)+Z;
121  const int32 BB = permutation(B+1)+Z; // THE 8 CUBE CORNERS,
122 
123  real resultInterpolation = lerp(w, lerp(v, lerp(u, grad(permutation(AA ), x , y , z ), // AND ADD
124  grad(permutation(BA ), x-1, y , z )), // BLENDED
125  lerp(u, grad(permutation(AB ), x , y-1, z ), // RESULTS
126  grad(permutation(BB ), x-1, y-1, z ))),// FROM 8
127  lerp(v, lerp(u, grad(permutation(AA+1), x , y , z-1 ), // CORNERS
128  grad(permutation(BA+1), x-1, y , z-1 )), // OF CUBE
129  lerp(u, grad(permutation(AB+1), x , y-1, z-1 ),
130  grad(permutation(BB+1), x-1, y-1, z-1 ))));
131  if (!m_callbackInterpolation(pos, resultInterpolation))
132  {
133  return false;
134  }
135  const int8 resultCasted(static_cast<int8>(math::clamp<real>(resultInterpolation, -127., 127.)));
136 
137  resultVoxel->setInterpolation(resultCasted);
138 
139  return true;
140  }
141 
142 
146  noise(const blub::axisAlignedBox& desc, const vector3& scale, const uint32& seed, const t_callbackInterpolation &callbackInterpolation)
147  : m_aab(desc)
148  , m_scale(scale)
149  , m_callbackInterpolation(callbackInterpolation)
150  , m_permutation(256)
151  {
152  std::srand(seed);
153  std::iota(m_permutation.begin(), m_permutation.end(), 0);
154  std::random_shuffle(m_permutation.begin(), m_permutation.end());
155  }
156 
157 protected:
158  const blub::axisAlignedBox m_aab;
159  const vector3 m_scale;
160  const t_callbackInterpolation m_callbackInterpolation;
161 
162  vector<uint8_t> m_permutation;
163 
164 };
165 
166 
167 }
168 }
169 }
170 }
171 
172 
173 #endif // BLUB_PROCEDURAL_VOXEL_EDIT_NOISE_HPP
static pointer create(const blub::axisAlignedBox &desc, const vector3 &scale, const uint32 &seed=0, const t_callbackInterpolation &callbackInterpolation=[](const vector3 &, real &value){value *=1024;return true;})
creates an instance of the class and returns it as shared_ptr<>
Definition: noise.hpp:47
bool calculateOneVoxel(const vector3 &pos, t_voxel *resultVoxel) const override
calculateOneVoxel scales pos by scale set in constructor and calculates the noise.
Definition: noise.hpp:101
Definition: customVertexInformation.cpp:193
Definition: transform.hpp:20
noise(const blub::axisAlignedBox &desc, const vector3 &scale, const uint32 &seed, const t_callbackInterpolation &callbackInterpolation)
noise Contructor - same as create()
Definition: noise.hpp:146
void setInterpolation(const int8 &toSet)
setInterpolation sets interpolation
Definition: data.hpp:61
Definition: vector3.hpp:26
Definition: axisAlignedBox.hpp:20
The data class is the default voxel. Contains an 8-bit interpolation value. Replace/derive it and set...
Definition: data.hpp:27
const vector3 & getMinimum(void) const
Definition: axisAlignedBox.hpp:126
const vector3 & getMaximum(void) const
Definition: axisAlignedBox.hpp:141
virtual ~noise()
~noise destructor
Definition: noise.hpp:57
Definition: deadlineTimer.hpp:10
blub::axisAlignedBox getAxisAlignedBoundingBox(const transform &trans) const override
getAxisAlignedBoundingBox returns transformed aab of the to generate voxel
Definition: noise.hpp:67
Definition: customVertexInformation.cpp:177