Panda3D
|
00001 // Filename: stTerrain.cxx 00002 // Created by: drose (11Oct10) 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 #include "stTerrain.h" 00016 #include "indent.h" 00017 00018 TypeHandle STTerrain::_type_handle; 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: STTerrain::Constructor 00022 // Access: Protected 00023 // Description: 00024 //////////////////////////////////////////////////////////////////// 00025 STTerrain:: 00026 STTerrain() { 00027 _is_valid = false; 00028 _min_height = 0.0f; 00029 _max_height = 1.0f; 00030 } 00031 00032 //////////////////////////////////////////////////////////////////// 00033 // Function: STTerrain::Copy Constructor 00034 // Access: Protected 00035 // Description: 00036 //////////////////////////////////////////////////////////////////// 00037 STTerrain:: 00038 STTerrain(const STTerrain ©) : 00039 TypedReferenceCount(copy), 00040 Namable(copy), 00041 _is_valid(copy._is_valid), 00042 _normal_map(copy._normal_map), 00043 _splat_layers(copy._splat_layers), 00044 _min_height(copy._min_height), 00045 _max_height(copy._max_height) 00046 { 00047 set_vertex_format(copy._vertex_format); 00048 } 00049 00050 //////////////////////////////////////////////////////////////////// 00051 // Function: STTerrain::Destructor 00052 // Access: Published, Virtual 00053 // Description: 00054 //////////////////////////////////////////////////////////////////// 00055 STTerrain:: 00056 ~STTerrain() { 00057 } 00058 00059 //////////////////////////////////////////////////////////////////// 00060 // Function: STTerrain::clear 00061 // Access: Published, Virtual 00062 // Description: Resets the terrain to its initial, unloaded state. 00063 //////////////////////////////////////////////////////////////////// 00064 void STTerrain:: 00065 clear() { 00066 _is_valid = false; 00067 _min_height = 0.0f; 00068 _max_height = 1.0f; 00069 00070 _normal_map = ""; 00071 _splat_map = ""; 00072 _splat_layers.clear(); 00073 00074 set_vertex_format(NULL); 00075 } 00076 00077 //////////////////////////////////////////////////////////////////// 00078 // Function: STTerrain::load_data 00079 // Access: Published, Virtual 00080 // Description: This will be called at some point after 00081 // initialization. It should be overridden by a derived 00082 // class to load up the terrain data from its source and 00083 // fill in the data members of this class appropriately, 00084 // especially _is_valid. After this call, if _is_valid 00085 // is true, then get_height() etc. will be called to 00086 // query the terrain's data. 00087 //////////////////////////////////////////////////////////////////// 00088 void STTerrain:: 00089 load_data() { 00090 } 00091 00092 //////////////////////////////////////////////////////////////////// 00093 // Function: STTerrain::get_height 00094 // Access: Published, Virtual 00095 // Description: After load_data() has been called, this should return 00096 // the computed height value at point (x, y) of the 00097 // terrain, where x and y are unbounded and may refer to 00098 // any 2-d point in space. 00099 //////////////////////////////////////////////////////////////////// 00100 PN_stdfloat STTerrain:: 00101 get_height(PN_stdfloat x, PN_stdfloat y) const { 00102 return 0.0f; 00103 } 00104 00105 //////////////////////////////////////////////////////////////////// 00106 // Function: STTerrain::get_smooth_height 00107 // Access: Published, Virtual 00108 // Description: After load_data() has been called, this should return 00109 // the approximate average height value over a circle of 00110 // the specified radius, centered at point (x, y) of the 00111 // terrain. 00112 //////////////////////////////////////////////////////////////////// 00113 PN_stdfloat STTerrain:: 00114 get_smooth_height(PN_stdfloat x, PN_stdfloat y, PN_stdfloat radius) const { 00115 return get_height(x, y); 00116 } 00117 00118 //////////////////////////////////////////////////////////////////// 00119 // Function: STTerrain::get_slope 00120 // Access: Published, Virtual 00121 // Description: After load_data() has been called, this should return 00122 // the directionless slope at point (x, y) of the 00123 // terrain, where 0.0 is flat and 1.0 is vertical. This 00124 // is used for determining the legal points to place 00125 // trees and grass. 00126 //////////////////////////////////////////////////////////////////// 00127 PN_stdfloat STTerrain:: 00128 get_slope(PN_stdfloat x, PN_stdfloat y) const { 00129 return 0.0f; 00130 } 00131 00132 //////////////////////////////////////////////////////////////////// 00133 // Function: STTerrain::placement_is_acceptable 00134 // Access: Published 00135 // Description: Returns true if the elevation and slope of point (x, 00136 // y) fall within the requested limits, false otherwise. 00137 //////////////////////////////////////////////////////////////////// 00138 bool STTerrain:: 00139 placement_is_acceptable(PN_stdfloat x, PN_stdfloat y, 00140 PN_stdfloat height_min, PN_stdfloat height_max, 00141 PN_stdfloat slope_min, PN_stdfloat slope_max) { 00142 PN_stdfloat height = get_height(x, y); 00143 if (height < height_min || height > height_max) { 00144 return false; 00145 } 00146 00147 PN_stdfloat slope = get_slope(x, y); 00148 if (slope < slope_min || slope > slope_max) { 00149 return false; 00150 } 00151 00152 return true; 00153 } 00154 00155 //////////////////////////////////////////////////////////////////// 00156 // Function: STTerrain::fill_vertices 00157 // Access: Published, Virtual 00158 // Description: After load_data() has been called, this will be 00159 // called occasionally to populate the vertices for a 00160 // terrain cell. 00161 // 00162 // It will be passed a GeomVertexData whose format will 00163 // match get_vertex_format(), and already allocated with 00164 // num_xy * num_xy rows. This method should fill the 00165 // rows of the data with the appropriate vertex data for 00166 // the terrain, over the grid described by the corners 00167 // (start_x, start_y) up to and including (start_x + 00168 // size_x, start_y + size_xy)--a square of the terrain 00169 // with num_xy vertices on a side, arranged in row-major 00170 // order. 00171 //////////////////////////////////////////////////////////////////// 00172 void STTerrain:: 00173 fill_vertices(GeomVertexData *data, 00174 PN_stdfloat start_x, PN_stdfloat start_y, 00175 PN_stdfloat size_xy, int num_xy) const { 00176 } 00177 00178 //////////////////////////////////////////////////////////////////// 00179 // Function: STTerrain::output 00180 // Access: Published, Virtual 00181 // Description: 00182 //////////////////////////////////////////////////////////////////// 00183 void STTerrain:: 00184 output(ostream &out) const { 00185 Namable::output(out); 00186 } 00187 00188 //////////////////////////////////////////////////////////////////// 00189 // Function: STTerrain::write 00190 // Access: Published, Virtual 00191 // Description: 00192 //////////////////////////////////////////////////////////////////// 00193 void STTerrain:: 00194 write(ostream &out, int indent_level) const { 00195 indent(out, indent_level) 00196 << *this << "\n"; 00197 } 00198 00199 //////////////////////////////////////////////////////////////////// 00200 // Function: STTerrain::get_st_vertex_format 00201 // Access: Public 00202 // Description: Returns a pointer to the SpeedTree array of vertex 00203 // attribs that defines the vertex format for SpeedTree. 00204 //////////////////////////////////////////////////////////////////// 00205 const SpeedTree::SVertexAttribDesc *STTerrain:: 00206 get_st_vertex_format() const { 00207 // return SpeedTree::std_vertex_format; 00208 nassertr(!_st_vertex_attribs.empty(), NULL); 00209 00210 return &_st_vertex_attribs[0]; 00211 } 00212 00213 //////////////////////////////////////////////////////////////////// 00214 // Function: STTerrain::set_vertex_format 00215 // Access: Protected 00216 // Description: Should be called in load_data() by a derived class to 00217 // fill in the _vertex_format member. This will also 00218 // compute and store the appropriate value for 00219 // _st_vertex_attribs. 00220 //////////////////////////////////////////////////////////////////// 00221 bool STTerrain:: 00222 set_vertex_format(const GeomVertexFormat *format) { 00223 if (format == NULL) { 00224 _vertex_format = NULL; 00225 _st_vertex_attribs.clear(); 00226 _is_valid = false; 00227 return true; 00228 } 00229 00230 _vertex_format = GeomVertexFormat::register_format(format); 00231 if (!convert_vertex_format(_st_vertex_attribs, _vertex_format)) { 00232 _is_valid = false; 00233 return false; 00234 } 00235 00236 return true; 00237 } 00238 00239 //////////////////////////////////////////////////////////////////// 00240 // Function: STTerrain::convert_vertex_format 00241 // Access: Protected, Static 00242 // Description: Populates the indicated st_vertex_attribs vector with 00243 // an array of SpeedTree vertex attribute entries that 00244 // corresponds to the requested format. Returns true on 00245 // success, or false if the format cannot be represented 00246 // in SpeedTree. 00247 //////////////////////////////////////////////////////////////////// 00248 bool STTerrain:: 00249 convert_vertex_format(STTerrain::VertexAttribs &st_vertex_attribs, 00250 const GeomVertexFormat *format) { 00251 st_vertex_attribs.clear(); 00252 00253 if (format->get_num_arrays() != 1) { 00254 speedtree_cat.error() 00255 << "Cannot represent multi-array vertex format in SpeedTree.\n"; 00256 return false; 00257 } 00258 00259 const GeomVertexArrayFormat *array = format->get_array(0); 00260 00261 int num_columns = array->get_num_columns(); 00262 for (int ci = 0; ci < num_columns; ++ci) { 00263 const GeomVertexColumn *column = array->get_column(ci); 00264 st_vertex_attribs.push_back(SpeedTree::SVertexAttribDesc()); 00265 SpeedTree::SVertexAttribDesc &attrib = st_vertex_attribs.back(); 00266 if (!convert_vertex_column(attrib, column)) { 00267 st_vertex_attribs.clear(); 00268 return false; 00269 } 00270 } 00271 00272 st_vertex_attribs.push_back(SpeedTree::st_attrib_end); 00273 00274 return true; 00275 } 00276 00277 //////////////////////////////////////////////////////////////////// 00278 // Function: STTerrain::convert_vertex_column 00279 // Access: Protected, Static 00280 // Description: Converts the indicated vertex column definition to 00281 // the corresponding SpeedTree::SVertexAttribDesc 00282 // format. Returns true on success, false on failure. 00283 //////////////////////////////////////////////////////////////////// 00284 bool STTerrain:: 00285 convert_vertex_column(SpeedTree::SVertexAttribDesc &st_attrib, 00286 const GeomVertexColumn *column) { 00287 switch (column->get_numeric_type()) { 00288 case GeomEnums::NT_stdfloat: 00289 st_attrib.m_eDataType = SpeedTree::VERTEX_ATTRIB_TYPE_FLOAT; 00290 break; 00291 00292 default: 00293 speedtree_cat.error() 00294 << "Unsupported vertex numeric type for " << *column << "\n"; 00295 return false; 00296 } 00297 00298 st_attrib.m_uiNumElements = column->get_num_components(); 00299 00300 if (column->get_name() == InternalName::get_vertex()) { 00301 st_attrib.m_eSemantic = SpeedTree::VERTEX_ATTRIB_SEMANTIC_POS; 00302 00303 } else if (column->get_name() == InternalName::get_texcoord()) { 00304 st_attrib.m_eSemantic = SpeedTree::VERTEX_ATTRIB_SEMANTIC_TEXCOORD0; 00305 00306 } else { 00307 speedtree_cat.error() 00308 << "Unsupported vertex semantic name for " << *column << "\n"; 00309 return false; 00310 } 00311 00312 nassertr(st_attrib.SizeOfAttrib() == column->get_total_bytes(), false); 00313 00314 return true; 00315 } 00316