Commit | Line | Data |
---|---|---|
1be87278 | 1 | from panda3d.core import AmbientLight, DirectionalLight, Point3 |
c8d8653f | 2 | from panda3d.bullet import BulletPlaneShape, BulletGhostNode# BulletRigidBodyNode |
1be87278 FC |
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() | |
c8d8653f | 16 | self._set_mouse_plane() |
1be87278 FC |
17 | Background() |
18 | self.items = [Box(world)] | |
37ba71d8 | 19 | taskMgr.add(self.on_frame, 'on_frame') |
1be87278 FC |
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): | |
49c79300 | 44 | self.accept('mouse1', self.on_click_l) |
c8d8653f | 45 | self.accept('mouse1-up', self.on_release) |
49c79300 FC |
46 | self.accept('mouse3', self.on_click_r) |
47 | self.accept('mouse3-up', self.on_release) | |
c8d8653f FC |
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) | |
1be87278 | 58 | |
37ba71d8 FC |
59 | def _get_hits(self): |
60 | if not base.mouseWatcherNode.has_mouse(): return [] | |
1be87278 FC |
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 | |
37ba71d8 FC |
66 | return self._world.ray_test_all(p_from, p_to).get_hits() |
67 | ||
49c79300 | 68 | def _on_click(self, method): |
c8d8653f FC |
69 | for hit in self._get_hits(): |
70 | if hit.get_node() == self._mouse_plane_node: | |
71 | pos = hit.get_hit_pos() | |
37ba71d8 | 72 | for hit in self._get_hits(): |
1be87278 | 73 | for item in [i for i in self.items if hit.get_node() == i.node]: |
49c79300 FC |
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') | |
c8d8653f FC |
81 | |
82 | def on_release(self): | |
49c79300 | 83 | [item.on_release() for item in self.items] |
37ba71d8 FC |
84 | |
85 | def on_frame(self, task): | |
c8d8653f FC |
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] | |
37ba71d8 FC |
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] | |
c8d8653f FC |
96 | if pos: |
97 | [itm.on_mouse_move(pos) for itm in self.items] | |
37ba71d8 | 98 | return task.cont |
c8d8653f FC |
99 | |
100 | def on_play(self): | |
101 | [itm.play() for itm in self.items] |