From 13263131bcd31eeab174a2604ff01a9a12e7910e Mon Sep 17 00:00:00 2001 From: Flavio Calva Date: Wed, 12 Jan 2022 19:04:06 +0100 Subject: [PATCH] better arrangement of the side panel --- lib/engine/gui/cursor.py | 7 +++--- lib/lib/p3d/gfx.py | 20 ++++++++++++++++ pmachines/items/box.py | 45 +++++++++++++++++++++------------- pmachines/scene.py | 6 ++--- pmachines/sidepanel.py | 52 ++++++++++++++++++++++++---------------- prj.org | 1 - 6 files changed, 85 insertions(+), 46 deletions(-) diff --git a/lib/engine/gui/cursor.py b/lib/engine/gui/cursor.py index 9044867..a73c1c3 100644 --- a/lib/engine/gui/cursor.py +++ b/lib/engine/gui/cursor.py @@ -44,10 +44,9 @@ class MouseCursor(GameObject, MouseCursorFacade): def __on_frame(self, task): mwn = base.mouseWatcherNode - if not mwn: mouse = 0, 0 - elif not mwn.hasMouse(): mouse = 0, 0 - else: mouse = mwn.get_mouse_x(), mwn.get_mouse_y() - if not mouse: return task.again + if not mwn or not mwn.hasMouse(): + return task.again + mouse = mwn.get_mouse_x(), mwn.get_mouse_y() h_x = mouse[0] * base.getAspectRatio() + self.hotspot_dx self.cursor_img.set_pos((h_x, mouse[1] - self.hotspot_dy)) return task.again diff --git a/lib/lib/p3d/gfx.py b/lib/lib/p3d/gfx.py index 0e2fcad..1c038c5 100755 --- a/lib/lib/p3d/gfx.py +++ b/lib/lib/p3d/gfx.py @@ -119,6 +119,26 @@ class P3dGfxMgr: p2d = Point2() return p2d if base.camLens.project(p3d, p2d) else None + @staticmethod + def screen_coord(pos): + new_node = NodePath('temp') + new_node.set_pos(pos) + coord3d = new_node.get_pos(base.cam) + new_node.remove_node() + coord2d = Point2() + base.camLens.project(coord3d, coord2d) + coord_r2d = Point3(coord2d[0], 0, coord2d[1]) + coord_a2d = base.aspect2d.get_relative_point(render2d, coord_r2d) + return coord_a2d[0], coord_a2d[2] + + @staticmethod + def world_from_to(pos): + p_from, p_to = Point3(), Point3() # in camera coordinates + base.camLens.extrude(pos, p_from, p_to) + p_from = render.get_relative_point(base.cam, p_from) # global coords + p_to = render.get_relative_point(base.cam, p_to) # global coords + return p_from, p_to + @property def shader_support(self): return base.win.get_gsg().get_supports_basic_shaders() diff --git a/pmachines/items/box.py b/pmachines/items/box.py index 929756d..90d7d3f 100644 --- a/pmachines/items/box.py +++ b/pmachines/items/box.py @@ -1,7 +1,7 @@ from panda3d.core import CullFaceAttrib, Point3, NodePath, Point2, Texture from panda3d.bullet import BulletBoxShape, BulletRigidBodyNode from direct.gui.OnscreenText import OnscreenText - +from lib.lib.p3d.gfx import P3dGfxMgr class Box: @@ -26,25 +26,31 @@ class Box: self._repos() def _repos(self): - p_from, p_to = Point3(), Point3() # in camera coordinates - base.camLens.extrude((-1, 1), p_from, p_to) - p_from = render.get_relative_point(base.cam, p_from) # global coords - p_to = render.get_relative_point(base.cam, p_to) # global coords + p_from, p_to = P3dGfxMgr.world_from_to((-1, 1)) for hit in self._world.ray_test_all(p_from, p_to).get_hits(): if hit.get_node() == self._plane_node: pos = hit.get_hit_pos() + corner = P3dGfxMgr.screen_coord(pos) bounds = self._np.get_tight_bounds() bounds = bounds[0] - self._np.get_pos(), bounds[1] - self._np.get_pos() - margin = .3, .3 - dpos = bounds[1][0] + margin[0], 0, -bounds[1][2] - margin[1] - self._np.set_pos(pos + dpos) - new_node = NodePath('temp') - new_node.set_pos(pos + dpos + (bounds[1][0], bounds[1][1], -bounds[1][2])) - coord3d = new_node.get_pos(base.cam) - coord2d = Point2() - base.camLens.project(coord3d, coord2d) - coord_r2d = Point3(coord2d[0], 0, coord2d[1]) - coord_a2d = base.aspect2d.get_relative_point(render2d, coord_r2d) + self._np.set_pos(pos) + dist = -1, -1 + def __update(set, get, delta): + set(get() + delta) + top_left = self._np.get_pos() + (bounds[0][0], bounds[0][1], bounds[1][2]) + tl2d = P3dGfxMgr.screen_coord(top_left) + tmpnode = NodePath('tmp') + tmpnode.set_pos(tl2d[0], 0, tl2d[1]) + cornernode = NodePath('corner') + cornernode.set_pos(corner[0], 0, corner[1]) + dist = tmpnode.get_pos(cornernode) + tmpnode.remove_node() + cornernode.remove_node() + return dist + while dist[0] < .01: + dist = __update(self._np.set_x, self._np.get_x, .01) + while dist[2] > -.01: + dist = __update(self._np.set_z, self._np.get_z, -.01) if not hasattr(self, '_txt'): font = base.loader.load_font('assets/fonts/Hanken-Book.ttf') font.clear() @@ -53,8 +59,13 @@ class Box: font.set_outline((0, 0, 0, 1), .8, .2) self._txt = OnscreenText( str(self._count), font=font, scale=0.06, fg=(.9, .9, .9, 1)) - self._txt['pos'] = coord_a2d[0], coord_a2d[2] - new_node.remove_node() + pos = self._np.get_pos() + (bounds[1][0], bounds[0][1], bounds[0][2]) + p2d = P3dGfxMgr.screen_coord(pos) + self._txt['pos'] = p2d + + def get_corner(self): + bounds = self._np.get_tight_bounds() + return bounds[1][0], bounds[1][1], bounds[0][2] def _set_outline_model(self): self._outline_model = loader.load_model('assets/gltf/box/box.gltf') diff --git a/pmachines/scene.py b/pmachines/scene.py index 77e980a..2d5838a 100644 --- a/pmachines/scene.py +++ b/pmachines/scene.py @@ -8,6 +8,7 @@ from pmachines.items.background import Background from pmachines.items.box import Box from pmachines.sidepanel import SidePanel from lib.engine.gui.cursor import MouseCursor +from lib.lib.p3d.gfx import P3dGfxMgr class Scene(DirectObject): @@ -113,10 +114,7 @@ class Scene(DirectObject): def _get_hits(self): if not base.mouseWatcherNode.has_mouse(): return [] - p_from, p_to = Point3(), Point3() # in camera coordinates - base.camLens.extrude(base.mouseWatcherNode.get_mouse(), p_from, p_to) - p_from = render.get_relative_point(base.cam, p_from) # global coords - p_to = render.get_relative_point(base.cam, p_to) # global coords + p_from, p_to = P3dGfxMgr.world_from_to(base.mouseWatcherNode.get_mouse()) return self._world.ray_test_all(p_from, p_to).get_hits() def _on_click(self, method): diff --git a/pmachines/sidepanel.py b/pmachines/sidepanel.py index b27f196..270e064 100644 --- a/pmachines/sidepanel.py +++ b/pmachines/sidepanel.py @@ -1,6 +1,7 @@ from textwrap import dedent from panda3d.core import GeomVertexData, GeomVertexFormat, Geom, \ GeomVertexWriter, GeomTriangles, GeomNode, Shader, Point3 +from lib.lib.p3d.gfx import P3dGfxMgr class SidePanel: @@ -8,41 +9,51 @@ class SidePanel: def __init__(self, world, plane_node, top_l, bottom_r, y): self._world = world self._plane_node = plane_node - self._set(top_l, bottom_r, y) + self._set((-1, 1), y) def update(self, items): - p_from, p_to = Point3(), Point3() # in camera coordinates - base.camLens.extrude((-1, 1), p_from, p_to) - p_from = render.get_relative_point(base.cam, p_from) # global coords - p_to = render.get_relative_point(base.cam, p_to) # global coords + p_from, p_to = P3dGfxMgr.world_from_to((-1, 1)) for hit in self._world.ray_test_all(p_from, p_to).get_hits(): if hit.get_node() == self._plane_node: pos = hit.get_hit_pos() - top_l = pos[0] - .8, pos[2] + .8 - bottom_r = pos[0], pos[2] - y = 1 + y = 0 + corner = -20, 20 for item in items: if not item._instantiated: bounds = item._np.get_tight_bounds() - if bounds[1][0] > bottom_r[0]: - bottom_r = bounds[1][0], bottom_r[1] - if bounds[0][2] < bottom_r[1]: - bottom_r = bottom_r[0], bounds[0][2] if bounds[1][1] > y: y = bounds[1][1] - bottom_r = bottom_r[0] + .3, bottom_r[1] - .3 - self._set(top_l, bottom_r, y) + icorner = item.get_corner() + icorner = P3dGfxMgr.screen_coord(icorner) + if icorner[0] > corner[0]: + corner = icorner[0], corner[1] + if icorner[1] < corner[1]: + corner = corner[0], icorner[1] + self._set((pos[0], pos[2]), y) + bounds = self._np.get_tight_bounds() + corner3d = bounds[1][0], bounds[1][1], bounds[0][2] + corner2d = P3dGfxMgr.screen_coord(corner3d) + def __update(dscale): + scale = self._np.get_scale() + self._np.set_scale(scale + dscale) + bounds = self._np.get_tight_bounds() + corner3d = bounds[1][0], bounds[1][1], bounds[0][2] + return P3dGfxMgr.screen_coord(corner3d) + while corner2d[0] < corner[0] + .01: + corner2d = __update((.01, 0, 0)) + while corner2d[1] > corner[1] - .01: + corner2d = __update((0, 0, .01)) - def _set(self, top_l, bottom_r, y): + def _set(self, pos, y): if hasattr(self, '_np'): self._np.remove_node() vdata = GeomVertexData('quad', GeomVertexFormat.get_v3(), Geom.UHStatic) vdata.setNumRows(2) vertex = GeomVertexWriter(vdata, 'vertex') - vertex.add_data3(bottom_r[0], y, bottom_r[1]) - vertex.add_data3(bottom_r[0], y, top_l[1]) - vertex.add_data3(top_l[0], y, top_l[1]) - vertex.add_data3(top_l[0], y, bottom_r[1]) + vertex.add_data3(.5, 0, -.5) + vertex.add_data3(.5, 0, .5) + vertex.add_data3(-.5, 0, .5) + vertex.add_data3(-.5, 0, -.5) prim = GeomTriangles(Geom.UHStatic) prim.add_vertices(0, 1, 2) prim.add_vertices(0, 2, 3) @@ -53,6 +64,7 @@ class SidePanel: node.add_geom(geom) self._np = render.attach_new_node(node) self._np.setTransparency(True) + self._np.set_pos(pos[0], y, pos[1]) vert = '''\ #version 150 uniform mat4 p3d_ModelViewProjectionMatrix; @@ -63,7 +75,7 @@ class SidePanel: #version 150 out vec4 p3d_FragColor; void main() { - p3d_FragColor = vec4(.04, .04, .04, .06); }''' + p3d_FragColor = vec4(.04, .04, .04, .08); }''' self._np.set_shader(Shader.make(Shader.SL_GLSL, dedent(vert), dedent(frag))) # mat = Material() # mat.set_base_color((1, 1, 1, 1)) diff --git a/prj.org b/prj.org index 68d6d24..f12568d 100644 --- a/prj.org +++ b/prj.org @@ -1,6 +1,5 @@ * issues * todo -** place the instantiable and the bg-panel considering 2d margins ** manage the physics of the to-be-instantiated with a ghost ** instructions ** main menu -- 2.30.2