ya2 · news · projects · code · about

better arrangement of the side panel
[pmachines.git] / pmachines / items / box.py
index cb8c5efcab81d495618a0e85bd348f149e314eb1..90d7d3fea14def966b51d7eb24a9f41fe541e786 100644 (file)
@@ -1,23 +1,71 @@
-from panda3d.core import CullFaceAttrib
+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:
 
-    def __init__(self, world):
+    def __init__(self, world, plane_node, count, cb_inst):
         self._world = world
+        self._plane_node = plane_node
+        self._count = count
+        self._cb_inst = cb_inst
         shape = BulletBoxShape((.5, .5, .5))
         self.node = BulletRigidBodyNode('box')
         self.node.add_shape(shape)
         self._np = render.attach_new_node(self.node)
-        self._np.set_pos(0, 0, 1)
         world.attach_rigid_body(self.node)
         model = loader.load_model('assets/gltf/box/box.gltf')
         model.flatten_light()
         model.reparent_to(self._np)
         self._set_outline_model()
         self._start_drag_pos = None
-        self._start_rot_info = None
+        self._prev_rot_info = None
+        self._instantiated = False
         taskMgr.add(self.on_frame, 'on_frame')
+        self._repos()
+
+    def _repos(self):
+        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()
+        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()
+            font.set_pixels_per_unit(60)
+            font.set_minfilter(Texture.FTLinearMipmapLinear)
+            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))
+        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')
@@ -42,29 +90,41 @@ class Box:
     def on_click_l(self, pos):
         self._start_drag_pos = pos, self._np.get_pos()
         loader.load_sfx('assets/audio/sfx/grab.ogg').play()
+        if not self._instantiated:
+            self._instantiated = True
+            self._txt.destroy()
+            self._count -= 1
+            if self._count:
+                box = Box(self._world, self._plane_node, self._count, self._cb_inst)
+                self._cb_inst(box)
 
     def on_click_r(self, pos):
-        self._start_rot_info = pos, self._np.get_pos(), self._np.get_r()
+        self._prev_rot_info = pos, self._np.get_pos(), self._np.get_r()
         loader.load_sfx('assets/audio/sfx/grab.ogg').play()
 
     def on_release(self):
-        if self._start_drag_pos or self._start_rot_info:
+        if self._start_drag_pos or self._prev_rot_info:
             loader.load_sfx('assets/audio/sfx/release.ogg').play()
-        self._start_drag_pos = self._start_rot_info = None
+        self._start_drag_pos = self._prev_rot_info = None
 
     def on_mouse_on(self):
         self._outline_model.show()
 
     def on_mouse_off(self):
-        if self._start_drag_pos or self._start_rot_info: return
+        if self._start_drag_pos or self._prev_rot_info: return
         self._outline_model.hide()
 
     def on_mouse_move(self, pos):
         if self._start_drag_pos:
             d_pos =  pos - self._start_drag_pos[0]
             self._np.set_pos(self._start_drag_pos[1] + d_pos)
-        if self._start_rot_info:
-            start_vec = self._start_rot_info[0] - self._start_rot_info[1]
-            curr_vec = pos - self._start_rot_info[1]
+        if self._prev_rot_info:
+            start_vec = self._prev_rot_info[0] - self._prev_rot_info[1]
+            curr_vec = pos - self._prev_rot_info[1]
             d_angle = curr_vec.signed_angle_deg(start_vec, (0, -1, 0))
-            self._np.set_r(self._start_rot_info[2] + d_angle)
+            self._np.set_r(self._prev_rot_info[2] + d_angle)
+            self._prev_rot_info = pos, self._np.get_pos(), self._np.get_r()
+
+    def on_aspect_ratio_changed(self):
+        if not self._instantiated:
+            self._repos()