class Exit (BlockRenderer): size = (.3,) * 3 size_arrow = (.9,) * 3 color = (.5,) * 3 shape_class = shapes.Disc color_on = hex_color_f("34B27D") color_arr = hex_color_f("DBDB5780") def __init__(self, batch, group, x, y, block): super(Exit, self).__init__(batch, group, x, y, block) self.arrows = shapes.Arrows(batch, group, (x, y, 0), self.size_arrow, self.color_arr) self.alpha_arr = Spring(self.color_arr[3], .2, .01) self.color_spr = Spring(Vector3(*self.color), .1, .01) self.is_on = block.is_on def delete(self): super(Exit, self).delete() self.arrows.delete() def update(self): if self.is_on != self.block.is_on: self.is_on = self.block.is_on if self.is_on: self.alpha_arr.next_value = 1 self.color_spr.next_value = Vector3(*self.color_on) else: self.alpha_arr.next_value = self.color_arr[3] self.color_spr.next_value = Vector3(*self.color) self.alpha_arr.tick() self.color_spr.tick() self.shape.vlist.colors[:] = tuple(self.color_spr.value) * self.shape.vertex_count self.arrows.vlist.colors[3::4] = (self.alpha_arr.value,) * self.arrows.vertex_count
class Mirror (BlockRenderer): size = (.8, .1, .9) color = (.1, .9, .9) def __init__(self, batch, group, x, y, block): group = RotateGroup(x, y, block.slope, parent=group) super(Mirror, self).__init__(batch, group, 0, 0, block) self.group = group self.slope = Spring(block.slope, 0.2, 0.1) def update(self): self.slope.next_value = self.block.slope self.slope.tick() self.group.angle = 45 * self.slope.value
class Launcher (BlockRenderer): size = (.4, .4, .8) color = hex_color_f("4D77CB") rotate = (math.pi / 2, 0, 0) shape_class = shapes.Pyramid def __init__(self, batch, group, x, y, block): group = RotateGroup(x, y, block.all_states_idx, parent=group) super(Launcher, self).__init__(batch, group, 0, 0, block) self.group = group self.state = Spring(block.all_states_idx, 0.2, 0.1) def update(self): self.state.next_value = self.block.all_states_idx self.state.tick() self.group.angle = 90 * self.state.value
class Popup (object): SPEED = 0.2 SNAP = 0.001 SLEEP = 60 POS_Y = 0.3 def __init__(self, text, color): font = PopupFont() self.label = pyglet.text.Label( text, anchor_x = 'center', font_name = font.name, font_size = font.size, anchor_y = 'baseline', color = color ) self.offset = Spring(Vector2(1.5, self.POS_Y), self.SPEED, self.SNAP) self.offset.next_value = Vector2(.5, self.POS_Y) self.sleep = self.SLEEP self.done = False def tick(self): self.offset.tick() if self.offset.static: if self.done: self.label.delete() return DONE if self.sleep > 0: self.sleep -= 1 else: self.offset.next_value = Vector2(-.5, self.POS_Y) self.done = True def draw(self, window): x, y = self.offset.value.xy glPushMatrix() glTranslatef(x * window.width, y * window.height, 0) self.label.draw() glPopMatrix()
class Camera(object): SPEED = 0.1 CLIP = 0.01 def __init__(self, eye, center, up): self.eye = Spring(eye, self.SPEED, self.CLIP) self.vec = Spring(center - eye, self.SPEED, self.CLIP) self.up = Spring(up, self.SPEED, self.CLIP) self.ofs = Spring(0, 0.1, 0.01) self.modelview = (GLdouble * 16)() self.projection = (GLdouble * 16)() self.viewport = (GLint * 4)() self.unproj = [GLdouble(), GLdouble(), GLdouble()] def resize(self, x, y, w, h): glViewport(x, y, w, h) self.viewport[:] = (x, y, w, h) glMatrixMode(gl.GL_PROJECTION) glLoadIdentity() glu.gluPerspective(45.0, w / h, 0.1, 50) glMatrixMode(gl.GL_MODELVIEW) def move(self, eye, center, up): self.eye.next_value = eye self.vec.next_value = center - eye self.up.next_value = up def shake(self, amount): self.ofs.value = amount def tick(self): self.eye.tick() self.vec.tick() self.up.tick() self.ofs.tick() def setup(self): eye = self.eye.value + Vector3(uniform(0, 1), uniform(0, 1), uniform(0, 1)) * self.ofs.value center = eye + self.vec.value up = self.up.value gluLookAt(eye.x, eye.y, eye.z, center.x, center.y, center.z, up.x, up.y, up.z) glGetDoublev(GL_MODELVIEW_MATRIX, self.modelview) glGetDoublev(GL_PROJECTION_MATRIX, self.projection) def _unproject(self, x, y, z): gluUnProject( x, y, z, self.modelview, self.projection, self.viewport, self.unproj[0], self.unproj[1], self.unproj[2] ) return Vector3(*[v.value for v in self.unproj]) def unproject(self, (x, y)): # http://stackoverflow.com/questions/9406269/object-picking-with-ray-casting l0 = self._unproject(x, y, 0.1) l1 = self._unproject(x, y, 0.9) ld = l1 - l0 # http://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection # assuming that p0 = (0, 0, 0), and n = (0, 0, -1) d = -l0.z / ld.z p = l0 + ld * d return p