Panda3D
 All Classes Functions Variables Enumerations
stBasicTerrain.I
00001 // Filename: stBasicTerrain.I
00002 // Created by:  drose (12Oct10)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 
00016 ////////////////////////////////////////////////////////////////////
00017 //     Function: STBasicTerrain::set_height_map
00018 //       Access: Published
00019 //  Description: Specifies the image filename that will define the
00020 //               height map of the terrain.  This will require a
00021 //               subsequent call to load_data() to actually read the
00022 //               data.
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 //     Function: STBasicTerrain::get_height_map
00032 //       Access: Published
00033 //  Description: Returns the image filename that defines the
00034 //               height map of the terrain.
00035 ////////////////////////////////////////////////////////////////////
00036 INLINE const Filename &STBasicTerrain::
00037 get_height_map() const {
00038   return _height_map;
00039 }
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: STBasicTerrain::get_size
00043 //       Access: Published
00044 //  Description: Returns the length, in scene graph units, of one edge
00045 //               of the heightmap as it is manifested by the terrain.
00046 //               Increasing this number spreads the heightmap out over
00047 //               a greater area.
00048 ////////////////////////////////////////////////////////////////////
00049 INLINE PN_stdfloat STBasicTerrain::
00050 get_size() const {
00051   return _size;
00052 }
00053 
00054 ////////////////////////////////////////////////////////////////////
00055 //     Function: STBasicTerrain::interpolate
00056 //       Access: Protected, Static
00057 //  Description: Convenience function to calculate the linear
00058 //               interpolation from A to B.
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 //     Function: STBasicTerrain::InterpolationData::Constructor
00067 //       Access: Public
00068 //  Description: 
00069 ////////////////////////////////////////////////////////////////////
00070 template<class ValueType>
00071 STBasicTerrain::InterpolationData<ValueType>::
00072 InterpolationData() : _width(0), _height(0) 
00073 {
00074 }
00075 
00076 ////////////////////////////////////////////////////////////////////
00077 //     Function: STBasicTerrain::InterpolationData::reset
00078 //       Access: Public
00079 //  Description: Resets the array to an empty array of width x height
00080 //               cells.
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 //     Function: STBasicTerrain::InterpolationData::get_nearest_neighbor
00093 //       Access: Public
00094 //  Description: Returns the value nearest to (u, v) in the data.
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 //     Function: STBasicTerrain::InterpolationData::calc_bilnear_interpolation
00108 //       Access: Public
00109 //  Description: Interpolates the value at (u, v) between its four
00110 //               nearest neighbors.
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 //     Function: STBasicTerrain::InterpolationData::calc_smooth
00144 //       Access: Public
00145 //  Description: Approximates the average value at (u, v) over the
00146 //               indicated radius, assuming a polynomial curve.
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 //     Function: STBasicTerrain::InterpolationData::is_present
00185 //       Access: Public
00186 //  Description: Returns true if the data is present--that is, reset()
00187 //               was called with non-zero values--or false otherwise.
00188 ////////////////////////////////////////////////////////////////////
00189 template<class ValueType>
00190 bool STBasicTerrain::InterpolationData<ValueType>::
00191 is_present() const {
00192   return !_data.empty();
00193 }
 All Classes Functions Variables Enumerations