Fixing and shifting Textnode

For the first time I’d dug the P3D core to fix and shift something.
Actually there is an issue in textnode that raises using it coupled with textproperties with different glyphscales: having 2 adjacent rows with a scale smaller than default, we see a lot of space between the lines and if the 2 rows are with scales larger than the default, we see those lines overlapping each other.
Executing this python code you’ll show what I’m talking about:

(…see below the continue of the thread…)

I’m obviously open to critics and suggestions.

Today I’d fixed another couple of issues, that involves paragraph alignment. Actually the behavior is that the text is centered and right aligned to the xz 0,0 coords and this is not a problem we have one block of text with uniform properties e.g. with the same alignment but if we add other property pushes with different alignments the text becomes all messed up. Plus if we take the newline off the \2 push closure the alignment won’t be performed.

Executing this piece of .py, cumulative with the above one, you’ll see what I’m saying:

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.gui.DirectGui import *
import direct.gui.DirectGuiGlobals as DGG
#----
from direct.directtools.DirectGeometry import *
def line2dpusher(coords, color=(.7, .7, .7, .7)):
  if not locals().has_key('lines'):
    lines=render2d.attachNewNode('lines')
    line=LineNodePath(lines)
    line.setColor(*color)
    line.setThickness(1)
  line.reset()
  l=line
  switch=0
  for xz in coords:
    switch=not switch
    if switch: l.moveTo(xz[0], 0, xz[1])
    else: l.drawTo(xz[0], 0, xz[1])
  l.create()
#----
if __name__ == '__main__':
  basescale=.07
  #
  tpGdflt = TextProperties()
  tpGdflt.setGlyphScale(.9)
  tpGbig = TextProperties()
  tpGbig.setGlyphScale(2.)
  tpGsmall = TextProperties()
  tpGsmall.setGlyphScale(.6)
  tpRalign = TextProperties()
  tpRalign.setAlign(TextNode.ARight)
  tpCalign = TextProperties()
  tpCalign.setAlign(TextNode.ACenter)

  tpMgr = TextPropertiesManager.getGlobalPtr()
  tpMgr.setProperties("big", tpGbig)
  tpMgr.setProperties("sml", tpGsmall)
  tpMgr.setProperties("dflt", tpGdflt)
  tpMgr.setProperties("right", tpRalign)
  tpMgr.setProperties("center", tpCalign)
  #
  text=TextNode('tnode')
  t1='''Default text
\1center\1Centered (\\n off push)\2
\1center\1Centered\n\2\1right\1Right aligned (\\n off push)\2
\1right\1Right aligned
\2\1big\1Big glyphscales overlaps on adiacent rows.
\2\1sml\1Using small scales instead leave lot of space from line to line.
\2\1dflt\1Another issue happens nesting glyphs with scales != 1.0 \1sml\1into another \1sml\1and another...\2\2\2
'''
  tn=render.attachNewNode(text)
  tn=render2d.attachNewNode(text)
  #
  ww=1.
  h1=text.calcWidth(ord('M'))
  text.setGlyphScale(basescale)
  h2=text.calcWidth(ord('M'))
  text.setGlyphScale(1.)
  ww3d=(h1*ww)/h2
  tn.setPos(0,0,.8)
  #
  tn.setScale(basescale)
  text.setText(t1)
  #
  text.setWordwrap(ww3d)
  print repr(t1)
  #
  x=0
  line2dpusher(((x,1), (x,-1)),(.0,.7,.0,.7))
  z=0
  line2dpusher(((-1,z), (1,z)),(.7,.0,.0,.7))
  #
  run()

And here the 3 .diff, cumulative as well, of all my fixing around:
this first for textAssembler.cxx

--- text.ori/textAssembler.cxx	2008-05-28 20:38:32.000000000 +0200
+++ text/textAssembler.cxx	2008-10-21 15:53:42.000000000 +0200
@@ -1074,11 +1075,10 @@
 
     // First, assemble all the glyphs of this row.
     PlacedGlyphs row_placed_glyphs;
-    float row_width, line_height;
+    float row_width, line_height, wordwrap;
     TextProperties::Alignment align;
     assemble_row(row, row_placed_glyphs,
-                 row_width, line_height, align);
-
+                 row_width, line_height, align, wordwrap);
     // Now move the row to its appropriate position.  This might
     // involve a horizontal as well as a vertical translation.
     LMatrix4f mat = LMatrix4f::ident_mat();
@@ -1095,20 +1095,23 @@
     _lr[1] = ypos - 0.2f * line_height;
 
     // Apply the requested horizontal alignment to the row.
+    //[fabius] now we put wordwrap into the calculations
     float xpos;
     switch (align) {
     case TextProperties::A_left:
       xpos = 0.0f;
-      _lr[0] = max(_lr[0], row_width);
+      _lr[0] = max(_lr[0], max(row_width, wordwrap));
       break;
 
     case TextProperties::A_right:
       xpos = -row_width;
+      if (wordwrap > row_width) xpos += wordwrap;
       _ul[0] = min(_ul[0], xpos);
       break;
 
     case TextProperties::A_center:
       xpos = -0.5f * row_width;
+      if (wordwrap > row_width) xpos += (wordwrap * 0.5f);
       _ul[0] = min(_ul[0], xpos);
       _lr[0] = max(_lr[0], -xpos);
       break;
@@ -1148,7 +1151,7 @@
 assemble_row(TextAssembler::TextRow &row,
              TextAssembler::PlacedGlyphs &row_placed_glyphs,
              float &row_width, float &line_height, 
-             TextProperties::Alignment &align) {
+             TextProperties::Alignment &align, float &wordwrap) {
   Thread *current_thread = Thread::get_current_thread();
 
   line_height = 0.0f;
@@ -1184,6 +1186,11 @@
 
     // 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();
 
     // And the height of the row is the maximum of all the fonts used
@@ -1192,7 +1199,8 @@
       LVecBase4f frame = graphic->get_frame();
       line_height = max(line_height, frame[3] - frame[2]);
     } else {
-      line_height = max(line_height, font->get_line_height());
+      //[fabius] this is not the right place to calc line height (see below)
+//       line_height = max(line_height, font->get_line_height());
     }
 
     if (character == ' ') {
@@ -1290,7 +1298,9 @@
       }
 
       glyph_scale *= properties->get_glyph_scale();
-
+      //[fabius] a good place to take wordwrap size
+      if (properties->get_wordwrap() > 0.0f)
+        wordwrap = properties->get_wordwrap();
       // Now compute the matrix that will transform the glyph (or
       // glyphs) into position.
       LMatrix4f glyph_xform = LMatrix4f::scale_mat(glyph_scale);
@@ -1345,6 +1355,8 @@
       placement->_properties = properties;
 
       xpos += advance * glyph_scale;
+      //[fabius] the line height is calculated char by char here
+      line_height = max(line_height, font->get_line_height()*glyph_scale);
     }
   }
 
@@ -1364,8 +1376,9 @@
     TextFont *font = properties->get_font();
     nassertv(font != (TextFont *)NULL);
 
-    align = properties->get_align();
-    line_height = max(line_height, font->get_line_height());
+    //[fabius] not here but above
+/*     align = properties->get_align();
+    line_height = max(line_height, font->get_line_height());*/
   }
 }

the second for textAssembler.h

--- text.ori/textAssembler.h	2008-05-28 20:38:32.000000000 +0200
+++ text/textAssembler.h	2008-10-21 10:05:59.000000000 +0200
@@ -195,7 +195,7 @@
   void assemble_row(TextRow &row,
                     PlacedGlyphs &row_placed_glyphs,
                     float &row_width, float &line_height, 
-                    TextProperties::Alignment &align);
+                    TextProperties::Alignment &align, float &wordwrap);
 
   // These interfaces are for implementing cheesy accent marks and
   // ligatures when the font doesn't support them.

an the third for textProperties.cxx

Hoping to be useful other than me.

Excellent work, many thanks! I’ve incorporated your changes.

One further change I made: rather than modifying the definition of setGlyphScale(), which was intended to be relative and I therefore don’t think is broken, I added a new property called setTextScale(), which can be absolute the way you want, in the same way that HTML font sizes are absolute.

David

Actually, I had to revert the changes, sorry.

The problem is that, in changing the meaning of “centered” and “right-justified”, you have broken lots and lots of existing code that relies on the old meaning. We can’t just arbitrarily change the line that the text centers upon without real good reason.

Do you need to change that meaning to make your improvements work?

David

well David, these changes are made for what I told you in other threads as is to fit P3D text into my idea of an html render.
I had to use Textnode and related because I simply don’t know and can’t find any direction in this site on how to add new stuff to the core and as I see it is very complicated to do just reading the sources. I tried to do my mod without shifting existing stuff too much and is a pity to see that isn’t back-compatible.

The change I did is mainly for reasons I explained before, as is, to sum up, that the actual code works just if you got an uniform block of text but not if you mix up things, e.g. using 2 rows with different alignments you ain’t a block of text formatted correctly, expecially when wordwrap is involved. Since I don’t know what you’ve seen of my code applied, I’ll post pictures to show you:

= Actual code =

= My mod =

Anyway, as soon as I finish my html render component I would love to share it to the P3D ppl so the problem to me will be: how to add this C++ stuff into the project, considering also that I touched a crucial component like TextAssembler?

Can you implement a HTML renderer using the original definitions of “center” and “right-justified”? It would be lame to have to have two completely different implementations of TextAssembler, just to support HTML.

There are very good reasons for having “center” and “right” line up along the 0 line, instead of between the margins. In particular, it makes these properties meaningful even when there is only one line of text. It makes it easy, for instance, to center a single line of text within a button, no matter how wide that text is.

David

I agree that would be best to have a unified text management but the answer to your question if I could manage that outside C++ is no, for the reason I tried to explain above, as is that the actual code do not support correctly mixing up formatting properties for different strings in the same text block. Anyway I believe I can find a way to make live both behaviors together, I just need some other time to think over.

Hmm, maybe we just need to add another boolean TextProperty that defines whether the centerline is at (0,0,0) or between the margins.

David

David, check this out: is a quite simple idea I had, considering that at the end is only a problem about indentation: how about to add 2 more alignment constants, e.g ABoxedCenter and ABoxedRight? I could put there the mods to alignment I did.
The remaining issue is about nested scales: can I add another non mandatory parameter to setGlyphScale, called e.g. ‘fixedscale’ that is false by default?

ABoxedCenter and ABoxedRight sounds like a fine solution.

Do you object to having a separate text scale and glyph scale parameter? I think the name “glyph scale” is intended to connote scaling individual glyphs, which is not the same thing as the text scale.

Here’s the patch file from my first application of your changes, including my extension to add text scale and glyph scale. You can apply this to the head of the CVS tree, and build from there.

David

Index: textAssembler.cxx
===================================================================
RCS file: /cvsroot/panda3d/panda/src/text/textAssembler.cxx,v
retrieving revision 1.24
retrieving revision 1.23
diff -u -r1.24 -r1.23
--- textAssembler.cxx	21 Oct 2008 23:34:03 -0000	1.24
+++ textAssembler.cxx	21 Oct 2008 23:21:29 -0000	1.23
@@ -636,7 +636,7 @@
     // A space is a special case.
     TextFont *font = properties.get_font();
     nassertr(font != (TextFont *)NULL, 0.0f);
-    return font->get_space_advance();
+    return font->get_space_advance() * properties.get_glyph_scale() * properties.get_text_scale();
   }
 
   bool got_glyph;
@@ -659,7 +659,7 @@
     advance += second_glyph->get_advance();
   }
 
-  glyph_scale *= properties.get_glyph_scale();
+  glyph_scale *= properties.get_glyph_scale() * properties.get_text_scale();
 
   return advance * glyph_scale;
 }
@@ -672,7 +672,7 @@
 float TextAssembler::
 calc_width(const TextGraphic *graphic, const TextProperties &properties) {
   LVecBase4f frame = graphic->get_frame();
-  return (frame[1] - frame[0]) * properties.get_glyph_scale();
+  return (frame[1] - frame[0]) * properties.get_glyph_scale() * properties.get_text_scale();
 }
 
 #ifndef CPPPARSER  // interrogate has a bit of trouble with wstring.
@@ -1079,11 +1079,10 @@
 
     // First, assemble all the glyphs of this row.
     PlacedGlyphs row_placed_glyphs;
-    float row_width, line_height;
+    float row_width, line_height, wordwrap;
     TextProperties::Alignment align;
     assemble_row(row, row_placed_glyphs,
-                 row_width, line_height, align);
-
+                 row_width, line_height, align, wordwrap);
     // Now move the row to its appropriate position.  This might
     // involve a horizontal as well as a vertical translation.
     LMatrix4f mat = LMatrix4f::ident_mat();
@@ -1100,20 +1099,23 @@
     _lr[1] = ypos - 0.2f * line_height;
 
     // Apply the requested horizontal alignment to the row.
+    //[fabius] now we put wordwrap into the calculations
     float xpos;
     switch (align) {
     case TextProperties::A_left:
       xpos = 0.0f;
-      _lr[0] = max(_lr[0], row_width);
+      _lr[0] = max(_lr[0], max(row_width, wordwrap));
       break;
 
     case TextProperties::A_right:
       xpos = -row_width;
+      if (wordwrap > row_width) xpos += wordwrap;
       _ul[0] = min(_ul[0], xpos);
       break;
 
     case TextProperties::A_center:
       xpos = -0.5f * row_width;
+      if (wordwrap > row_width) xpos += (wordwrap * 0.5f);
       _ul[0] = min(_ul[0], xpos);
       _lr[0] = max(_lr[0], -xpos);
       break;
@@ -1153,7 +1155,7 @@
 assemble_row(TextAssembler::TextRow &row,
              TextAssembler::PlacedGlyphs &row_placed_glyphs,
              float &row_width, float &line_height, 
-             TextProperties::Alignment &align) {
+             TextProperties::Alignment &align, float &wordwrap) {
   Thread *current_thread = Thread::get_current_thread();
 
   line_height = 0.0f;
@@ -1189,6 +1191,11 @@
 
     // 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();
 
     // And the height of the row is the maximum of all the fonts used
@@ -1197,7 +1204,8 @@
       LVecBase4f frame = graphic->get_frame();
       line_height = max(line_height, frame[3] - frame[2]);
     } else {
-      line_height = max(line_height, font->get_line_height());
+      //[fabius] this is not the right place to calc line height (see below)
+//       line_height = max(line_height, font->get_line_height());
     }
 
     if (character == ' ') {
@@ -1220,7 +1228,7 @@
       placement->_graphic_model = graphic->get_model().node();
 
       LVecBase4f frame = graphic->get_frame();
-      float glyph_scale = properties->get_glyph_scale();
+      float glyph_scale = properties->get_glyph_scale() * properties->get_text_scale();
 
       float advance = (frame[1] - frame[0]);
 
@@ -1294,8 +1302,11 @@
         advance += second_glyph->get_advance();
       }
 
-      glyph_scale *= properties->get_glyph_scale();
-
+      glyph_scale *= properties->get_glyph_scale() * properties->get_text_scale();
+      //[fabius] a good place to take wordwrap size
+      if (properties->get_wordwrap() > 0.0f) {
+        wordwrap = properties->get_wordwrap();
+      }
       // Now compute the matrix that will transform the glyph (or
       // glyphs) into position.
       LMatrix4f glyph_xform = LMatrix4f::scale_mat(glyph_scale);
@@ -1350,6 +1361,8 @@
       placement->_properties = properties;
 
       xpos += advance * glyph_scale;
+      //[fabius] the line height is calculated char by char here
+      line_height = max(line_height, font->get_line_height()*glyph_scale);
     }
   }
 
@@ -1369,8 +1382,9 @@
     TextFont *font = properties->get_font();
     nassertv(font != (TextFont *)NULL);
 
-    align = properties->get_align();
-    line_height = max(line_height, font->get_line_height());
+    //[fabius] not here but above
+/*     align = properties->get_align();
+    line_height = max(line_height, font->get_line_height());*/
   }
 }
   
Index: textAssembler.h
===================================================================
RCS file: /cvsroot/panda3d/panda/src/text/textAssembler.h,v
retrieving revision 1.16
retrieving revision 1.15
diff -u -r1.16 -r1.15
--- textAssembler.h	21 Oct 2008 23:34:03 -0000	1.16
+++ textAssembler.h	21 Oct 2008 23:21:29 -0000	1.15
@@ -195,7 +195,7 @@
   void assemble_row(TextRow &row,
                     PlacedGlyphs &row_placed_glyphs,
                     float &row_width, float &line_height, 
-                    TextProperties::Alignment &align);
+                    TextProperties::Alignment &align, float &wordwrap);
 
   // These interfaces are for implementing cheesy accent marks and
   // ligatures when the font doesn't support them.
Index: textProperties.I
===================================================================
RCS file: /cvsroot/panda3d/panda/src/text/textProperties.I,v
retrieving revision 1.6
retrieving revision 1.5
diff -u -r1.6 -r1.5
--- textProperties.I	21 Oct 2008 23:34:03 -0000	1.6
+++ textProperties.I	21 Oct 2008 23:21:29 -0000	1.5
@@ -850,9 +850,18 @@
 //     Function: TextProperties::set_glyph_scale
 //       Access: Published
 //  Description: Specifies the factor by which to scale each letter of
-//               the text as it is placed.  This can be used (possibly
-//               in conjunction with set_glyph_shift()) to implement
-//               superscripting or subscripting.
+//               the text as it is placed, in addition to any scales
+//               inherited from the node or from set_text_scale().
+//               This can be used (possibly in conjunction with
+//               set_glyph_shift()) to implement superscripting or
+//               subscripting.
+//
+//               The glyph scale is cumulative when applied to nested
+//               TextProperties.  It is intended primarily for
+//               implementing superscripts, not for scaling the text
+//               in general.  See also set_text_scale(), which is
+//               intended primarily for scaling the text in general,
+//               and is not cumulative.
 ////////////////////////////////////////////////////////////////////
 INLINE void TextProperties::
 set_glyph_scale(float glyph_scale) {
@@ -937,3 +946,52 @@
 get_glyph_shift() const {
   return _glyph_shift;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextProperties::set_text_scale
+//       Access: Published
+//  Description: Specifies the factor by which to scale the text, in
+//               addition to any scalings imposed by the node, as well
+//               as in addition to the glyph scale.
+//
+//               The text scale is not cumulative when applied to
+//               nested TextProperties.  See also set_glyph_scale(),
+//               which is cumulative.
+////////////////////////////////////////////////////////////////////
+INLINE void TextProperties::
+set_text_scale(float text_scale) {
+  _text_scale = text_scale;
+  _specified |= F_has_text_scale;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextProperties::clear_text_scale
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void TextProperties::
+clear_text_scale() {
+  _specified &= ~F_has_text_scale;
+  _text_scale = 0.0f;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextProperties::has_text_scale
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE bool TextProperties::
+has_text_scale() const {
+  return (_specified & F_has_text_scale) != 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextProperties::get_text_scale
+//       Access: Published
+//  Description: Returns the scale factor of the text as specified
+//               by set_text_scale().
+////////////////////////////////////////////////////////////////////
+INLINE float TextProperties::
+get_text_scale() const {
+  return _text_scale;
+}
Index: textProperties.cxx
===================================================================
RCS file: /cvsroot/panda3d/panda/src/text/textProperties.cxx,v
retrieving revision 1.10
retrieving revision 1.9
diff -u -r1.10 -r1.9
--- textProperties.cxx	21 Oct 2008 23:34:03 -0000	1.10
+++ textProperties.cxx	21 Oct 2008 23:21:29 -0000	1.9
@@ -50,6 +50,7 @@
   _tab_width = text_tab_width;
   _glyph_scale = 1.0f;
   _glyph_shift = 0.0f;
+  _text_scale = 1.0f;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -89,6 +90,7 @@
   _tab_width = copy._tab_width;
   _glyph_scale = copy._glyph_scale;
   _glyph_shift = copy._glyph_shift;
+  _text_scale = copy._text_scale;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -159,6 +161,9 @@
   if ((_specified & F_has_glyph_shift) && _glyph_shift != other._glyph_shift) {
     return false;
   }
+  if ((_specified & F_has_text_scale) && _text_scale != other._text_scale) {
+    return false;
+  }
   return true;
 }
 
@@ -227,15 +232,19 @@
     set_tab_width(other.get_tab_width());
   }
 
-
   // The glyph scale and shift are a special case: rather than
-  // replacing the previous value, they modify it.
+  // replacing the previous value, they modify it, so that they apply
+  // cumulatively to nested TextProperties.
   if (other.has_glyph_shift()) {
     set_glyph_shift(other.get_glyph_shift() * get_glyph_scale() + get_glyph_shift());
   }
   if (other.has_glyph_scale()) {
     set_glyph_scale(other.get_glyph_scale() * get_glyph_scale());
   }
+
+  if (other.has_text_scale()) {
+    set_text_scale(other.get_text_scale());
+  }
 }
 
 
@@ -344,6 +353,11 @@
     indent(out, indent_level)
       << "glyph shift is " << get_glyph_shift() << "\n";
   }
+
+  if (has_text_scale()) {
+    indent(out, indent_level)
+      << "text scale is " << get_text_scale() << "\n";
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
Index: textProperties.h
===================================================================
RCS file: /cvsroot/panda3d/panda/src/text/textProperties.h,v
retrieving revision 1.7
retrieving revision 1.6
diff -u -r1.7 -r1.6
--- textProperties.h	21 Oct 2008 23:34:03 -0000	1.7
+++ textProperties.h	21 Oct 2008 23:21:29 -0000	1.6
@@ -157,6 +157,11 @@
   INLINE bool has_glyph_shift() const;
   INLINE float get_glyph_shift() const;
 
+  INLINE void set_text_scale(float text_scale);
+  INLINE void clear_text_scale();
+  INLINE bool has_text_scale() const;
+  INLINE float get_text_scale() const;
+
   void add_properties(const TextProperties &other);
 
   void write(ostream &out, int indent_level = 0) const;
@@ -183,6 +188,7 @@
     F_has_glyph_shift                  = 0x00008000,
     F_has_underscore                   = 0x00010000,
     F_has_underscore_height            = 0x00020000,
+    F_has_text_scale                   = 0x00040000,
   };
 
   int _specified;
@@ -205,6 +211,7 @@
   float _tab_width;
   float _glyph_scale;
   float _glyph_shift;
+  float _text_scale;
 
   static PT(TextFont) _default_font;
   static bool _loaded_default_font;

This makes more since:

Because its unknown how big the area is. one can write simple routines to convert one into another but this 1st one makes since from general perspective, because this is not HTML when i say center i want the text to center relative to itself not some thing else.

Oh and a little off topic feature request since we are talking about text. How hard would it be to make a logical clip planes for text? For instance i if tell the “logical clip region” to be 100x100 it would only generate geometry in that location and would cut geometry at half letters and cut off bottoms if have too. I am using clip planes to produce this effect now but the problem is that if i have 50 text boxes like that on screen FPS significantly drops because #1 i cant flatten all the text into one goem (because of clip planes would stop working) and #2 the clip planes them selfs have to be reset at every node point. Creating logical clip plane that would prevent geometry generation would fantastic.

you’re right, like that is more appropriate.

where do I find P3D CVS connection parameters for my client?

You can find that here:
sourceforge.net/cvs/?group_id=38909

You can also browse the online CVS here if you quickly want to find a file or fix:
panda3d.cvs.sourceforge.net/panda3d/

Don’t make you slide off by the fact I’m doin’ an html renderer treeform, or you’ll miss the point that is just a different way to manage text: the actual is paragraph-centric and the other is document-centric. Nobody deny you to center text in the other way (see 2nd pic) and then center the whole frame to 0,0,0 - it is just a matter of a simple 0.5width 0.5height calculation overhead but then you have great potential under the hood opening panda not just to do simple text banners but very complex and nice formatted text pages and in my vision a lot more, such as input forms and so on, and all with great productivity. Try to do what you see above in the 2nd pic with the actual Textnode code and then tell me if was that easy.

I would push more this question, since is lot of time I’m thinking about: considering that text 99% of times is almost static geometry, wouldn’t be better, as an alternative, to render the text glyphs geometry directly over a texture and then get rid of 'em freeing them out since we don’t need 'em until we gotta modify the text content again?

Thankyou pro-soft appreciated it.

Not terribly easy, but for a long time I’ve been wanting to add a feature to support logical clip planes for geometry in general. That hasn’t happened yet, but it still might one day, and when it does it could be applied to text as well as to anything else.

Why can’t you flatten the text? You mean because all of your text nodes have different clip planes?

Note that there is a new feature on the CVS trunk, nodePath.setScissor(), which allows you to set a scissor region in screen space or in node space. This may be closer to what you’re aiming for with the clip planes here.

This is debatable. It might be better, but it might be worse. Rendering the whole paragraph into a texture consumes additional texture memory, and requires more time to generate and upload the texture. Modern graphics cards can render 10,000 vertices as fast as 4 (as long as they’re all in the same node), so saving a few thousand vertices doesn’t generally buy you much, if anything. (The story is different on an integrated graphics card–there, every vertex counts, and texture memory is often unified with system memory, so that’s cheaper.)

David

setScissor is a great addition, thats what i wanted originally and will try it out. Which might solve some of the problem with speed. But i still would have 50 different text nodes instead of one. Also text is much easer to clip because they are all quads while just any geometry is hard (triangles turning into 2 triangles and uv/normal computation would be just crazy.

In my aff:star city game i have buildings and i want the text above them to be centered there is no paragraph because the text is floating in 3d always facing the player. Center makes more sense in that case.

I’m experiencing difficulties building from CVS, some advice needed:

the error popped out is:

Generating dependencies...
g++ -o built/bin/p3dcparse -Lbuilt/lib -L/usr/X11R6/lib built/tmp/dcparse_dcparse.o -lp3direct -lpanda -lpandaexpress -lp3dtool -lp3dtoolconfig -lp3pystub -lpthread -ldl
built/lib/libp3direct.so: undefined reference to `PyExc_RuntimeError'
collect2: ld returned 1 exit status
Storing dependency cache.

do I’d to start the HEAD checkout over a 1.5.3 source? I tellya 'cos I’d found at the beginning some important stuff missing as the whole thirdparty folder.

Weird, that looks like it’s not in the pystub file. I just checked in a fix; can you “cvs update” the dtool/src/pystub/pystub.cxx file and try again?

About the thirdparty thing, it’s generally not a good idea to cvs checkout over an old 1.5.3 copy. Instead, download just the thirdparty dir from the 1.5.3 download page and place it in the panda3d source root.
Also, you will need the samples, or you can also create an empty “samples” dir. You do need a samples dir otherwise makepanda will choke.

pro-rsoft, the fix unlocked the situation but now it’s stucked again:

built/bin/genpycode
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/uzzo/Work/c/panda/CVS/panda3d/built/direct/../../direct/src/ffi/jGenPyCode.py", line 74, in <module>
    from direct.ffi import DoGenPyCode
  File "/home/uzzo/Work/c/panda/CVS/panda3d/built/direct/../../direct/src/ffi/DoGenPyCode.py", line 11, in <module>
    from direct.ffi import FFIConstants
  File "/home/uzzo/Work/c/panda/CVS/panda3d/built/direct/../../direct/src/ffi/FFIConstants.py", line 3, in <module>
    from direct.directnotify.DirectNotifyGlobal import *
  File "/home/uzzo/Work/c/panda/CVS/panda3d/built/direct/../../direct/src/directnotify/DirectNotifyGlobal.py", line 3, in <module>
    import DirectNotify
  File "/home/uzzo/Work/c/panda/CVS/panda3d/built/direct/../../direct/src/directnotify/DirectNotify.py", line 5, in <module>
    import Notifier
  File "/home/uzzo/Work/c/panda/CVS/panda3d/built/direct/../../direct/src/directnotify/Notifier.py", line 6, in <module>
    from direct.showbase import PythonUtil
  File "/home/uzzo/Work/c/panda/CVS/panda3d/built/direct/../../direct/src/showbase/PythonUtil.py", line 51, in <module>
    import profile
ImportError: No module named profile
Storing dependency cache.

wazzup now?