예제 #1
0
파일: scatter.py 프로젝트: arasbm/kivy
    def apply_angle_scale_trans(self, angle, scale, trans, point=Vector(0, 0)):
        '''Update matrix transformation by adding new angle,
           scale and translate.

        :Parameters:
            `angle` : float
                Rotation angle to add
            `scale` : float
                Scaling value to add
            `trans` : Vector
                Vector translation to add
            `point` : Vector, default to (0, 0)
                Point to apply transformation
        '''
        old_scale = self.scale
        new_scale = old_scale * scale
        if new_scale < self.scale_min or old_scale > self.scale_max:
            scale = 1.

        t = Matrix().translate(
            trans[0] * self.do_translation_x,
            trans[1] * self.do_translation_y,
            0)
        t = t.multiply(Matrix().translate(point[0], point[1], 0))
        t = t.multiply(Matrix().rotate(angle, 0, 0, 1))
        t = t.multiply(Matrix().scale(scale, scale, scale))
        t = t.multiply(Matrix().translate(-point[0], -point[1], 0))
        self.apply_transform(t)
예제 #2
0
파일: __init__.py 프로젝트: estuans/kivy
    def update_viewport(self):
        from kivy.graphics.opengl import glViewport
        from kivy.graphics.transformation import Matrix
        from math import radians

        w, h = self.system_size
        w2, h2 = w / 2., h / 2.
        r = radians(self.rotation)

        # prepare the viewport
        glViewport(0, 0, w, h)

        # do projection matrix
        projection_mat = Matrix()
        projection_mat.view_clip(0.0, w, 0.0, h, -1.0, 1.0, 0)
        self.render_context['projection_mat'] = projection_mat

        # do modelview matrix
        modelview_mat = Matrix().translate(w2, h2, 0)
        modelview_mat = modelview_mat.multiply(Matrix().rotate(r, 0, 0, 1))

        w, h = self.size
        w2, h2 = w / 2., h / 2.
        modelview_mat = modelview_mat.multiply(Matrix().translate(-w2, -h2, 0))
        self.render_context['modelview_mat'] = modelview_mat

        # redraw canvas
        self.canvas.ask_update()

        # and update childs
        self.update_childsize()
예제 #3
0
파일: scatter.py 프로젝트: Bakterija/kivy
    def apply_transform(self, trans, post_multiply=False, anchor=(0, 0)):
        '''
        Transforms the scatter by applying the "trans" transformation
        matrix (on top of its current transformation state). The resultant
        matrix can be found in the :attr:`~Scatter.transform` property.

        :Parameters:
            `trans`: :class:`~kivy.graphics.transformation.Matrix`.
                Transformation matix to be applied to the scatter widget.
            `anchor`: tuple, defaults to (0, 0).
                The point to use as the origin of the transformation
                (uses local widget space).
            `post_multiply`: bool, defaults to False.
                If True, the transform matrix is post multiplied
                (as if applied before the current transform).

        Usage example::

            from kivy.graphics.transformation import Matrix
            mat = Matrix().scale(3, 3, 3)
            scatter_instance.apply_transform(mat)

        '''
        t = Matrix().translate(anchor[0], anchor[1], 0)
        t = t.multiply(trans)
        t = t.multiply(Matrix().translate(-anchor[0], -anchor[1], 0))

        if post_multiply:
            self.transform = self.transform.multiply(t)
        else:
            self.transform = t.multiply(self.transform)
예제 #4
0
    def apply_angle_scale_trans(self, angle, scale, trans, point=Vector(0, 0)):
        '''Update matrix transformation by adding new angle,
           scale and translate.

        :Parameters:
            `angle` : float
                Rotation angle to add
            `scale` : float
                Scaling value to add
            `trans` : Vector
                Vector translation to add
            `point` : Vector, default to (0, 0)
                Point to apply transformation
        '''
        old_scale = self.scale
        new_scale = old_scale * scale
        if new_scale < self.scale_min or old_scale > self.scale_max:
            scale = 1.

        t = Matrix().translate(
            trans[0] * self.do_translation_x,
            trans[1] * self.do_translation_y,
            0)
        t = t.multiply(Matrix().translate(point[0], point[1], 0))
        t = t.multiply(Matrix().rotate(angle, 0, 0, 1))
        t = t.multiply(Matrix().scale(scale, scale, scale))
        t = t.multiply(Matrix().translate(-point[0], -point[1], 0))
        self.apply_transform(t)
예제 #5
0
    def apply_transform(self, trans, post_multiply=False, anchor=(0, 0)):
        '''
        Transforms the scatter by applying the "trans" transformation
        matrix (on top of its current transformation state). The resultant
        matrix can be found in the :attr:`~Scatter.transform` property.

        :Parameters:
            `trans`: :class:`~kivy.graphics.transformation.Matrix`.
                Transformation matix to be applied to the scatter widget.
            `anchor`: tuple, defaults to (0, 0).
                The point to use as the origin of the transformation
                (uses local widget space).
            `post_multiply`: bool, defaults to False.
                If True, the transform matrix is post multiplied
                (as if applied before the current transform).

        Usage example::

            from kivy.graphics.transformation import Matrix
            mat = Matrix().scale(3, 3, 3)
            scatter_instance.apply_transform(mat)

        '''
        t = Matrix().translate(anchor[0], anchor[1], 0)
        t = t.multiply(trans)
        t = t.multiply(Matrix().translate(-anchor[0], -anchor[1], 0))

        if post_multiply:
            self.transform = self.transform.multiply(t)
        else:
            self.transform = t.multiply(self.transform)
예제 #6
0
    def update_viewport(self):
        from kivy.graphics.opengl import glViewport
        from kivy.graphics.transformation import Matrix
        from math import radians

        w, h = self.system_size
        if self._density != 1:
            w, h = self.size

        smode = self.softinput_mode
        target = self._system_keyboard.target
        targettop = target.to_window(0, target.y)[1] if target else 0
        kheight = self.keyboard_height

        w2, h2 = w / 2., h / 2.
        r = radians(self.rotation)

        x, y = 0, 0
        _h = h
        if smode == 'pan':
            y = kheight
        elif smode == 'below_target':
            y = 0 if kheight < targettop else (kheight - targettop) + dp(9)
        if smode == 'scale':
            _h -= kheight

        # prepare the viewport
        glViewport(x, y, w, _h)

        # do projection matrix
        projection_mat = Matrix()
        projection_mat.view_clip(0.0, w, 0.0, h, -1.0, 1.0, 0)
        self.render_context['projection_mat'] = projection_mat

        # do modelview matrix
        modelview_mat = Matrix().translate(w2, h2, 0)
        modelview_mat = modelview_mat.multiply(Matrix().rotate(r, 0, 0, 1))

        w, h = self.size
        w2, h2 = w / 2., h / 2.
        modelview_mat = modelview_mat.multiply(Matrix().translate(-w2, -h2, 0))
        self.render_context['modelview_mat'] = modelview_mat

        # redraw canvas
        self.canvas.ask_update()

        # and update childs
        self.update_childsize()
예제 #7
0
    def update_glsl(self, *largs):
        width = self.width if self.width > 1 else 100
        height = self.height if self.height > 1 else 100
        asp = width / float(height)
        proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 600, 1)
        proj = Matrix()
        proj.perspective(self.perspective_value, asp, 1, 1000)

        matrix_camera = Matrix().identity()
        matrix_camera.look_at(0, 100, 300, 100, 0, -100, 0, 1, 0)
        self.canvas['projection_mat'] = proj
        self.canvas['diffuse_light'] = (0.0, 1.0, 0.0)
        self.canvas['ambient_light'] = (0.1, 0.1, 0.1)
        if self.shadow:
            self.canvas['texture1'] = 1
            self.canvas["enabled_shadow"] = 1.0
        else:

            self.canvas["enabled_shadow"] = 0.0
            self.canvas["texture1"] = 0

        depthProjectionMatrix = Matrix().view_clip(-100 * self.shadow_threshold, 100 * self.shadow_threshold,
                                                   -100 * self.shadow_threshold, 100 * self.shadow_threshold,
                                                   -100 * self.shadow_threshold, 200 * self.shadow_threshold * 2, 0)
        depthViewMatrix = Matrix().look_at(-0.5, -50, -100, 0, 0, 0, 0, 1, 0)
        depthModelMatrix = Matrix().identity()
        depthMVP = depthProjectionMatrix.multiply(depthViewMatrix).multiply(depthModelMatrix)
        self.canvas['depthMVP'] = depthMVP
        self.canvas['cond'] = (0.0, 0.7)
        self.canvas['val_sin'] = (self.alpha, 0.0)

        if self.shadow:
            self.update_fbo(largs[0])
예제 #8
0
    def update_glsl(self, *largs):
        width = self.width if self.width > 1 else 100
        height = self.height if self.height > 1 else 100

        asp = width / float(height)
        proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 600, 1)
        proj = Matrix()
        proj.perspective(self.perspective_value, asp, 1, 1000)

        matrix_camera = Matrix().identity()
        matrix_camera = matrix_camera.look_at(*self.look_at)

        self.canvas['projection_mat'] = proj
        self.canvas['camera'] = matrix_camera

        self.canvas['diffuse_light'] = (0.0, 1.0, 0.0)
        self.canvas['ambient_light'] = (0.1, 0.1, 0.1)
        if self.shadow:
            self.canvas['texture1'] = 1
            self.canvas["enabled_shadow"] = 1.0
        else:

            self.canvas["enabled_shadow"] = 0.0
            self.canvas["texture1"] = 0

        depthProjectionMatrix = Matrix().view_clip(
            -100 * self.shadow_threshold, 100 * self.shadow_threshold,
            -100 * self.shadow_threshold, 100 * self.shadow_threshold,
            -100 * self.shadow_threshold, 200 * self.shadow_threshold * 2, 0)
        _shadow_pos = self._shadow_pos
        _shadow_target = self._shadow_target
        depthViewMatrix = Matrix().look_at(
            _shadow_target[0], _shadow_target[1],
            _shadow_target[2] + self._shadow_offset, _shadow_pos[0],
            _shadow_pos[1], _shadow_pos[2], 0, 1, 0)

        depthModelMatrix = Matrix().identity()
        depthMVP = depthProjectionMatrix.multiply(depthViewMatrix).multiply(
            depthModelMatrix)
        self.canvas['depthMVP'] = depthMVP
        self.canvas['cond'] = (0.0, 0.7)
        self.canvas['val_sin'] = (self.alpha, 0.0)

        if self.shadow:
            self.update_fbo(largs[0])
            # label.text = str(Clock.get_rfps())

        if self.parent.parent is None:
            # del self.parent

            self.parent.canvas3d = None
            self.fbo_list.clear()
            self.fbo = None
            for a in self.nodes:
                a.remove_a()
            self.nodes = []
            self.parent._nodes = []
            self.parent.clear_widgets()
            self.adding_queue = []
            self.nt.cancel()
예제 #9
0
    def update_glsl(self, *largs):
        width = self.width if self.width > 1 else 100
        height = self.height if self.height > 1 else 100
        asp = width / float(height)
        proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 600, 1)
        proj = Matrix()
        proj.perspective(self.perspective_value, asp, 1, 1000)

        matrix_camera = Matrix().identity()
        matrix_camera.look_at(0, 100, 300, 100, 0, -100, 0, 1, 0)
        self.canvas['projection_mat'] = proj
        self.canvas['diffuse_light'] = (0.0, 1.0, 0.0)
        self.canvas['ambient_light'] = (0.1, 0.1, 0.1)
        if self.shadow:
            self.canvas['texture1'] = 1
            self.canvas["enabled_shadow"] = 1.0
        else:

            self.canvas["enabled_shadow"] = 0.0
            self.canvas["texture1"] = 0

        depthProjectionMatrix = Matrix().view_clip(
            -100 * self.shadow_threshold, 100 * self.shadow_threshold,
            -100 * self.shadow_threshold, 100 * self.shadow_threshold,
            -100 * self.shadow_threshold, 200 * self.shadow_threshold * 2, 0)
        depthViewMatrix = Matrix().look_at(-0.5, -50, -100, 0, 0, 0, 0, 1, 0)
        depthModelMatrix = Matrix().identity()
        depthMVP = depthProjectionMatrix.multiply(depthViewMatrix).multiply(
            depthModelMatrix)
        self.canvas['depthMVP'] = depthMVP
        self.canvas['cond'] = (0.0, 0.7)
        self.canvas['val_sin'] = (self.alpha, 0.0)

        if self.shadow:
            self.update_fbo(largs[0])
예제 #10
0
    def __init__(self, fs, length1, length2 = 1):
        size = (length1, length2)

        # it doesn't look like we can use float textures on mobile kivy, but people sometimes interconvert floats with 32bit rgba in shaders.
        # we would then have 3 shaders or texture rows or such, for x coord, y coord, angle, etc

        #Logger.info('float: ' + str(gl.getExtension('OES_texture_float')))
        texture = Texture.create(
            size = size,
            #bufferfmt = 'float'
        )
        self._fbo = Fbo(
            size = size,
            texture = texture,
            vs = default_vs,
            fs = header_fs + fs, 
        )

        # these matrices are to transform
        # window coordinates into data
        # coordinates
        centermat = Matrix()
        centermat.translate(-.5,-.5,-.5)
        idxscale = 1.0 / 255.0;
        idxmat = Matrix()
        idxmat.scale(idxscale, idxscale, idxscale)
        self._fbo['frag_coord2idx'] = idxmat.multiply(centermat)
        ratiomat = Matrix()
        ratiomat.scale(1.0 / length1, 1.0 / length2, 1.0)
        self._fbo['frag_coord2ratio'] = ratiomat

        self._texture_bindings = {}

        self._fbo.add_reload_observer(self._populate_fbo)
        self._populate_fbo(self._fbo)
예제 #11
0
    def update_fbo(self, time):
        width = self.width if self.width > 1 else 100
        height = self.height if self.height > 1 else 100

        asp = (width / float(height))
        proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 1600, 1)
        proj = Matrix()
        proj.perspective(self.perspective_value, asp, 1, 1000)

        lightInvDir = (0.5, 2, 2)
        depthProjectionMatrix = Matrix().view_clip(
            -100 * self.shadow_threshold, 100 * self.shadow_threshold,
            -100 * self.shadow_threshold, 100 * self.shadow_threshold,
            -100 * self.shadow_threshold, 200 * self.shadow_threshold * 2, 0)
        _shadow_pos = self._shadow_pos
        _shadow_target = self._shadow_target

        depthViewMatrix = Matrix().look_at(
            _shadow_target[0], _shadow_target[1],
            _shadow_target[2] + self._shadow_offset, _shadow_pos[0],
            _shadow_pos[1], _shadow_pos[2], 0, 1, 0)
        depthModelMatrix = Matrix().identity()
        depthMVP = depthProjectionMatrix.multiply(depthViewMatrix).multiply(
            depthModelMatrix)

        self.fbo['projection_mat'] = proj
        self.fbo['depthMVP'] = depthMVP
        self.fbo['diffuse_light'] = (0.0, 1.0, 0.0)
        self.fbo['ambient_light'] = self.ambient_light
        for m_pos in range(len(self.nodes)):
            motion_matrix = Matrix().view_clip(-asp, asp, -1, 1, 1, 600, 1)
            angle = self.nodes[m_pos].rotate[0] * 3.14 / 180
            pos = self.nodes[m_pos].get_pos()

            trans = self.nodes[m_pos].translate[:]

            result = [0, 0, 0]
            result[0] = 0.3 if trans[0] < pos[0] else -0.3
            result[1] = 0.3 if trans[1] < pos[1] else -0.3
            result[2] = 0.3 if trans[2] < pos[2] else -0.3

            motion_matrix = motion_matrix.translate(trans[0] + 0.1,
                                                    trans[1] + 0.1, trans[2])
            self.motion_blur_fbo['oldTransformation{0}'.format(
                str(m_pos))] = motion_matrix

        self.motion_blur_fbo['projection_mat'] = proj
        self.motion_blur_fbo['depthMVP'] = depthMVP

        matrix_camera = Matrix().identity()
        matrix_camera = matrix_camera.look_at(*self.look_at)

        if self.picking_fbo:
            self.picking_fbo['projection_mat'] = proj
            self.picking_fbo['camera'] = matrix_camera

        self.alpha += 10 * time
        self.fbo['cond'] = (0.0, 0.7)
        self.fbo['val_sin'] = (self.alpha, 0.0)
예제 #12
0
    def update_viewport(self):
        from kivy.graphics.opengl import glViewport
        from kivy.graphics.transformation import Matrix
        from math import radians

        w, h = self.system_size
        if self._density != 1:
            w, h = self.size

        smode = self.softinput_mode
        kheight = self.keyboard_height

        w2, h2 = w / 2.0, h / 2.0
        r = radians(self.rotation)

        x, y = 0, 0
        _h = h
        if smode:
            y = kheight
        if smode == "scale":
            _h -= kheight

        # prepare the viewport
        glViewport(x, y, w, _h)

        # do projection matrix
        projection_mat = Matrix()
        projection_mat.view_clip(0.0, w, 0.0, h, -1.0, 1.0, 0)
        self.render_context["projection_mat"] = projection_mat

        # do modelview matrix
        modelview_mat = Matrix().translate(w2, h2, 0)
        modelview_mat = modelview_mat.multiply(Matrix().rotate(r, 0, 0, 1))

        w, h = self.size
        w2, h2 = w / 2.0, h / 2.0
        modelview_mat = modelview_mat.multiply(Matrix().translate(-w2, -h2, 0))
        self.render_context["modelview_mat"] = modelview_mat

        # redraw canvas
        self.canvas.ask_update()

        # and update childs
        self.update_childsize()
예제 #13
0
    def update_viewport(self):
        from kivy.graphics.opengl import glViewport
        from kivy.graphics.transformation import Matrix
        from math import radians

        w, h = self.system_size

        smode = self.softinput_mode
        kheight = self.keyboard_height

        w2, h2 = w / 2., h / 2.
        r = radians(self.rotation)


        x, y = 0, 0
        _h = h
        if smode:
            y = kheight
        if smode == 'scale':
            _h -= kheight

        # prepare the viewport
        glViewport(x, y, w, _h)

        # do projection matrix
        projection_mat = Matrix()
        projection_mat.view_clip(0.0, w, 0.0, h, -1.0, 1.0, 0)
        self.render_context['projection_mat'] = projection_mat

        # do modelview matrix
        modelview_mat = Matrix().translate(w2, h2, 0)
        modelview_mat = modelview_mat.multiply(Matrix().rotate(r, 0, 0, 1))

        w, h = self.size
        w2, h2 = w / 2., h / 2.
        modelview_mat = modelview_mat.multiply(Matrix().translate(-w2, -h2, 0))
        self.render_context['modelview_mat'] = modelview_mat

        # redraw canvas
        self.canvas.ask_update()

        # and update childs
        self.update_childsize()
예제 #14
0
    def apply_image_transform(self, x=0, y=0, scale=1, post_multiply=False, anchor=(0, 0)):
        # Test if the x move is valid
        t = Matrix()
        t = t.translate(x, 0, 0)

        if not self.test_valid(t.multiply(self.transform)):
            x = 0

        # Test if the y move is valid
        t = Matrix()
        t = t.translate(0, y, 0)

        if not self.test_valid(t.multiply(self.transform)):
            y = 0

        # Test if the scale is valid
        t = Matrix().translate(anchor[0], anchor[1], 0)
        t = t.scale(scale, scale, scale)
        t = t.multiply(Matrix().translate(-anchor[0], -anchor[1], 0))

        if not self.test_valid(t.multiply(self.transform)):
            scale = 1

        # Compile final matrix
        t = Matrix().translate(anchor[0], anchor[1], 0)
        t = t.translate(x, y, 0)
        t = t.scale(scale, scale, scale)
        t = t.multiply(Matrix().translate(-anchor[0], -anchor[1], 0))

        if post_multiply:
            self.transform = self.transform.multiply(t)
        else:
            self.transform = t.multiply(self.transform)
예제 #15
0
    def apply_transform(self, trans, post_multiply=False, anchor=(0, 0)):
        '''
        Transforms scatter by trans (on top of its current transformation state)

        :Parameters:
            `trans`: transformation matrix from transformation lib.
                Transformation to be applied to the scatter widget
            `anchor`: tuple, default to (0, 0)
                The point to use as the origin of the transformation
                (uses local widget space)
            `post_multiply`: bool, default to False
                If true the transform matrix is post multiplied
                (as if applied before the current transform)
        '''
        t = Matrix().translate(anchor[0], anchor[1], 0)
        t = t.multiply(trans)
        t = t.multiply(Matrix().translate(-anchor[0], -anchor[1], 0))

        if post_multiply:
            self.transform = self.transform.multiply(t)
        else:
            self.transform = t.multiply(self.transform)
예제 #16
0
    def apply_transform(self, trans, post_multiply=False, anchor=(0, 0)):
        '''
        Transforms scatter by trans (on top of its current transformation state)

        :Parameters:
            `trans`: transformation matrix from transformation lib.
                Transformation to be applied to the scatter widget
            `anchor`: tuple, default to (0, 0)
                The point to use as the origin of the transformation
                (uses local widget space)
            `post_multiply`: bool, default to False
                If true the transform matrix is post multiplied
                (as if applied before the current transform)
        '''
        t = Matrix().translate(anchor[0], anchor[1], 0)
        t = t.multiply(trans)
        t = t.multiply(Matrix().translate(-anchor[0], -anchor[1], 0))

        if post_multiply:
            self.transform = self.transform.multiply(t)
        else:
            self.transform = t.multiply(self.transform)
예제 #17
0
    def update_fbo(self, time):
        width = self.width if self.width > 1 else 100
        height = self.height if self.height > 1 else 100
        asp = (width / float(height))
        proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 600, 1)
        proj = Matrix()
        proj.perspective(self.perspective_value, asp, 1, 1000)

        lightInvDir = (0.5, 2, 2)
        depthProjectionMatrix = Matrix().view_clip(-100 * self.shadow_threshold, 100 * self.shadow_threshold,
                                                   -100 * self.shadow_threshold, 100 * self.shadow_threshold,
                                                   -100 * self.shadow_threshold, 200 * self.shadow_threshold * 2, 0)
        depthViewMatrix = Matrix().look_at(-0.5, -50, -100, 0, 0, 0, 0, 1, 0)
        depthModelMatrix = Matrix().identity()
        depthMVP = depthProjectionMatrix.multiply(depthViewMatrix).multiply(depthModelMatrix)

        self.fbo['projection_mat'] = proj
        self.fbo['depthMVP'] = depthMVP
        self.fbo['diffuse_light'] = (0.0, 1.0, 0.0)
        self.fbo['ambient_light'] = (0.1, 0.1, 0.1)
        for m_pos in range(len(self.nodes)):
            motion_matrix = Matrix().view_clip(-asp, asp, -1, 1, 1, 600, 1)
            angle = self.nodes[m_pos].rotate[0] * 3.14 / 180
            pos = self.nodes[m_pos].get_pos()

            trans = self.nodes[m_pos].translate[:]

            result = [0, 0, 0]
            result[0] = 0.3 if trans[0] < pos[0] else -0.3
            result[1] = 0.3 if trans[1] < pos[1] else -0.3
            result[2] = 0.3 if trans[2] < pos[2] else -0.3

            motion_matrix = motion_matrix.translate(trans[0] + 0.1,
                                                    trans[1] + 0.1,
                                                    trans[2])
            self.motion_blur_fbo['oldTransformation{0}'.format(str(m_pos))] = motion_matrix

        self.motion_blur_fbo['projection_mat'] = proj
        self.motion_blur_fbo['depthMVP'] = depthMVP

        if self.picking_fbo:
            self.picking_fbo['projection_mat'] = proj

        self.alpha += 10 * time
        self.fbo['cond'] = (0.0, 0.7)
        self.fbo['val_sin'] = (self.alpha, 0.0)
예제 #18
0
class SingleRotate(object):
    
    def __init__(self, angle, axis, render_context):
        # It shold be way to get current context
        # but in simple case we may just pass it to constructor 
       self.context = render_context
       self._axis = axis
       self._angle = angle
       self.renderer = render_context
       self.prev_mvm = Matrix()
       self.matrix = Matrix()
       Callback(self._rotate) # here we perform rotation

    def radians(self, degrees):
       """ Calculate radians from angle here """
       return degrees * (3.14159265 / 180.) 

    @property
    def angle(self):
       return self._angle 

    @angle.setter
    def angle(self, v):
       self._angle = v
       angle = self.radians(self._angle)
       ax, ay, az = self._axis
       # calculate rotated matrix and store it
       self.matrix = Matrix().rotate(angle, ax, ay, az)

    def clear(self):
       Callback(self._clear)

    def _rotate(self, *args):
       " This sets rotation in callback "
       # get previous matrix and save it
       self.prev_mvm = self.renderer['modelview_mat']
       # do multiply for rotation
       self.context['modelview_mat'] = self.prev_mvm.multiply(self.matrix)

    def _clear(self, *args):
       self.renderer['modelview_mat'] = self.prev_mvm
예제 #19
0
class SingleRotate(object):
    def __init__(self, angle, axis, render_context):
        # It shold be way to get current context
        # but in simple case we may just pass it to constructor
        self.context = render_context
        self._axis = axis
        self._angle = angle
        self.renderer = render_context
        self.prev_mvm = Matrix()
        self.matrix = Matrix()
        Callback(self._rotate)  # here we perform rotation

    def radians(self, degrees):
        """ Calculate radians from angle here """
        return degrees * (3.14159265 / 180.)

    @property
    def angle(self):
        return self._angle

    @angle.setter
    def angle(self, v):
        self._angle = v
        angle = self.radians(self._angle)
        ax, ay, az = self._axis
        # calculate rotated matrix and store it
        self.matrix = Matrix().rotate(angle, ax, ay, az)

    def clear(self):
        Callback(self._clear)

    def _rotate(self, *args):
        " This sets rotation in callback "
        # get previous matrix and save it
        self.prev_mvm = self.renderer['modelview_mat']
        # do multiply for rotation
        self.context['modelview_mat'] = self.prev_mvm.multiply(self.matrix)

    def _clear(self, *args):
        self.renderer['modelview_mat'] = self.prev_mvm
예제 #20
0
class MachineScreen(Widget):

    # Watched by the root app class. Set to True to close menus.
    close_menus = BooleanProperty()

    # Watched by the root app class. If either of these are set to not None, a menu will be shown
    # in the root class.
    selected_state = ObjectProperty(None, allownone=True)
    selected_transition = ObjectProperty(None, allownone=True)

    def __init__(self, **kwargs):
        super(MachineScreen, self).__init__(**kwargs)

        self.start_state = None
        # This gets set by the root widget
        self.undo_handler = None

        self.states = []
        self.transitions = []

        self.handled_touches = []

        # TODO: DON'T HARD CODE THIS
        self.blank_char = '_'

        self.canvas_created = False

        # Used to differentiate between objects.
        self.unique_id = 0

        self.bgGrabbed = False
        self.grabbed_object = None
        self.initial_grab_pt = None
        self.grabPt = (0, 0)

        self.held_state = None

        # Listened to by main.py to close state/transition menus.
        self.close_menus = False
        self.selected_state = None

        # Initial distance between two touches.
        self.initial_dist = 1
        self.multitouch = False
        self.previous_scale = 1
        self.temp_scale = 1

        # We check the simulator to see if its running when handling touches.
        self.turing_simulator = None

        self.state_group = InstructionGroup()
        self.transition_group = InstructionGroup()

        self.transitionline = TempTransitionLine(self.get_unique_id())

    """
    Desc: Each object (for now state and transition) has a unique id. This is used predominately
          in the display queue and in the undo handler.
    """

    def get_unique_id(self):
        self.unique_id += 1
        return self.unique_id

    """
    Desc: Creates a new machine by wiping the current states and transitions.
          Clears the frame buffer, and resets the undo_handler.
    """

    def create_new_machine(self):

        # Removing visual components
        self.fbo.bind()
        self.fbo.clear_buffer()
        for state in self.states:

            invalid_transitions = state.delete()
            self.state_group.remove_group(state.get_unique_id())

            for transition in invalid_transitions:
                self.transition_group.remove_group(transition.get_unique_id())

        self.fbo.release()

        self.undo_handler.reset()

        self.states = []
        self.transitions = []
        self.start_state = None

    # ------------------------ GRAPHICS ----------------------- #
    """
    Desc: Called on the first resize (moving from default (100,100) dimensions)
          Builds the frame buffer which we draw everything onto (much faster than individual widgets)
          Also sets up our transformation matricies that we use for scaling and translations.
    """

    def initialise_canvas(self, size):
        self.matrix = Matrix()

        with self.canvas:
            self.fbo = Fbo(size=size)
            Color(1, 1, 1, 1)
            self.bg = Rectangle(size=self.size,
                                pos=self.pos,
                                texture=self.fbo.texture)
            self.canvas_created = True
        with self.fbo:
            self.matrix_instruction = MatrixInstruction()
            self.matrix_instruction.matrix = self.matrix

        self.fbo.add(self.transition_group)
        self.fbo.add(self.state_group)

    """
    Desc: Bound in the root class, updates the widget size when app size is adjusted.
    """

    def resize(self, size, pos):
        if not self.canvas_created:
            self.initialise_canvas(size)
        self.bg.size = size

    """
    Desc: Adds an instruction group at given index.
    WARNING: Don't add at multiple index's without first clearing the
    original instruction group from the display list.
    """

    def add_at_index(self, ins, index):
        self.fbo.bind()
        self.fbo.clear_buffer()
        self.fbo.insert(index, ins)
        self.fbo.release()

    """
    Desc: Moves an instruction group to the top of another instruction group.
    EG. Moving a state to the top of the state display list.
    The ins must already be in the ins_group or an exception will be raised.
    """

    def add_to_top(self, ins_group, ins, ins_uid):
        self.fbo.bind()
        self.fbo.clear_buffer()
        ins_group.remove_group(ins_uid)
        ins_group.add(ins)
        self.fbo.release()
        self.fbo.ask_update()

    """
    Desc: Updates the screen after the change of a graphic instruction.
    If the graphic instruction doesn't change, this will clear the screen.
    """

    def update_graphic_ins(self, ins, args):
        self.fbo.bind()
        self.fbo.clear_buffer()
        return_value = ins(*args)
        self.fbo.release()
        self.fbo.ask_update()
        return return_value

    """
    Desc: Pans the main fbo by a vector delta.
    """

    def pan(self, delta):
        self.matrix = self.matrix.multiply(Matrix().translate(
            delta[0], delta[1], 0))

        self.fbo.bind()
        self.fbo.clear_buffer()
        self.matrix_instruction.matrix = self.matrix
        self.fbo.release()

    """
    Desc: Zooms the fbo at a world point by a factor. Keeps the screen centred on the zoom.
    """

    def zoom(self, origin, factor):
        self.matrix = self.matrix.multiply(Matrix().translate(
            origin[0], origin[1], 0))
        self.matrix = self.matrix.multiply(Matrix().scale(
            factor, factor, factor))
        self.matrix = self.matrix.multiply(Matrix().translate(
            -origin[0], -origin[1], 0))

        self.fbo.bind()
        self.fbo.clear_buffer()
        self.matrix_instruction.matrix = self.matrix
        self.fbo.release()

    # -------------------- COORDINATE FUNCTIONS --------------------- #
    """
    Desc: Uses the transformation matrix we are using on the fbo to transfer a point on the root screen
    to world space. (Used for adding transitions etc.)
    """

    def screen_to_world(self, screenPos):
        worldPos = self.matrix.inverse().transform_point(
            screenPos[0], screenPos[1] - self.parent.y, 0)
        return worldPos

    """
    Desc: Uses the transformation matrix we are using on the fbo to transfer a point on our world screen to
    the root app screen. (Used for getting the proper point to put state/transition menus at)
    """

    def world_to_screen(self, objPos):
        screenPos = self.matrix.transform_point(objPos[0], objPos[1], 0)
        return (screenPos[0], screenPos[1] + self.parent.y, 0)

    # -------------------- TOUCH EVENT HANDLERS ---------------------- #
    """
    Desc: Handles a touch onto the gui. All touches are stored for later use (with multitouch functionality) and 
    also movement functionality such as dragging a state around.
    """

    def handle_touch_down(self, instance, touch):
        if touch not in self.handled_touches:
            # Set up the reference variable. A single touch won't shut menus
            # but a move (outside stray) or 'click' will shut menu.
            self.close_menus = False
            # Only want to handle at max 2 touches.
            if len(self.handled_touches) < 2:
                self.handled_touches.append(touch)

                if not self.multitouch and len(self.handled_touches) == 2:
                    self.multitouch = True

                    # As this is the first multitouch, we want to close menus, drop held objects etc.
                    self.close_menus = True
                    self.bgGrabbed = False
                    self.grabbed_object = None

                    if self.held_state:
                        self.unhold_state(None)

                if self.multitouch and len(self.handled_touches) == 2:

                    # Set up for scaling.
                    self.initial_dist = Vector(
                        self.handled_touches[0].pos).distance(
                            Vector(self.handled_touches[1].pos))
                    # Remember the current scale before more scaling.
                    self.temp_scale = self.previous_scale

    """
    Desc: Handles a touch up (no matter where it happened, or even if we're tracking it)
    If we are tracking the touch, various things can happen. If its a zoom we stop zooming,
    if we're creating a transition we'll create it etc.
    """

    def handle_touch_up(self, instance, touch):
        # We no longer need to remember the touch, so remove it.
        if touch in self.handled_touches:
            self.handled_touches.remove(touch)

        # To get out of multitouch mode all touches need to be removed. Simplifies things a bit.
        if len(self.handled_touches) == 0:
            self.multitouch = False

        # If a touch and hold had been activated, we need to unhighlight the state.
        self.unhold_state(touch.pos)
        self.bgGrabbed = False
        if self.grabbed_object:
            self.undo_handler.add_action(
                Action_MoveObject(self.grabbed_object.get_unique_id(),
                                  self.initial_grab_pt,
                                  self.grabbed_object.get_position()))
        self.grabbed_object = None

    """
    Desc: Handles a touch move on the gui. We are only interested in moves which origininated on the gui.
    """

    def handle_touch_move(self, instance, move_triggered):
        # Handling new touches to the machine.
        touch = instance.curr_touch_move
        if touch in self.handled_touches:

            if not self.multitouch:
                if touch.strayed:
                    self.close_menus = True
                    if not self.held_state:
                        if not self.grabbed_object and not self.bgGrabbed:
                            self.handle_initial_grab(touch.opos)
                        self.handle_grab(touch.pos)
                    else:
                        self.handle_transition_move(touch)
            else:
                self.handle_scale()

    """
    Desc: Listens to the touchhandler for a click_triggered event. (ie, a quick tap)
          If a transition or state is under the tap, it will be selected and an event will
          be fired too the root app to create the respective menu.
    """

    def handle_click(self, instance, click_triggered):
        if click_triggered and not self.turing_simulator.run_mode:
            world_pos = self.screen_to_world(instance.initial_touch.opos)
            for state in self.states:
                if Vector(world_pos).distance(Vector(
                        state.pos)) < state.radius:

                    if self.selected_transition:
                        self.deselect_objects()
                        self.close_menus = True

                    if self.selected_state and state is not self.selected_state:
                        self.deselect_objects()

                    self.update_graphic_ins(state.set_highlight, (0, 1, 1))
                    # Brings the selected state to the top of the display list.
                    self.add_to_top(self.state_group,
                                    state.get_instruction_group(),
                                    state.get_unique_id())
                    self.selected_state = state
                    return

            for transition in self.transitions:
                if transition.collide_point(world_pos):

                    if self.selected_state:
                        self.deselect_objects()
                        self.close_menus = True

                    if self.selected_transition and transition is not self.selected_transition:
                        self.deselect_objects()

                    self.update_graphic_ins(transition.set_highlight,
                                            (0, 1, 1))
                    self.add_to_top(self.transition_group,
                                    transition.get_instruction_group(),
                                    transition.get_unique_id())
                    self.selected_transition = transition
                    return

            # If we're at this point we know that no states/transitions have
            # been selected.
            self.close_menus = True

    """
    Desc: Listens to the touchhandler for a hold_triggered event. If this happens ontop of a state we go into 
    transition creation mode.
    """

    def handle_hold(self, instance, hold_triggered):
        if hold_triggered and not self.turing_simulator.run_mode:
            world_pos = self.screen_to_world(instance.initial_touch.opos)
            for state in self.states:
                if Vector(world_pos).distance(Vector(
                        state.pos)) < state.radius:
                    self.update_graphic_ins(state.set_highlight, (1, 1, 0))
                    self.held_state = state

    """
    Desc: Listens to the touchhandler for a double_triggered event. If the double tap is on empty space
    a new state will be created.
    """

    def handle_double_touch(self, instance, double_triggered):
        if double_triggered and not self.turing_simulator.run_mode:
            world_pos = self.screen_to_world(instance.initial_touch.opos)
            for state in self.states:
                if Vector(world_pos).distance(Vector(
                        state.pos)) < state.radius:
                    return
            self.add_state(instance.initial_touch.opos, False)

    # --------------------------  MACHINE FUNCTIONS ------------------------ #
    # (Majority of these will be called by the above touch handlers)

    # Checks if either the background or a state has been selected on the move
    # Background selected: Pan's camera
    # State selected: Move state
    def handle_initial_grab(self, pos):
        world_pos = self.screen_to_world(pos)
        self.grabPt = (world_pos[0], world_pos[1])
        if not self.turing_simulator.run_mode:
            for state in self.states:
                if Vector(world_pos).distance(Vector(
                        state.pos)) < state.radius:
                    self.grabbed_object = state
                    self.add_to_top(self.state_group,
                                    state.get_instruction_group(),
                                    state.get_unique_id())
                    break
            for transition in self.transitions:
                if transition.collide_point(world_pos):
                    self.grabbed_object = transition
                    self.add_to_top(self.transition_group,
                                    transition.get_instruction_group(),
                                    transition.get_unique_id())
                    break
        if self.grabbed_object:
            self.initial_grab_pt = self.grabbed_object.get_position()
        else:
            self.bgGrabbed = True

    def handle_grab(self, pos):
        world_pos = self.screen_to_world(pos)
        if self.grabbed_object:
            self.update_graphic_ins(self.grabbed_object.set_position,
                                    [world_pos])
        elif self.bgGrabbed:
            # pan by the delta position
            self.pan(
                (world_pos[0] - self.grabPt[0], world_pos[1] - self.grabPt[1]))

    def handle_transition_move(self, touch):
        world_pos = self.screen_to_world(touch.pos)
        world_pos = (world_pos[0], world_pos[1])
        if self.transitionline.displayed:
            if Vector(world_pos).distance(Vector(
                    self.held_state.pos)) > self.held_state.radius:
                self.update_graphic_ins(
                    self.transitionline.update_line,
                    (self.held_state.pos, world_pos, False))
            else:
                self.update_graphic_ins(self.transitionline.update_line,
                                        (self.held_state.pos, world_pos, True))
        else:
            if Vector(world_pos).distance(Vector(
                    self.held_state.pos)) > self.held_state.radius:
                self.transitionline.update_line(self.held_state.pos, world_pos,
                                                False)
                # Need to remove the held state and re-add it
                self.update_graphic_ins(self.state_group.remove_group,
                                        [self.held_state.get_unique_id()])
                self.add_at_index(self.transitionline.get_instruction_group(),
                                  3)
                self.add_at_index(self.held_state.get_instruction_group(), 4)
                self.transitionline.displayed = True

    def handle_scale(self):
        if len(self.handled_touches) == 2:
            new_dist = Vector(self.handled_touches[0].pos).distance(
                Vector(self.handled_touches[1].pos))
            new_scale = (new_dist / self.initial_dist) * self.temp_scale

            if new_scale < .8:
                new_scale = .8
            if new_scale > 3:
                new_scale = 3

            pivot_pt = self.screen_to_world(
                (Vector(self.handled_touches[0].pos) +
                 Vector(self.handled_touches[1].pos)) / 2)

            self.zoom(pivot_pt, new_scale / self.previous_scale)

            self.previous_scale = new_scale

    # If any states/transitions are selected removes the highlight and forgets
    # the object.
    def deselect_objects(self):
        if self.selected_state:
            # Stop the hold highlight disappearing.
            if self.selected_state is not self.held_state:
                self.update_graphic_ins(self.selected_state.set_highlight,
                                        (.8, .8, .8))
            self.selected_state = None

        if self.selected_transition:
            self.update_graphic_ins(self.selected_transition.set_highlight,
                                    (.8, .8, .8))
            self.selected_transition = None

    # Handles a touch up after a hold.
    # For now this is when a transition has tried to be created.
    # pos: (x, y) or None if no transition is wanted to be created.
    def unhold_state(self, pos):
        if self.transitionline.displayed:
            if pos:
                world_pos = self.screen_to_world(pos)
                for state in self.states:
                    if Vector(world_pos).distance(Vector(
                            state.pos)) < state.radius:
                        # Create a new transition.
                        self.add_transition(self.held_state, state, None, 'L',
                                            self.blank_char, self.blank_char)
                        break
            # Remove the state from the main buffer
            self.update_graphic_ins(self.fbo.remove_group,
                                    [self.held_state.get_unique_id()])
            # Add it back to the state_group instruction group
            self.update_graphic_ins(self.state_group.add,
                                    [self.held_state.get_instruction_group()])
            # Remove the temporary transition line from the main buffer
            self.update_graphic_ins(self.fbo.remove_group,
                                    [self.transitionline.get_unique_id()])
            self.transitionline.displayed = False
        if self.held_state:
            self.update_graphic_ins(self.held_state.set_highlight,
                                    (.8, .8, .8))
            self.held_state = None

    def add_transition(self,
                       from_state,
                       to_state,
                       anchor_offset,
                       direction,
                       read_sym,
                       write_sym,
                       unique_id=-1,
                       from_undo=False):

        if from_state == to_state:
            if not anchor_offset:
                anchor_offset = Vector(
                    self.transitionline.loop_ctrl_pt) - Vector(from_state.pos)
        else:
            if not anchor_offset:
                anchor_offset = (20, 20)
        if unique_id == -1:
            u_id = self.get_unique_id()
        else:
            u_id = unique_id

        new_transition = TuringTransition(from_state, to_state, anchor_offset,
                                          direction, read_sym, write_sym, u_id)

        self.transitions.append(new_transition)
        from_state.add_out_transition(new_transition)

        if from_state is not to_state:
            to_state.add_in_transition(new_transition)

        if not from_undo:
            self.undo_handler.add_action(Action_AddTransition(new_transition))

        self.update_graphic_ins(self.transition_group.add,
                                [new_transition.get_instruction_group()])

    def delete_transition(self, transition, from_undo=False):
        if not from_undo:
            self.undo_handler.add_action(Action_DeleteTransition(transition))

        self.update_graphic_ins(self.transition_group.remove_group,
                                [transition.get_unique_id()])
        transition.delete()
        self.transitions.remove(transition)

    def add_state(self,
                  new_pos,
                  absolute,
                  name='',
                  from_undo=False,
                  unique_id=-1):
        if not absolute:
            world_pos = self.screen_to_world(new_pos)
        else:
            world_pos = new_pos

        if name == '':
            state_name = 'state' + str(len(self.states))
            i = 1
            while self.get_state_by_name(state_name):
                state_name = 'state' + str(len(self.states) + i)
                i += 1
        else:
            state_name = name

        self.deselect_objects()

        if unique_id == -1:
            u_id = self.get_unique_id()
        else:
            u_id = unique_id

        new_state = TuringState(world_pos, state_name, u_id)
        self.states.append(new_state)

        self.update_graphic_ins(self.state_group.add,
                                [new_state.get_instruction_group()])

        if not from_undo:
            self.undo_handler.add_action(
                Action_AddState(state_name, world_pos,
                                new_state.get_unique_id()))

        return new_state

    def delete_state(self, state, from_undo=False):
        # Create the undo action now (before transitions are lost etc)
        if not from_undo:
            print('handle meh')
            self.undo_handler.add_action(
                Action_DeleteState(state.name, state.pos, state.final_state,
                                   state.start_state,
                                   state.out_transitions, state.in_transitions,
                                   state.get_unique_id()))
        # Makes sure we remove all references of the state
        if state == self.start_state:
            self.start_state = None

        # Remove connected transitions
        invalid_transitions = state.delete()

        # Prepare the fbo for a redraw.
        self.fbo.bind()
        self.fbo.clear_buffer()

        # Remove invalid transitions from display and local storage.
        for transition in invalid_transitions:
            self.transition_group.remove_group(transition.get_unique_id())
            self.transitions.remove(transition)

        # Remove from the display list
        self.state_group.remove_group(state.get_unique_id())

        # Remove from the state list
        self.states.remove(state)

        self.fbo.release()

    def get_state_by_name(self, name):
        for state in self.states:
            if state.name == name:
                return state
        return None

    def get_obj_by_id(self, unique_id):
        for state in self.states:
            if state.get_unique_id() == unique_id:
                return state
        for transition in self.transitions:
            if transition.get_unique_id() == unique_id:
                return transition
        return None
예제 #21
0
파일: __init__.py 프로젝트: zarar7576/plyer
 def _update_labels(self):
     xlabel = self._xlabel
     ylabel = self._ylabel
     x = self.x
     y = self.y
     width = self.width
     height = self.height
     padding = self.padding
     x_next = padding + x
     y_next = padding + y
     xextent = x + width
     yextent = y + height
     ymin = self.ymin
     ymax = self.ymax
     xmin = self.xmin
     precision = self.precision
     x_overlap = False
     y_overlap = False
     # set up x and y axis labels
     if xlabel:
         xlabel.text = self.xlabel
         xlabel.texture_update()
         xlabel.size = xlabel.texture_size
         xlabel.pos = (x + width / 2. - xlabel.width / 2., padding + y)
         y_next += padding + xlabel.height
     if ylabel:
         ylabel.text = self.ylabel
         ylabel.texture_update()
         ylabel.size = ylabel.texture_size
         ylabel.x = padding + x - (ylabel.width / 2. - ylabel.height / 2.)
         x_next += padding + ylabel.height
     xpoints = self._ticks_majorx
     xlabels = self._x_grid_label
     xlabel_grid = self.x_grid_label
     ylabel_grid = self.y_grid_label
     ypoints = self._ticks_majory
     ylabels = self._y_grid_label
     # now x and y tick mark labels
     if len(ylabels) and ylabel_grid:
         # horizontal size of the largest tick label, to have enough room
         ylabels[0].text = precision % ypoints[0]
         ylabels[0].texture_update()
         y1 = ylabels[0].texture_size
         y_start = y_next + (
             padding + y1[1]
             if len(xlabels) and xlabel_grid else 0
         ) + (padding + y1[1] if not y_next else 0)
         yextent = y + height - padding - y1[1] / 2.
         if self.ylog:
             ymax = log10(ymax)
             ymin = log10(ymin)
         ratio = (yextent - y_start) / float(ymax - ymin)
         y_start -= y1[1] / 2.
         func = (lambda x: 10 ** x) if self.ylog else lambda x: x
         y1 = y1[0]
         for k in xrange(len(ylabels)):
             ylabels[k].text = precision % func(ypoints[k])
             ylabels[k].texture_update()
             ylabels[k].size = ylabels[k].texture_size
             y1 = max(y1, ylabels[k].texture_size[0])
             ylabels[k].pos = (x_next, y_start + (ypoints[k] - ymin) *
                               ratio)
         if len(ylabels) > 1 and ylabels[0].top > ylabels[1].y:
             y_overlap = True
         else:
             x_next += y1 + padding
     if len(xlabels) and xlabel_grid:
         func = log10 if self.xlog else lambda x: x
         # find the distance from the end that'll fit the last tick label
         xlabels[0].text = precision % func(xpoints[-1])
         xlabels[0].texture_update()
         xextent = x + width - xlabels[0].texture_size[0] / 2. - padding
         # find the distance from the start that'll fit the first tick label
         if not x_next:
             xlabels[0].text = precision % func(xpoints[0])
             xlabels[0].texture_update()
             x_next = padding + xlabels[0].texture_size[0] / 2.
         xmin = func(xmin)
         ratio = (xextent - x_next) / float(func(self.xmax) - xmin)
         func = (lambda x: 10 ** x) if self.xlog else lambda x: x
         right = -1
         for k in xrange(len(xlabels)):
             xlabels[k].text = precision % func(xpoints[k])
             # update the size so we can center the labels on ticks
             xlabels[k].texture_update()
             xlabels[k].size = xlabels[k].texture_size
             xlabels[k].pos = (x_next + (xpoints[k] - xmin) * ratio -
                               xlabels[k].texture_size[0] / 2., y_next)
             if xlabels[k].x < right:
                 x_overlap = True
                 break
             right = xlabels[k].right
         if not x_overlap:
             y_next += padding + xlabels[0].texture_size[1]
     # now re-center the x and y axis labels
     if xlabel:
         xlabel.x = x_next + (xextent - x_next) / 2. - xlabel.width / 2.
     if ylabel:
         ylabel.y = y_next + (yextent - y_next) / 2. - ylabel.height / 2.
         t = Matrix().translate(ylabel.center[0], ylabel.center[1], 0)
         t = t.multiply(Matrix().rotate(-radians(270), 0, 0, 1))
         ylabel.transform = t.multiply(Matrix().translate(-ylabel.center[0],
                                                          -ylabel.center[1],
                                                          0))
     if x_overlap:
         for k in xrange(len(xlabels)):
             xlabels[k].text = ''
     if y_overlap:
         for k in xrange(len(ylabels)):
             ylabels[k].text = ''
     return x_next, y_next, xextent, yextent
예제 #22
0
 def apply_transform(self, rescale, anchor=(0, 0)):
     trans = Matrix().scale(rescale, rescale, rescale)
     t = Matrix().translate(anchor[0], anchor[1], 0)
     t = t.multiply(trans)
     t = t.multiply(Matrix().translate(-anchor[0], -anchor[1], 0))
     self.transform.matrix = t
예제 #23
0
파일: camera.py 프로젝트: sulik011/pong
class Camera(Object3D):
    """
    Base camera class
    """

    scale = NumericProperty(1.0)
    _right = ObjectProperty(Vector3(1, 0, 0))
    _up = ObjectProperty(Vector3(0, 1, 0))
    _back = ObjectProperty(Vector3(0, 0, 1))
    up = ObjectProperty(Vector3(0, 1, 0))

    def __init__(self):
        super(Camera, self).__init__()
        self.projection_matrix = Matrix()
        self.modelview_matrix = Matrix()
        self.model_matrix = Matrix()
        self.viewport_matrix = (0, 0, 0, 0)
        self.renderer = None  # renderer camera is bound to
        self._look_at = None
        self.look_at(Vector3(0, 0, -1))

    def _set_position(self, val):
        super(Camera, self).on_pos_changed(val)
        self.look_at(self._look_at)
        self.update()

    def on_pos_changed(self, coord, v):
        """ Camera position was changed """
        self.look_at(self._look_at)
        self.update()

    def on_up(self, instance, up):
        """ Camera up vector was changed """
        pass

    def on_scale(self, instance, scale):
        """ Handler for change scale parameter event """

    def look_at(self, *v):
        if len(v) == 1:
            v = v[0]
        m = Matrix()
        pos = self._position
        m = m.look_at(pos[0], pos[1], pos[2], v[0], v[1], v[2], self.up[0],
                      self.up[1], self.up[2])
        m = m.rotate(radians(self.rot.x), 1.0, 0.0, 0.0)
        m = m.rotate(radians(self.rot.y), 0.0, 1.0, 0.0)
        m = m.rotate(radians(self.rot.z), 0.0, 0.0, 1.0)
        self.modelview_matrix = m

        # set camera vectors from view matrix
        self._right = Vector3(m[0], m[1], m[2])
        self._up = Vector3(m[4], m[5], m[6])
        self._back = Vector3(m[8], m[9], m[10])
        self._look_at = v
        self.update()

    def bind_to(self, renderer):
        """ Bind this camera to renderer """
        self.renderer = renderer

    def update(self):
        if self.renderer:
            self.viewport_matrix = (self.renderer._viewport.pos[0],
                                    self.renderer._viewport.pos[1],
                                    self.renderer._viewport.size[0],
                                    self.renderer._viewport.size[1])
            model_matrix = self.modelview_matrix.multiply(
                self.renderer.fbo['view_mat'].inverse())
            self.model_matrix = model_matrix
            self.renderer._update_matrices()

    def update_projection_matrix(self):
        """ This function should be overridden in the subclasses
예제 #24
0
 def apply_transform(self, rescale, anchor=(0, 0)):
     trans = Matrix().scale(rescale, rescale, rescale)
     t = Matrix().translate(anchor[0], anchor[1], 0)
     t = t.multiply(trans)
     t = t.multiply(Matrix().translate(-anchor[0], -anchor[1], 0))
     self.transform.matrix = t
예제 #25
0
    def _update_labels(self):
        xlabel = self._xlabel
        ylabel = self._ylabel
        x = self.x
        y = self.y
        width = self.width
        height = self.height
        padding = self.padding
        x_next = padding + x
        y_next = padding + y
        xextent = width + x
        yextent = height + y
        ymin = self.ymin
        ymax = self.ymax
        xmin = self.xmin
        x_overlap = False
        y_overlap = False
        # set up x and y axis labels
        if xlabel:
            xlabel.text = self.xlabel
            xlabel.texture_update()
            xlabel.size = xlabel.texture_size
            xlabel.pos = int(x + width / 2. - xlabel.width / 2.), int(padding +
                                                                      y)
            y_next += padding + xlabel.height
        if ylabel:
            ylabel.text = self.ylabel
            ylabel.texture_update()
            ylabel.size = ylabel.texture_size
            ylabel.x = padding + x - (ylabel.width / 2. - ylabel.height / 2.)
            x_next += padding + ylabel.height
        xpoints = self._ticks_majorx
        xlabels = self._x_grid_label
        xlabel_grid = self.x_grid_label
        ylabel_grid = self.y_grid_label
        ypoints = self._ticks_majory
        ylabels = self._y_grid_label
        # now x and y tick mark labels
        if len(ylabels) and ylabel_grid:
            # horizontal size of the largest tick label, to have enough room
            funcexp = exp10 if self.ylog else identity
            funclog = log10 if self.ylog else identity
            ylabels[0].text = self._format_ylabel_text(funcexp(ypoints[0]))
            ylabels[0].texture_update()
            y1 = ylabels[0].texture_size
            y_start = y_next + (padding + y1[1] if len(xlabels) and xlabel_grid else 0) + \
                               (padding + y1[1] if not y_next else 0)
            yextent = y + height - padding - y1[1] / 2.

            ymin = funclog(ymin)
            ratio = (yextent - y_start) / float(funclog(ymax) - ymin)
            y_start -= y1[1] / 2.
            y1 = y1[0]
            for k in range(len(ylabels)):
                ylabels[k].text = self._format_ylabel_text(funcexp(ypoints[k]))
                ylabels[k].texture_update()
                ylabels[k].size = ylabels[k].texture_size
                y1 = max(y1, ylabels[k].texture_size[0])
                ylabels[k].pos = tuple(
                    map(int, (x_next, y_start + (ypoints[k] - ymin) * ratio)))
            if len(ylabels) > 1 and ylabels[0].top > ylabels[1].y:
                y_overlap = True
            x_next += y1 + padding
        if len(xlabels) and xlabel_grid:
            funcexp = exp10 if self.xlog else identity
            funclog = log10 if self.xlog else identity
            # find the distance from the end that'll fit the last tick label
            xlabels[0].text = self._format_xlabel_text(funcexp(xpoints[-1]))
            xlabels[0].texture_update()
            xextent = x + width - xlabels[0].texture_size[0] / 2. - padding
            # find the distance from the start that'll fit the first tick label
            if not x_next:
                xlabels[0].text = self._format_label_text(funcexp(xpoints[0]))
                xlabels[0].texture_update()
                x_next = padding + xlabels[0].texture_size[0] / 2.
            xmin = funclog(xmin)
            ratio = (xextent - x_next) / float(funclog(self.xmax) - xmin)
            right = -1
            for k in range(len(xlabels)):
                xlabels[k].text = self._format_xlabel_text(funcexp(xpoints[k]))
                # update the size so we can center the labels on ticks
                xlabels[k].texture_update()
                xlabels[k].size = xlabels[k].texture_size
                xlabels[k].pos = tuple(
                    map(int, (x_next + (xpoints[k] - xmin) * ratio -
                              xlabels[k].texture_size[0] / 2., y_next)))
                if xlabels[k].x < right:
                    x_overlap = True
                right = xlabels[k].right
            y_next += padding + xlabels[0].texture_size[1]
        # now re-center the x and y axis labels
        if xlabel:
            xlabel.x = int(x_next + (xextent - x_next) / 2. -
                           xlabel.width / 2.)
        if ylabel:
            ylabel.y = int(y_next + (yextent - y_next) / 2. -
                           ylabel.height / 2.)
            t = Matrix().translate(ylabel.center[0], ylabel.center[1], 0)
            t = t.multiply(Matrix().rotate(-radians(270), 0, 0, 1))
            ylabel.transform = t.multiply(Matrix().translate(
                -int(ylabel.center_x), -int(ylabel.center_y), 0))
        if x_overlap:
            for k in range(1, len(xlabels) - 1):
                xlabels[k].text = ''
        if y_overlap:
            for k in range(1, len(ylabels) - 1):
                ylabels[k].text = ''
        return x_next, y_next, xextent, yextent