⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 animsand.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    {
        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 + -