00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 INLINE void STBasicTerrain::
00025 set_height_map(const Filename &height_map) {
00026 _height_map = height_map;
00027 _is_valid = false;
00028 }
00029
00030
00031
00032
00033
00034
00035
00036 INLINE const Filename &STBasicTerrain::
00037 get_height_map() const {
00038 return _height_map;
00039 }
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 INLINE PN_stdfloat STBasicTerrain::
00050 get_size() const {
00051 return _size;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060 INLINE PN_stdfloat STBasicTerrain::
00061 interpolate(PN_stdfloat a, PN_stdfloat b, PN_stdfloat t) {
00062 return (a + (b - a) * t);
00063 }
00064
00065
00066
00067
00068
00069
00070 template<class ValueType>
00071 STBasicTerrain::InterpolationData<ValueType>::
00072 InterpolationData() : _width(0), _height(0)
00073 {
00074 }
00075
00076
00077
00078
00079
00080
00081
00082 template<class ValueType>
00083 void STBasicTerrain::InterpolationData<ValueType>::
00084 reset(int width, int height) {
00085 _width = width;
00086 _height = height;
00087 _data.clear();
00088 _data.insert(_data.begin(), width * height, ValueType());
00089 }
00090
00091
00092
00093
00094
00095
00096 template<class ValueType>
00097 ValueType STBasicTerrain::InterpolationData<ValueType>::
00098 get_nearest_neighbor(PN_stdfloat u, PN_stdfloat v) const {
00099 int u = int(u * _width + 0.5f);
00100 int v = int(v * _height + 0.5f);
00101 int index = u + v * _width;
00102 nassertr(index >= 0 && index < (int)_data.size(), 0);
00103 return _data[index];
00104 }
00105
00106
00107
00108
00109
00110
00111
00112 template<class ValueType>
00113 ValueType STBasicTerrain::InterpolationData<ValueType>::
00114 calc_bilinear_interpolation(PN_stdfloat u, PN_stdfloat v) const {
00115 u -= cfloor(u);
00116 v -= cfloor(v);
00117
00118 u *= (PN_stdfloat)_width;
00119 v *= (PN_stdfloat)_height;
00120
00121 const int lower_x = int(u);
00122 const int lower_y = int(v);
00123 const int higher_x = (lower_x + 1) % _width;
00124 const int higher_y = (lower_y + 1) % _height;
00125
00126 const PN_stdfloat ratio_x = u - PN_stdfloat(lower_x);
00127 const PN_stdfloat ratio_y = v - PN_stdfloat(lower_y);
00128 const PN_stdfloat inv_ratio_x = 1.0f - ratio_x;
00129 const PN_stdfloat inv_ratio_y = 1.0f - ratio_y;
00130
00131 nassertr(lower_x + lower_y * _width >= 0 && higher_x + higher_y * _width < (int)_data.size(), 0);
00132
00133 const ValueType &t1 = _data[lower_x + lower_y * _width];
00134 const ValueType &t2 = _data[higher_x + lower_y * _width];
00135 const ValueType &t3 = _data[lower_x + higher_y * _width];
00136 const ValueType &t4 = _data[higher_x + higher_y * _width];
00137
00138 return (t1 * inv_ratio_x + t2 * ratio_x) * inv_ratio_y +
00139 (t3 * inv_ratio_x + t4 * ratio_x) * ratio_y;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148 template<class ValueType>
00149 ValueType STBasicTerrain::InterpolationData<ValueType>::
00150 calc_smooth(PN_stdfloat u, PN_stdfloat v, PN_stdfloat radius) const {
00151 ValueType retval = 0;
00152
00153 if (radius <= 0.0f) {
00154 retval = calc_bilinear_interpolation(u, v);
00155
00156 } else {
00157 const PN_stdfloat test_points[9][2] = {
00158 { 0.0f * radius, 0.0f * radius },
00159 { 0.8f * radius, 0.0f * radius },
00160 { -0.8f * radius, 0.0f * radius },
00161 { 0.0f * radius, 0.8f * radius },
00162 { 0.0f * radius, -0.8f * radius },
00163 { 0.25f * radius, 0.25f * radius },
00164 { 0.25f * radius, -0.25f * radius },
00165 { -0.25f * radius, 0.25f * radius },
00166 { -0.25f * radius, -0.25f * radius }
00167 };
00168
00169 PN_stdfloat total_weight = 0.0f;
00170 for (int i = 0; i < 9; ++i) {
00171 const PN_stdfloat *test_point = test_points[i];
00172 PN_stdfloat weight = (1.0f - sqrt((test_point[0] * test_point[0]) + (test_point[1] * test_point[1])));
00173 total_weight += weight;
00174 retval += weight * calc_bilinear_interpolation(u + test_point[0], v + test_point[1]);
00175 }
00176
00177 retval /= total_weight;
00178 }
00179
00180 return retval;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 template<class ValueType>
00190 bool STBasicTerrain::InterpolationData<ValueType>::
00191 is_present() const {
00192 return !_data.empty();
00193 }