Пример #1
0
 def clone(self, parent):
     k = self.__class__(self.time(), self.value(), parent)
     k.__inTangent = Vec2(self.inTangent)
     k.__outTangent = Vec2(self.outTangent)
     k.__tangentBroken = self.tangentBroken
     k.__tangentMode = self.tangentMode
     return k
Пример #2
0
    def __frameOnKeys(self, keys):
        boundsMin = None
        boundsMax = None

        for key in keys:
            point = key.point()
            if boundsMin is None:
                boundsMin = Vec2(point)
                boundsMax = Vec2(boundsMin)
                continue
            boundsMin.x = min(boundsMin.x, point.x)
            boundsMin.y = min(boundsMin.y, point.y)
            boundsMax.x = max(boundsMax.x, point.x)
            boundsMax.y = max(boundsMax.y, point.y)
        if boundsMin is None:
            return

        # Determine padding on both sides (32 pixels please)
        paddingX = (32.0 / max(1.0, self.width())) * (
            (boundsMax.x - boundsMin.x) if
            (boundsMax.x != boundsMin.x) else 1.0)
        paddingY = (32.0 / max(1.0, self.height())) * (
            (boundsMax.y - boundsMin.y) if
            (boundsMax.y != boundsMin.y) else 1.0)

        region = boundsMin.x - paddingX, boundsMin.y - paddingY, boundsMax.x - boundsMin.x + 2 * paddingX, boundsMax.y - boundsMin.y + 2 * paddingY
        self.__cameraUndoStack.push(CameraFrameAction(self.__camera, region))
        self.repaint()
Пример #3
0
 def __init__(self, time, value, parent):
     self.__point = Vec2(time, value)
     self.__parent = parent
     # note that tangent X values have been deprecated and is not exported; they were for cubic bezier curves that never got made
     self.inTangent = Vec2(0.0, 0.0)
     self.outTangent = Vec2(0.0, 0.0)
     self.__inTangentType = Key.TYPE_LINEAR
     self.__outTangentType = Key.TYPE_LINEAR
     self.__tangentBroken = False
     self.__tangentMode = Key.TANGENT_AUTO
Пример #4
0
 def addKeyWithTangents(self, inTangentX, inTangentY, time, value,
                        outTangentX, outTangentY, tangentBroken,
                        tangentMode):
     k = Key(time, value, self)
     self.__keys.append(k)
     self.sortKeys()
     k.inTangent = Vec2(inTangentX, inTangentY)
     k.outTangent = Vec2(outTangentX, outTangentY)
     k.tangentBroken = tangentBroken
     k.tangentMode = tangentMode
     return k
Пример #5
0
 def updateTangents(self):
     if self.__tangentMode == Key.TANGENT_USER:
         return
     if self.__tangentMode == Key.TANGENT_STEPPED:
         # this leave the input tangent as is, so you can go set e.g. "linear" to get the input, then back to "stepped"
         # TODO: have "output is stepped" as separate state ("in tangent" with "stepped output" control is tedious)
         self.outTangent = Vec2(0.0, float('inf'))
         return
     if self.__tangentMode == Key.TANGENT_FLAT:
         self.inTangent = Vec2(0.0, 0.0)
         self.outTangent = Vec2(0.0, 0.0)
     else:
         self.__parent.updateTangents(self, self.__tangentMode)
Пример #6
0
    def mapTangentToScreen(self, key, isInTangent):
        # Calculate the tangent position on screen (as a PointF)
        point = key.point()

        cameraRect = self.__camera.region()
        screenSize = Vec2(float(self.width()), float(self.height()))
        viewPort = Vec2(cameraRect[2], cameraRect[3])

        delta = Vec2(-key.inTangent if isInTangent else key.outTangent)
        if delta.sqrLen() == 0:
            delta = Vec2(-1.0 if isInTangent else 1.0, 0.0)
        px = (delta * screenSize) / viewPort
        px.normalize()
        px *= 50.0
        delta = (px / screenSize) * viewPort

        return Vec2(point.x + delta.x, point.y + delta.y)
Пример #7
0
 def keyDirection(a, b):
     keyDifference = b.point() - a.point()
     try:
         keyDifference.normalize()
     except ZeroDivisionError:
         return Vec2(0.0, 0.0)
     keyDifference.x = abs(keyDifference.x)
     return keyDifference
Пример #8
0
 def _apply(self):
     """
     Set key state.
     """
     i = 0
     for key in self.__selection:
         x = self.__restoreData[i][0] + self.__delta[0]
         y = self.__restoreData[i][1] + self.__delta[1]
         if self.__snap[0]:
             x = round(x * self.__snap[0]) / float(self.__snap[0])
         if self.__snap[1]:
             y = round(y * self.__snap[1]) / float(self.__snap[1])
         key.setPoint(Vec2(x, y))
         i += 1
Пример #9
0
 def setPoint(self, point):
     self.__point = Vec2(point)
     self.__parent.sortKeys()
     self.__parent.keyChanged(self)
Пример #10
0
 def point(self):
     return Vec2(self.__point)
Пример #11
0
    def updateTangents(self, key, mode):
        idx = self.__keys.index(key)
        first = idx == 0
        last = idx == len(self.__keys) - 1

        if first and last:
            return

        def keyDirection(a, b):
            keyDifference = b.point() - a.point()
            try:
                keyDifference.normalize()
            except ZeroDivisionError:
                return Vec2(0.0, 0.0)
            keyDifference.x = abs(keyDifference.x)
            return keyDifference

        def finalize():
            if not first and key.inTangent.length() != 0:
                pd = self.__keys[idx].time() - self.__keys[idx - 1].time()
                try:
                    key.inTangent *= pd / key.inTangent.x
                except ZeroDivisionError:
                    pass
            if not last and key.outTangent.length() != 0:
                nd = self.__keys[idx + 1].time() - self.__keys[idx].time()
                try:
                    key.outTangent *= nd / key.outTangent.x
                except ZeroDivisionError:
                    pass

        if mode == Key.TANGENT_LINEAR:
            if first:
                key.inTangent = Vec2(0.0, 0.0)
            else:
                key.inTangent = keyDirection(self.__keys[idx],
                                             self.__keys[idx - 1])
                key.inTangent.x = -key.inTangent.x

            if last:
                key.outTangent = Vec2(0.0, 0.0)
            else:
                key.outTangent = keyDirection(self.__keys[idx],
                                              self.__keys[idx + 1])

            finalize()
            return

        elif mode == Key.TANGENT_SPLINE:
            if first:
                key.outTangent = keyDirection(self.__keys[idx],
                                              self.__keys[idx + 1])
                key.inTangent = key.outTangent
            elif last:
                key.inTangent = keyDirection(self.__keys[idx],
                                             self.__keys[idx - 1])
                key.inTangent.x = -key.inTangent.x
                key.outTangent = -key.inTangent
            else:
                key.outTangent = keyDirection(self.__keys[idx - 1],
                                              self.__keys[idx + 1])
                key.inTangent = -key.outTangent

            finalize()
            return

        elif mode == Key.TANGENT_AUTO:

            def sgn(x):
                return -1 if x < 1 else 1 if x > 1 else 0

            if first or last or sgn(self.__keys[idx - 1].value() - key.value()
                                    ) == sgn(self.__keys[idx + 1].value() -
                                             key.value()):
                key.inTangent = Vec2(0.0, 0.0)
                key.outTangent = Vec2(0.0, 0.0)
            else:
                key.outTangent = keyDirection(self.__keys[idx - 1],
                                              self.__keys[idx + 1])
                key.inTangent = -key.outTangent

            finalize()
            return

        elif mode in (Key.TANGENT_USER, Key.TANGENT_STEPPED):
            return

        assert False, 'Invalid tangent mode for key.'