//static void TBAnimationManager::Update() { double time_now = TBSystem::GetTimeMS(); TBLinkListOf<TBAnimationObject>::Iterator iter = animating_objects.IterateForward(); while (TBAnimationObject *obj = iter.GetAndStep()) { // Adjust the start time if it's the first update time for this object. if (obj->adjust_start_time) { obj->animation_start_time = time_now; obj->adjust_start_time = false; } // Calculate current progress // If animation_duration is 0, it should just complete immediately. float progress = 1.0f; if (obj->animation_duration != 0) { progress = (float)(time_now - obj->animation_start_time) / (float)obj->animation_duration; progress = MIN(progress, 1.0f); } // Apply animation curve float tmp; switch (obj->animation_curve) { case ANIMATION_CURVE_SLOW_DOWN: tmp = 1 - progress; progress = 1 - tmp * tmp * tmp; break; case ANIMATION_CURVE_SPEED_UP: progress = progress * progress * progress; break; case ANIMATION_CURVE_BEZIER: progress = SMOOTHSTEP(progress); break; case ANIMATION_CURVE_SMOOTH: progress = SmoothCurve(progress, 0.6f); break; default: // linear (progress is already linear) break; } // Update animation obj->InvokeOnAnimationUpdate(progress); // Remove completed animations if (progress == 1.0f) { animating_objects.Remove(obj); obj->InvokeOnAnimationStop(false); delete obj; } } }
/* compute curvature of curve after gaussian smoothing from "Shape similarity retrieval under affine transforms", Mokhtarian & Abbasi 2002 curvex - x position of points curvey - y position of points kappa - curvature coeff for each point sigma - gaussian sigma */ void ComputeCurveCSS(const vector<double>& curvex, const vector<double>& curvey, vector<double>& kappa, vector<double>& smoothX, vector<double>& smoothY, double sigma, bool isOpen ) { vector<double> X, XX, Y, YY; SmoothCurve(curvex, curvey, smoothX, smoothY, X, XX, Y, YY, sigma, isOpen); kappa.resize(curvex.size()); for (int i = 0; i<(int)curvex.size(); i++) { // Mokhtarian 02' eqn (4) kappa[i] = (X[i] * YY[i] - XX[i] * Y[i]) / pow(X[i] * X[i] + Y[i] * Y[i], 1.5); } }
float SmoothCurve_Tweak( float x, float flPeakPos, float flPeakSharpness ) { float flMovedPeak = MovePeak( x, flPeakPos ); float flSharpened = Gain( flMovedPeak, flPeakSharpness ); return SmoothCurve( flSharpened ); }
void C_Hairball::ClientThink() { // Do some AI-type stuff.. move the entity around. //C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); //m_vecAngles = SetAbsAngles( pPlayer->GetAbsAngles() ); // copy player angles. Assert( !GetMoveParent() ); // Sophisticated AI. m_flCurSpinTime += gpGlobals->frametime; if ( m_flCurSpinTime < m_flSpinDuration ) { float div = m_flCurSpinTime / m_flSpinDuration; QAngle angles = GetLocalAngles(); angles.x += m_flSpinRateX * SmoothCurve( div ); angles.y += m_flSpinRateY * SmoothCurve( div ); SetLocalAngles( angles ); } else { // Flip between stopped and starting. if ( fabs( m_flSpinRateX ) > 0.01f ) { m_flSpinRateX = m_flSpinRateY = 0; m_flSpinDuration = RandomFloat( 1, 2 ); } else { static float flXSpeed = 3; static float flYSpeed = flXSpeed * 0.1f; m_flSpinRateX = RandomFloat( -M_PI*flXSpeed, M_PI*flXSpeed ); m_flSpinRateY = RandomFloat( -M_PI*flYSpeed, M_PI*flYSpeed ); m_flSpinDuration = RandomFloat( 1, 4 ); } m_flCurSpinTime = 0; } if ( m_flSitStillTime > 0 ) { m_flSitStillTime -= gpGlobals->frametime; if ( m_flSitStillTime <= 0 ) { // Shoot out some random lines and find the longest one. m_vMoveDir.Init( 1, 0, 0 ); float flLongestFraction = 0; for ( int i=0; i < 15; i++ ) { Vector vDir( RandomFloat( -1, 1 ), RandomFloat( -1, 1 ), RandomFloat( -1, 1 ) ); VectorNormalize( vDir ); trace_t trace; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vDir * 10000, MASK_SOLID, NULL, COLLISION_GROUP_NONE, &trace ); if ( trace.fraction != 1.0 ) { if ( trace.fraction > flLongestFraction ) { flLongestFraction = trace.fraction; m_vMoveDir = vDir; } } } m_vMoveDir *= 650; // set speed. m_flSitStillTime = -1; // Move in this direction.. } } else { // Move in the specified direction. Vector vEnd = GetAbsOrigin() + m_vMoveDir * gpGlobals->frametime; trace_t trace; UTIL_TraceLine( GetAbsOrigin(), vEnd, MASK_SOLID, NULL, COLLISION_GROUP_NONE, &trace ); if ( trace.fraction < 1 ) { // Ok, stop moving. m_flSitStillTime = RandomFloat( 1, 3 ); } else { SetLocalOrigin( GetLocalOrigin() + m_vMoveDir * gpGlobals->frametime ); } } // Transform the base hair positions so we can lock them down. VMatrix mTransform; mTransform.SetupMatrixOrgAngles( GetLocalOrigin(), GetLocalAngles() ); for ( int i=0; i < m_HairPositions.Count(); i++ ) { Vector3DMultiplyPosition( mTransform, m_HairPositions[i], m_TransformedHairPositions[i] ); } if ( m_bFirstThink ) { m_bFirstThink = false; for ( int i=0; i < m_HairPositions.Count(); i++ ) { for ( int j=0; j < m_nNodesPerHair; j++ ) { m_Nodes[i*m_nNodesPerHair+j].Init( m_TransformedHairPositions[i] ); } } } // Simulate the physics and apply constraints. m_Physics.Simulate( m_Nodes.Base(), m_Nodes.Count(), &m_Delegate, gpGlobals->frametime, 0.98 ); }