From 6db2257ca12612d47d37cc9896fd083c987c6c11 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 28 Oct 2008 21:36:26 +0000 Subject: [PATCH] TextGraphic::set_instance_flag() --- panda/src/pgraph/modelNode.I | 33 ++++++++++++++++++-------- panda/src/pgraph/modelNode.cxx | 16 +++++++++++-- panda/src/pgraph/modelNode.h | 2 ++ panda/src/pgraph/sceneGraphReducer.cxx | 12 +++++++++- panda/src/text/textAssembler.cxx | 31 +++++++++++++++++------- panda/src/text/textGraphic.I | 33 ++++++++++++++++++++++++-- panda/src/text/textGraphic.h | 4 ++++ 7 files changed, 108 insertions(+), 23 deletions(-) diff --git a/panda/src/pgraph/modelNode.I b/panda/src/pgraph/modelNode.I index f3e1541843..0bbe313477 100644 --- a/panda/src/pgraph/modelNode.I +++ b/panda/src/pgraph/modelNode.I @@ -32,21 +32,34 @@ ModelNode(const string &name) : // Access: Public // Description: Sets the preserve_transform flag. This restricts the // ability of a flatten operation to affect the -// transform stored on this node. If the flag is: +// transform stored on this node, and/or the node +// itself. In the order from weakest to strongest +// restrictions, the possible flags are: // -// PT_none - the transform may be adjusted at will. +// PT_drop_node - This node should be removed at the +// next flatten call. // -// PT_local - the local (and net) transform should not +// PT_none - The transform may be adjusted at will. The +// node itself will not be removed. This is the +// default. +// +// PT_net - Preserve the net transform from the root, +// but it's acceptable to modify the local transform +// stored on this particular node if necessary, so long +// as the net transform is not changed. This eliminates +// the need to drop an extra transform on the node +// above. +// +// PT_local - The local (and net) transform should not // be changed in any way. If necessary, an extra // transform will be left on the node above to guarantee -// this. This is the strongest restriction. +// this. This is a stronger restriction than PT_net. // -// PT_net - preserve the net transform from the -// root, but it's acceptable to modify the local -// transform stored on this particular node if -// necessary, so long as the net transform is not -// changed. This eliminates the need to drop an extra -// transform on the node above. +// PT_no_touch - The local transform will not be +// changed, the node will not be removed, and +// furthermore any flatten operation will not continue +// below this node--this node and all descendents are +// protected from the effects of flatten. //////////////////////////////////////////////////////////////////// INLINE void ModelNode:: set_preserve_transform(ModelNode::PreserveTransform preserve_transform) { diff --git a/panda/src/pgraph/modelNode.cxx b/panda/src/pgraph/modelNode.cxx index b2b45a4c45..b07678f507 100644 --- a/panda/src/pgraph/modelNode.cxx +++ b/panda/src/pgraph/modelNode.cxx @@ -74,6 +74,18 @@ safe_to_flatten() const { return _preserve_transform == PT_drop_node; } +//////////////////////////////////////////////////////////////////// +// Function: ModelNode::safe_to_flatten_below +// Access: Public, Virtual +// Description: Returns true if a flatten operation may safely +// continue past this node, or false if nodes below this +// node may not be molested. +//////////////////////////////////////////////////////////////////// +bool ModelNode:: +safe_to_flatten_below() const { + return _preserve_transform != PT_no_touch; +} + //////////////////////////////////////////////////////////////////// // Function: ModelNode::safe_to_transform // Access: Public, Virtual @@ -101,7 +113,7 @@ safe_to_transform() const { //////////////////////////////////////////////////////////////////// bool ModelNode:: safe_to_modify_transform() const { - return _preserve_transform != PT_local; + return _preserve_transform != PT_local && _preserve_transform != PT_no_touch; } //////////////////////////////////////////////////////////////////// @@ -128,7 +140,7 @@ safe_to_combine() const { //////////////////////////////////////////////////////////////////// bool ModelNode:: preserve_name() const { - return _preserve_transform != PT_drop_node; + return _preserve_transform != PT_drop_node && _preserve_transform != PT_no_touch; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/modelNode.h b/panda/src/pgraph/modelNode.h index 81ab574a63..930d8cc6fc 100644 --- a/panda/src/pgraph/modelNode.h +++ b/panda/src/pgraph/modelNode.h @@ -43,6 +43,7 @@ public: virtual PandaNode *combine_with(PandaNode *other); virtual bool safe_to_flatten() const; + virtual bool safe_to_flatten_below() const; virtual bool safe_to_transform() const; virtual bool safe_to_modify_transform() const; virtual bool safe_to_combine() const; @@ -55,6 +56,7 @@ PUBLISHED: PT_local, PT_net, PT_drop_node, + PT_no_touch, }; INLINE void set_preserve_transform(PreserveTransform preserve_transform); diff --git a/panda/src/pgraph/sceneGraphReducer.cxx b/panda/src/pgraph/sceneGraphReducer.cxx index a810ff5e8d..27696e1e9e 100644 --- a/panda/src/pgraph/sceneGraphReducer.cxx +++ b/panda/src/pgraph/sceneGraphReducer.cxx @@ -290,6 +290,16 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, // Check to see if we can't propagate any of these attribs past // this node for some reason. + if (!node->safe_to_flatten_below()) { + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() + << "Not applying further; " << *node + << " doesn't allow flattening below itself.\n"; + } + next_attribs.apply_to_node(node, attrib_types); + return; + } + int apply_types = 0; const RenderEffects *effects = node->get_effects(); @@ -414,7 +424,7 @@ r_flatten(PandaNode *grandparent_node, PandaNode *parent_node, if (!parent_node->safe_to_flatten_below()) { if (pgraph_cat.is_spam()) { pgraph_cat.spam() - << "Not traversing farther; " << *parent_node + << "Not traversing further; " << *parent_node << " doesn't allow flattening below itself.\n"; } diff --git a/panda/src/text/textAssembler.cxx b/panda/src/text/textAssembler.cxx index 1fc4b15aba..2f547dacd0 100644 --- a/panda/src/text/textAssembler.cxx +++ b/panda/src/text/textAssembler.cxx @@ -27,6 +27,7 @@ #include "geomVertexFormat.h" #include "geomVertexData.h" #include "geom.h" +#include "modelNode.h" #include @@ -1208,12 +1209,13 @@ assemble_row(TextAssembler::TextRow &row, // We get the row's alignment property from that of the last // character to be placed in the row (or the newline character). - //[fabius] differently as stated above this is not a sure way to get it so we'll set it as soon as we found it - if ( - (align == TextProperties::A_left) && - (properties->get_align() != TextProperties::A_left) - ) - align = properties->get_align(); + + //[fabius] differently as stated above this is not a sure way to + //get it so we'll set it as soon as we found it + if ((align == TextProperties::A_left) && + (properties->get_align() != TextProperties::A_left)) { + align = properties->get_align(); + } // And the height of the row is the maximum of all the fonts used // within the row. @@ -1242,7 +1244,20 @@ assemble_row(TextAssembler::TextRow &row, GlyphPlacement *placement = new GlyphPlacement; row_placed_glyphs.push_back(placement); - placement->_graphic_model = graphic->get_model().node(); + PT(PandaNode) model = graphic->get_model().node(); + if (graphic->get_instance_flag()) { + // Instance the model in. Create a ModelNode so it doesn't + // get flattened. + PT(ModelNode) model_node = new ModelNode(""); + model_node->set_preserve_transform(ModelNode::PT_no_touch); + model_node->add_child(model); + placement->_graphic_model = model_node.p(); + } else { + // Copy the model in. This the preferred way; it's a little + // cheaper to render than instancing (because flattening is + // more effective). + placement->_graphic_model = model->copy_subgraph(); + } LVecBase4f frame = graphic->get_frame(); float glyph_scale = properties->get_glyph_scale() * properties->get_text_scale(); @@ -2061,7 +2076,7 @@ copy_graphic_to(PandaNode *node, const RenderState *state, intermediate_node->set_transform(TransformState::make_mat(new_xform)); intermediate_node->set_state(state); - intermediate_node->add_child(_graphic_model->copy_subgraph()); + intermediate_node->add_child(_graphic_model); } } diff --git a/panda/src/text/textGraphic.I b/panda/src/text/textGraphic.I index 94334badf0..874262e190 100644 --- a/panda/src/text/textGraphic.I +++ b/panda/src/text/textGraphic.I @@ -21,6 +21,7 @@ INLINE TextGraphic:: TextGraphic() { _frame = LVecBase4f::zero(); + _instance_flag = false; } //////////////////////////////////////////////////////////////////// @@ -31,7 +32,8 @@ TextGraphic() { INLINE TextGraphic:: TextGraphic(const NodePath &model, const LVecBase4f &frame) : _model(model), - _frame(frame) + _frame(frame), + _instance_flag(false) { } @@ -43,7 +45,8 @@ TextGraphic(const NodePath &model, const LVecBase4f &frame) : INLINE TextGraphic:: TextGraphic(const NodePath &model, float left, float right, float bottom, float top) : _model(model), - _frame(left, right, bottom, top) + _frame(left, right, bottom, top), + _instance_flag(false) { } @@ -110,3 +113,29 @@ INLINE void TextGraphic:: set_frame(float left, float right, float bottom, float top) { _frame.set(left, right, bottom, top); } + +//////////////////////////////////////////////////////////////////// +// Function: TextGraphic::get_instance_flag +// Access: Published +// Description: Returns the instance_flag. See set_instance_flag(). +//////////////////////////////////////////////////////////////////// +INLINE bool TextGraphic:: +get_instance_flag() const { + return _instance_flag; +} + +//////////////////////////////////////////////////////////////////// +// Function: TextGraphic::set_instance_flag +// Access: Published +// Description: Sets the instance_flag. When this is true, the +// graphic is directly instanced to the scene graph +// whenever it appears; when it is false, the graphic is +// copied. The default is false, which is best for most +// applications. You might need to set it true for +// special kinds of "graphics" like interactive +// elements, for instance a PGEntry. +//////////////////////////////////////////////////////////////////// +INLINE void TextGraphic:: +set_instance_flag(bool instance_flag) { + _instance_flag = instance_flag; +} diff --git a/panda/src/text/textGraphic.h b/panda/src/text/textGraphic.h index 2f44f2beaf..0761e7ef10 100644 --- a/panda/src/text/textGraphic.h +++ b/panda/src/text/textGraphic.h @@ -53,9 +53,13 @@ PUBLISHED: INLINE void set_frame(const LVecBase4f &frame); INLINE void set_frame(float left, float right, float bottom, float top); + INLINE bool get_instance_flag() const; + INLINE void set_instance_flag(bool instance_flag); + private: NodePath _model; LVecBase4f _frame; + bool _instance_flag; }; #include "textGraphic.I"