ya2 · news · projects · code · about

better arrangement of the side panel
authorFlavio Calva <f.calva@gmail.com>
Wed, 12 Jan 2022 18:04:06 +0000 (19:04 +0100)
committerFlavio Calva <f.calva@gmail.com>
Wed, 12 Jan 2022 18:04:06 +0000 (19:04 +0100)
lib/engine/gui/cursor.py
lib/lib/p3d/gfx.py
pmachines/items/box.py
pmachines/scene.py
pmachines/sidepanel.py
prj.org

index 90448679816a7ed0406cc2e1d5427858280962df..a73c1c355c8bb95799cf2f4fdc7c4ced58778080 100644 (file)
@@ -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
index 0e2fcad9fcced6fc468e302cb306fffbaa28a65b..1c038c5fd23789bc27b1d18235fd23c890b31bef 100755 (executable)
@@ -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()
index 929756db62e40afa07b62f7037bfcf47b16df958..90d7d3fea14def966b51d7eb24a9f41fe541e786 100644 (file)
@@ -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')
index 77e980aa58d44fb523989bdb50ffb1ed3e2e6213..2d5838addfce89d6f4608230f74b9a0bd83d7d95 100644 (file)
@@ -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):
index b27f1963261533d34f710adffee451c603217bbb..270e06417037bdaa385ec6affedfcd8932bc72f3 100644 (file)
@@ -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 68d6d246dbfa28a82c965c9daba471f9a37c9d73..f12568da463690a517e3693d7cdb43d4ae6b1eb5 100644 (file)
--- 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