ya2 · news · projects · code · about

on aspect ratio changed
[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 25 Background()
7850ccc4 26 self.items = [Box(world, self._mouse_plane_node, 3, self.cb_inst)]
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):
651713a9 104 shape = BulletPlaneShape((0, -1, 0), 0)
c8d8653f
FC
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 []
7850ccc4 114 p_from, p_to = Point3(), Point3() # in camera coordinates
1be87278
FC
115 base.camLens.extrude(base.mouseWatcherNode.get_mouse(), p_from, p_to)
116 p_from = render.get_relative_point(base.cam, p_from) # global coords
117 p_to = render.get_relative_point(base.cam, p_to) # global coords
37ba71d8
FC
118 return self._world.ray_test_all(p_from, p_to).get_hits()
119
49c79300 120 def _on_click(self, method):
c8d8653f
FC
121 for hit in self._get_hits():
122 if hit.get_node() == self._mouse_plane_node:
123 pos = hit.get_hit_pos()
37ba71d8 124 for hit in self._get_hits():
1be87278 125 for item in [i for i in self.items if hit.get_node() == i.node]:
49c79300 126 getattr(item, method)(pos)
79f81d48
FC
127 img = 'move' if method == 'on_click_l' else 'rotate'
128 self._cursor.set_image('assets/buttons/%s.png' % img)
49c79300
FC
129
130 def on_click_l(self):
131 self._on_click('on_click_l')
132
133 def on_click_r(self):
134 self._on_click('on_click_r')
c8d8653f
FC
135
136 def on_release(self):
49c79300 137 [item.on_release() for item in self.items]
79f81d48 138 self._cursor.set_image('assets/buttons/arrowUpLeft.png')
37ba71d8 139
651713a9
FC
140 def on_aspect_ratio_changed(self):
141 [item.on_aspect_ratio_changed() for item in self.items]
142
37ba71d8 143 def on_frame(self, task):
c8d8653f
FC
144 hits = self._get_hits()
145 pos = None
146 for hit in self._get_hits():
147 if hit.get_node() == self._mouse_plane_node:
148 pos = hit.get_hit_pos()
149 hit_nodes = [hit.get_node() for hit in hits]
37ba71d8
FC
150 items_hit = [itm for itm in self.items if itm.node in hit_nodes]
151 items_no_hit = [itm for itm in self.items if itm not in items_hit]
152 [itm.on_mouse_on() for itm in items_hit]
153 [itm.on_mouse_off() for itm in items_no_hit]
c8d8653f
FC
154 if pos:
155 [itm.on_mouse_move(pos) for itm in self.items]
37ba71d8 156 return task.cont
c8d8653f 157
7850ccc4
FC
158 def cb_inst(self, item):
159 self.items += [item]
160
c8d8653f
FC
161 def on_play(self):
162 [itm.play() for itm in self.items]
36099535
FC
163
164 def on_next(self):
165 print('on_next')
166
167 def on_prev(self):
168 print('on_prev')
169
170 def on_rewind(self):
171 print('on_rewind')
172
173 def on_home(self):
174 print('on_home')
175
176 def on_information(self):
177 print('on_information')