Panda3D
|
00001 // Filename: speedTreeNode.h 00002 // Created by: drose (30Sep10) 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 #ifndef SPEEDTREENODE_H 00016 #define SPEEDTREENODE_H 00017 00018 #include "pandabase.h" 00019 #include "pandaNode.h" 00020 #include "pointerTo.h" 00021 #include "stTree.h" 00022 #include "stTransform.h" 00023 #include "stTerrain.h" 00024 #include "callbackObject.h" 00025 #include "loaderOptions.h" 00026 #include "transformState.h" 00027 #include "nodePath.h" 00028 #include "pStatCollector.h" 00029 #include "randomizer.h" 00030 #include "speedtree_api.h" 00031 00032 class Loader; 00033 00034 // There is a SpeedTree bug that prevents reliably deleting a 00035 // CForestRender object, as of version 5.2. Presumably it will be 00036 // fixed beginning in version 5.3. 00037 #if SPEEDTREE_VERSION_MAJOR > 5 || (SPEEDTREE_VERSION_MAJOR == 5 && SPEEDTREE_VERSION_MINOR >= 3) 00038 #undef ST_DELETE_FOREST_HACK 00039 #else 00040 #define ST_DELETE_FOREST_HACK 00041 #endif 00042 00043 //////////////////////////////////////////////////////////////////// 00044 // Class : SpeedTreeNode 00045 // Description : Interfaces with the SpeedTree library to render 00046 // SpeedTree objects, especially trees, within the 00047 // Panda3D scene graph. 00048 // 00049 // SpeedTree also includes some support for a simple 00050 // terrain system, which is available here as well. 00051 // SpeedTree's rather lame grass system is not presently 00052 // exposed. 00053 //////////////////////////////////////////////////////////////////// 00054 class EXPCL_PANDASPEEDTREE SpeedTreeNode : public PandaNode { 00055 private: 00056 // This definition is required by InstanceList, below. 00057 typedef pvector<SpeedTree::CInstance> STInstances; 00058 00059 PUBLISHED: 00060 // This nested class keeps a linear list of transforms, for the 00061 // purpose of recording instances of a particular STTree. It is 00062 // used below. 00063 class InstanceList { 00064 public: 00065 INLINE InstanceList(const STTree *tree); 00066 INLINE bool operator < (const InstanceList &other) const; 00067 00068 PUBLISHED: 00069 INLINE const STTree *get_tree() const; 00070 00071 INLINE int get_num_instances() const; 00072 INLINE STTransform get_instance(int n) const; 00073 MAKE_SEQ(get_instances, get_num_instances, get_instance); 00074 INLINE void set_instance(int n, const STTransform &transform); 00075 00076 INLINE int add_instance(const STTransform &transform); 00077 INLINE void remove_instance(int n); 00078 00079 void output(ostream &out) const; 00080 void write(ostream &out, int indent_level = 0) const; 00081 00082 public: 00083 void write_datagram(BamWriter *manager, Datagram &dg); 00084 void fillin(DatagramIterator &scan, BamReader *manager); 00085 00086 private: 00087 PT(STTree) _tree; 00088 STInstances _instances; 00089 friend class SpeedTreeNode; 00090 }; 00091 00092 PUBLISHED: 00093 SpeedTreeNode(const string &name); 00094 virtual ~SpeedTreeNode(); 00095 00096 INLINE bool is_valid() const; 00097 00098 INLINE int get_num_trees() const; 00099 INLINE const STTree *get_tree(int n) const; 00100 MAKE_SEQ(get_trees, get_num_trees, get_tree); 00101 const InstanceList &get_instance_list(int n) const; 00102 MAKE_SEQ(get_instance_lists, get_num_trees, get_instance_list); 00103 INLINE STTree *modify_tree(int n); 00104 00105 int count_total_instances() const; 00106 00107 InstanceList &add_tree(const STTree *tree); 00108 int remove_tree(const STTree *tree); 00109 void remove_all_trees(); 00110 00111 bool has_instance_list(const STTree *tree) const; 00112 const InstanceList &get_instance_list(const STTree *tree) const; 00113 InstanceList &modify_instance_list(const STTree *tree); 00114 00115 void add_instance(const STTree *tree, const STTransform &transform); 00116 void add_instances(const NodePath &root, const TransformState *transform = TransformState::make_identity()); 00117 void add_instances_from(const SpeedTreeNode *other); 00118 void add_instances_from(const SpeedTreeNode *other, const TransformState *transform); 00119 void add_random_instances(const STTree *tree, int quantity, 00120 PN_stdfloat x_min, PN_stdfloat x_max, 00121 PN_stdfloat y_min, PN_stdfloat y_max, 00122 PN_stdfloat scale_min, PN_stdfloat scale_max, 00123 PN_stdfloat height_min, PN_stdfloat height_max, 00124 PN_stdfloat slope_min, PN_stdfloat slope_max, 00125 Randomizer &randomizer = Randomizer()); 00126 00127 bool add_from_stf(const Filename &stf_filename, 00128 const LoaderOptions &options = LoaderOptions()); 00129 bool add_from_stf(istream &in, const Filename &pathname, 00130 const LoaderOptions &options = LoaderOptions(), 00131 Loader *loader = NULL); 00132 00133 bool setup_terrain(const Filename &terrain_file); 00134 void set_terrain(STTerrain *terrain); 00135 INLINE void clear_terrain(); 00136 INLINE bool has_terrain() const; 00137 INLINE STTerrain *get_terrain() const; 00138 00139 void snap_to_terrain(); 00140 00141 void reload_config(); 00142 00143 void set_wind(double strength, const LVector3 &direction); 00144 00145 INLINE void set_time_delta(double delta); 00146 INLINE double get_time_delta() const; 00147 INLINE static void set_global_time_delta(double delta); 00148 INLINE static double get_global_time_delta(); 00149 00150 static bool authorize(const string &license = ""); 00151 00152 public: 00153 SpeedTreeNode(const SpeedTreeNode ©); 00154 00155 virtual PandaNode *make_copy() const; 00156 virtual PandaNode *combine_with(PandaNode *other); 00157 virtual void apply_attribs_to_vertices(const AccumulatedAttribs &attribs, 00158 int attrib_types, 00159 GeomTransformer &transformer); 00160 00161 virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data); 00162 virtual bool is_renderable() const; 00163 virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data); 00164 00165 void prepare_scene(GraphicsStateGuardianBase *gsgbase, const RenderState *net_state); 00166 00167 virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds, 00168 int &internal_vertices, 00169 int pipeline_stage, 00170 Thread *current_thread) const; 00171 00172 virtual void output(ostream &out) const; 00173 virtual void write(ostream &out, int indent_level) const; 00174 00175 static void write_error(ostream &out); 00176 00177 protected: 00178 void set_transparent_texture_mode(SpeedTree::ETextureAlphaRenderMode eMode) const; 00179 00180 private: 00181 void init_node(); 00182 void r_add_instances(PandaNode *node, const TransformState *transform, 00183 Thread *current_thread); 00184 00185 void repopulate(); 00186 void update_terrain_cells(); 00187 bool validate_api(GraphicsStateGuardian *gsg); 00188 void draw_callback(CallbackData *cbdata); 00189 void render_forest_into_shadow_maps(); 00190 void setup_for_render(GraphicsStateGuardian *gsg); 00191 void cull_forest(); 00192 00193 void print_forest_stats(const SpeedTree::CForest::SPopulationStats &forest_stats) const; 00194 00195 private: 00196 class DrawCallback : public CallbackObject { 00197 public: 00198 ALLOC_DELETED_CHAIN(DrawCallback); 00199 INLINE DrawCallback(SpeedTreeNode *node); 00200 virtual void do_callback(CallbackData *cbdata); 00201 00202 private: 00203 PT(SpeedTreeNode) _node; 00204 00205 public: 00206 static TypeHandle get_class_type() { 00207 return _type_handle; 00208 } 00209 static void init_type() { 00210 CallbackObject::init_type(); 00211 register_type(_type_handle, "SpeedTreeNode::DrawCallback", 00212 CallbackObject::get_class_type()); 00213 } 00214 virtual TypeHandle get_type() const { 00215 return get_class_type(); 00216 } 00217 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00218 00219 private: 00220 static TypeHandle _type_handle; 00221 }; 00222 00223 private: 00224 string _os_shaders_dir; 00225 00226 // A list of instances per each unique tree. 00227 typedef ov_set<InstanceList *, IndirectLess<InstanceList> > Trees; 00228 Trees _trees; 00229 00230 #ifdef ST_DELETE_FOREST_HACK 00231 SpeedTree::CForestRender &_forest_render; 00232 #else 00233 SpeedTree::CForestRender _forest_render; 00234 #endif // ST_DELETE_FOREST_HACK 00235 SpeedTree::CView _view; 00236 SpeedTree::SForestCullResultsRender _visible_trees; 00237 SpeedTree::CForest::SPopulationStats _population_stats; 00238 bool _needs_repopulate; 00239 bool _is_valid; 00240 00241 PT(STTerrain) _terrain; 00242 SpeedTree::CTerrainRender _terrain_render; 00243 SpeedTree::STerrainCullResults _visible_terrain; 00244 00245 SpeedTree::Vec3 _light_dir; 00246 00247 class ShadowInfo { 00248 public: 00249 ShadowInfo() {}; 00250 00251 SpeedTree::CView _light_view; 00252 SpeedTree::SForestCullResultsRender _light_cull; 00253 PN_stdfloat _shadow_split; 00254 }; 00255 typedef pvector<ShadowInfo> ShadowInfos; 00256 ShadowInfos _shadow_infos; 00257 00258 double _time_delta; 00259 static double _global_time_delta; 00260 00261 static bool _authorized; 00262 static bool _done_first_init; 00263 00264 static PStatCollector _cull_speedtree_pcollector; 00265 static PStatCollector _cull_speedtree_shadows_pcollector; 00266 static PStatCollector _cull_speedtree_trees_pcollector; 00267 static PStatCollector _cull_speedtree_terrain_pcollector; 00268 static PStatCollector _draw_speedtree_pcollector; 00269 static PStatCollector _draw_speedtree_shadows_pcollector; 00270 static PStatCollector _draw_speedtree_trees_pcollector; 00271 static PStatCollector _draw_speedtree_terrain_pcollector; 00272 static PStatCollector _draw_speedtree_terrain_update_pcollector; 00273 00274 public: 00275 static void register_with_read_factory(); 00276 virtual void write_datagram(BamWriter *manager, Datagram &dg); 00277 00278 protected: 00279 static TypedWritable *make_from_bam(const FactoryParams ¶ms); 00280 void fillin(DatagramIterator &scan, BamReader *manager); 00281 00282 public: 00283 static TypeHandle get_class_type() { 00284 return _type_handle; 00285 } 00286 static void init_type() { 00287 PandaNode::init_type(); 00288 register_type(_type_handle, "SpeedTreeNode", 00289 PandaNode::get_class_type()); 00290 DrawCallback::init_type(); 00291 } 00292 virtual TypeHandle get_type() const { 00293 return get_class_type(); 00294 } 00295 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00296 00297 private: 00298 static TypeHandle _type_handle; 00299 00300 friend class SpeedTreeNode::DrawCallback; 00301 }; 00302 00303 INLINE ostream &operator << (ostream &out, const SpeedTreeNode::InstanceList &instances) { 00304 instances.output(out); 00305 return out; 00306 } 00307 00308 #include "speedTreeNode.I" 00309 00310 #endif