textnode over model

Hello,

I am programming a space game with space ships. I wish to have the name of the player over the spaceship.
What are your preconisations? A textnode?
How can I manage this efficiently?

thank you

I’d use a DirectFrame with a text, but a TextNode is just as good.
If the spaceship is ‘self.model’ and the text label is ‘self.gui’ you can use something like this:

taskMgr.doMethodLater(.1, self._update, 'updateTask')
    def _update(self, task=None):               
        p3 = base.cam.getRelativePoint(render, self.model.getPos(render))
        p2 = Point2()
        newPos=(0,0,0)
        if base.camLens.project(p3, p2):
            r2d = Point3(p2[0], 0, p2[1])
            newPos = pixel2d.getRelativePoint(render2d, r2d) 
        LerpPosInterval(self.gui, 0.1, newPos).start()               
        return task.again

The LerpPosInterval can be kicked out if you don’t want the label to lag behind, but then you would have to update the task each frame not just every now and then.

Yeah I knew this solution, but I am afraid it costs too many if there are many ships at screen on same time.

I was wondering, it was possible to create a node (textnode?) attached (reparent) to the ship node. So it follows the ship, calculated by panda, not by me.

Is it possible?

A billboard or compass effect could help, but if the text is attached to the 3d model then it will get bigger as the ship comes near and smaller as it gets far… a crazy idea I just had is to make a buffer with a orthographic camera and such a mask that it only renders the labels it could be faster then getting the relative point for each ship if you have 100+ ships.

I’d suggest to try the simplest thing that could possibly work and optimize it only if it really is a bottleneck.

my code

C_USER_WIDTH=1280
C_USER_HEIGHT=720
C_RATIO=float(float(C_USER_WIDTH)/float(C_USER_HEIGHT))

self.textObject = OnscreenText(text = "this is my ship", pos = (-0.95, 0.95), scale = 0.03,fg=(1,1,1,1))
nShip=ship.getNode()
		
if isInView(nShip)!=True: 
	self.textObject.hide() 
else: 
	self.textObject.show() 
	pos=self.map3dToAspect2d(render,nShip.getPos(render))
	if pos!=None:
		x=pos.getX()
		z=pos.getZ()
		z=C_USER_HEIGHT/2*z*-1+0.1
		x=(x*C_USER_WIDTH/(C_RATIO*2))
		self.textObject.setPos(x, z)