// Filename: sceneGraphReducer.h // Created by: drose (14Mar02) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // // All use of this software is subject to the terms of the revised BSD // license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// #ifndef SCENEGRAPHREDUCER_H #define SCENEGRAPHREDUCER_H #include "pandabase.h" #include "transformState.h" #include "renderAttrib.h" #include "renderState.h" #include "accumulatedAttribs.h" #include "geomTransformer.h" #include "pStatCollector.h" #include "pStatTimer.h" #include "typedObject.h" #include "pointerTo.h" #include "graphicsStateGuardianBase.h" class PandaNode; //////////////////////////////////////////////////////////////////// // Class : SceneGraphReducer // Description : An interface for simplifying ("flattening") scene // graphs by eliminating unneeded nodes and collapsing // out unneeded state changes and transforms. // // This class is designed so that it may be inherited // from and specialized, if needed, to fine-tune the // flattening behavior, but normally the default // behavior is sufficient. //////////////////////////////////////////////////////////////////// class EXPCL_PANDA_PGRAPH SceneGraphReducer { PUBLISHED: INLINE SceneGraphReducer(GraphicsStateGuardianBase *gsg = NULL); INLINE ~SceneGraphReducer(); enum AttribTypes { TT_transform = 0x001, TT_color = 0x002, TT_color_scale = 0x004, TT_tex_matrix = 0x008, TT_clip_plane = 0x010, TT_cull_face = 0x020, TT_apply_texture_color = 0x040, TT_other = 0x080, }; enum CombineSiblings { CS_geom_node = 0x001, CS_within_radius = 0x002, CS_other = 0x004, CS_recurse = 0x008, }; enum CollectVertexData { // If set, two GeomVertexDatas with different names will not be // collected together. CVD_name = 0x001, // If set, a ModelNode begins a subgraph of nodes whose // GeomVertexDatas will not be collected with nodes outside the // subgraph. CVD_model = 0x002, // If set, a non-identity transform begins a subgraph of nodes // whose GeomVertexDatas will not be collected with nodes outside // the subgraph. CVD_transform = 0x004, // If set, GeomVertexDatas with any usage_hint other than // UH_static will not be collected with any other Geoms in a // different GeomNode. However, two different dynamic Geoms // within the same node might still be collected together. CVD_avoid_dynamic = 0x008, // If set, only those GeomVertexDatas within the same node might // be collected together. CVD_one_node_only = 0x010, // If set, two GeomVertexDatas with different formats will not be // collected together. If not set, GeomVertexDatas of different // formats may be combined by expanding all GeomVertexDatas to the // union of all defined columns. CVD_format = 0x020, // If set, two GeomVertexDatas with different usage hints (for // instance, UH_static vs. UH_dynamic) will not be collected // together. CVD_usage_hint = 0x040, // If set, GeomVertexDatas with unanimated vertices will not be // combined with GeomVertexDatas with animated vertices. CVD_animation_type = 0x080, }; enum MakeNonindexed { // If set, only composite primitives such as tristrips and trifans // will be made nonindexed; simple primitives such as triangles // will be left indexed. MN_composite_only = 0x001, // If set any GeomVertexData with any animation indication will // not be adjusted, whether the animation is to be performed on // the CPU or on the graphics pipe. MN_avoid_animated = 0x002, // If set, any GeomVertexData or Geom with a usage_hint other than // UH_static will not be made nonindexed. MN_avoid_dynamic = 0x004, }; void set_gsg(GraphicsStateGuardianBase *gsg); void clear_gsg(); INLINE GraphicsStateGuardianBase *get_gsg() const; INLINE void set_combine_radius(PN_stdfloat combine_radius); INLINE PN_stdfloat get_combine_radius() const; INLINE void apply_attribs(PandaNode *node, int attrib_types = ~(TT_clip_plane | TT_cull_face | TT_apply_texture_color)); INLINE void apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, int attrib_types, GeomTransformer &transformer); int flatten(PandaNode *root, int combine_siblings_bits); int remove_column(PandaNode *root, const InternalName *column); int make_compatible_state(PandaNode *root); INLINE int make_compatible_format(PandaNode *root, int collect_bits = ~0); void decompose(PandaNode *root); INLINE int collect_vertex_data(PandaNode *root, int collect_bits = ~0); INLINE int make_nonindexed(PandaNode *root, int nonindexed_bits = ~0); void unify(PandaNode *root, bool preserve_order); void remove_unused_vertices(PandaNode *root); INLINE void premunge(PandaNode *root, const RenderState *initial_state); bool check_live_flatten(PandaNode *node); protected: void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, int attrib_types, GeomTransformer &transformer); int r_flatten(PandaNode *grandparent_node, PandaNode *parent_node, int combine_siblings_bits); int flatten_siblings(PandaNode *parent_node, int combine_siblings_bits); bool consider_child(PandaNode *grandparent_node, PandaNode *parent_node, PandaNode *child_node); bool consider_siblings(PandaNode *parent_node, PandaNode *child1, PandaNode *child2); bool do_flatten_child(PandaNode *grandparent_node, PandaNode *parent_node, PandaNode *child_node); PandaNode *do_flatten_siblings(PandaNode *parent_node, PandaNode *child1, PandaNode *child2); PT(PandaNode) collapse_nodes(PandaNode *node1, PandaNode *node2, bool siblings); void choose_name(PandaNode *preserve, PandaNode *source1, PandaNode *source2); int r_remove_column(PandaNode *node, const InternalName *column, GeomTransformer &transformer); int r_make_compatible_state(PandaNode *node, GeomTransformer &transformer); int r_collect_vertex_data(PandaNode *node, int collect_bits, GeomTransformer &transformer, bool format_only); int r_make_nonindexed(PandaNode *node, int collect_bits); void r_unify(PandaNode *node, int max_indices, bool preserve_order); void r_register_vertices(PandaNode *node, GeomTransformer &transformer); void r_decompose(PandaNode *node); void r_premunge(PandaNode *node, const RenderState *state); private: PT(GraphicsStateGuardianBase) _gsg; PN_stdfloat _combine_radius; GeomTransformer _transformer; static PStatCollector _flatten_collector; static PStatCollector _apply_collector; static PStatCollector _remove_column_collector; static PStatCollector _compatible_state_collector; static PStatCollector _collect_collector; static PStatCollector _make_nonindexed_collector; static PStatCollector _unify_collector; static PStatCollector _remove_unused_collector; static PStatCollector _premunge_collector; }; #include "sceneGraphReducer.I" #endif