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