ya2 · news · projects · code · about

outline
[pmachines.git] / pmachines / scene.py
... / ...
CommitLineData
1from panda3d.core import AmbientLight, DirectionalLight, Point3
2from direct.showbase.DirectObject import DirectObject
3from pmachines.items.background import Background
4from pmachines.items.box import Box
5
6
7class 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)]
17 taskMgr.add(self.on_frame, 'on_frame')
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
44 def _get_hits(self):
45 if not base.mouseWatcherNode.has_mouse(): return []
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
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():
55 for item in [i for i in self.items if hit.get_node() == i.node]:
56 item.on_click(hit)
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