ya2 · news · projects · code · about

dbc6282a6dcf22a8764b0b142ecd7d1aa3443a7a
[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_l)
45 self.accept('mouse1-up', self.on_release)
46 self.accept('mouse3', self.on_click_r)
47 self.accept('mouse3-up', self.on_release)
48 self.accept('p-up', self.on_play)
49
50 def _set_mouse_plane(self):
51 shape = BulletPlaneShape((0, -1, 0), 1)
52 #self._mouse_plane_node = BulletRigidBodyNode('mouse plane')
53 self._mouse_plane_node = BulletGhostNode('mouse plane')
54 self._mouse_plane_node.addShape(shape)
55 #np = render.attachNewNode(self._mouse_plane_node)
56 #self._world.attachRigidBody(self._mouse_plane_node)
57 self._world.attachGhost(self._mouse_plane_node)
58
59 def _get_hits(self):
60 if not base.mouseWatcherNode.has_mouse(): return []
61 p_from = Point3() # in camera coordinates
62 p_to = Point3() # in camera coordinates
63 base.camLens.extrude(base.mouseWatcherNode.get_mouse(), p_from, p_to)
64 p_from = render.get_relative_point(base.cam, p_from) # global coords
65 p_to = render.get_relative_point(base.cam, p_to) # global coords
66 return self._world.ray_test_all(p_from, p_to).get_hits()
67
68 def _on_click(self, method):
69 for hit in self._get_hits():
70 if hit.get_node() == self._mouse_plane_node:
71 pos = hit.get_hit_pos()
72 for hit in self._get_hits():
73 for item in [i for i in self.items if hit.get_node() == i.node]:
74 getattr(item, method)(pos)
75
76 def on_click_l(self):
77 self._on_click('on_click_l')
78
79 def on_click_r(self):
80 self._on_click('on_click_r')
81
82 def on_release(self):
83 [item.on_release() for item in self.items]
84
85 def on_frame(self, task):
86 hits = self._get_hits()
87 pos = None
88 for hit in self._get_hits():
89 if hit.get_node() == self._mouse_plane_node:
90 pos = hit.get_hit_pos()
91 hit_nodes = [hit.get_node() for hit in hits]
92 items_hit = [itm for itm in self.items if itm.node in hit_nodes]
93 items_no_hit = [itm for itm in self.items if itm not in items_hit]
94 [itm.on_mouse_on() for itm in items_hit]
95 [itm.on_mouse_off() for itm in items_no_hit]
96 if pos:
97 [itm.on_mouse_move(pos) for itm in self.items]
98 return task.cont
99
100 def on_play(self):
101 [itm.play() for itm in self.items]