Panda3D
speedTreeNode.h
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 speedTreeNode.h
10  * @author drose
11  * @date 2010-09-30
12  */
13 
14 #ifndef SPEEDTREENODE_H
15 #define SPEEDTREENODE_H
16 
17 #include "pandabase.h"
18 #include "pandaNode.h"
19 #include "pointerTo.h"
20 #include "stTree.h"
21 #include "stTransform.h"
22 #include "stTerrain.h"
23 #include "callbackObject.h"
24 #include "loaderOptions.h"
25 #include "transformState.h"
26 #include "nodePath.h"
27 #include "pStatCollector.h"
28 #include "randomizer.h"
29 #include "speedtree_api.h"
30 
31 class Loader;
32 
33 // There is a SpeedTree bug that prevents reliably deleting a CForestRender
34 // object, as of version 5.2. Presumably it will be fixed beginning in
35 // version 5.3.
36 #if SPEEDTREE_VERSION_MAJOR > 5 || (SPEEDTREE_VERSION_MAJOR == 5 && SPEEDTREE_VERSION_MINOR >= 3)
37 #undef ST_DELETE_FOREST_HACK
38 #else
39 #define ST_DELETE_FOREST_HACK
40 #endif
41 
42 /**
43  * Interfaces with the SpeedTree library to render SpeedTree objects,
44  * especially trees, within the Panda3D scene graph.
45  *
46  * SpeedTree also includes some support for a simple terrain system, which is
47  * available here as well. SpeedTree's rather lame grass system is not
48  * presently exposed.
49  */
50 class EXPCL_PANDASPEEDTREE SpeedTreeNode : public PandaNode {
51 private:
52  // This definition is required by InstanceList, below.
54 
55 PUBLISHED:
56  // This nested class keeps a linear list of transforms, for the purpose of
57  // recording instances of a particular STTree. It is used below.
58  class InstanceList {
59  public:
60  INLINE InstanceList(const STTree *tree);
61  INLINE bool operator < (const InstanceList &other) const;
62 
63  PUBLISHED:
64  INLINE const STTree *get_tree() const;
65 
66  INLINE int get_num_instances() const;
67  INLINE STTransform get_instance(int n) const;
68  MAKE_SEQ(get_instances, get_num_instances, get_instance);
69  INLINE void set_instance(int n, const STTransform &transform);
70 
71  INLINE int add_instance(const STTransform &transform);
72  INLINE void remove_instance(int n);
73 
74  void output(std::ostream &out) const;
75  void write(std::ostream &out, int indent_level = 0) const;
76 
77  public:
78  void write_datagram(BamWriter *manager, Datagram &dg);
79  void fillin(DatagramIterator &scan, BamReader *manager);
80 
81  private:
82  PT(STTree) _tree;
83  STInstances _instances;
84  friend class SpeedTreeNode;
85  };
86 
87 PUBLISHED:
88  explicit SpeedTreeNode(const std::string &name);
89  virtual ~SpeedTreeNode();
90 
91  INLINE bool is_valid() const;
92 
93  INLINE int get_num_trees() const;
94  INLINE const STTree *get_tree(int n) const;
95  MAKE_SEQ(get_trees, get_num_trees, get_tree);
96  const InstanceList &get_instance_list(int n) const;
97  MAKE_SEQ(get_instance_lists, get_num_trees, get_instance_list);
98  INLINE STTree *modify_tree(int n);
99 
100  int count_total_instances() const;
101 
102  InstanceList &add_tree(const STTree *tree);
103  int remove_tree(const STTree *tree);
104  void remove_all_trees();
105 
106  bool has_instance_list(const STTree *tree) const;
107  const InstanceList &get_instance_list(const STTree *tree) const;
109 
110  void add_instance(const STTree *tree, const STTransform &transform);
111  void add_instances(const NodePath &root, const TransformState *transform = TransformState::make_identity());
112  void add_instances_from(const SpeedTreeNode *other);
113  void add_instances_from(const SpeedTreeNode *other, const TransformState *transform);
114  void add_random_instances(const STTree *tree, int quantity,
115  PN_stdfloat x_min, PN_stdfloat x_max,
116  PN_stdfloat y_min, PN_stdfloat y_max,
117  PN_stdfloat scale_min, PN_stdfloat scale_max,
118  PN_stdfloat height_min, PN_stdfloat height_max,
119  PN_stdfloat slope_min, PN_stdfloat slope_max,
120  Randomizer &randomizer = Randomizer());
121 
122  bool add_from_stf(const Filename &stf_filename,
123  const LoaderOptions &options = LoaderOptions());
124  bool add_from_stf(std::istream &in, const Filename &pathname,
125  const LoaderOptions &options = LoaderOptions(),
126  Loader *loader = nullptr);
127 
128  bool setup_terrain(const Filename &terrain_file);
129  void set_terrain(STTerrain *terrain);
130  INLINE void clear_terrain();
131  INLINE bool has_terrain() const;
132  INLINE STTerrain *get_terrain() const;
133 
134  void snap_to_terrain();
135 
136  void reload_config();
137 
138  void set_wind(double strength, const LVector3 &direction);
139 
140  INLINE void set_time_delta(double delta);
141  INLINE double get_time_delta() const;
142  INLINE static void set_global_time_delta(double delta);
143  INLINE static double get_global_time_delta();
144  MAKE_PROPERTY(time_delta, get_time_delta, set_time_delta);
145  MAKE_PROPERTY(global_time_delta, get_global_time_delta,
147 
148  static bool authorize(const std::string &license = "");
149 
150 public:
151  SpeedTreeNode(const SpeedTreeNode &copy);
152 
153  virtual PandaNode *make_copy() const;
154  virtual PandaNode *combine_with(PandaNode *other);
155  virtual void apply_attribs_to_vertices(const AccumulatedAttribs &attribs,
156  int attrib_types,
157  GeomTransformer &transformer);
158 
159  virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
160  virtual bool is_renderable() const;
161  virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data);
162 
163  void prepare_scene(GraphicsStateGuardianBase *gsgbase, const RenderState *net_state);
164 
165  virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
166  int &internal_vertices,
167  int pipeline_stage,
168  Thread *current_thread) const;
169 
170  virtual void output(std::ostream &out) const;
171  virtual void write(std::ostream &out, int indent_level) const;
172 
173  static void write_error(std::ostream &out);
174 
175 protected:
176  void set_transparent_texture_mode(SpeedTree::ETextureAlphaRenderMode eMode) const;
177 
178 private:
179  void init_node();
180  void r_add_instances(PandaNode *node, const TransformState *transform,
181  Thread *current_thread);
182 
183  void repopulate();
184  void update_terrain_cells();
185  bool validate_api(GraphicsStateGuardian *gsg);
186  void draw_callback(CallbackData *cbdata);
187  void render_forest_into_shadow_maps();
188  void setup_for_render(GraphicsStateGuardian *gsg);
189  void cull_forest();
190 
191  void print_forest_stats(const SpeedTree::CForest::SPopulationStats &forest_stats) const;
192 
193 private:
194  class DrawCallback : public CallbackObject {
195  public:
196  ALLOC_DELETED_CHAIN(DrawCallback);
197  INLINE DrawCallback(SpeedTreeNode *node);
198  virtual void do_callback(CallbackData *cbdata);
199 
200  private:
201  PT(SpeedTreeNode) _node;
202 
203  public:
204  static TypeHandle get_class_type() {
205  return _type_handle;
206  }
207  static void init_type() {
208  CallbackObject::init_type();
209  register_type(_type_handle, "SpeedTreeNode::DrawCallback",
210  CallbackObject::get_class_type());
211  }
212  virtual TypeHandle get_type() const {
213  return get_class_type();
214  }
215  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
216 
217  private:
218  static TypeHandle _type_handle;
219  };
220 
221 private:
222  std::string _os_shaders_dir;
223 
224  // A list of instances per each unique tree.
226  Trees _trees;
227 
228 #ifdef ST_DELETE_FOREST_HACK
229  SpeedTree::CForestRender &_forest_render;
230 #else
231  SpeedTree::CForestRender _forest_render;
232 #endif // ST_DELETE_FOREST_HACK
233  SpeedTree::CView _view;
234  SpeedTree::SForestCullResultsRender _visible_trees;
235  SpeedTree::CForest::SPopulationStats _population_stats;
236  bool _needs_repopulate;
237  bool _is_valid;
238 
239  PT(STTerrain) _terrain;
240  SpeedTree::CTerrainRender _terrain_render;
241  SpeedTree::STerrainCullResults _visible_terrain;
242 
243  SpeedTree::Vec3 _light_dir;
244 
245  class ShadowInfo {
246  public:
247  ShadowInfo() {};
248 
249  SpeedTree::CView _light_view;
250  SpeedTree::SForestCullResultsRender _light_cull;
251  PN_stdfloat _shadow_split;
252  };
253  typedef pvector<ShadowInfo> ShadowInfos;
254  ShadowInfos _shadow_infos;
255 
256  double _time_delta;
257  static double _global_time_delta;
258 
259  static bool _authorized;
260  static bool _done_first_init;
261 
262  static PStatCollector _cull_speedtree_pcollector;
263  static PStatCollector _cull_speedtree_shadows_pcollector;
264  static PStatCollector _cull_speedtree_trees_pcollector;
265  static PStatCollector _cull_speedtree_terrain_pcollector;
266  static PStatCollector _draw_speedtree_pcollector;
267  static PStatCollector _draw_speedtree_shadows_pcollector;
268  static PStatCollector _draw_speedtree_trees_pcollector;
269  static PStatCollector _draw_speedtree_terrain_pcollector;
270  static PStatCollector _draw_speedtree_terrain_update_pcollector;
271 
272 public:
273  static void register_with_read_factory();
274  virtual void write_datagram(BamWriter *manager, Datagram &dg);
275 
276 protected:
277  static TypedWritable *make_from_bam(const FactoryParams &params);
278  void fillin(DatagramIterator &scan, BamReader *manager);
279 
280 public:
281  static TypeHandle get_class_type() {
282  return _type_handle;
283  }
284  static void init_type() {
285  PandaNode::init_type();
286  register_type(_type_handle, "SpeedTreeNode",
287  PandaNode::get_class_type());
288  DrawCallback::init_type();
289  }
290  virtual TypeHandle get_type() const {
291  return get_class_type();
292  }
293  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
294 
295 private:
296  static TypeHandle _type_handle;
297 
298  friend class SpeedTreeNode::DrawCallback;
299 };
300 
301 INLINE std::ostream &operator << (std::ostream &out, const SpeedTreeNode::InstanceList &instances) {
302  instances.output(out);
303  return out;
304 }
305 
306 #include "speedTreeNode.I"
307 
308 #endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
STTerrain * get_terrain() const
Returns the terrain associated with the node, or NULL if there is no terrain.
Definition: speedTreeNode.I:90
Indicates a coordinate-system transform on vertices.
bool has_terrain() const
Returns true if a valid terrain has been associated with the node, false otherwise.
Definition: speedTreeNode.I:81
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: pandaNode.cxx:3589
virtual void apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, GeomTransformer &transformer)
Applies whatever attributes are specified in the AccumulatedAttribs object (and by the attrib_types b...
Definition: pandaNode.cxx:288
static void write_error(std::ostream &out)
Writes the current SpeedTree error message to the indicated stream.
int count_total_instances() const
Returns the total number of trees that will be rendered by this node, counting all instances of all t...
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
virtual PandaNode * combine_with(PandaNode *other)
Collapses this PandaNode with the other PandaNode, if possible, and returns a pointer to the combined...
Definition: pandaNode.cxx:325
Specifies parameters that may be passed to the loader.
Definition: loaderOptions.h:23
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void output(std::ostream &out) const
Writes a brief description of the node to the indicated output stream.
void add_instances(const NodePath &root, const TransformState *transform=TransformState::make_identity())
Walks the scene graph beginning at root, looking for nested SpeedTreeNodes.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool has_instance_list(const STTree *tree) const
Returns true if the indicated tree has any instances within this node, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A convenient class for loading models from disk, in bam or egg format (or any of a number of other fo...
Definition: loader.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear_terrain()
Removes the terrain associated with the node.
Definition: speedTreeNode.I:72
This collects together the pieces of data that are accumulated for each node while walking the scene ...
bool setup_terrain(const Filename &terrain_file)
A convenience function to set up terrain geometry by reading a terrain.txt file as defined by SpeedTr...
bool is_valid() const
Returns true if the node is valid and ready to render, false otherwise.
Definition: speedTreeNode.I:20
int remove_tree(const STTree *tree)
Removes all instances of the indicated tree.
This is the abstract base class that defines the interface needed to describe a terrain for rendering...
Definition: stTerrain.h:34
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
This is a generic data block that is passed along to a CallbackObject when a callback is made.
Definition: callbackData.h:29
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data)
This function will be called during the cull traversal to perform any additional operations that shou...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void register_with_read_factory()
Tells the BamReader how to create objects of type PandaNode.
Definition: pandaNode.cxx:3580
STTree * modify_tree(int n)
Returns a modifiable STTree pointer for the nth tree instance.
Definition: speedTreeNode.I:61
A specialization of ordered_vector that emulates a standard STL set: one copy of each element is allo...
void snap_to_terrain()
Adjusts all the trees in this node so that their Z position matches the height of the terrain at thei...
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
A lightweight class that represents a single element that may be timed and/or counted via stats.
void set_terrain(STTerrain *terrain)
Associated a terrain with the node.
get_instance_list
Returns a list of transforms that corresponds to the instances at which the indicated tree appears.
Definition: speedTreeNode.h:97
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
This class is used by the SceneGraphReducer to maintain and accumulate the set of attributes we have ...
void add_instance(const STTree *tree, const STTransform &transform)
Adds a new instance of the indicated tree at the indicated transform.
void remove_all_trees()
Removes all instances of all trees from the node.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data)
Adds the node's contents to the CullResult we are building up during the cull traversal,...
Definition: pandaNode.cxx:478
Interfaces with the SpeedTree library to render SpeedTree objects, especially trees,...
Definition: speedTreeNode.h:50
void prepare_scene(GraphicsStateGuardianBase *gsgbase, const RenderState *net_state)
Walks through the scene graph beginning at this node, and does whatever initialization is required to...
virtual PandaNode * make_copy() const
Returns a newly-allocated PandaNode that is a shallow copy of this one.
Definition: pandaNode.cxx:487
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
bool add_from_stf(const Filename &stf_filename, const LoaderOptions &options=LoaderOptions())
Opens and reads the named STF (SpeedTree Forest) file, and adds the SRT files named within as instanc...
set_global_time_delta
Specifies an offset that is to be added each frame to the global clock's frame_time for the purpose o...
Represents a transform that may be applied to a particular instance of a tree when added to the Speed...
Definition: stTransform.h:26
This is a generic object that can be assigned to a callback at various points in the rendering proces...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void reload_config()
Re-reads the current setting of all of the relevant config variables and applies them to this node.
virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds, int &internal_vertices, int pipeline_stage, Thread *current_thread) const
Returns a newly-allocated BoundingVolume that represents the internal contents of the node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
A thread; that is, a lightweight process.
Definition: thread.h:46
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A handy class to return random numbers.
Definition: randomizer.h:26
Encapsulates all the communication with a particular instance of a given rendering backend.
get_tree
Returns the STTree pointer for the nth tree.
Definition: speedTreeNode.h:95
void add_instances_from(const SpeedTreeNode *other)
Adds all of the instances defined within the indicated SpeedTreeNode as instances of this node.
A class to retrieve the individual data elements previously stored in a Datagram.
static bool authorize(const std::string &license="")
Make this call to initialized the SpeedTree API and verify the license.
InstanceList & modify_instance_list(const STTree *tree)
Returns a modifiable list of transforms that corresponds to the instances of this tree.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
void add_random_instances(const STTree *tree, int quantity, PN_stdfloat x_min, PN_stdfloat x_max, PN_stdfloat y_min, PN_stdfloat y_max, PN_stdfloat scale_min, PN_stdfloat scale_max, PN_stdfloat height_min, PN_stdfloat height_max, PN_stdfloat slope_min, PN_stdfloat slope_max, Randomizer &randomizer=Randomizer())
Creates a number of random instances of the indicated true, within the indicated range.
InstanceList & add_tree(const STTree *tree)
Adds a new tree for rendering.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool is_renderable() const
Returns true if there is some value to visiting this particular node during the cull traversal for an...
Definition: pandaNode.cxx:468
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
Encapsulates a single tree model in the SpeedTree library, as loaded from an SRT file.
Definition: stTree.h:28
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_wind(double strength, const LVector3 &direction)
Specifies the overall wind strength and direction.
An object specifically designed to transform the vertices of a Geom without disturbing indexing or af...
set_time_delta
Specifies an offset that is to be added each frame to the global clock's frame_time for the purpose o...