updating 3d text

I am trying to render some text (one word strings) from MySQL database in 3D. Don’t know if this is a right way to go, but at this moment I got:

  1. a task that is fetching data from my database (column 1 - word I want to render - this might be change via PHP web interface from time to time; column 4 - position on the screen; ).
  2. inside the same task (to keep my 3d world up to date with the database) I am rendering my “string” and repositioning it according to “pos” from database.

All works great, apart when I change my string in the database a new one is overlaying old version, rather than replacing it. Already tried to removeNode etc. but no luck so far. Any suggestions would be very much appreciated. Below is my code:

def makeText(string,pos):
…text = TextNode(‘text’)
…text.setText(string)
…text3d = NodePath(text)
…text3d.reparentTo(render)
…text3d.setPos(0,0,pos*3)

def mainLoop(task):
…query = con.execute(‘select title,id from sales ORDER BY id ASC’)
…rows = con.rowcount
…i = 0
…while i < rows:
…result = con.fetchone()
…string = result[0]
…pos = result[1]
…i=i+1
…makeText(string,pos)
…return Task.cont

taskMgr.add(mainLoop,“readData”)

run()

Your makeText() function is creating a new TextNode every time it is called. If you want to avoid accumulating these TextNodes, you will have to keep a handle to the TextNode (or its NodePath), and either re-use it by calling setText() on the same TextNode object, or destroy the old one by calling removeNode on its NodePath.

In any case, the key is to keep a handle to the TextNode from one pass to the next. For instance, you could return it from the previous call to makeText(), and pass it back in again the next time.

David

David,

thanks a lot for you reply. I am aware this is more Pyton related question rather than Panda3d itself, but I just tried to change my code to add unique names, that can be deleted/updated every time makeText function is called. I ended up with this error:

text+str(n) = TextNode(‘text’)
SyntaxError: can’t assign to operator

Any help would be very much appreciated. Below is my new code:

n = 0

def makeText(n,string,pos):
…text+str(n) = TextNode(‘text’)
…text+str(n).setText(string)
…text3d = NodePath(text+str(n))
…text3d.reparentTo(render)
…text3d.setPos(0,0,pos*3)

def mainLoop(task):
…global n
…n=n+1
…query = con.execute(‘select title,id from sales ORDER BY id ASC’)
…rows = con.rowcount
…i = 0
…while i < rows:
…result = con.fetchone()
…string = result[0]
…pos = result[1]
…i=i+1
…print n
…makeText(n,string,pos)
…return Task.cont

taskMgr.add(mainLoop,“readData”)

run()

You can’t construct variable names that way. If you wanted, you could store all of your TextNodes in a big global dictionary, something like:

nodes = {}
def makeText(n,string,pos):
..nodes[n] = TextNode('text')
..nodes[n].setText(string)
..text3d = NodePath(nodes[n])
..text3d.reparentTo(render)
..text3d.setPos(0,0,pos*3) 

Note that this still suffers from the same problem of not clearing the previous TextNode; it will simply overwrite the previous entry in the dictionary, without first removing it from the screen. Instead, you should write your function something like this:

nodes = {}
def makeText(n,string,pos):
..tn = nodes.get(n, None)
..if tn == None:
....tn = TextNode('text')
....nodes[n] = tn
..tn.setText(string)
..text3d = NodePath(tn)
..text3d.reparentTo(render)
..text3d.setPos(0,0,pos*3) 

David

Thanks again.

Dictionart of NodePaths works great. Actaully I decided to keep my n (renamed to uid) in MySQL database as auto_increment value for each new/modified “object”. So database keeps track of uniqu id of each node now.

Cheers