Panda3D
stTerrain.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file stTerrain.cxx
10  * @author drose
11  * @date 2010-10-11
12  */
13 
14 #include "stTerrain.h"
15 #include "indent.h"
16 
17 TypeHandle STTerrain::_type_handle;
18 
19 /**
20  *
21  */
22 STTerrain::
23 STTerrain() {
24  _is_valid = false;
25  _min_height = 0.0f;
26  _max_height = 1.0f;
27 }
28 
29 /**
30  *
31  */
32 STTerrain::
33 STTerrain(const STTerrain &copy) :
34  TypedReferenceCount(copy),
35  Namable(copy),
36  _is_valid(copy._is_valid),
37  _normal_map(copy._normal_map),
38  _splat_layers(copy._splat_layers),
39  _min_height(copy._min_height),
40  _max_height(copy._max_height)
41 {
42  set_vertex_format(copy._vertex_format);
43 }
44 
45 /**
46  *
47  */
48 STTerrain::
49 ~STTerrain() {
50 }
51 
52 /**
53  * Resets the terrain to its initial, unloaded state.
54  */
55 void STTerrain::
56 clear() {
57  _is_valid = false;
58  _min_height = 0.0f;
59  _max_height = 1.0f;
60 
61  _normal_map = "";
62  _splat_map = "";
63  _splat_layers.clear();
64 
65  set_vertex_format(nullptr);
66 }
67 
68 /**
69  * This will be called at some point after initialization. It should be
70  * overridden by a derived class to load up the terrain data from its source
71  * and fill in the data members of this class appropriately, especially
72  * _is_valid. After this call, if _is_valid is true, then get_height() etc.
73  * will be called to query the terrain's data.
74  */
75 void STTerrain::
77 }
78 
79 /**
80  * After load_data() has been called, this should return the computed height
81  * value at point (x, y) of the terrain, where x and y are unbounded and may
82  * refer to any 2-d point in space.
83  */
84 PN_stdfloat STTerrain::
85 get_height(PN_stdfloat x, PN_stdfloat y) const {
86  return 0.0f;
87 }
88 
89 /**
90  * After load_data() has been called, this should return the approximate
91  * average height value over a circle of the specified radius, centered at
92  * point (x, y) of the terrain.
93  */
94 PN_stdfloat STTerrain::
95 get_smooth_height(PN_stdfloat x, PN_stdfloat y, PN_stdfloat radius) const {
96  return get_height(x, y);
97 }
98 
99 /**
100  * After load_data() has been called, this should return the directionless
101  * slope at point (x, y) of the terrain, where 0.0 is flat and 1.0 is
102  * vertical. This is used for determining the legal points to place trees and
103  * grass.
104  */
105 PN_stdfloat STTerrain::
106 get_slope(PN_stdfloat x, PN_stdfloat y) const {
107  return 0.0f;
108 }
109 
110 /**
111  * Returns true if the elevation and slope of point (x, y) fall within the
112  * requested limits, false otherwise.
113  */
114 bool STTerrain::
115 placement_is_acceptable(PN_stdfloat x, PN_stdfloat y,
116  PN_stdfloat height_min, PN_stdfloat height_max,
117  PN_stdfloat slope_min, PN_stdfloat slope_max) {
118  PN_stdfloat height = get_height(x, y);
119  if (height < height_min || height > height_max) {
120  return false;
121  }
122 
123  PN_stdfloat slope = get_slope(x, y);
124  if (slope < slope_min || slope > slope_max) {
125  return false;
126  }
127 
128  return true;
129 }
130 
131 /**
132  * After load_data() has been called, this will be called occasionally to
133  * populate the vertices for a terrain cell.
134  *
135  * It will be passed a GeomVertexData whose format will match
136  * get_vertex_format(), and already allocated with num_xy * num_xy rows. This
137  * method should fill the rows of the data with the appropriate vertex data
138  * for the terrain, over the grid described by the corners (start_x, start_y)
139  * up to and including (start_x + size_x, start_y + size_xy)--a square of the
140  * terrain with num_xy vertices on a side, arranged in row-major order.
141  */
142 void STTerrain::
144  PN_stdfloat start_x, PN_stdfloat start_y,
145  PN_stdfloat size_xy, int num_xy) const {
146 }
147 
148 /**
149  *
150  */
151 void STTerrain::
152 output(std::ostream &out) const {
153  Namable::output(out);
154 }
155 
156 /**
157  *
158  */
159 void STTerrain::
160 write(std::ostream &out, int indent_level) const {
161  indent(out, indent_level)
162  << *this << "\n";
163 }
164 
165 /**
166  * Returns a pointer to the SpeedTree array of vertex attribs that defines the
167  * vertex format for SpeedTree.
168  */
169 const SpeedTree::SVertexAttribDesc *STTerrain::
171  // return SpeedTree::std_vertex_format;
172  nassertr(!_st_vertex_attribs.empty(), nullptr);
173 
174  return &_st_vertex_attribs[0];
175 }
176 
177 /**
178  * Should be called in load_data() by a derived class to fill in the
179  * _vertex_format member. This will also compute and store the appropriate
180  * value for _st_vertex_attribs.
181  */
182 bool STTerrain::
183 set_vertex_format(const GeomVertexFormat *format) {
184  if (format == nullptr) {
185  _vertex_format = nullptr;
186  _st_vertex_attribs.clear();
187  _is_valid = false;
188  return true;
189  }
190 
191  _vertex_format = GeomVertexFormat::register_format(format);
192  if (!convert_vertex_format(_st_vertex_attribs, _vertex_format)) {
193  _is_valid = false;
194  return false;
195  }
196 
197  return true;
198 }
199 
200 /**
201  * Populates the indicated st_vertex_attribs vector with an array of SpeedTree
202  * vertex attribute entries that corresponds to the requested format. Returns
203  * true on success, or false if the format cannot be represented in SpeedTree.
204  */
205 bool STTerrain::
206 convert_vertex_format(STTerrain::VertexAttribs &st_vertex_attribs,
207  const GeomVertexFormat *format) {
208  st_vertex_attribs.clear();
209 
210  if (format->get_num_arrays() != 1) {
211  speedtree_cat.error()
212  << "Cannot represent multi-array vertex format in SpeedTree.\n";
213  return false;
214  }
215 
216  const GeomVertexArrayFormat *array = format->get_array(0);
217 
218  int num_columns = array->get_num_columns();
219  for (int ci = 0; ci < num_columns; ++ci) {
220  const GeomVertexColumn *column = array->get_column(ci);
221  st_vertex_attribs.push_back(SpeedTree::SVertexAttribDesc());
222  SpeedTree::SVertexAttribDesc &attrib = st_vertex_attribs.back();
223  if (!convert_vertex_column(attrib, column)) {
224  st_vertex_attribs.clear();
225  return false;
226  }
227  }
228 
229  st_vertex_attribs.push_back(SpeedTree::st_attrib_end);
230 
231  return true;
232 }
233 
234 /**
235  * Converts the indicated vertex column definition to the corresponding
236  * SpeedTree::SVertexAttribDesc format. Returns true on success, false on
237  * failure.
238  */
239 bool STTerrain::
240 convert_vertex_column(SpeedTree::SVertexAttribDesc &st_attrib,
241  const GeomVertexColumn *column) {
242  switch (column->get_numeric_type()) {
243  case GeomEnums::NT_stdfloat:
244  st_attrib.m_eDataType = SpeedTree::VERTEX_ATTRIB_TYPE_FLOAT;
245  break;
246 
247  default:
248  speedtree_cat.error()
249  << "Unsupported vertex numeric type for " << *column << "\n";
250  return false;
251  }
252 
253  st_attrib.m_uiNumElements = column->get_num_components();
254 
255  if (column->get_name() == InternalName::get_vertex()) {
256  st_attrib.m_eSemantic = SpeedTree::VERTEX_ATTRIB_SEMANTIC_POS;
257 
258  } else if (column->get_name() == InternalName::get_texcoord()) {
259  st_attrib.m_eSemantic = SpeedTree::VERTEX_ATTRIB_SEMANTIC_TEXCOORD0;
260 
261  } else {
262  speedtree_cat.error()
263  << "Unsupported vertex semantic name for " << *column << "\n";
264  return false;
265  }
266 
267  nassertr(st_attrib.SizeOfAttrib() == column->get_total_bytes(), false);
268 
269  return true;
270 }
get_num_columns
Returns the number of different columns in the array.
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
const SpeedTree::SVertexAttribDesc * get_st_vertex_format() const
Returns a pointer to the SpeedTree array of vertex attribs that defines the vertex format for SpeedTr...
Definition: stTerrain.cxx:170
A base class for things which need to inherit from both TypedObject and from ReferenceCount.
This is the abstract base class that defines the interface needed to describe a terrain for rendering...
Definition: stTerrain.h:34
virtual PN_stdfloat get_slope(PN_stdfloat x, PN_stdfloat y) const
After load_data() has been called, this should return the directionless slope at point (x,...
Definition: stTerrain.cxx:106
virtual void fill_vertices(GeomVertexData *data, PN_stdfloat start_x, PN_stdfloat start_y, PN_stdfloat size_xy, int num_xy) const
After load_data() has been called, this will be called occasionally to populate the vertices for a te...
Definition: stTerrain.cxx:143
This defines how a single column is interleaved within a vertex array stored within a Geom.
void output(std::ostream &out) const
Outputs the Namable.
Definition: namable.I:61
A base class for all things which can have a name.
Definition: namable.h:26
virtual PN_stdfloat get_smooth_height(PN_stdfloat x, PN_stdfloat y, PN_stdfloat radius) const
After load_data() has been called, this should return the approximate average height value over a cir...
Definition: stTerrain.cxx:95
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
get_num_arrays
Returns the number of individual arrays required by the format.
virtual void clear()
Resets the terrain to its initial, unloaded state.
Definition: stTerrain.cxx:56
This class defines the physical layout of the vertex data stored within a Geom.
This describes the structure of a single array within a Geom data.
virtual PN_stdfloat get_height(PN_stdfloat x, PN_stdfloat y) const =0
After load_data() has been called, this should return the computed height value at point (x,...
Definition: stTerrain.cxx:85
virtual void load_data()=0
This will be called at some point after initialization.
Definition: stTerrain.cxx:76
const InternalName * get_name() const
Returns the name of this particular data field, e.g.
int get_total_bytes() const
Returns the number of bytes used by each element of the column: component_bytes * num_components.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
int get_num_components() const
Returns the number of components of the column: the number of instances of the NumericType in each el...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_array
Returns the description of the nth array used by the format.
get_column
Returns the specification with the indicated name, or NULL if the name is not used.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool placement_is_acceptable(PN_stdfloat x, PN_stdfloat y, PN_stdfloat height_min, PN_stdfloat height_max, PN_stdfloat slope_min, PN_stdfloat slope_max)
Returns true if the elevation and slope of point (x, y) fall within the requested limits,...
Definition: stTerrain.cxx:115