Reparent a TextNode to an Object?

Hi, I’m new to panda3D, or generally game engine.

This should be a very basic question: Will the text still be shown if the TextNode is reparented to an object, not the render itself?
I loaded a card model(Card.glb), reparented it to the render, then loaded the blue mana crystal model(Mana.glb), and reparented it to the card model, it shows up at the top left corner.
Then I called the attachNewNode() method, in order to reposition the text, and here comes the issue:
1.When I make self.render invoke attachNewNode(), the text shows up correctly
2.When I make card invoke attachNewNode(), the text doesn’t show up.

The code is as follows:

    card = self.loader.loadModel("Models\\SpellModels\\Card.glb")
	card.reparentTo(self.render)
	card.setPos(0, -3, 0)

    """Mana display of the card"""
	mana = self.loader.loadModel("Models\\SpellModels\\Mana.glb")
	mana.reparentTo(card)
	manaText = TextNode("mana")
	manaText.setText('1')
	manaTextNode = self.render.attachNewNode(manaText)
	manaTextNode.setScale(2)
	manaTextNode.setPos(0, 0, 0)
	manaText.setAlign(TextNode.ACenter)
	

The above code gives me the result:
Question

When I change “self.render” to “card” in manaTextNode = self.render.attachNewNode(manaText), then the number ‘1’ is gone.

Does the TextNode have to be parented to the render, or am I missing something?

Any comment is appreciated : )

There should be no problem with parenting your object to your card-model, I believe.

I’m guessing that the problem lies with the positioning and/or orientation of the TextNode when attached to the card.

You see, when setting a NodePath’s position (or orientation, or scale, etc.), and doing so the default way, one is in fact setting that position (or orientation, or scale, etc.) relative to its parent. Thus, when setting the TextNode’s position after attaching it to “render”, you’re setting its position relative to “render”–but when setting its position after attaching it to the card, you’re setting its position relative to the card.

I’m guessing that your card-model has its origin-point somewhere near its centre. If so, then with a position of (0, 0, 0) the TextNode will also appear somewhere near the card’s centre, and so be overlapping it. This might lead to depth-testing causing the TextNode to be hidden by the card.

A quick test for this might be to set the TextNode’s position to something slightly greater than zero–say (1, 1, 1). (You could just adjust one of the axes, but I don’t know which axis corresponds to the direction “away from the face of the card”. Thus I’m just choosing a relatively safe value by offsetting on all axes.) Note that, depending on the orientation of the card, you may have to negate one or more of those values.

If the TextNode appears, then the problem may well be as I described above.

If so, then, to actually fix it I’d suggest two things:

  1. Offset the TextNode by a small amount in the direction “away from the face of the card”.
    • That is, if card has its back facing the y-axis, and this its sides running along the x- and z- axes, offset the TextNode along the y-axis.
  2. Apply a depth-offset to the TextNode to reduce z-fighting.
    • This is done by simply calling "setDepthOffset(<some value>)" on your TextNode’s NodePath, where “some value” is an integer value by which to adjust the TextNode’s apparent depth. A value of “1” may well be fine.

It could also be that the model has some material, light, or other attribute applied that now transitively gets applied to the text. You can disable the specific attribute on the text by doing something like manaTextNode.setMaterialOff(1) and .setLightOff(1).

1 Like

Is the TextNode in the image you have described at the correct position as you need, or should it be somewhere on top of the card?