ya2 · news · projects · code · about

bd7d9bfaf3d02192ef27163af439899667ff9a62
[pmachines.git] / pmachines / scene.py
1 from panda3d.core import AmbientLight, DirectionalLight, Point3
2 from panda3d.bullet import BulletPlaneShape, BulletGhostNode# BulletRigidBodyNode
3 from direct.showbase.DirectObject import DirectObject
4 from pmachines.items.background import Background
5 from pmachines.items.box import Box
6
7
8 class Scene(DirectObject):
9
10 def __init__(self, world):
11 super().__init__()
12 self._world = world
13 self._set_camera()
14 self._set_lights()
15 self._set_input()
16 self._set_mouse_plane()
17 Background()
18 self.items = [Box(world)]
19 taskMgr.add(self.on_frame, 'on_frame')
20
21 def _set_camera(self):
22 base.camera.set_pos(0, -20, 0)
23 base.camera.look_at(0, 0, 0)
24
25 def _set_directional_light(self, name, hpr, color):
26 light = DirectionalLight(name)
27 light_np = render.attach_new_node(light)
28 light_np.set_hpr(*hpr)
29 light.set_color(color)
30 render.set_light(light_np)
31
32 def _set_lights(self):
33 alight = AmbientLight('alight') # for ao
34 alight.set_color((.4, .4, .4, 1))
35 alnp = render.attach_new_node(alight)
36 render.set_light(alnp)
37 self._set_directional_light('key light', (315, -60, 0),
38 (3.6, 3.6, 3.6, 1))
39 self._set_directional_light('fill light', (195, -30, 0),
40 (.4, .4, .4, 1))
41 self._set_directional_light('rim light', (75, -30, 0), (.3, .3, .3, 1))
42
43 def _set_input(self):
44 self.accept('mouse1', self.on_click)
45 self.accept('mouse1-up', self.on_release)
46 self.accept('p-up', self.on_play)
47
48 def _set_mouse_plane(self):
49 shape = BulletPlaneShape((0, -1, 0), 1)
50 #self._mouse_plane_node = BulletRigidBodyNode('mouse plane')
51 self._mouse_plane_node = BulletGhostNode('mouse plane')
52 self._mouse_plane_node.addShape(shape)
53 #np = render.attachNewNode(self._mouse_plane_node)
54 #self._world.attachRigidBody(self._mouse_plane_node)
55 self._world.attachGhost(self._mouse_plane_node)
56
57 def _get_hits(self):
58 if not base.mouseWatcherNode.has_mouse(): return []
59 p_from = Point3() # in camera coordinates
60 p_to = Point3() # in camera coordinates
61 base.camLens.extrude(base.mouseWatcherNode.get_mouse(), p_from, p_to)
62 p_from = render.get_relative_point(base.cam, p_from) # global coords
63 p_to = render.get_relative_point(base.cam, p_to) # global coords
64 return self._world.ray_test_all(p_from, p_to).get_hits()
65
66 def on_click(self):
67 for hit in self._get_hits():
68 if hit.get_node() == self._mouse_plane_node:
69 pos = hit.get_hit_pos()
70 for hit in self._get_hits():
71 for item in [i for i in self.items if hit.get_node() == i.node]:
72 item.on_click(pos)
73
74 def on_release(self):
75 for hit in self._get_hits():
76 for item in [i for i in self.items if hit.get_node() == i.node]:
77 item.on_release()
78
79 def on_frame(self, task):
80 hits = self._get_hits()
81 pos = None
82 for hit in self._get_hits():
83 if hit.get_node() == self._mouse_plane_node:
84 pos = hit.get_hit_pos()
85 hit_nodes = [hit.get_node() for hit in hits]
86 items_hit = [itm for itm in self.items if itm.node in hit_nodes]
87 items_no_hit = [itm for itm in self.items if itm not in items_hit]
88 [itm.on_mouse_on() for itm in items_hit]
89 [itm.on_mouse_off() for itm in items_no_hit]
90 if pos:
91 [itm.on_mouse_move(pos) for itm in self.items]
92 return task.cont
93
94 def on_play(self):
95 [itm.play() for itm in self.items]