Commit | Line | Data |
---|---|---|
1be87278 FC |
1 | from panda3d.core import AmbientLight, DirectionalLight, Point3 |
2 | from direct.showbase.DirectObject import DirectObject | |
3 | from pmachines.items.background import Background | |
4 | from pmachines.items.box import Box | |
5 | ||
6 | ||
7 | class Scene(DirectObject): | |
8 | ||
9 | def __init__(self, world): | |
10 | super().__init__() | |
11 | self._world = world | |
12 | self._set_camera() | |
13 | self._set_lights() | |
14 | self._set_input() | |
15 | Background() | |
16 | self.items = [Box(world)] | |
37ba71d8 | 17 | taskMgr.add(self.on_frame, 'on_frame') |
1be87278 FC |
18 | |
19 | def _set_camera(self): | |
20 | base.camera.set_pos(0, -20, 0) | |
21 | base.camera.look_at(0, 0, 0) | |
22 | ||
23 | def _set_directional_light(self, name, hpr, color): | |
24 | light = DirectionalLight(name) | |
25 | light_np = render.attach_new_node(light) | |
26 | light_np.set_hpr(*hpr) | |
27 | light.set_color(color) | |
28 | render.set_light(light_np) | |
29 | ||
30 | def _set_lights(self): | |
31 | alight = AmbientLight('alight') # for ao | |
32 | alight.set_color((.4, .4, .4, 1)) | |
33 | alnp = render.attach_new_node(alight) | |
34 | render.set_light(alnp) | |
35 | self._set_directional_light('key light', (315, -60, 0), | |
36 | (3.6, 3.6, 3.6, 1)) | |
37 | self._set_directional_light('fill light', (195, -30, 0), | |
38 | (.4, .4, .4, 1)) | |
39 | self._set_directional_light('rim light', (75, -30, 0), (.3, .3, .3, 1)) | |
40 | ||
41 | def _set_input(self): | |
42 | self.accept('mouse1-up', self.on_click) | |
43 | ||
37ba71d8 FC |
44 | def _get_hits(self): |
45 | if not base.mouseWatcherNode.has_mouse(): return [] | |
1be87278 FC |
46 | p_from = Point3() # in camera coordinates |
47 | p_to = Point3() # in camera coordinates | |
48 | base.camLens.extrude(base.mouseWatcherNode.get_mouse(), p_from, p_to) | |
49 | p_from = render.get_relative_point(base.cam, p_from) # global coords | |
50 | p_to = render.get_relative_point(base.cam, p_to) # global coords | |
37ba71d8 FC |
51 | return self._world.ray_test_all(p_from, p_to).get_hits() |
52 | ||
53 | def on_click(self): | |
54 | for hit in self._get_hits(): | |
1be87278 FC |
55 | for item in [i for i in self.items if hit.get_node() == i.node]: |
56 | item.on_click(hit) | |
37ba71d8 FC |
57 | |
58 | def on_frame(self, task): | |
59 | hit_nodes = [hit.get_node() for hit in self._get_hits()] | |
60 | items_hit = [itm for itm in self.items if itm.node in hit_nodes] | |
61 | items_no_hit = [itm for itm in self.items if itm not in items_hit] | |
62 | [itm.on_mouse_on() for itm in items_hit] | |
63 | [itm.on_mouse_off() for itm in items_no_hit] | |
64 | return task.cont |