Parcourir la source

TextGraphic::set_instance_flag()

David Rose il y a 17 ans
Parent
commit
6db2257ca1

+ 23 - 10
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) {

+ 14 - 2
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;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 0
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);

+ 11 - 1
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";
     }
     

+ 23 - 8
panda/src/text/textAssembler.cxx

@@ -27,6 +27,7 @@
 #include "geomVertexFormat.h"
 #include "geomVertexData.h"
 #include "geom.h"
+#include "modelNode.h"
 
 #include <ctype.h>
   
@@ -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);
   }
 }
 

+ 31 - 2
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;
+}

+ 4 - 0
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"