ya2 · news · projects · code · about

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