Panda3D
perlinNoise3.cxx
1 // Filename: perlinNoise3.cxx
2 // Created by: drose (05Oct05)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "perlinNoise3.h"
16 #include "cmath.h"
17 
18 ////////////////////////////////////////////////////////////////////
19 // Function: PerlinNoise3::noise
20 // Access: Published
21 // Description: Returns the noise function of the three inputs.
22 ////////////////////////////////////////////////////////////////////
23 double PerlinNoise3::
24 noise(const LVecBase3d &value) const {
25  // Convert the vector to our local coordinate space.
26  LVecBase3d vec = _input_xform.xform_point(value);
27 
28  double x = vec[0];
29  double y = vec[1];
30  double z = vec[2];
31 
32  // Find unit cube that contains point.
33  double xf = cfloor(x);
34  double yf = cfloor(y);
35  double zf = cfloor(z);
36 
37  int X = ((int)xf) & _table_size_mask;
38  int Y = ((int)yf) & _table_size_mask;
39  int Z = ((int)zf) & _table_size_mask;
40 
41  // Find relative x,y,z of point in cube.
42  x -= xf;
43  y -= yf;
44  z -= zf;
45 
46  // Compute fade curves for each of x,y,z.
47  double u = fade(x);
48  double v = fade(y);
49  double w = fade(z);
50 
51  // Hash coordinates of the 8 cube corners. The 8 corners correspond
52  // to AA, BA, AB, BB, AA + 1, BA + 1, AB + 1, and BB + 1.
53  int A = _index[X] + Y;
54  int AA = _index[A] + Z;
55  int AB = _index[A + 1] + Z;
56  int B = _index[X + 1] + Y;
57  int BA = _index[B] + Z;
58  int BB = _index[B + 1] + Z;
59 
60  // and add blended results from 8 corners of cube.
61  double result =
62  lerp(w, lerp(v, lerp(u, grad(_index[AA], x, y, z),
63  grad(_index[BA], x - 1, y, z)),
64  lerp(u, grad(_index[AB], x, y - 1, z),
65  grad(_index[BB], x - 1, y - 1, z))),
66  lerp(v, lerp(u, grad(_index[AA + 1], x, y, z - 1),
67  grad(_index[BA + 1], x - 1, y, z - 1)),
68  lerp(u, grad(_index[AB + 1], x, y - 1, z - 1),
69  grad(_index[BB + 1], x - 1, y - 1, z - 1))));
70 
71  return result;
72 }
73 
74 ////////////////////////////////////////////////////////////////////
75 // Function: PerlinNoise3::init_unscaled_xform
76 // Access: Private
77 // Description: Come up with a random rotation to apply to the input
78 // coordinates. This will reduce the problem of the
79 // singularities on the axes, by sending the axes in
80 // some crazy direction.
81 ////////////////////////////////////////////////////////////////////
82 void PerlinNoise3::
83 init_unscaled_xform() {
84  LRotationd rot(_randomizer.random_real_unit(),
85  _randomizer.random_real_unit(),
86  _randomizer.random_real_unit(),
87  _randomizer.random_real_unit());
88  rot.normalize();
89  rot.extract_to_matrix(_unscaled_xform);
90 
91  // And come up with a random translation too, just so the
92  // singularity at (0, 0, 0) is also unpredicatable.
93  _unscaled_xform.set_row(3, LVecBase3d(_randomizer.random_real_unit(),
94  _randomizer.random_real_unit(),
95  _randomizer.random_real_unit()));
96 }
void set_row(int row, const LVecBase4d &v)
Replaces the indicated row of the matrix.
Definition: lmatrix.h:5452
LVecBase3d xform_point(const LVecBase3d &v) const
The matrix transforms a 3-component point (including translation component) and returns the result...
Definition: lmatrix.h:5932
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:1471
This is a unit quaternion representing a rotation.
Definition: lrotation.h:334
double noise(double x, double y, double z) const
Returns the noise function of the three inputs.
Definition: perlinNoise3.I:122