Hey guys, I’m struggling to find the maximum and minimum relative coordinates of an embedded Panda scene in PyQT5. I want to put an UCS there independent of 3D world. How to determine the maximum and minimum relative coordinates in this case and how to insert it close to lower left corner?
This is how it is now with the greater UCS fixed on (0,0,0) and the smallest on (-2,5,-1)
origin = [-2, 5, -1.0]
coords_np, axis_x_np, axis_y_np, axis_z_np = create_axes_cross("coords", 3, True)
coords_np.reparentTo(self.showbase.cam)
coords_np.setPos(self.showbase.cam, tuple(origin))
coords_np.setScale(0.1)
If you want to keep the orientation of your axis tripod relative to the camera, then you could just reparent it to base.a2dBottomLeft
.
But if you want its orientation to follow that of the scene while rotating the camera, then perhaps this post might be of use to you.
It works on the previous version of my program (not embedded PyQT5). However when I try to insert my tripod into my embedded showbase, the tripod is not shown. Any idea what may causing it?
The working file is at tests/main_test.py
The not working file is just main.py (line 53, 54)
Ugh, looks like QPanda3D renders to a separate texture buffer instead of to the regular window, so any new display regions need to be added to that buffer. Another problem (likely for the same reason) seems to be that neither the window-event
nor the aspectRatioChanged
event gets thrown when the window is resized.
The way to solve this is to not use QPanda3D change the code in AxisTripod.py
as follows:
class AxisTripod:
def __init__(self, showbase):
self._buffer = showbase.buff
self._dr_pixel_size = 68 # size of display region in pixels
dr = self._buffer.make_display_region(0, 1., 0., 1.)
dr.sort = 2
lens = OrthographicLens()
lens.film_size = .235
self._cam_target = cam_target = NodePath("tripod_cam_target")
cam_target.set_compass(showbase.cam)
cam_node = Camera("tripod_cam")
camera = cam_target.attach_new_node(cam_node)
camera.node().set_lens(lens)
dr.camera = camera
dr.set_clear_color_active(False)
dr.set_clear_depth_active(True)
self._display_region = dr
self._root = camera.attach_new_node("world_axes")
self._root.set_y(10.)
self.model = self.__create_model()
node = self._root.node()
node.set_bounds(OmniBoundingVolume())
node.final = True
self._buffer_size = (0, 0)
showbase.task_mgr.do_method_later(.2, self.__update_region_size, "update_region_size")
def __create_model(self):
vertex_format = GeomVertexFormat.get_v3c4()
vertex_data = GeomVertexData("axis_tripod_data", vertex_format, Geom.UH_static)
pos_writer = GeomVertexWriter(vertex_data, "vertex")
col_writer = GeomVertexWriter(vertex_data, "color")
lines = GeomLines(Geom.UH_static)
for i in range(3):
v_pos = VBase3()
pos_writer.add_data3(v_pos)
v_pos[i] = .1
pos_writer.add_data3(v_pos)
color = VBase4(0., 0., 0., 1.)
color[i] = 1.
col_writer.add_data4(color)
col_writer.add_data4(color)
lines.add_vertices(i * 2, i * 2 + 1)
geom = Geom(vertex_data)
geom.add_primitive(lines)
node = GeomNode("axis_tripod")
node.add_geom(geom)
model = self._root.attach_new_node(node)
return model
def __update_region_size(self, task):
win_w, win_h = self._buffer.size
if self._buffer_size == (win_w, win_h):
return task.again
aspect_ratio = win_w / win_h
size_h = self._dr_pixel_size / win_w
size_v = size_h * aspect_ratio
self._buffer_size = (win_w, win_h)
self._display_region.dimensions = (0., size_h, 0., size_v)
return task.again
So __update_region_size
has now become a task which runs every 0.2 seconds such that it doesn’t impact performance too much.
1 Like