ya2 · news · projects · code · about

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