What are the “screen units”, in which are measured TextNode card dimentions ( TextNode.set(/get)CardActual(l, r, b, t) ), how to convert they to the aspect2d(render2d) coordinates ?
O…k, little explanation, i attach TextNode to DirectFrame and want to set dynamic wordwrap in respect to changing of frame size, advise me any way to do that.
I too, would like to know how to either: a. Get each character’s height/width or b. Dynamically wrap a textnode based off a frameSize/bounds and be able to determine the height of the wrapped lines.
Any help for us?
powerpup118,
a) TextNode.calcWidth(wchar_t character),TextNode.getLineHeight() …
b)TextNode.getCardActual()
isn’t this ?
The best way to get the bounds of the TextNode is via TextNode.getHeight() and TextNode.getWidth(). You can also get the absolute positions with getLeft(), getRight(), getBottom(), getTop().
For wordwrapping, don’t overlook TextNode.setWordwrap(), which folds the line at the specified width. Then you can use TextNode.getHeight() to figure out how many lines you ended up with.
David
selfanswer: “screen units” are the 2d-units (aspect2d), convertion not needed. Size of text managed by NodePath scale. TextNode return unscaled data (f.e. TextNode.getCardActual()); left, right, wordwarp etc. must be scaled to NodePath scale.
zumodrive.com/share/90P8MjI3YT
- TextNode (def showText3) and OnscreenText (def showText2) scaled to equal width, TextNode_scale = 0.41 Onscreen_scale=0.375 - why they are different (tested with equal content)?
- DirectFrame parented to the TextNode and to the OnscreenText are of same size (def showText3, def showText2), TextNode_DirectFrame scaled with parent but Onscreen_DirectFrame is not, why ?
- TextNode_vert_size=(0.08+0.33)/0.41=1=OnscreenText _vert_size, text1_vert_size=0.23+0.92=1.15 - why they are diferent, i expect 1, may be font ?
You can inspect the code for OnscreenText yourself; it’s quite simple. Perhaps that can help you understand what it’s doing with the scale. Note that OnscreenText is implemented with a TextNode, which you’ll find in self.textNode.
David
[color=red]NEW QUESTION
I need to move objects - mrk, mrk1. Them coordinates are changed, but objects visually are stay at place. Whats wrong?
import copy as pyCopy
from panda3d.core import TextNode, PandaNode, NodePath, GeomNode, Texture
from panda3d.core import VBase3, VBase4, BoundingBox, Point3, CardMaker
from direct.showbase.ShowBase import ShowBase
print
app=ShowBase('main_app')
text='Example: text without wordwrap,\nthis text is only for test\npurposes.'
class TextLabel(TextNode):
def __init__(self, content=text):
TextNode.__init__(self,'test_text')
txt_np=aspect2d.attachNewNode(self)
self.setText(content)
self.setTextColor(0,0.6,0.4,1)
self.setCardAsMargin(0.0,0.0,0.0,0.0)
self.setBoundsType(BoundingBox.BTBox)
self.orientByNP()
#self.opientByPN()
print 'text node: ', self.getName()
txt_pos=PandaNode.getTransform(self)
print 'text Transform: ', str(txt_pos)[:-1]
def orientByNP(self):
np=NodePath(self)
np.setScale(VBase3(0.1,0.1,0.1))
np.setPos(VBase3(-0.5,0,0.5))
#np.flattenLight()
def opientByPN(self):
txt_pos=PandaNode.getTransform(self)
txt_pos=txt_pos.setScale(0.1)
txt_pos=txt_pos.setPos(VBase3(-0.5,0,0.5))
print txt_pos.getPos()
PandaNode.setTransform(self, txt_pos)
class Marker(GeomNode):
def __init__(self, name='dot', clr=(0.9,0,0,1)):
PandaNode.__init__(self, name)
tmp=CardMaker(name)
tmp.setColor(clr)
tmp.setFrame(-0.01,0.01,-0.01,0.01)
self=tmp.generate()
mnp=aspect2d.attachNewNode(self)
print self
print 'marker initial position: ', mnp.getPos()
def moveTo(self, np=None):
if np is None: return
mnp=NodePath(self)
mnp.setPos(np.getPos())
print 'new marker position: ', mnp.getPos()
lblTxt=NodePath(TextLabel())
print 'Bounds of Txt: ', lblTxt.getTightBounds()
lblTxt.showTightBounds()
mrk=Marker()
mrk1=Marker(clr=(0.3,0,8,1))
#mrk.moveTo(lblTxt)
NodePath(mrk).setPos(-0.7, 0, -0.5)
NodePath(mrk1).setPos(aspect2d,-0.7, 0, -0.5)
app.run()
self=tmp.generate()
This line does not change the current instance. All it does is change the value of “self” from the current instance to this new thing. So mrk and mrk1 both remain an empty GeomNode, while you create a new GeomNode onscreen that you don’t keep a handle to.
You shouldn’t be subclassing GeomNode anyway; that will lead to heartache later. Instead, create an object that doesn’t subclass GeomNode, but stores a pointer to a GeomNode within it. That will be much more reliable, and it will work the way you expect it to.
David
Yes, it was somehow not very ). New vertion:
class Marker(PandaNode):
def __init__(self, name='dot', clr=(0.9,0,0,1)):
PandaNode.__init__(self, name)
tmp=CardMaker(name)
. . .
self.addChild(tmp.generate())
mnp=aspect2d.attachNewNode(self)
. . .
The following TextNode methods do not account for the transformation:
getCardActual(), getFrameActual(), getLeft(),getTop(), getUpperLeft3d(), setWordwrap()…
I’ll have to make corrections (for transformation) when reading/setting values or is there a more comfortable way?
See getCardTransformed() and getUpperLeft3d()/getLowerRight3d().
Also note that I don’t recommend subclassing from PandaNode in Python, for the same reason I don’t recommend subclassing from GeomNode. You can do what you want, though.
David
What are the heartache await for me with this approach (subclassing from PandaNode in Python)? It concerns all classes of panda3d.core excluding NodePath, does not concern classes in panda3d.direct.xxx ?
Mmm, turns out I have already seen, when inherited TextNode.
Thanx