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

📄 animsand.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                        {                            if (t >= m_pdPacedTime[i] && t <= m_pdPacedTime[i + 1])                            {                                break;                            }                        }                        if (i + 1 < m_pElement->m_ulNumValues)                        {                            // 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()");

⌨️ 快捷键说明

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