OpenVDB  9.0.1
OpenSimplexNoise.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 /// @file math/OpenSimplexNoise.h
5 ///
6 /// @authors Francisco Gochez
7 ///
8 /// @brief Methods for generating OpenSimplexNoise (n-dimensional gradient noise)
9 ///
10 /// @details This code is based on https://gist.github.com/tombsar/716134ec71d1b8c1b530
11 /// (accessed on 22/05/2019). We have simplified that code in a number of ways,
12 /// most notably by removing the template on dimension (this only generates 3
13 /// dimensional noise) and removing the base class as it's unnecessary for our
14 /// uses. We also assume C++ 2011 or above and have thus removed a number of
15 /// ifdef blocks.
16 ///
17 /// The OSN namespace contains the original copyright.
18 ///
19 
20 #ifndef OPENVDB_AX_MATH_OPEN_SIMPLEX_NOISE_HAS_BEEN_INCLUDED
21 #define OPENVDB_AX_MATH_OPEN_SIMPLEX_NOISE_HAS_BEEN_INCLUDED
22 
23 #include <openvdb/version.h>
24 #include <cstdint>
25 
26 namespace openvdb {
28 namespace OPENVDB_VERSION_NAME {
29 
30 namespace ax {
31 namespace math {
32 
33 template <typename NoiseT>
34 void curlnoise(double (*out)[3], const double (*in)[3])
35 {
36  float delta = 0.0001f;
37  float a, b;
38 
39  // noise coordinates for vector potential components.
40  float p[3][3] = {
41  { static_cast<float>((*in)[0]) + 000.0f, static_cast<float>((*in)[1]) + 000.0f, static_cast<float>((*in)[2]) + 000.0f }, // x
42  { static_cast<float>((*in)[0]) + 256.0f, static_cast<float>((*in)[1]) - 256.0f, static_cast<float>((*in)[2]) + 256.0f }, // y
43  { static_cast<float>((*in)[0]) - 512.0f, static_cast<float>((*in)[1]) + 512.0f, static_cast<float>((*in)[2]) - 512.0f }, // z
44  };
45 
47  // Compute curl.x
48  a = (NoiseT::noise(p[2][0], p[2][1] + delta, p[2][2]) - NoiseT::noise(p[2][0], p[2][1] - delta, p[2][2])) / (2.0f * delta);
49  b = (NoiseT::noise(p[1][0], p[1][1], p[1][2] + delta) - NoiseT::noise(p[1][0], p[1][1], p[1][2] - delta)) / (2.0f * delta);
50  (*out)[0] = a - b;
51 
52  // Compute curl.y
53  a = (NoiseT::noise(p[0][0], p[0][1], p[0][2] + delta) - NoiseT::noise(p[0][0], p[0][1], p[0][2] - delta)) / (2.0f * delta);
54  b = (NoiseT::noise(p[2][0] + delta, p[2][1], p[2][2]) - NoiseT::noise(p[2][0] - delta, p[2][1], p[2][2])) / (2.0f * delta);
55  (*out)[1] = a - b;
56 
57  // Compute curl.z
58  a = (NoiseT::noise(p[1][0] + delta, p[1][1], p[1][2]) - NoiseT::noise(p[1][0] - delta, p[1][1], p[1][2])) / (2.0f * delta);
59  b = (NoiseT::noise(p[0][0], p[0][1] + delta, p[0][2]) - NoiseT::noise(p[0][0], p[0][1] - delta, p[0][2])) / (2.0f * delta);
60  (*out)[2] = a - b;
62 }
63 
64 template <typename NoiseT>
65 void curlnoise(double (*out)[3], double x, double y, double z)
66 {
67  const double in[3] = {x, y, z};
68  curlnoise<NoiseT>(out, &in);
69 }
70 
71 }
72 }
73 }
74 }
75 
76 namespace OSN
77 {
78 
79 // The following is the original copyright notice:
80 /*
81  *
82  *
83  * OpenSimplex (Simplectic) Noise in C++
84  * by Arthur Tombs
85  *
86  * Modified 2015-01-08
87  *
88  * This is a derivative work based on OpenSimplex by Kurt Spencer:
89  * https://gist.github.com/KdotJPG/b1270127455a94ac5d19
90  *
91  * Anyone is free to make use of this software in whatever way they want.
92  * Attribution is appreciated, but not required.
93  *
94  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
95  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
96  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
97  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
98  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
99  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
100  * OTHER DEALINGS IN THE SOFTWARE.
101  */
102 
103 // 3D Implementation of the OpenSimplexNoise generator.
104 class OSNoise
105 {
106 public:
107  using inttype = int64_t;
108 
109  // Initializes the class using a permutation array generated from a 64-bit seed.
110  // Generates a proper permutation (i.e. doesn't merely perform N successive
111  // pair swaps on a base array).
112  // Uses a simple 64-bit LCG.
113  OSNoise(inttype seed = 0LL);
114 
115  OSNoise(const int * p);
116 
117  template <typename T>
118  T eval(const T x, const T y, const T z) const;
119 
120 private:
121 
122  template <typename T>
123  inline T extrapolate(const inttype xsb,
124  const inttype ysb,
125  const inttype zsb,
126  const T dx,
127  const T dy,
128  const T dz) const;
129 
130  template <typename T>
131  inline T extrapolate(const inttype xsb,
132  const inttype ysb,
133  const inttype zsb,
134  const T dx,
135  const T dy,
136  const T dz,
137  T (&de) [3]) const;
138 
139  int mPerm [256];
140  // Array of gradient values for 3D. Values are defined below the class definition.
141  static const int sGradients [72];
142 
143  // Because 72 is not a power of two, extrapolate cannot use a bitmask to index
144  // into the perm array. Pre-calculate and store the indices instead.
145  int mPermGradIndex [256];
146 };
147 
148 }
149 
150 #endif // OPENVDB_AX_MATH_OPEN_SIMPLEX_NOISE_HAS_BEEN_INCLUDED
#define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
Bracket code with OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN/_END, to inhibit warnings about type conve...
Definition: Platform.h:206
Definition: OpenSimplexNoise.h:104
Definition: OpenSimplexNoise.h:76
#define OPENVDB_NO_TYPE_CONVERSION_WARNING_END
Definition: Platform.h:207
void curlnoise(double(*out)[3], double x, double y, double z)
Definition: OpenSimplexNoise.h:65
Definition: Exceptions.h:13
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
int64_t inttype
Definition: OpenSimplexNoise.h:107
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202