202 lines
7.2 KiB
C
202 lines
7.2 KiB
C
|
/**
|
||
|
* 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."
|
||
|
*
|
||
|
* @file sceneGraphReducer.h
|
||
|
* @author drose
|
||
|
* @date 2002-03-14
|
||
|
*/
|
||
|
|
||
|
#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;
|
||
|
|
||
|
/**
|
||
|
* 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 explicit SceneGraphReducer(GraphicsStateGuardianBase *gsg = nullptr);
|
||
|
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
|