Panda3D
stBasicTerrain.I
1 // Filename: stBasicTerrain.I
2 // Created by: drose (12Oct10)
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 
16 ////////////////////////////////////////////////////////////////////
17 // Function: STBasicTerrain::set_height_map
18 // Access: Published
19 // Description: Specifies the image filename that will define the
20 // height map of the terrain. This will require a
21 // subsequent call to load_data() to actually read the
22 // data.
23 ////////////////////////////////////////////////////////////////////
24 INLINE void STBasicTerrain::
25 set_height_map(const Filename &height_map) {
26  _height_map = height_map;
27  _is_valid = false;
28 }
29 
30 ////////////////////////////////////////////////////////////////////
31 // Function: STBasicTerrain::get_height_map
32 // Access: Published
33 // Description: Returns the image filename that defines the
34 // height map of the terrain.
35 ////////////////////////////////////////////////////////////////////
36 INLINE const Filename &STBasicTerrain::
37 get_height_map() const {
38  return _height_map;
39 }
40 
41 ////////////////////////////////////////////////////////////////////
42 // Function: STBasicTerrain::get_size
43 // Access: Published
44 // Description: Returns the length, in scene graph units, of one edge
45 // of the heightmap as it is manifested by the terrain.
46 // Increasing this number spreads the heightmap out over
47 // a greater area.
48 ////////////////////////////////////////////////////////////////////
49 INLINE PN_stdfloat STBasicTerrain::
50 get_size() const {
51  return _size;
52 }
53 
54 ////////////////////////////////////////////////////////////////////
55 // Function: STBasicTerrain::interpolate
56 // Access: Protected, Static
57 // Description: Convenience function to calculate the linear
58 // interpolation from A to B.
59 ////////////////////////////////////////////////////////////////////
60 INLINE PN_stdfloat STBasicTerrain::
61 interpolate(PN_stdfloat a, PN_stdfloat b, PN_stdfloat t) {
62  return (a + (b - a) * t);
63 }
64 
65 ////////////////////////////////////////////////////////////////////
66 // Function: STBasicTerrain::InterpolationData::Constructor
67 // Access: Public
68 // Description:
69 ////////////////////////////////////////////////////////////////////
70 template<class ValueType>
71 STBasicTerrain::InterpolationData<ValueType>::
72 InterpolationData() : _width(0), _height(0)
73 {
74 }
75 
76 ////////////////////////////////////////////////////////////////////
77 // Function: STBasicTerrain::InterpolationData::reset
78 // Access: Public
79 // Description: Resets the array to an empty array of width x height
80 // cells.
81 ////////////////////////////////////////////////////////////////////
82 template<class ValueType>
83 void STBasicTerrain::InterpolationData<ValueType>::
84 reset(int width, int height) {
85  _width = width;
86  _height = height;
87  _data.clear();
88  _data.insert(_data.begin(), width * height, ValueType());
89 }
90 
91 ////////////////////////////////////////////////////////////////////
92 // Function: STBasicTerrain::InterpolationData::get_nearest_neighbor
93 // Access: Public
94 // Description: Returns the value nearest to (u, v) in the data.
95 ////////////////////////////////////////////////////////////////////
96 template<class ValueType>
97 ValueType STBasicTerrain::InterpolationData<ValueType>::
98 get_nearest_neighbor(PN_stdfloat u, PN_stdfloat v) const {
99  int u = int(u * _width + 0.5f);
100  int v = int(v * _height + 0.5f);
101  int index = u + v * _width;
102  nassertr(index >= 0 && index < (int)_data.size(), 0);
103  return _data[index];
104 }
105 
106 ////////////////////////////////////////////////////////////////////
107 // Function: STBasicTerrain::InterpolationData::calc_bilnear_interpolation
108 // Access: Public
109 // Description: Interpolates the value at (u, v) between its four
110 // nearest neighbors.
111 ////////////////////////////////////////////////////////////////////
112 template<class ValueType>
113 ValueType STBasicTerrain::InterpolationData<ValueType>::
114 calc_bilinear_interpolation(PN_stdfloat u, PN_stdfloat v) const {
115  u -= cfloor(u);
116  v -= cfloor(v);
117 
118  u *= (PN_stdfloat)_width;
119  v *= (PN_stdfloat)_height;
120 
121  const int lower_x = int(u);
122  const int lower_y = int(v);
123  const int higher_x = (lower_x + 1) % _width;
124  const int higher_y = (lower_y + 1) % _height;
125 
126  const PN_stdfloat ratio_x = u - PN_stdfloat(lower_x);
127  const PN_stdfloat ratio_y = v - PN_stdfloat(lower_y);
128  const PN_stdfloat inv_ratio_x = 1.0f - ratio_x;
129  const PN_stdfloat inv_ratio_y = 1.0f - ratio_y;
130 
131  nassertr(lower_x + lower_y * _width >= 0 && higher_x + higher_y * _width < (int)_data.size(), 0);
132 
133  const ValueType &t1 = _data[lower_x + lower_y * _width];
134  const ValueType &t2 = _data[higher_x + lower_y * _width];
135  const ValueType &t3 = _data[lower_x + higher_y * _width];
136  const ValueType &t4 = _data[higher_x + higher_y * _width];
137 
138  return (t1 * inv_ratio_x + t2 * ratio_x) * inv_ratio_y +
139  (t3 * inv_ratio_x + t4 * ratio_x) * ratio_y;
140 }
141 
142 ////////////////////////////////////////////////////////////////////
143 // Function: STBasicTerrain::InterpolationData::calc_smooth
144 // Access: Public
145 // Description: Approximates the average value at (u, v) over the
146 // indicated radius, assuming a polynomial curve.
147 ////////////////////////////////////////////////////////////////////
148 template<class ValueType>
149 ValueType STBasicTerrain::InterpolationData<ValueType>::
150 calc_smooth(PN_stdfloat u, PN_stdfloat v, PN_stdfloat radius) const {
151  ValueType retval = 0;
152 
153  if (radius <= 0.0f) {
154  retval = calc_bilinear_interpolation(u, v);
155 
156  } else {
157  const PN_stdfloat test_points[9][2] = {
158  { 0.0f * radius, 0.0f * radius },
159  { 0.8f * radius, 0.0f * radius },
160  { -0.8f * radius, 0.0f * radius },
161  { 0.0f * radius, 0.8f * radius },
162  { 0.0f * radius, -0.8f * radius },
163  { 0.25f * radius, 0.25f * radius },
164  { 0.25f * radius, -0.25f * radius },
165  { -0.25f * radius, 0.25f * radius },
166  { -0.25f * radius, -0.25f * radius }
167  };
168 
169  PN_stdfloat total_weight = 0.0f;
170  for (int i = 0; i < 9; ++i) {
171  const PN_stdfloat *test_point = test_points[i];
172  PN_stdfloat weight = (1.0f - sqrt((test_point[0] * test_point[0]) + (test_point[1] * test_point[1])));
173  total_weight += weight;
174  retval += weight * calc_bilinear_interpolation(u + test_point[0], v + test_point[1]);
175  }
176 
177  retval /= total_weight;
178  }
179 
180  return retval;
181 }
182 
183 ////////////////////////////////////////////////////////////////////
184 // Function: STBasicTerrain::InterpolationData::is_present
185 // Access: Public
186 // Description: Returns true if the data is present--that is, reset()
187 // was called with non-zero values--or false otherwise.
188 ////////////////////////////////////////////////////////////////////
189 template<class ValueType>
190 bool STBasicTerrain::InterpolationData<ValueType>::
191 is_present() const {
192  return !_data.empty();
193 }
void set_height_map(const Filename &height_map)
Specifies the image filename that will define the height map of the terrain.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
const Filename & get_height_map() const
Returns the image filename that defines the height map of the terrain.
PN_stdfloat get_size() const
Returns the length, in scene graph units, of one edge of the heightmap as it is manifested by the ter...