ya2 · news · projects · code · about

instantiation
[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):
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 []
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
FC
139
140 def on_frame(self, task):
c8d8653f
FC
141 hits = self._get_hits()
142 pos = None
143 for hit in self._get_hits():
144 if hit.get_node() == self._mouse_plane_node:
145 pos = hit.get_hit_pos()
146 hit_nodes = [hit.get_node() for hit in hits]
37ba71d8
FC
147 items_hit = [itm for itm in self.items if itm.node in hit_nodes]
148 items_no_hit = [itm for itm in self.items if itm not in items_hit]
149 [itm.on_mouse_on() for itm in items_hit]
150 [itm.on_mouse_off() for itm in items_no_hit]
c8d8653f
FC
151 if pos:
152 [itm.on_mouse_move(pos) for itm in self.items]
37ba71d8 153 return task.cont
c8d8653f 154
7850ccc4
FC
155 def cb_inst(self, item):
156 self.items += [item]
157
c8d8653f
FC
158 def on_play(self):
159 [itm.play() for itm in self.items]
36099535
FC
160
161 def on_next(self):
162 print('on_next')
163
164 def on_prev(self):
165 print('on_prev')
166
167 def on_rewind(self):
168 print('on_rewind')
169
170 def on_home(self):
171 print('on_home')
172
173 def on_information(self):
174 print('on_information')