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