ya2 · news · projects · code · about

buttons
[pmachines.git] / pmachines / scene.py
CommitLineData
1be87278 1from panda3d.core import AmbientLight, DirectionalLight, Point3
36099535
FC
2from panda3d.bullet import BulletPlaneShape, BulletGhostNode
3from direct.gui.OnscreenImage import OnscreenImage
4from direct.gui.DirectGui import DirectButton
5from direct.gui.DirectGuiGlobals import FLAT, DISABLED, NORMAL
1be87278
FC
6from direct.showbase.DirectObject import DirectObject
7from pmachines.items.background import Background
8from pmachines.items.box import Box
9
10
11class Scene(DirectObject):
12
13 def __init__(self, world):
14 super().__init__()
15 self._world = world
16 self._set_camera()
36099535 17 self._set_gui()
1be87278
FC
18 self._set_lights()
19 self._set_input()
c8d8653f 20 self._set_mouse_plane()
1be87278
FC
21 Background()
22 self.items = [Box(world)]
37ba71d8 23 taskMgr.add(self.on_frame, 'on_frame')
1be87278
FC
24
25 def _set_camera(self):
26 base.camera.set_pos(0, -20, 0)
27 base.camera.look_at(0, 0, 0)
28
36099535
FC
29 def _set_gui(self):
30 def load_img_btn(path, col):
31 img = OnscreenImage('assets/buttons/%s.png' % path)
32 img.set_transparency(True)
33 img.set_color(col)
34 img.detach_node()
35 return img
36 def load_images_btn(path):
37 colors = [
38 (.6, .6, .6, 1), # ready
39 (1, 1, 1, 1), # press
40 (.8, .8, .8, 1), # rollover
41 (.4, .4, .4, .4)] # disabled
42 return [load_img_btn(path, col) for col in colors]
43 abl, abr = base.a2dBottomLeft, base.a2dBottomRight
44 btn_info = [
45 ('home', self.on_home, DISABLED, abl),
46 ('information', self.on_information, DISABLED, abl),
47 ('right', self.on_play, NORMAL, abr),
48 ('next', self.on_next, DISABLED, abr),
49 ('previous', self.on_prev, DISABLED, abr),
50 ('rewind', self.on_rewind, DISABLED, abr)]
51 num_l = num_r = 0
52 for binfo in btn_info:
53 imgs = load_images_btn(binfo[0])
54 if binfo[3] == base.a2dBottomLeft:
55 sign, num = 1, num_l
56 num_l += 1
57 else:
58 sign, num = -1, num_r
59 num_r += 1
60 fcols = (.4, .4, .4, .14), (.3, .3, .3, .05)
61 btn = DirectButton(
62 image=imgs, scale=.05, pos=(sign * (.06 + .11 * num), 1, .06),
63 parent=binfo[3], command=binfo[1], state=binfo[2], relief=FLAT,
64 frameColor=fcols[0] if binfo[2] == NORMAL else fcols[1])
65 btn.set_transparency(True)
66
1be87278
FC
67 def _set_directional_light(self, name, hpr, color):
68 light = DirectionalLight(name)
69 light_np = render.attach_new_node(light)
70 light_np.set_hpr(*hpr)
71 light.set_color(color)
72 render.set_light(light_np)
73
74 def _set_lights(self):
75 alight = AmbientLight('alight') # for ao
76 alight.set_color((.4, .4, .4, 1))
77 alnp = render.attach_new_node(alight)
78 render.set_light(alnp)
79 self._set_directional_light('key light', (315, -60, 0),
80 (3.6, 3.6, 3.6, 1))
81 self._set_directional_light('fill light', (195, -30, 0),
82 (.4, .4, .4, 1))
83 self._set_directional_light('rim light', (75, -30, 0), (.3, .3, .3, 1))
84
85 def _set_input(self):
49c79300 86 self.accept('mouse1', self.on_click_l)
c8d8653f 87 self.accept('mouse1-up', self.on_release)
49c79300
FC
88 self.accept('mouse3', self.on_click_r)
89 self.accept('mouse3-up', self.on_release)
c8d8653f
FC
90
91 def _set_mouse_plane(self):
92 shape = BulletPlaneShape((0, -1, 0), 1)
93 #self._mouse_plane_node = BulletRigidBodyNode('mouse plane')
94 self._mouse_plane_node = BulletGhostNode('mouse plane')
95 self._mouse_plane_node.addShape(shape)
96 #np = render.attachNewNode(self._mouse_plane_node)
97 #self._world.attachRigidBody(self._mouse_plane_node)
98 self._world.attachGhost(self._mouse_plane_node)
1be87278 99
37ba71d8
FC
100 def _get_hits(self):
101 if not base.mouseWatcherNode.has_mouse(): return []
1be87278
FC
102 p_from = Point3() # in camera coordinates
103 p_to = Point3() # in camera coordinates
104 base.camLens.extrude(base.mouseWatcherNode.get_mouse(), p_from, p_to)
105 p_from = render.get_relative_point(base.cam, p_from) # global coords
106 p_to = render.get_relative_point(base.cam, p_to) # global coords
37ba71d8
FC
107 return self._world.ray_test_all(p_from, p_to).get_hits()
108
49c79300 109 def _on_click(self, method):
c8d8653f
FC
110 for hit in self._get_hits():
111 if hit.get_node() == self._mouse_plane_node:
112 pos = hit.get_hit_pos()
37ba71d8 113 for hit in self._get_hits():
1be87278 114 for item in [i for i in self.items if hit.get_node() == i.node]:
49c79300
FC
115 getattr(item, method)(pos)
116
117 def on_click_l(self):
118 self._on_click('on_click_l')
119
120 def on_click_r(self):
121 self._on_click('on_click_r')
c8d8653f
FC
122
123 def on_release(self):
49c79300 124 [item.on_release() for item in self.items]
37ba71d8
FC
125
126 def on_frame(self, task):
c8d8653f
FC
127 hits = self._get_hits()
128 pos = None
129 for hit in self._get_hits():
130 if hit.get_node() == self._mouse_plane_node:
131 pos = hit.get_hit_pos()
132 hit_nodes = [hit.get_node() for hit in hits]
37ba71d8
FC
133 items_hit = [itm for itm in self.items if itm.node in hit_nodes]
134 items_no_hit = [itm for itm in self.items if itm not in items_hit]
135 [itm.on_mouse_on() for itm in items_hit]
136 [itm.on_mouse_off() for itm in items_no_hit]
c8d8653f
FC
137 if pos:
138 [itm.on_mouse_move(pos) for itm in self.items]
37ba71d8 139 return task.cont
c8d8653f
FC
140
141 def on_play(self):
142 [itm.play() for itm in self.items]
36099535
FC
143
144 def on_next(self):
145 print('on_next')
146
147 def on_prev(self):
148 print('on_prev')
149
150 def on_rewind(self):
151 print('on_rewind')
152
153 def on_home(self):
154 print('on_home')
155
156 def on_information(self):
157 print('on_information')