Here is an MWE:
from direct.showbase.ShowBase import ShowBase
from panda3d.core import (GeomVertexFormat, GeomVertexData, GeomVertexWriter,
Geom, GeomNode, GeomLines, NodePath, TextNode)
from direct.task import Task
from math import pi, sin, cos
class Object3D(NodePath):
Out, In = range(2)
def __init__(self, geom_node):
super().__init__(geom_node)
self._arrows = ([], [])
def add_arrow(self, arrow, inout=0):
self._arrows[inout].append(arrow)
from object3d import Object3D
from panda3d.core import TextNode
def setPos(self, x, y, z):
for inout in range(2):
for arrow in self._arrows[inout]:
arrow.set_endpoint_pos(inout, x, y, z)
super().setPos(x, y, z)
class Arrow3D(Object3D):
def __init__(self, text:str, dom, cod):
format = GeomVertexFormat.getV3()
data = GeomVertexData("Data", format, Geom.UHStatic)
vertices = GeomVertexWriter(data, "vertex")
vertices.addData3f(*dom.getPos())
print (*dom.getPos())
vertices.addData3f(*cod.getPos())
arrow = GeomLines(Geom.UHStatic)
arrow.addVertices(0, 1)
geom = Geom(data)
geom.addPrimitive(arrow)
arrow = GeomNode(text)
arrow.addGeom(geom)
super().__init__(arrow)
self.setBillboardAxis()
self.setColor(0.0, 1.0, 0.0)
self.setScale(5.0)
self.setPos(-50, 200, 0)
self._dom = dom
self._cod = cod
class Text3D(Object3D):
def __init__(self, text:str):
text3d = TextNode(text)
text3d.setText(text)
super().__init__(text3d)
self.setBillboardAxis()
self.setColor(0.0, 1.0, 0.0)
from text3d import Text3D
from direct.showbase.ShowBase import ShowBase
from arrow3d import Arrow3D
class App(ShowBase):
def __init__(self):
ShowBase.__init__(self)
p = self.render.attachNewNode("Dummy")
A = self.text('Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', parent=p)
B = self.text('B', parent=p)
a = self.arrow('a', A, B, parent=p)
self.render.setScale(1.0)
#B.setPos(50, 0, 0)
self.camera.setPos(10000.0, 0.0, 10000)
p.setScale(1.0)
# Add the spinCameraTask procedure to the task manager.
self.camera.setHpr(180, 0, 0)
self.camera.setPos(100, -10000000, 0)
def text(self, text:str, parent=None):
text = Text3D(text)
self.set_parent(text, parent)
return text
def arrow(self, text:str, dom, cod, parent=None):
arrow = Arrow3D(text, dom, cod)
self.set_parent(arrow, parent)
return arrow
def set_parent(self, node_path, parent=None):
if parent is None:
parent = self.render
node_path.reparentTo(parent)
if __name__ == '__main__':
app = App()
app.run()
Right-press + drag to zoom out and the text zooms into view, but no matter what camera position / hpr initially set, the text won’t just start out in front of the camera.
I’m missing something!