📄 animsand.cpp
字号:
// m_ulActiveDuration takes into speed modifications. We // need to undo this before we compute the remainder time. UINT32 ulNewAD = m_ulActiveDuration; if (m_pElement->m_dSpeed != 1.0) { double dNewAD = (double) ulNewAD * fabs(m_pElement->m_dSpeed); ulNewAD = (UINT32) floor(dNewAD + 0.5); } // m_ulSimpleDuration does NOT take into account autoReverse, // but m_ulActiveDuration does. So we need to add in the // effect of autoReverse to m_ulSimpleDuration UINT32 ulNewSD = m_pElement->m_ulSimpleDuration; if (m_pElement->m_bAutoReverse) { ulNewSD *= 2; } // Now we can compute the remainder time if (ulNewSD) { ulModTime = ulNewAD % ulNewSD; } // Now, our active duration an even multiple of simple duration? if (ulModTime) { // Active duration is NOT an even multiple of simple duration, // so we just evaluate the cumulative animation function // at the end of the active duration. Make sure // and pass the time through time manipulations. UINT32 ulADTM = ComputeFilteredSimpleTime(m_ulActiveDuration); cRet = CumulativeAnimationFunction(ulADTM, pUnder, pDepend); } else { // Active duration IS an even multiple of simple duration // // Are we cumulative or not? if (m_pElement->m_ucAccumulate == kAccumulateNone) { // We are non-cumulative - simply evaluate at the // simple duration. First pass the simple duration // through time manipulations UINT32 ulSD = m_pElement->m_ulSimpleDuration; if (m_pElement->m_bAutoReverse) { ulSD *= 2; } if (m_pElement->m_dSpeed != 1.0 && m_pElement->m_dSpeed != 0.0) { double dSDSpeed = (double) ulSD / fabs(m_pElement->m_dSpeed); ulSD = (UINT32) floor(dSDSpeed + 0.5); } UINT32 ulSDTM = ComputeFilteredSimpleTime(ulSD); cRet = SimpleAnimationFunction(ulSDTM, pUnder, pDepend); } else { // We ARE cumulative // // Compute the multiple UINT32 ulMult = 1; UINT32 ulCumTime = 0; if (m_pElement->m_ulSimpleDuration) { if (m_pElement->m_bAutoReverse) { ulMult = m_ulActiveDuration / (2 * m_pElement->m_ulSimpleDuration); ulCumTime = 2 * m_pElement->m_ulSimpleDuration * (ulMult - 1); } else { ulMult = m_ulActiveDuration / m_pElement->m_ulSimpleDuration; ulCumTime = m_pElement->m_ulSimpleDuration * (ulMult - 1); } } // Compute the frozen value UINT32 ulCumTimeTM = ComputeFilteredSimpleTime(ulCumTime); CAttr cCum = CumulativeAnimationFunction(ulCumTimeTM, pUnder, pDepend); UINT32 ulSDTM = 0; if (m_pElement->m_bAutoReverse) { ulSDTM = ComputeFilteredSimpleTime(2 * m_pElement->m_ulSimpleDuration); } else { ulSDTM = ComputeFilteredSimpleTime(m_pElement->m_ulSimpleDuration); } cRet = SimpleAnimationFunction(ulSDTM, pUnder, pDepend); cRet.Add(&cCum, pDepend); } } // Save the last time m_ulLastTime = ulTM; } } return cRet;}BOOL CAnimationSandwichLayer::HigherPriority(CAnimationSandwichLayer* pLayer){ BOOL bRet = TRUE; if (pLayer) { if (m_ulDelay > pLayer->m_ulDelay) { // We start later than pLayer, so we're higher priority bRet = TRUE; } else if (m_ulDelay == pLayer->m_ulDelay) { // We start at the same time as pLayer, so the spec // says we first have to look at sync relationships if (m_pElement->m_BeginEventSourceID == pLayer->m_pElement->m_pNode->m_id) { // pLayer is our syncbase, so we are higher priority bRet = TRUE; } else if (pLayer->m_pElement->m_BeginEventSourceID == m_pElement->m_pNode->m_id) { // We are pLayer's syncbase, so pLayer is higher priority bRet = FALSE; } else { // There is no sync relationship between us and pLayer, // so we have to look at lexical order. First look at // the line the tag starts if (m_pElement->m_pNode->m_ulTagStartLine > pLayer->m_pElement->m_pNode->m_ulTagStartLine) { // We start lexically later, so we are // higher priority bRet = TRUE; } else if (m_pElement->m_pNode->m_ulTagStartLine == pLayer->m_pElement->m_pNode->m_ulTagStartLine) { // We start on the same line, so look // at the starting column if (m_pElement->m_pNode->m_ulTagStartColumn > pLayer->m_pElement->m_pNode->m_ulTagStartColumn) { // We start lexically later, so we are // higher priority bRet = TRUE; } else if (m_pElement->m_pNode->m_ulTagStartColumn == pLayer->m_pElement->m_pNode->m_ulTagStartColumn) { // Huh? How can a different element start at // the same line and column that we do? Probably // bogus, so make an arbitrary choice bRet = TRUE; } else { // We start lexically earlier, so we are NOT // higher priority bRet = FALSE; } } else { // We start lexically earlier, so we are NOT // higher priority bRet = FALSE; } } } else { // pLayer starts later than us, so it's higher priority bRet = FALSE; } } return bRet;}void CAnimationSandwichLayer::AdjustActiveDuration(UINT32 ulTime){ if (ulTime >= m_ulDelay) { m_ulActiveDuration = ulTime - m_ulDelay; }}CAttr CAnimationSandwichLayer::SimpleAnimationFunction(UINT32 ulTime, CAttr* pUnder, CAttr* pDepend){ CAttr cRet; if (pUnder) { // Initialize the return to the underlying value cRet = *pUnder; // Do we have an indefinite simple duration? if (m_pElement->m_bIndefiniteSimpleDuration) { // Our simple duration is indefinite, so interpolation // is not defined. We should set ourselves to value(0). // // What kind of animation are we? if (m_pElement->m_pNode->m_tag == SMILSet) { // If this is a set, then we know there is // only one values, so we need to just // set the value to m_ppValue[1] if (m_pElement->m_ppValue[1]) { cRet = *m_pElement->m_ppValue[1]; } } else if (m_pElement->m_ucAnimationType == kAnimTypeTo) { // If this is a to-animation, then value(0) // is the underlying value. cRet = *pUnder; } else { // Assign the value(0) if we have one if (m_pElement->m_ppValue[0]) { cRet = *m_pElement->m_ppValue[0]; } } } else { // Our simple duration is not indefinite // // We are just defined over the simple duration if (ulTime <= m_pElement->m_ulSimpleDuration) { if (m_pElement->m_pNode->m_tag == SMILSet) { // If this is a set, then we know there is // only two values, so we need to just // set the value to m_ppValue[1] if (m_pElement->m_ppValue[1]) { cRet = *m_pElement->m_ppValue[1]; } } else { // What is our calcmode? if (m_pElement->m_ucCalcMode == kCalcModeDiscrete) { // Divide the interval into m_ulNumValues segments UINT32 ulIndex = m_pElement->m_ulNumValues; if (m_pElement->m_ulSimpleDuration) { ulIndex = m_pElement->m_ulNumValues * ulTime / m_pElement->m_ulSimpleDuration; } // Make sure that m_pElement->m_ulSimpleDuration maps // to index m_ulNumValues - 1 and not m_ulNumValues if (ulIndex >= m_pElement->m_ulNumValues) { ulIndex = m_pElement->m_ulNumValues - 1; } // If we are a "to" animation, then m_ppValue[0] is // a placeholder for the underlying value. Therefore, // if we are a "to" animation and have selected index 0, // then we need to replace it by the underlying value if (m_pElement->m_ucAnimationType == kAnimTypeTo && ulIndex == 0) { cRet = *pUnder; } else if (m_pElement->m_ucAnimationType == kAnimTypeFromBy && ulIndex == 1) { // On a from-by animation, you are interpolating // between the from value and the sum of the from // and by values. m_ppValue[0] is the from value. // However, m_ppValue[1] is the by value, not the // sum of the from and by values. So if we have // chosen index 1, then we need to compute the sum // of the from and by values // if (m_pElement->m_ppValue[0] && m_pElement->m_ppValue[1]) { // First assign the from value cRet = *m_pElement->m_ppValue[0]; // Then add the by value cRet.Add(m_pElement->m_ppValue[1], pDepend); } } else { // Simply return the proper value if (m_pElement->m_ppValue[ulIndex]) { cRet = *m_pElement->m_ppValue[ulIndex]; } } } else if (m_pElement->m_ucCalcMode == kCalcModeLinear || (m_pElement->m_ucCalcMode == kCalcModePaced && m_pElement->m_ulNumValues == 2)) { // Is this a "to" animation? if (m_pElement->m_ucAnimationType == kAnimTypeTo) { // If we are a "to" animation, then we interpolate // between the underlying value and the "to" value, // which is (m_ppValue[1]). if (m_pElement->m_ppValue[1]) { // Do the interpolation double t1 = 0.0; double t2 = (double) m_pElement->m_ulSimpleDuration; double t = ulTime; cRet.Interp(pUnder, t1, m_pElement->m_ppValue[1], t2, t, pDepend); } } else if (m_pElement->m_ucAnimationType == kAnimTypeFromBy) { // On a from-by animation, you are interpolating // between the from value and the sum of the from // and by values. m_ppValue[0] is the from value. // However, m_ppValue[1] is the by value, not the // sum of the from and by values. So we need to // compute the sum of the from and by values if (m_pElement->m_ppValue[0] && m_pElement->m_ppValue[1]) { CAttr cSum = *m_pElement->m_ppValue[0]; cSum.Add(m_pElement->m_ppValue[1], pDepend); // Then we interpolate between m_ppValue[0] (the // "from" value) and cSum (the sum of the "from" // and "by" values). double t1 = 0.0; double t2 = (double) m_pElement->m_ulSimpleDuration; double t = (double) ulTime; cRet.Interp(m_pElement->m_ppValue[0], t1, &cSum, t2, t, pDepend); } } else { // Divide the interval into m_ulNumValues-1 segments UINT32 ulIndex = m_pElement->m_ulNumValues - 1; if (m_pElement->m_ulSimpleDuration) { ulIndex = (m_pElement->m_ulNumValues - 1) * ulTime / m_pElement->m_ulSimpleDuration; } // Now interpolate between this value and the next if (ulIndex + 1 < m_pElement->m_ulNumValues && m_pElement->m_ppValue[ulIndex] && m_pElement->m_ppValue[ulIndex + 1]) { // Do the interpolation double t1 = ulIndex * m_pElement->m_ulSimpleDuration / (m_pElement->m_ulNumValues - 1); double t2 = (ulIndex + 1) * m_pElement->m_ulSimpleDuration / (m_pElement->m_ulNumValues - 1); double t = ulTime; cRet.Interp(m_pElement->m_ppValue[ulIndex], t1, m_pElement->m_ppValue[ulIndex + 1], t2, t, pDepend); } else { // The only way this can happen is if // ulTime == m_pElement->m_ulSimpleDuration, so if this // if the case, we need to return the un-interpolated // value of m_ppValue[m_pElement->m_ulNumValues - 1] if (m_pElement->m_ppValue[m_pElement->m_ulNumValues - 1]) { cRet = *m_pElement->m_ppValue[m_pElement->m_ulNumValues - 1]; } } } } else if (m_pElement->m_ucCalcMode == kCalcModePaced) { // If we need to recompute the paced tables, // then do it now if (m_bRecomputePace || (!m_bRecomputePace && m_bFirstTime)) { RecomputePace(pDepend); } // Find out what index we're at double t = (double) ulTime; UINT32 i = 0; for (i = 0; i < m_pElement->m_ulNumValues - 1; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -