ya2 · news · projects · code · about

box
authorFlavio Calva <f.calva@gmail.com>
Fri, 7 Jan 2022 18:50:05 +0000 (19:50 +0100)
committerFlavio Calva <f.calva@gmail.com>
Fri, 7 Jan 2022 18:50:05 +0000 (19:50 +0100)
assets/blend/box/box.blend
pmachines/items/background.py
pmachines/items/box.py [new file with mode: 0644]
pmachines/pmachines.py
pmachines/scene.py [new file with mode: 0644]

index 9ee6b040288e59e6dff2e991fce1e0de3b6887ed..dfadde569b4211e640d6bd1bb9768180bb162488 100644 (file)
Binary files a/assets/blend/box/box.blend and b/assets/blend/box/box.blend differ
index 1161186f7f5bebaf83330cf1ba8ca1a4b70c4817..cdbb1d8dfc775f5858d42ddfc308b4ce46643e5a 100644 (file)
@@ -7,7 +7,7 @@ class Background:
     def __init__(self):
         root = NodePath('background_root')
         root.reparent_to(render)
-        ncols, nrows = 8, 5
+        ncols, nrows = 12, 8
         start_size, end_size = 5, 2.5
         offset = 5
         for col, row in product(range(ncols), range(nrows)):
@@ -16,6 +16,6 @@ class Background:
             model.reparent_to(root)
             total_width, total_height = end_size * ncols, end_size * nrows
             left, bottom = -total_width/2, -total_height/2
-            model.set_pos(left + end_size * col, -offset, bottom + end_size * row)
+            model.set_pos(left + end_size * col, offset, bottom + end_size * row)
         root.clear_model_nodes()
         root.flatten_strong()
diff --git a/pmachines/items/box.py b/pmachines/items/box.py
new file mode 100644 (file)
index 0000000..71c0c00
--- /dev/null
@@ -0,0 +1,18 @@
+from panda3d.bullet import BulletBoxShape, BulletRigidBodyNode
+
+class Box:
+
+    def __init__(self, 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)
+        world.attach_rigid_body(self.node)
+        model = loader.load_model('assets/gltf/box/box.gltf')
+        model.flatten_light()
+        model.reparent_to(np)
+
+    def on_click(self, hit):
+        print(hit.get_hit_pos())
index 08669ee24c683c91a3c4441b0ced75f8bb827b2a..2e9e73d9a90ea947b4d07255d632dfa9641912a1 100755 (executable)
@@ -5,10 +5,10 @@ from sys import platform, argv
 from logging import info
 from os.path import exists
 from os import makedirs
-from panda3d.core import Filename, load_prc_file_data, AmbientLight, \
-    DirectionalLight, AntialiasAttrib
+from panda3d.core import Filename, load_prc_file_data, AntialiasAttrib
+from panda3d.bullet import BulletWorld, BulletDebugNode
 from direct.showbase.ShowBase import ShowBase
-from pmachines.items.background import Background
+from pmachines.scene import Scene
 
 
 class Pmachines:
@@ -18,44 +18,14 @@ class Pmachines:
         self.base = ShowBase()
         info('platform: %s' % platform)
         info('exists main.py: %s' % exists('main.py'))
-        self._prepare_windows()
+        self._prepare_window()
         args = self._parse_args()
         self.updating = args.update
         self.version = args.version
         if args.update:
             return
-        self._set_camera()
-        self._set_lights()
-        Background()
-
-    def _set_camera(self):
-        base.camera.set_pos(0, -20, 0)
-        base.camera.look_at(0, 0, 0)
-        self.base.disable_mouse()
-
-    def _set_lights(self):
-        alight = AmbientLight('alight')  # for ao
-        alight.setColor((.4, .4, .4, 1))
-        alnp = render.attachNewNode(alight)
-        render.setLight(alnp)
-
-        directionalLight = DirectionalLight('directionalLight')
-        directionalLightNP = render.attachNewNode(directionalLight)
-        directionalLightNP.setHpr(315, -60, 0)
-        directionalLight.setColor((3.6, 3.6, 3.6, 1))
-        render.setLight(directionalLightNP)
-
-        directionalLight = DirectionalLight('directionalLight')
-        directionalLightNP = render.attachNewNode(directionalLight)
-        directionalLightNP.setHpr(195, -30, 0)
-        directionalLight.setColor((.4, .4, .4, 1))
-        render.setLight(directionalLightNP)
-
-        directionalLight = DirectionalLight('directionalLight')
-        directionalLightNP = render.attachNewNode(directionalLight)
-        directionalLightNP.setHpr(75, -30, 0)
-        directionalLight.setColor((.3, .3, .3, 1))
-        render.setLight(directionalLightNP)
+        self._set_physics()
+        Scene(self.world)
 
     def _configure(self):
         load_prc_file_data('', 'window-title pmachines')
@@ -71,7 +41,7 @@ class Pmachines:
         args = parser.parse_args(cmd_line)
         return args
 
-    def _prepare_windows(self):
+    def _prepare_window(self):
         data_path = ''
         if (platform.startswith('win') or platform.startswith('linux')) and (
                 not exists('main.py') or __file__.startswith('/app/bin/')):
@@ -89,4 +59,22 @@ class Pmachines:
             use_occlusion_maps=True,
             msaa_samples=4)
         render.setAntialias(AntialiasAttrib.MAuto)
-        base.set_background_color(0, 0, 0, 1)
+        self.base.set_background_color(0, 0, 0, 1)
+        self.base.disable_mouse()
+
+    def _set_physics(self):
+        debug_node = BulletDebugNode('Debug')
+        debug_node.show_wireframe(True)
+        debug_node.show_constraints(True)
+        debug_node.show_bounding_boxes(True)
+        debug_node.show_normals(True)
+        debug_np = render.attach_new_node(debug_node)
+        debug_np.show()
+        self.world = BulletWorld()
+        self.world.set_gravity((0, 0, -9.81))
+        self.world.set_debug_node(debug_np.node())
+        def update(task):
+            dt = globalClock.get_dt()
+            self.world.do_physics(dt)
+            return task.cont
+        taskMgr.add(update, 'update')
diff --git a/pmachines/scene.py b/pmachines/scene.py
new file mode 100644 (file)
index 0000000..3baf29a
--- /dev/null
@@ -0,0 +1,52 @@
+from panda3d.core import AmbientLight, DirectionalLight, Point3
+from direct.showbase.DirectObject import DirectObject
+from pmachines.items.background import Background
+from pmachines.items.box import Box
+
+
+class Scene(DirectObject):
+
+    def __init__(self, world):
+        super().__init__()
+        self._world = world
+        self._set_camera()
+        self._set_lights()
+        self._set_input()
+        Background()
+        self.items = [Box(world)]
+
+    def _set_camera(self):
+        base.camera.set_pos(0, -20, 0)
+        base.camera.look_at(0, 0, 0)
+
+    def _set_directional_light(self, name, hpr, color):
+        light = DirectionalLight(name)
+        light_np = render.attach_new_node(light)
+        light_np.set_hpr(*hpr)
+        light.set_color(color)
+        render.set_light(light_np)
+
+    def _set_lights(self):
+        alight = AmbientLight('alight')  # for ao
+        alight.set_color((.4, .4, .4, 1))
+        alnp = render.attach_new_node(alight)
+        render.set_light(alnp)
+        self._set_directional_light('key light', (315, -60, 0),
+                                    (3.6, 3.6, 3.6, 1))
+        self._set_directional_light('fill light', (195, -30, 0),
+                                    (.4, .4, .4, 1))
+        self._set_directional_light('rim light', (75, -30, 0), (.3, .3, .3, 1))
+
+    def _set_input(self):
+        self.accept('mouse1-up', self.on_click)
+
+    def on_click(self):
+        if not base.mouseWatcherNode.has_mouse(): return
+        p_from = Point3()  # in camera coordinates
+        p_to = 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
+        for hit in self._world.ray_test_all(p_from, p_to).get_hits():
+            for item in [i for i in self.items if hit.get_node() == i.node]:
+                item.on_click(hit)