📄 animsand.cpp
字号:
} // Compute y(q) dRet = ComputeBezier(dQ, y1, y2); } else { HX_ASSERT(FALSE && "Illegal input parameters in ComputeBezierOutputTime()"); } return dRet;}double CAnimationSandwichLayer::SolveForBezierT(double x, double x1, double x2, double tol){ double dRet = 0.0; if (x >= 0.0 && x <= 1.0 && x1 >= 0.0 && x1 <= 1.0 && x2 >= 0.0 && x2 <= 1.0 && tol > 0.0 && tol <= 1.0) { double tL = 0.0; double xL = 0.0; double tR = 1.0; double xR = 1.0; double tM = 0.5; double xM = ComputeBezier(tM, x1, x2); UINT32 i = 0; while (fabs(xM - x) > tol && i < BEZIER_MAX_ITERATIONS) { // Is our computed mid-point smaller or // larger than our desired value? if (xM > x) { // Take the left-hand interval tR = tM; } else { // Take the right-hand interval tL = tM; } // Compute new mid-point tM = (tL + tR) / 2.0; // Compute new value xM = ComputeBezier(tM, x1, x2); // Increment the iteration count ++i; } // Set the return value dRet = tM; // Check if we blew our max iteration count if (i >= BEZIER_MAX_ITERATIONS) { HX_ASSERT(FALSE && "SolveForBezierT(): Could not get within tolerance in max iterations"); } } else { HX_ASSERT(FALSE && "Illegal input parameters in SolveForBezierT()"); } return dRet;}double CAnimationSandwichLayer::ComputeBezier(double t, double a1, double a2){ double dRet = 0.0; if (t >= 0.0 && t <= 1.0 && a1 >= 0.0 && a1 <= 1.0 && a2 >= 0.0 && a2 <= 1.0) { double t2 = t * t; double t3 = t2 * t; double ti = 1.0 - t; double ti2 = ti * ti; dRet = 3.0 * t * ti2 * a1 + 3.0 * t2 * ti * a2 + t3; } else { HX_ASSERT(FALSE && "Illegal input parameters in ComputeBezier()"); } return dRet;}#endif // #if defined(XXXMEH_SPLINE_ANIMATION)CAnimationSandwich::CAnimationSandwich(const char* pszTargetElementID, SMILNodeTag eTargetElementTag, UINT32 ulAttrName){ MLOG_LEAKCHECK("CON CAnimationSandwich this=0x%08x\n", this); m_pTargetElementID = new CHXString(pszTargetElementID); m_eTargetElementTag = eTargetElementTag; m_ulAttrName = ulAttrName; m_pLayerList = NULL;}CAnimationSandwich::~CAnimationSandwich(){ MLOG_LEAKCHECK("DES CAnimationSandwich this=0x%08x\n", this); ClearAllLayers(); HX_DELETE(m_pTargetElementID); HX_DELETE(m_pLayerList);}void CAnimationSandwich::ClearAllLayers(){ if (m_pLayerList) { LISTPOSITION pos = m_pLayerList->GetHeadPosition(); while (pos) { CAnimationSandwichLayer* pLayer = (CAnimationSandwichLayer*) m_pLayerList->GetNext(pos); HX_DELETE(pLayer); } m_pLayerList->RemoveAll(); }}const char* CAnimationSandwich::GetTargetElementID() const{ const char* pRet = NULL; if (m_pTargetElementID) { pRet = (const char*) *m_pTargetElementID; } return pRet;}HX_RESULT CAnimationSandwich::AddLayer(CAnimationSandwichLayer* pLayer){ HX_RESULT retVal = HXR_OK; if (pLayer) { if (!m_pLayerList) { m_pLayerList = new CHXSimpleList(); } if (m_pLayerList) { BOOL bAdded = FALSE; LISTPOSITION pos = m_pLayerList->GetHeadPosition(); while (pos) { CAnimationSandwichLayer* pListLayer = (CAnimationSandwichLayer*) m_pLayerList->GetAt(pos); if (pListLayer->HigherPriority(pLayer)) { // The current layer in the list is higher priority // than the layer we want to add, so we must insert // ourselves BEFORE this layer m_pLayerList->InsertBefore(pos, (void*) pLayer); // Set the flag bAdded = TRUE; // Now jump out of the loop break; } m_pLayerList->GetNext(pos); } // If we didn't add ourselves, then that // means we are the highest priority, so // add ourselves to the tail of the list if (!bAdded) { m_pLayerList->AddTail((void*) pLayer); } } else { retVal = HXR_OUTOFMEMORY; } } return retVal;}void CAnimationSandwich::RemoveLayer(const char* pszAnimID){ if (pszAnimID && m_pLayerList) { LISTPOSITION pos = m_pLayerList->GetHeadPosition(); while (pos) { CAnimationSandwichLayer* pLayer = (CAnimationSandwichLayer*) m_pLayerList->GetAt(pos); if (pLayer && pLayer->GetAnimationElementID() && !strcmp(pszAnimID, pLayer->GetAnimationElementID())) { // We need to remove this layer // // First remove it from the list pos = m_pLayerList->RemoveAt(pos); // Next delete the object itself HX_DELETE(pLayer); } else { m_pLayerList->GetNext(pos); } } }}void CAnimationSandwich::FreezeLayers(const char* pszAnimID, UINT32 ulCurTime){ if (pszAnimID && m_pLayerList) { LISTPOSITION pos = m_pLayerList->GetHeadPosition(); while (pos) { CAnimationSandwichLayer* pLayer = (CAnimationSandwichLayer*) m_pLayerList->GetNext(pos); if (pLayer && pLayer->GetAnimationElementID() && !strcmp(pszAnimID, pLayer->GetAnimationElementID()) && pLayer->IsActive(ulCurTime)) { // We need to freeze this layer. We do this // by adjusting the layer's m_ulActiveDuration // such that pLayer->m_ulDelay + pLayer->m_ulActiveDuration // is equal to the current time. pLayer->AdjustActiveDuration(ulCurTime); } } }}CAttr CAnimationSandwich::GetValue(UINT32 ulTime, CAttr* pUnder, CAttr* pDepend){ CAttr cRet; if (pUnder) { // Initialize the running value CAttr cUnder(*pUnder); // Now run through the layers if (m_pLayerList) { LISTPOSITION pos = m_pLayerList->GetHeadPosition(); while (pos) { CAnimationSandwichLayer* pLayer = (CAnimationSandwichLayer*) m_pLayerList->GetNext(pos); if (pLayer && (pLayer->IsActive(ulTime) || pLayer->IsFrozen(ulTime))) { // Evaluate this layer CAttr cRes = pLayer->AnimationEffectFunction(ulTime, &cUnder, pDepend); // Now we either have to replace OR add if (pLayer->IsAdditive() && !pLayer->IsToAnimation()) { cUnder.Add(&cRes, pDepend); } else { cUnder = cRes; } } } } // Now set the return value cRet = cUnder; } return cRet;}UINT32 CAnimationSandwich::GetNumLayers() const{ UINT32 ulRet = 0; if (m_pLayerList) { ulRet = m_pLayerList->GetCount(); } return ulRet;}void CAnimationSandwich::AdjustLayers(UINT32 ulTime){ if (m_pLayerList) { LISTPOSITION pos = m_pLayerList->GetHeadPosition(); while (pos) { CAnimationSandwichLayer* pLayer = (CAnimationSandwichLayer*) m_pLayerList->GetAt(pos); if (!pLayer->IsActive(ulTime) && !pLayer->IsFrozen(ulTime)) { // We need to remove this layer // // First remove it from the list pos = m_pLayerList->RemoveAt(pos); // Next delete the object itself HX_DELETE(pLayer); } else { m_pLayerList->GetNext(pos); } } }}BOOL CAnimationSandwich::MatchingSandwich(CSmilAnimateElement* pAnim){ BOOL bRet = FALSE; if (pAnim && pAnim->m_pTargetElementID && m_pTargetElementID && *pAnim->m_pTargetElementID == *m_pTargetElementID) { // We know that this animate element has the // same target element ID as we do. Now we // need to check if it has the same attributeName. // If the animate element is an <animateMotion>, then // our sandwich could be either left or top. If the // animate element is not <animateMotion>, then the // attributeName has to match exactly. if (pAnim->m_pNode && pAnim->m_pNode->m_tag == SMILAnimateMotion) { if (m_ulAttrName == kAttrNameLeft || m_ulAttrName == kAttrNameTop) { bRet = TRUE; } } else { UINT32 ulAttrName = pAnim->m_ucAttributeName; if (ulAttrName == m_ulAttrName) { bRet = TRUE; } } } return bRet;}BOOL CAnimationSandwich::AtLeastOneActiveLayer(UINT32 ulTime){ BOOL bRet = FALSE; if (m_pLayerList && m_pLayerList->GetCount() > 0) { LISTPOSITION pos = m_pLayerList->GetHeadPosition(); while (pos) { CAnimationSandwichLayer* pLayer = (CAnimationSandwichLayer*) m_pLayerList->GetNext(pos); if (pLayer && pLayer->IsActive(ulTime)) { bRet = TRUE; break; } } } return bRet;}CSmilAnimateInfo::CSmilAnimateInfo(){ m_pSandwich = NULL; m_pUnder = NULL; m_pDepend = NULL;}CSmilAnimateInfo::~CSmilAnimateInfo(){ HX_DELETE(m_pSandwich); HX_DELETE(m_pUnder); HX_DELETE(m_pDepend);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -