Panda3D

stTerrain.cxx

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 &copy) :
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 
 All Classes Functions Variables Enumerations