ya2 · news · projects · code · about

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