Simple two nodes + a line, line is not positioned properly

Here is the MWE:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import (GeomVertexFormat, GeomVertexData, GeomVertexWriter, 
                          Geom, GeomNode, GeomLines, NodePath, TextNode)


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
        

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())
        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)
        self.setScale(5.0)
        self.setPos(-50, 200, 0)        
        
        from text3d import Text3D
        from direct.showbase.ShowBase import ShowBase
        from arrow3d import Arrow3D
        
        
class App(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        A = self.text('A')
        B = self.text('B')
        B.setX(50)
        a = self.arrow('a', A, B)
        
    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()        

As you can see with the way I’ve specified the positions of the Arrow3D vertices, it should be shown connecting A to B, however, it seems centered on A:

How could I correct this?

End result desired is a simple arrow (with head) connecting two general Objec3D instances of which Text3D is a subclass.

When you construct your arrow, what happens if you remove the “-50” from you call to “self.setPos”?

At the moment you seem to be placing the object not only at a y-position of 200 (which makes sense), but also at an x-position of -50–despite already applying the positions of the two anchor-points (that is, your two text-objects). So given a left-hand anchor-point of (-50, 200, 0) (as you seem to have set your left-hand text-object to be), your arrow then presumably starts at (-50 - 50, 200, 0) = (-100, 200, 0).

1 Like

Thank you for your kind response.

#self.setScale(5.0)
#self.setPos(-50, 200, 0)

Commenting out those lines, and the line first appears over A and B correctly, except if I rotate the camera it’s a large offset “in front” or “behind” the two nodes. Check it out. Rotate with middle mouse button and zoom with right mouse button.

1 Like

Damn, son. You are my coding god. :smiley:

I commented those out (in all places) and now rotating the camera the the two nodes are dead on the line. Great work!

I will have to assign defaults in a more consistent way, probably in the construction code.

1 Like

Ah, I’m glad that you got it working, and to have been of service! :slight_smile:

1 Like