ya2 · news · projects · code · about

mouse cursor
[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,
74 frameColor=fcols[0] if binfo[2] == NORMAL else fcols[1])
75 btn.set_transparency(True)
76
1be87278
FC
77 def _set_directional_light(self, name, hpr, color):
78 light = DirectionalLight(name)
79 light_np = render.attach_new_node(light)
80 light_np.set_hpr(*hpr)
81 light.set_color(color)
82 render.set_light(light_np)
83
84 def _set_lights(self):
85 alight = AmbientLight('alight') # for ao
86 alight.set_color((.4, .4, .4, 1))
87 alnp = render.attach_new_node(alight)
88 render.set_light(alnp)
89 self._set_directional_light('key light', (315, -60, 0),
90 (3.6, 3.6, 3.6, 1))
91 self._set_directional_light('fill light', (195, -30, 0),
92 (.4, .4, .4, 1))
93 self._set_directional_light('rim light', (75, -30, 0), (.3, .3, .3, 1))
94
95 def _set_input(self):
49c79300 96 self.accept('mouse1', self.on_click_l)
c8d8653f 97 self.accept('mouse1-up', self.on_release)
49c79300
FC
98 self.accept('mouse3', self.on_click_r)
99 self.accept('mouse3-up', self.on_release)
c8d8653f
FC
100
101 def _set_mouse_plane(self):
102 shape = BulletPlaneShape((0, -1, 0), 1)
103 #self._mouse_plane_node = BulletRigidBodyNode('mouse plane')
104 self._mouse_plane_node = BulletGhostNode('mouse plane')
105 self._mouse_plane_node.addShape(shape)
106 #np = render.attachNewNode(self._mouse_plane_node)
107 #self._world.attachRigidBody(self._mouse_plane_node)
108 self._world.attachGhost(self._mouse_plane_node)
1be87278 109
37ba71d8
FC
110 def _get_hits(self):
111 if not base.mouseWatcherNode.has_mouse(): return []
1be87278
FC
112 p_from = Point3() # in camera coordinates
113 p_to = Point3() # in camera coordinates
114 base.camLens.extrude(base.mouseWatcherNode.get_mouse(), p_from, p_to)
115 p_from = render.get_relative_point(base.cam, p_from) # global coords
116 p_to = render.get_relative_point(base.cam, p_to) # global coords
37ba71d8
FC
117 return self._world.ray_test_all(p_from, p_to).get_hits()
118
49c79300 119 def _on_click(self, method):
c8d8653f
FC
120 for hit in self._get_hits():
121 if hit.get_node() == self._mouse_plane_node:
122 pos = hit.get_hit_pos()
37ba71d8 123 for hit in self._get_hits():
1be87278 124 for item in [i for i in self.items if hit.get_node() == i.node]:
49c79300 125 getattr(item, method)(pos)
79f81d48
FC
126 img = 'move' if method == 'on_click_l' else 'rotate'
127 self._cursor.set_image('assets/buttons/%s.png' % img)
49c79300
FC
128
129 def on_click_l(self):
130 self._on_click('on_click_l')
131
132 def on_click_r(self):
133 self._on_click('on_click_r')
c8d8653f
FC
134
135 def on_release(self):
49c79300 136 [item.on_release() for item in self.items]
79f81d48 137 self._cursor.set_image('assets/buttons/arrowUpLeft.png')
37ba71d8
FC
138
139 def on_frame(self, task):
c8d8653f
FC
140 hits = self._get_hits()
141 pos = None
142 for hit in self._get_hits():
143 if hit.get_node() == self._mouse_plane_node:
144 pos = hit.get_hit_pos()
145 hit_nodes = [hit.get_node() for hit in hits]
37ba71d8
FC
146 items_hit = [itm for itm in self.items if itm.node in hit_nodes]
147 items_no_hit = [itm for itm in self.items if itm not in items_hit]
148 [itm.on_mouse_on() for itm in items_hit]
149 [itm.on_mouse_off() for itm in items_no_hit]
c8d8653f
FC
150 if pos:
151 [itm.on_mouse_move(pos) for itm in self.items]
37ba71d8 152 return task.cont
c8d8653f
FC
153
154 def on_play(self):
155 [itm.play() for itm in self.items]
36099535
FC
156
157 def on_next(self):
158 print('on_next')
159
160 def on_prev(self):
161 print('on_prev')
162
163 def on_rewind(self):
164 print('on_rewind')
165
166 def on_home(self):
167 print('on_home')
168
169 def on_information(self):
170 print('on_information')