Ejemplo n.º 1
0
/// compute interpolation parameters from keyframes and an iterator
/// to the next keyframe (the first with time > t)
static void
interParams(const KeyFrameSet &keyFrames,
            double t,
            const KeyFrameSet::const_iterator &itup,
            double *tcur,
            double *vcur,
            double *vcurDerivRight,
            Natron::KeyframeType *interp,
            double *tnext,
            double *vnext,
            double *vnextDerivLeft,
            Natron::KeyframeType *interpNext)
{
    assert(itup == keyFrames.end() || t < itup->getTime());
    if (itup == keyFrames.begin()) {
        //if all keys have a greater time
        // get the first keyframe
        *tnext = itup->getTime();
        *vnext = itup->getValue();
        *vnextDerivLeft = itup->getLeftDerivative();
        *interpNext = itup->getInterpolation();
        *tcur = *tnext - 1.;
        *vcur = *vnext;
        *vcurDerivRight = 0.;
        *interp = Natron::KEYFRAME_NONE;
    } else if (itup == keyFrames.end()) {
        //if we found no key that has a greater time
        // get the last keyframe
        KeyFrameSet::const_reverse_iterator itlast = keyFrames.rbegin();
        *tcur = itlast->getTime();
        *vcur = itlast->getValue();
        *vcurDerivRight = itlast->getRightDerivative();
        *interp = itlast->getInterpolation();
        *tnext = *tcur + 1.;
        *vnext = *vcur;
        *vnextDerivLeft = 0.;
        *interpNext = Natron::KEYFRAME_NONE;
    } else {
        // between two keyframes
        // get the last keyframe with time <= t
        KeyFrameSet::const_iterator itcur = itup;
        --itcur;
        assert(itcur->getTime() <= t);
        *tcur = itcur->getTime();
        *vcur = itcur->getValue();
        *vcurDerivRight = itcur->getRightDerivative();
        *interp = itcur->getInterpolation();
        *tnext = itup->getTime();
        *vnext = itup->getValue();
        *vnextDerivLeft = itup->getLeftDerivative();
        *interpNext = itup->getInterpolation();
    }
}
Ejemplo n.º 2
0
KeyFrameSet::iterator Curve::refreshDerivatives(Curve::CurveChangedReason reason, KeyFrameSet::iterator key)
{
    // PRIVATE - should not lock
    double tcur = key->getTime();
    double vcur = key->getValue();
    
    double tprev, vprev, tnext, vnext, vprevDerivRight, vnextDerivLeft;
    Natron::KeyframeType prevType, nextType;
    if (key == _imp->keyFrames.begin()) {
        tprev = tcur;
        vprev = vcur;
        vprevDerivRight = 0.;
        prevType = Natron::KEYFRAME_NONE;
    } else {
        KeyFrameSet::const_iterator prev = key;
        --prev;
        tprev = prev->getTime();
        vprev = prev->getValue();
        vprevDerivRight = prev->getRightDerivative();
        prevType = prev->getInterpolation();
        
        //if prev is the first keyframe, and not edited by the user then interpolate linearly
        if (prev == _imp->keyFrames.begin() && prevType != Natron::KEYFRAME_FREE &&
            prevType != Natron::KEYFRAME_BROKEN) {
            prevType = Natron::KEYFRAME_LINEAR;
        }
    }
    
    KeyFrameSet::const_iterator next = key;
    ++next;
    if (next == _imp->keyFrames.end()) {
        tnext = tcur;
        vnext = vcur;
        vnextDerivLeft = 0.;
        nextType = Natron::KEYFRAME_NONE;
    } else {
        tnext = next->getTime();
        vnext = next->getValue();
        vnextDerivLeft = next->getLeftDerivative();
        nextType = next->getInterpolation();
        
        KeyFrameSet::const_iterator nextnext = next;
        ++nextnext;
        //if next is thelast keyframe, and not edited by the user then interpolate linearly
        if (nextnext == _imp->keyFrames.end() && nextType != Natron::KEYFRAME_FREE &&
            nextType != Natron::KEYFRAME_BROKEN) {
            nextType = Natron::KEYFRAME_LINEAR;
        }
    }
    
    double vcurDerivLeft,vcurDerivRight;

    assert(key->getInterpolation() != Natron::KEYFRAME_NONE &&
            key->getInterpolation() != Natron::KEYFRAME_BROKEN &&
            key->getInterpolation() != Natron::KEYFRAME_FREE);
    Natron::autoComputeDerivatives(prevType,
                                   key->getInterpolation(),
                                   nextType,
                                   tprev, vprev,
                                   tcur, vcur,
                                   tnext, vnext,
                                   vprevDerivRight,
                                   vnextDerivLeft,
                                   &vcurDerivLeft, &vcurDerivRight);


    KeyFrame newKey(*key);
    newKey.setLeftDerivative(vcurDerivLeft);
    newKey.setRightDerivative(vcurDerivRight);

    std::pair<KeyFrameSet::iterator,bool> newKeyIt = _imp->keyFrames.insert(newKey);

    // keyframe at this time exists, erase and insert again
    if (!newKeyIt.second) {
        _imp->keyFrames.erase(newKeyIt.first);
        newKeyIt = _imp->keyFrames.insert(newKey);
        assert(newKeyIt.second);
    }
    key = newKeyIt.first;
    
    if (reason != DERIVATIVES_CHANGED) {
        key = evaluateCurveChanged(DERIVATIVES_CHANGED,key);
    }
    return key;
}