void SkActive::pickUp(SkActive* existing) {
    SkTDOperandArray existingValues;
    for (int index = 0; index < fAnimators.count(); index++) {
        SkAnimateBase* animate = fAnimators[index];
        SkASSERT(animate->getValuesType() == SkType_Float);
        int components = animate->components();
        SkOperand* from = animate->getValues();
        SkOperand* to = &from[animate->components()];
        existingValues.setCount(components);
        existing->fInterpolators[index]->timeToValues(
            existing->fState[index].fTicks - existing->fState[index].fStartTime, existingValues.begin());
        SkScalar originalSum = 0;
        SkScalar workingSum = 0;
        for (int cIndex = 0; cIndex < components; cIndex++) {
            SkScalar delta = to[cIndex].fScalar - from[cIndex].fScalar;
            originalSum += SkScalarMul(delta, delta);
            delta = to[cIndex].fScalar - existingValues[cIndex].fScalar;
            workingSum += SkScalarMul(delta, delta);
        }
        if (workingSum < originalSum) {
            SkScalar originalDistance = SkScalarSqrt(originalSum);
            SkScalar workingDistance = SkScalarSqrt(workingSum);
            existing->fState[index].fDuration = (SkMSec) SkScalarMulDiv(fState[index].fDuration, 
                workingDistance, originalDistance);
        }
        fInterpolators[index]->reset(components, 2, SkType_Float);
        fInterpolators[index]->setKeyFrame(0, 0, existingValues.begin(), animate->blend[0]);
        fInterpolators[index]->setKeyFrame(1, fState[index].fDuration, to, animate->blend[0]);
    }
}
void SkActive::setInterpolator(int index, SkOperand* from) {
    if (from == NULL) // legitimate for set string
        return;
    SkAnimateBase* animate = fAnimators[index];
    int entries = animate->entries();
    SkASSERT(entries > 0);
    SkMSec duration = fState[index].fDuration;
    int components = animate->components();
    SkOperandInterpolator& interpolator = *fInterpolators[index];
    interpolator.reset(components, entries == 1 ? 2 : entries, animate->getValuesType()); 
    interpolator.setMirror(SkToBool(animate->fMirror));
    interpolator.setReset(SkToBool(animate->fReset));
    interpolator.setRepeatCount(animate->repeat);
    if (entries == 1) {
        interpolator.setKeyFrame(0, 0, from, animate->blend[0]);
        interpolator.setKeyFrame(1, duration, from, animate->blend[0]);
        return;
    }
    for (int entry = 0; entry < entries; entry++) {
        int blendIndex = SkMin32(animate->blend.count() - 1, entry);
        interpolator.setKeyFrame(entry, entry * duration / (entries - 1), from, 
            animate->blend[blendIndex]);
        from += components;
    }
}
Exemple #3
0
void SkActive::create(SkADrawable* drawable, SkMSec time) {
    fApply.fLastTime = time;
    fApply.refresh(fMaker);
    for (int index = 0; index < fAnimators.count(); index++) {
        SkAnimateBase* animate = fAnimators[index];
        SkOperandInterpolator& interpolator = *fInterpolators[index];
        int count = animate->components();
        if (animate->formula.size() > 0) {
            SkTDOperandArray values;
            values.setCount(count);
            SkDEBUGCODE(bool success = ) animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL,
                animate->getValuesType(), animate->formula);
            SkASSERT(success);
            fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time);
        } else {
bool SkActive::immediate(bool enable) {
    SkMSec time = 0;
    bool result = false;
    SkDrawable* drawable = fApply.scope;
    SkMSec final = fMaxTime;
    do {
        bool applied = fAnimators.count() == 0;
        fApply.fLastTime = time;
        fApply.refresh(fMaker);
        for (int index = 0; index < fAnimators.count(); index++) {
            SkAnimateBase* animate = fAnimators[index];
            SkState& state = fState[index];
            if (state.fMode != SkApply::kMode_immediate)
                continue;
            if (state.fBegin > time)
                continue;
            if (time > state.fBegin + state.fDuration)
                continue;
            applied = true;
            SkOperandInterpolator& interpolator = *fInterpolators[index];
            int count = animate->components();
            if (animate->formula.size() > 0) {
                SkTDOperandArray values;
                values.setCount(count);
                bool success = animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL, 
                    animate->getValuesType(), animate->formula);
                SkASSERT(success);
                fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time);
            } else {
                SkAutoSTMalloc<16, SkOperand> values(count);
                interpolator.timeToValues(time, values.get());
                fApply.applyValues(index, values.get(), count, animate->getValuesType(), time);
            }
        }
        if (enable)
            drawable->enable(fMaker);
        else if (applied)
            result |= drawable->draw(fMaker);
        time += SK_MSec1;
    } while (time <= final);
    return result;
}
Exemple #5
0
bool SkApply::interpolate(SkAnimateMaker& maker, SkMSec rawTime) {
    if (fActive == NULL)
        return false;
    bool result = false;
#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
    SkMSec time = maker.getAppTime();
    if (lastTime == (SkMSec) -1)
        lastTime = rawTime - 1;
    if (fActive != NULL && 
        strcmp(id, "a3") == 0 && rawTime > lastTime) {
        lastTime += 1000;
        SkString debugOut;
        debugOut.appendS32(time - maker.fDebugTimeBase);
        debugOut.append(" apply id=");
        debugOut.append(_id);
        debugOut.append("; ");
        debugOut.append(fActive->fAnimators[0]->_id);
        debugOut.append("=");
        debugOut.appendS32(rawTime - fActive->fState[0].fStartTime);
        debugOut.append(")");
        SkDebugf("%s\n", debugOut.c_str());
    }
#endif
    fActive->start();
    if (restore)
        fActive->initializeSave();
    int animators = fActive->fAnimators.count();
    for (int inner = 0; inner < animators; inner++) {
        SkAnimateBase* animate = fActive->fAnimators[inner];
        if (animate->fChanged) {
            animate->fChanged = false;
            animate->fStart = rawTime;
    //      SkTypedArray values;
    //      int count = animate->fValues.count();
    //      values.setCount(count);
    //      memcpy(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count);
            animate->onEndElement(maker);
    //      if (memcmp(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count) != 0) {
                fActive->append(this);
                fActive->start();
    //      }
        }
        SkMSec time = fActive->getTime(rawTime, inner);
        SkActive::SkState& state = fActive->fState[inner];
        if (SkMSec_LT(rawTime, state.fStartTime)) {
            if (fEnabling) {
                animate->fDelayed = true;
                maker.delayEnable(this, state.fStartTime);
            }
            continue;
        } else
            animate->fDelayed = false;
        SkMSec innerTime = fLastTime = state.getRelativeTime(time);
        if (restore) 
            fActive->restoreInterpolatorValues(inner);
        if (animate->fReset) {
            if (transition != SkApply::kTransition_reverse) {
                if (SkMSec_LT(state.fBegin + state.fDuration, innerTime)) {
                    if (animate->fResetPending) {
                        innerTime = 0;
                        animate->fResetPending = false;
                    } else
                        continue;
                }
            } else if (innerTime == 0) {
                    if (animate->fResetPending) {
                        innerTime = state.fBegin + state.fDuration;
                        animate->fResetPending = false;
                    } else
                        continue;
            }
        }
        int count = animate->components();
        SkAutoSTMalloc<16, SkOperand> values(count);
        SkInterpolatorBase::Result interpResult = fActive->fInterpolators[inner]->timeToValues(
            innerTime, values.get());
        result |= (interpResult != SkInterpolatorBase::kFreezeEnd_Result);
        if ((transition != SkApply::kTransition_reverse && interpResult == SkInterpolatorBase::kFreezeEnd_Result ||
                transition == SkApply::kTransition_reverse && fLastTime == 0) && state.fUnpostedEndEvent) {
//          SkDEBUGF(("interpolate: post on end\n"));
            state.fUnpostedEndEvent = false;
            maker.postOnEnd(animate, state.fBegin + state.fDuration);
            maker.fAdjustedStart = 0;    // !!! left over from synchronizing animation days, undoubtably out of date (and broken)
        }
        if (animate->formula.size() > 0) {
            if (fLastTime > animate->dur)
                fLastTime = animate->dur;
            SkTypedArray formulaValues;
            formulaValues.setCount(count);
            bool success = animate->fFieldInfo->setValue(maker, &formulaValues, 0, 0, NULL, 
                animate->getValuesType(), animate->formula);
            SkASSERT(success);
            if (restore)
                save(inner); // save existing value
            applyValues(inner, formulaValues.begin(), count, animate->getValuesType(), innerTime);
        } else {
            if (restore)
                save(inner); // save existing value
            applyValues(inner, values.get(), count, animate->getValuesType(), innerTime);
        }
    }
    return result;
}