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

📄 animsand.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                            // Do the interpolation
                            cRet.Interp(m_pElement->m_ppValue[i],     m_pdPacedTime[i],
                                        m_pElement->m_ppValue[i + 1], m_pdPacedTime[i + 1],
                                        (double) ulTime, pDepend);
                        }
                    }
                }
                // Now we can clear the first time flag
                m_bFirstTime = FALSE;
            }
        }
    }

    return cRet;
}

CAttr CAnimationSandwichLayer::CumulativeAnimationFunction(UINT32 ulTime,
                                                           CAttr* pUnder,
                                                           CAttr* pDepend)
{
    CAttr cRet;

    if (pUnder)
    {
        // Initialize to the underlying value
        cRet = *pUnder;
        // Are we cumulative or not?
        if (m_pElement->m_ucAccumulate == kAccumulateSum)
        {
            // We are a cumulative animation
            //
            // Modulo the time by the simple duration
            UINT32 ulModTime = 0;
            if (m_pElement->m_ulSimpleDuration)
            {
                ulModTime = ulTime % m_pElement->m_ulSimpleDuration;
            }
            // Evaluate the simple animation function at this time
            CAttr cMod = SimpleAnimationFunction(ulModTime, pUnder, pDepend);
            // Find the iteration
            UINT32 ulIter = 0;
            if (m_pElement->m_ulSimpleDuration)
            {
                ulIter = ulTime / m_pElement->m_ulSimpleDuration;
            }
            if (ulIter)
            {
                // Evaluate the animation at the simple duration
                cRet = SimpleAnimationFunction(m_pElement->m_ulSimpleDuration,
                                               pUnder, pDepend);
                // Multiply by iteration value
                cRet.Mult((double) ulIter);
                // Add the simple animation result
                cRet.Add(&cMod, pDepend);
            }
            else
            {
                // We're on the first iteration
                cRet = cMod;
            }
        }
        else
        {
            // We are a non-cumulative animation
            //
            // Modulo the time by the simple duration
            UINT32 ulModTime = 0;
            if (m_pElement->m_ulSimpleDuration)
            {
                ulModTime = ulTime % m_pElement->m_ulSimpleDuration;
            }
            // Evaluate the simple animation function at this time
            cRet = SimpleAnimationFunction(ulModTime, pUnder, pDepend);
        }
    }

    return cRet;
}

void CAnimationSandwichLayer::RecomputePace(CAttr* pDepend)
{
    if (!m_pdPacedDist)
    {
        m_pdPacedDist = new double [m_pElement->m_ulNumValues];
        if (m_pdPacedDist)
        {
            memset((void*) m_pdPacedDist, 0, sizeof(double) *
                   m_pElement->m_ulNumValues);
        }
    }
    if (!m_pdPacedTime)
    {
        m_pdPacedTime = new double [m_pElement->m_ulNumValues];
        if (m_pdPacedTime)
        {
            memset((void*) m_pdPacedTime, 0, sizeof(double) *
                   m_pElement->m_ulNumValues);
        }
    }
    if (m_pdPacedDist && m_pdPacedTime)
    {
        UINT32 i = 0;
        // Compute D()
        m_pdPacedDist[0] = 0.0;
        for (i = 1; i < m_pElement->m_ulNumValues; i++)
        {
            m_pdPacedDist[i] = m_pdPacedDist[i - 1] +
                               CAttr::Dist(m_pElement->m_ppValue[i - 1],
                                           m_pElement->m_ppValue[i],
                                           pDepend);
        }
        // Compute T()
        double dTotal = m_pdPacedDist[m_pElement->m_ulNumValues - 1];
        for (i = 0; i < m_pElement->m_ulNumValues; i++)
        {
            m_pdPacedTime[i] = m_pdPacedDist[i] * m_pElement->m_ulSimpleDuration / dTotal;
        }
    }
}

UINT32 CAnimationSandwichLayer::ComputeFilteredSimpleTime(UINT32 ulUnfilteredActiveTime)
{
    UINT32 ulRet = ulUnfilteredActiveTime;

    if (m_pElement &&
        (m_pElement->m_bAutoReverse       ||
         m_pElement->m_dSpeed      != 1.0 ||
         m_pElement->m_dAccelerate != 0.0 ||
         m_pElement->m_dDecelerate != 0.0))
    {
        // Compute the duration of the acceleration phase
        double dacc = ((double) m_pElement->m_ulSimpleDuration) *
                      m_pElement->m_dAccelerate;
        // Compute the duration of the deceleration phase
        double ddec = ((double) m_pElement->m_ulSimpleDuration) *
                      m_pElement->m_dDecelerate;
        // Compute the active filtered time (which takes
        // into account the speed attribute)
        double dActiveFilteredTime = 0.0;
        if (m_pElement->m_dSpeed > 0.0)
        {
            dActiveFilteredTime = ((double) ulUnfilteredActiveTime) *
                                  m_pElement->m_dSpeed;
        }
        else
        {
            dActiveFilteredTime = ((double) m_pElement->m_ulADNoSpeed) -
                                  (((double) ulUnfilteredActiveTime) *
                                   fabs(m_pElement->m_dSpeed));
        }
        // Compute the unfiltered simple time
        double dUnfilteredSimpleTime = dActiveFilteredTime;
        double dDur                  = (double) m_pElement->m_ulSimpleDuration;
        double dDurPrime             = dDur;
        if (m_pElement->m_bAutoReverse)
        {
            dDurPrime *= 2.0;
        }
        // Is there any repeating behavior?
        if (m_pElement->m_dRepeatCount == 1.0 &&
            (m_pElement->m_ulRepeatDur  == ((UINT32) -1) ||
             m_pElement->m_bRepeatDurIsIndefinite))
        {
            // No repeating behavior here, so unfiltered simple
            // time is equal to active filtered time
            dUnfilteredSimpleTime = dActiveFilteredTime;
        }
        else
        {
            // This animation repeats, so calcuate the
            // remainder
            if (dDurPrime != 0.0)
            {
                dUnfilteredSimpleTime =
                    dActiveFilteredTime -
                    dDurPrime * floor(dActiveFilteredTime / dDurPrime);
            }
        }
        // Account for autoReverse behavior
        double dUnfilteredSimpleTimePrime = dUnfilteredSimpleTime;
        if (m_pElement->m_bAutoReverse &&
            dUnfilteredSimpleTime >= dDur)
        {
            dUnfilteredSimpleTimePrime = (2.0 * dDur) - dUnfilteredSimpleTime;
        }
        // Compute the decel begin time
        double dDecelBegin = dDur - ddec;
        // Compute the filtered simple time
        double dFilteredSimpleTime = (double) dUnfilteredSimpleTimePrime;
        double dRDenom             = 1.0 -
                                     (m_pElement->m_dAccelerate / 2.0) - 
                                     (m_pElement->m_dDecelerate / 2.0);
        double dR = 1.0;
        if (dRDenom != 0.0)
        {
            dR = 1.0 / dRDenom;
        }
        if (dUnfilteredSimpleTimePrime >= 0.0 &&
            dUnfilteredSimpleTimePrime < dacc)
        {
            dFilteredSimpleTime = dUnfilteredSimpleTimePrime *
                                  ComputeRunRate(dUnfilteredSimpleTimePrime,
                                                 m_pElement->m_dAccelerate,
                                                 m_pElement->m_dDecelerate,
                                                 dDur) / 2.0;
        }
        else if (dUnfilteredSimpleTimePrime >= dacc &&
                 dUnfilteredSimpleTimePrime <= dDecelBegin)
        {
            dFilteredSimpleTime = dR * (dUnfilteredSimpleTimePrime - (dacc / 2.0));

        }
        else if (dUnfilteredSimpleTimePrime > dDecelBegin &&
                 dUnfilteredSimpleTimePrime <= dDur)
        {
            double tdec = dUnfilteredSimpleTime - dDecelBegin;
            double pd   = 1.0;
            if (ddec != 0.0)
            {
                pd = tdec / ddec;
            }
            dFilteredSimpleTime = dR * (dDur - (dacc / 2.0) - ddec +
                                        (tdec * (2.0 - pd) / 2.0));
            // Make sure we don't ever round up to dDur if
            // our input is less than dDur
            if (dUnfilteredSimpleTimePrime < dDur &&
                dFilteredSimpleTime >= dDur - 0.5)
            {
                dFilteredSimpleTime = dDur - 0.50000000001;
            }
        }
        // Now round to nearest integer
        ulRet = (UINT32) floor(dFilteredSimpleTime + 0.5);
    }

    return ulRet;
}

double CAnimationSandwichLayer::ComputeRunRate(double dT, double dAccel,
                                               double dDecel, double dDur)
{
    double dRet = 1.0;

    double dacc    = dDur * dAccel;
    double ddec    = dDur * dDecel;
    double dRDenom = 1.0 - (dAccel / 2.0) - (dDecel / 2.0);
    if (dRDenom != 0.0)
    {
        double dR = 1.0 / dRDenom;
        // Compute the decel begin time
        double dDecBegin = dDur - ddec;
        // Now compute the run rate
        if (dT >= 0.0 && dT < dacc)
        {
            if (dacc != 0.0)
            {
                dRet = dR * dT / dacc;
            }
        }
        else if (dT >= dacc && dT <= dDecBegin)
        {
            dRet = dR;
        }
        else if (dT > dDecBegin && dT <= dDur)
        {
            if (ddec != 0.0)
            {
                dRet = dR * (dDur - dT) / ddec;
            }
        }
    }

    return dRet;
}

#if defined(XXXMEH_SPLINE_ANIMATION)

double CAnimationSandwichLayer::ComputeSpline(double t,  double t1, double t2,
                                              double v1, double v2, double x1,
                                              double y1, double x2, double y2)
{
    double dRet = 0.0;

    if (x1 >= 0.0 && x1 <= 1.0 &&
        y1 >= 0.0 && y1 <= 1.0 &&
        x2 >= 0.0 && x2 <= 1.0 &&
        y2 >= 0.0 && y2 <= 1.0)
    {
        if (t2 >= t1)
        {
            if (t >= t1)
            {
                if (t <= t2)
                {
                    if (t2 > t1)
                    {
                        // We compute the spline interpolation
                        // in the following steps:
                        // a) Scale the time down to unit time
                        // b) Get the output bezier time (still in unit time)
                        // c) Use this output time as the 
                        //    input time for linear interpolation.
                        //
                        // Scale the time to unit time
                        double dInUnitT = (t - t1) / (t2 - t1);
                        // Get the output bezier time
                        double dOutUnitT = ComputeBezierOutputTime(dUnitT, x1, y1, x2, y2);
                        // Do a sanity check on the output time
                        if (dOutUnitT < 0.0)
                        {
                            dOutUnitT = 0.0;
                            HX_ASSERT(FALSE && "Bad value returned from ComputeBezierOutputTime()");
                        }
                        else if (dOutUnitT > 1.0)
                        {
                            dOutUnitT = 1.0;
                            HX_ASSERT(FALSE && "Bad value returned from ComputeBezierOutputTime()");
                        }
                        // Use this time to linearly interpolate
                        dRet = v1 + (v2 - v1) * dOutUnitT;
                    }
                    else
                    {
                        // t1 is equal to t2. So this is a discontinuous
                        // interval, so by endpoint-exclusive logic [a,b),
                        // we choose v2 for the output value. This is not
                        // an input error, so we don't assert.
                        dRet = v2;
                    }
                }
                else
                {
                    dRet = v2;
                    HX_ASSERT(FALSE && "ComputeSpline(): t is greater than t2 - v2 assigned");
                }
            }
            else
            {
                dRet = v1;
                HX_ASSERT(FALSE && "ComputeSpline(): t is less than t1 - v1 assigned");
            }
        }
        else
        {
            HX_ASSERT(FALSE && "ComputeSpline(): t2 cannot be less than t1");
        }
    }
    else
    {
        HX_ASSERT(FALSE && "Illegal bezier control parameters in ComputeSpline()");
    }

    return dRet;
}

double CAnimationSandwichLayer::ComputeBezierOutputTime(double t,
                                                        double x1, double y1,
                                                        double x2, double y2)
{
    double dRet = 0.0;

    if (t  >= 0.0 && t  <= 1.0 &&
        x1 >= 0.0 && x1 <= 1.0 &&
        y1 >= 0.0 && y1 <= 1.0 &&
        x2 >= 0.0 && x2 <= 1.0 &&
        y2 >= 0.0 && y2 <= 1.0)
    {
        // We get the output bezier-curve-warped time
        // by doing the following:
        //
        // a) Find q where x(q) = t
        // b) Compute y(q)
        //
        // Find the q where x(q) = t
        double dQ = SolveForBezierT(t, x1, x2, BEZIER_TOLERANCE);
        // Do a sanity check on this value
        if (dQ < 0.0)
        {
            dQ = 0.0;
            HX_ASSERT(FALSE && "Bad value returned from SolveForBezierT()");
        }
        else if (dQ > 1.0)
        {
            dQ = 1.0;
            HX_ASSERT(FALSE && "Bad value returned from SolveForBezierT()");
        }
        // Compute y(q)
        dRet = ComputeBezier(dQ, y1, y2);
    }
    else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -