If you do that, only the last line segment is drawn. There is however an alternative LineSegs.create() method that accepts an existing GeomNode to append the new segments to.
I made a code sample that draws a line as it follows the mouse cursor (not precisely, as I did not take the aspect ratio into account, but it’s just an example):
from panda3d.core import *
from direct.showbase.ShowBase import ShowBase
loadPrcFileData("", """
sync-video #f
"""
)
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.set_frame_rate_meter(True)
self.last_pos = Point2()
self.line_segs = ls = LineSegs("path")
ls.set_color(1., 1., 1.)
ls.set_thickness(2)
ls.move_to(0., 0., 0.)
self.path_geom = GeomNode("path")
self.path = self.aspect2d.attach_new_node(self.path_geom)
self.taskMgr.doMethodLater(0.1, self.__draw_path, "draw_path")
def __draw_path(self, task):
if not self.mouseWatcherNode.has_mouse():
return task.again
pos = self.mouseWatcherNode.get_mouse()
if pos != self.last_pos:
x, y = self.last_pos
self.line_segs.move_to(x, 0., y)
x, y = self.last_pos = Point2(pos)
self.line_segs.draw_to(x, 0., y)
self.line_segs.create(self.path_geom)
return task.again
app = MyApp()
app.run()
It works, but it slows down fairly quickly as more line segments are drawn.
A much more efficient way I’ve found is to use the low-level GeomLines primitive directly. Even when the screen is filled with line segments, the frame rate hardly drops. It’s just a single GeomPrimitive, whereas using a LineSegs object creates a new Geom for every new segment.
Here is the code:
from panda3d.core import *
from direct.showbase.ShowBase import ShowBase
loadPrcFileData("", """
sync-video #f
"""
)
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.set_frame_rate_meter(True)
self.last_pos = Point2()
self.new_pos = Point2()
self.path_prim = GeomLines(Geom.UH_static)
vertex_format = GeomVertexFormat.get_v3()
self.path_vertex_data = GeomVertexData("path_data", vertex_format, Geom.UH_static)
pos_writer = GeomVertexWriter(self.path_vertex_data, "vertex")
pos_writer.add_data3f(0., 0., 0.)
geom = Geom(self.path_vertex_data)
geom.add_primitive(self.path_prim)
geom_node = GeomNode("path")
geom_node.add_geom(geom)
self.path = path = self.aspect2d.attach_new_node(geom_node)
path.set_color(1., 1., 1.)
path.set_render_mode_thickness(2)
self.taskMgr.doMethodLater(0.1, self.__draw_path, "draw_path")
def __add_path_segment(self, point):
pos_writer = GeomVertexWriter(self.path_vertex_data, "vertex")
rows = self.path_vertex_data.get_num_rows()
pos_writer.set_row(rows)
pos_writer.add_data3f(point)
prim = self.path_prim
prim.add_vertices(rows - 1, rows)
def __draw_path(self, task):
if not self.mouseWatcherNode.has_mouse():
return task.again
pos = self.mouseWatcherNode.get_mouse()
if pos != self.last_pos:
x, y = self.last_pos = Point2(pos)
point = Point3(x, 0., y)
self.__add_path_segment(point)
return task.again
app = MyApp()
app.run()
Hope this helps.