ya2 · news · projects · code · about

drag and drop
authorFlavio Calva <f.calva@gmail.com>
Fri, 7 Jan 2022 19:28:11 +0000 (20:28 +0100)
committerFlavio Calva <f.calva@gmail.com>
Fri, 7 Jan 2022 19:28:11 +0000 (20:28 +0100)
pmachines/items/box.py
pmachines/scene.py
prj.org

index ffb88f058fb9c614619c1c6f7f02b9b354e3b383..52c577b9984cbbdc0c5e18747f286c09fb26aa48 100644 (file)
@@ -4,34 +4,47 @@ from panda3d.bullet import BulletBoxShape, BulletRigidBodyNode
 class Box:
 
     def __init__(self, world):
+        self._world = world
         shape = BulletBoxShape((.5, .5, .5))
         self.node = BulletRigidBodyNode('box')
-        # self.node.set_mass(1)  # static/dynamic
         self.node.add_shape(shape)
-        np = render.attach_new_node(self.node)
-        np.set_pos(0, 0, 1)
+        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(np)
-        self._set_outline_model(np)
+        model.reparent_to(self._np)
+        self._set_outline_model()
+        self._start_drag_pos = None
 
-    def _set_outline_model(self, np):
+    def _set_outline_model(self):
         self._outline_model = loader.load_model('assets/gltf/box/box.gltf')
         clockw = CullFaceAttrib.MCullClockwise
         self._outline_model.set_attrib(CullFaceAttrib.make(clockw))
-        self._outline_model.reparent_to(np)
+        self._outline_model.reparent_to(self._np)
         self._outline_model.set_scale(-1.08, -1.08, -1.08)
         self._outline_model.set_light_off()
         self._outline_model.set_color(.4, .4, .4, 1)
         self._outline_model.set_color_scale(.4, .4, .4, 1)
         self._outline_model.hide()
 
-    def on_click(self, hit):
-        print(hit.get_hit_pos())
+    def play(self):
+        self._world.remove_rigid_body(self.node)
+        self.node.set_mass(1)
+        self._world.attach_rigid_body(self.node)
+
+    def on_click(self, pos):
+        self._start_drag_pos = pos, self._np.get_pos()
+
+    def on_release(self):
+        self._start_drag_pos = None
 
     def on_mouse_on(self):
         self._outline_model.show()
 
     def on_mouse_off(self):
         self._outline_model.hide()
+
+    def on_mouse_move(self, pos):
+        if not self._start_drag_pos: return
+        self._np.set_pos(self._start_drag_pos[1] + (pos - self._start_drag_pos[0]))
index 925ed2b6b8b8647aa47c8c31d1ca20967ace078a..bd7d9bfaf3d02192ef27163af439899667ff9a62 100644 (file)
@@ -1,4 +1,5 @@
 from panda3d.core import AmbientLight, DirectionalLight, Point3
+from panda3d.bullet import BulletPlaneShape, BulletGhostNode# BulletRigidBodyNode
 from direct.showbase.DirectObject import DirectObject
 from pmachines.items.background import Background
 from pmachines.items.box import Box
@@ -12,6 +13,7 @@ class Scene(DirectObject):
         self._set_camera()
         self._set_lights()
         self._set_input()
+        self._set_mouse_plane()
         Background()
         self.items = [Box(world)]
         taskMgr.add(self.on_frame, 'on_frame')
@@ -39,7 +41,18 @@ class Scene(DirectObject):
         self._set_directional_light('rim light', (75, -30, 0), (.3, .3, .3, 1))
 
     def _set_input(self):
-        self.accept('mouse1-up', self.on_click)
+        self.accept('mouse1', self.on_click)
+        self.accept('mouse1-up', self.on_release)
+        self.accept('p-up', self.on_play)
+
+    def _set_mouse_plane(self):
+        shape = BulletPlaneShape((0, -1, 0), 1)
+        #self._mouse_plane_node = BulletRigidBodyNode('mouse plane')
+        self._mouse_plane_node = BulletGhostNode('mouse plane')
+        self._mouse_plane_node.addShape(shape)
+        #np = render.attachNewNode(self._mouse_plane_node)
+        #self._world.attachRigidBody(self._mouse_plane_node)
+        self._world.attachGhost(self._mouse_plane_node)
 
     def _get_hits(self):
         if not base.mouseWatcherNode.has_mouse(): return []
@@ -51,14 +64,32 @@ class Scene(DirectObject):
         return self._world.ray_test_all(p_from, p_to).get_hits()
 
     def on_click(self):
+        for hit in self._get_hits():
+            if hit.get_node() == self._mouse_plane_node:
+                pos = hit.get_hit_pos()
         for hit in self._get_hits():
             for item in [i for i in self.items if hit.get_node() == i.node]:
-                item.on_click(hit)
+                item.on_click(pos)
+
+    def on_release(self):
+        for hit in self._get_hits():
+            for item in [i for i in self.items if hit.get_node() == i.node]:
+                item.on_release()
 
     def on_frame(self, task):
-        hit_nodes = [hit.get_node() for hit in self._get_hits()]
+        hits = self._get_hits()
+        pos = None
+        for hit in self._get_hits():
+            if hit.get_node() == self._mouse_plane_node:
+                pos = hit.get_hit_pos()
+        hit_nodes = [hit.get_node() for hit in hits]
         items_hit = [itm for itm in self.items if itm.node in hit_nodes]
         items_no_hit = [itm for itm in self.items if itm not in items_hit]
         [itm.on_mouse_on() for itm in items_hit]
         [itm.on_mouse_off() for itm in items_no_hit]
+        if pos:
+            [itm.on_mouse_move(pos) for itm in self.items]
         return task.cont
+
+    def on_play(self):
+        [itm.play() for itm in self.items]
diff --git a/prj.org b/prj.org
index 2b869cd40d270fd609e2581868f4a80629b6e330..18187c345cd11a9be05d782cb638e83c7c6fc552 100644 (file)
--- a/prj.org
+++ b/prj.org
@@ -1,8 +1,9 @@
 * issues
 * todo
-** objects placement
-** shelf's logics (rotation, scale)
+** objects rotation
 ** buttons
+** mouse cursor
+** main menu
 ** magnet
 *  waiting
 ** version 0.0.yymmdd