void CFlex::DoBodyLean( void ) { CAI_NPC *myNpc = MyNPCPointer( ); if (myNpc) { Vector vecDelta; Vector vecPos; Vector vecOrigin = GetAbsOrigin(); if (m_vecPrevOrigin == vec3_origin) { m_vecPrevOrigin = vecOrigin; } vecDelta = vecOrigin - m_vecPrevOrigin; vecDelta.x = clamp( vecDelta.x, -50, 50 ); vecDelta.y = clamp( vecDelta.y, -50, 50 ); vecDelta.z = clamp( vecDelta.z, -50, 50 ); float dt = gpGlobals->curtime - GetLastThink(); bool bSkip = ((GetFlags() & (FL_FLY | FL_SWIM)) != 0) || (GetMoveParent() != NULL) || (GetGroundEntity() == NULL) || (GetGroundEntity()->IsMoving()); bSkip |= myNpc->TaskRanAutomovement() || (myNpc->GetVehicleEntity() != NULL); if (!bSkip) { if (vecDelta.LengthSqr() > m_vecPrevVelocity.LengthSqr()) { float decay = ExponentialDecay( 0.6, 0.1, dt ); m_vecPrevVelocity = m_vecPrevVelocity * (decay) + vecDelta * (1.f - decay); } else { float decay = ExponentialDecay( 0.4, 0.1, dt ); m_vecPrevVelocity = m_vecPrevVelocity * (decay) + vecDelta * (1.f - decay); } vecPos = m_vecPrevOrigin + m_vecPrevVelocity; float decay = ExponentialDecay( 0.5, 0.1, dt ); m_vecShift = m_vecShift * (decay) + (vecOrigin - vecPos) * (1.f - decay); // FIXME: Scale this m_vecLean = (vecOrigin - vecPos) * 1.0; // FIXME: Scale this } else { m_vecPrevVelocity = vecDelta; float decay = ExponentialDecay( 0.5, 0.1, dt ); m_vecShift = m_vecLean * decay; m_vecLean = m_vecShift * decay; } m_vecPrevOrigin = vecOrigin; /* DevMsg( "%.2f %.2f %.2f (%.2f %.2f %.2f)\n", m_vecLean.Get().x, m_vecLean.Get().y, m_vecLean.Get().z, vecDelta.x, vecDelta.y, vecDelta.z ); */ } }
float CAI_InterestTarget_t::Interest( void ) { float t = (gpGlobals->curtime - m_flStartTime) / (m_flEndTime - m_flStartTime); if (t < 0.0f || t > 1.0f) return 0.0f; if (m_flRamp && t < 1 - m_flRamp) { //t = t / m_flRamp; t = 1.0 - ExponentialDecay( 0.2, m_flRamp, t ); //t = 1.0 - ExponentialDecay( 0.01, 1 - m_flRamp, t ); } else if (t > 1.0f - m_flRamp) { t = (1.0 - t) / m_flRamp; t = 3.0f * t * t - 2.0f * t * t * t; } else { t = 1.0f; } // ramp t *= m_flInterest; return t; }
void UpdateVelocity( SimpleParticle *pParticle, float timeDelta ) { // Float up when lifetime is half gone. pParticle->m_vecVelocity[ 2 ] += 64 * timeDelta; // FIXME: optimize this.... pParticle->m_vecVelocity *= ExponentialDecay( 0.8, 0.05, timeDelta ); }
void C_AR2Explosion::SimulateParticles( CParticleSimulateIterator *pIterator ) { float dt = pIterator->GetTimeDelta(); AR2ExplosionParticle *pParticle = (AR2ExplosionParticle*)pIterator->GetFirst(); while ( pParticle ) { if (dt > 0.05) dt = 0.05; // yuck, air resistance function craps out at less then 20fps // Update its lifetime. pParticle->m_Lifetime += dt; // pDraw->GetTimeDelta(); if(pParticle->m_Lifetime > pParticle->m_Dwell) { // faded to nothing.... pIterator->RemoveParticle( pParticle ); } else { // Spin the thing pParticle->m_Roll += pParticle->m_RollSpeed * pIterator->GetTimeDelta(); // delayed? if ( pParticle->m_Lifetime >= 0.0f ) { // Move it (this comes after rendering to make it clear that moving the particle here won't change // its rendering for this frame since m_TransformedPos has already been set). pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * dt; // keep track of distance traveled pParticle->m_Dist = pParticle->m_Dist + pParticle->m_Velocity.Length() * dt; // Dampen velocity. float dist = pParticle->m_Velocity.Length() * dt; float r = dist * dist; // FIXME: this is a really screwy air-resistance function.... pParticle->m_Velocity = pParticle->m_Velocity * (100 / (100 + r )); // dampen roll static float dtime; static float decay; if (dtime != dt) { dtime = dt; decay = ExponentialDecay( 0.3, 1.0, dtime ); } if (fabs(pParticle->m_RollSpeed) > 0.2) pParticle->m_RollSpeed = pParticle->m_RollSpeed * decay; } } pParticle = (AR2ExplosionParticle*)pIterator->GetNext(); } }
void Interpolator_CurveInterpolate_NonNormalized( int interpolationType, const Vector &vPre, const Vector &vStart, const Vector &vEnd, const Vector &vNext, float f, Vector &vOut ) { vOut.Init(); switch ( interpolationType ) { default: Warning( "Unknown interpolation type %d\n", (int)interpolationType ); // break; // Fall through and use catmull_rom as default case INTERPOLATE_CATMULL_ROM_NORMALIZEX: case INTERPOLATE_DEFAULT: case INTERPOLATE_CATMULL_ROM: case INTERPOLATE_CATMULL_ROM_NORMALIZE: case INTERPOLATE_CATMULL_ROM_TANGENT: Catmull_Rom_Spline( vPre, vStart, vEnd, vNext, f, vOut ); break; case INTERPOLATE_EASE_IN: { f = sin( M_PI * f * 0.5f ); // Fixme, since this ignores vPre and vNext we could omit computing them aove VectorLerp( vStart, vEnd, f, vOut ); } break; case INTERPOLATE_EASE_OUT: { f = 1.0f - sin( M_PI * f * 0.5f + 0.5f * M_PI ); // Fixme, since this ignores vPre and vNext we could omit computing them aove VectorLerp( vStart, vEnd, f, vOut ); } break; case INTERPOLATE_EASE_INOUT: { f = SimpleSpline( f ); // Fixme, since this ignores vPre and vNext we could omit computing them aove VectorLerp( vStart, vEnd, f, vOut ); } break; case INTERPOLATE_LINEAR_INTERP: // Fixme, since this ignores vPre and vNext we could omit computing them aove VectorLerp( vStart, vEnd, f, vOut ); break; case INTERPOLATE_KOCHANEK_BARTELS: case INTERPOLATE_KOCHANEK_BARTELS_EARLY: case INTERPOLATE_KOCHANEK_BARTELS_LATE: { float t, b, c; Interpolator_GetKochanekBartelsParams( interpolationType, t, b, c ); Kochanek_Bartels_Spline ( t, b, c, vPre, vStart, vEnd, vNext, f, vOut ); } break; case INTERPOLATE_SIMPLE_CUBIC: Cubic_Spline( vPre, vStart, vEnd, vNext, f, vOut ); break; case INTERPOLATE_BSPLINE: BSpline( vPre, vStart, vEnd, vNext, f, vOut ); break; case INTERPOLATE_EXPONENTIAL_DECAY: { float dt = vEnd.x - vStart.x; if ( dt > 0.0f ) { float val = 1.0f - ExponentialDecay( 0.001, dt, f * dt ); vOut.y = vStart.y + val * ( vEnd.y - vStart.y ); } else { vOut.y = vStart.y; } } break; case INTERPOLATE_HOLD: { vOut.y = vStart.y; } break; } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPointCommentaryNode::UpdateViewThink( void ) { if ( !m_bActive ) return; CBasePlayer *pPlayer = GetCommentaryPlayer(); if ( !pPlayer ) return; // Swing the view towards the target if ( m_hViewTarget ) { QAngle angGoal; QAngle angCurrent; if ( m_hViewPositionMover ) { angCurrent = m_hViewPositionMover->GetAbsAngles(); VectorAngles( m_hViewTarget->WorldSpaceCenter() - m_hViewPositionMover->GetAbsOrigin(), angGoal ); } else { angCurrent = pPlayer->EyeAngles(); VectorAngles( m_hViewTarget->WorldSpaceCenter() - pPlayer->EyePosition(), angGoal ); } // Accelerate towards the target goal angles float dx = AngleDiff( angGoal.x, angCurrent.x ); float dy = AngleDiff( angGoal.y, angCurrent.y ); float mod = 1.0 - ExponentialDecay( 0.5, 0.3, gpGlobals->frametime ); float dxmod = dx * mod; float dymod = dy * mod; angCurrent.x = AngleNormalize( angCurrent.x + dxmod ); angCurrent.y = AngleNormalize( angCurrent.y + dymod ); if ( m_hViewPositionMover ) { m_hViewPositionMover->SetAbsAngles( angCurrent ); } else { pPlayer->SnapEyeAngles( angCurrent ); } SetNextThink( gpGlobals->curtime, s_pCommentaryUpdateViewThink ); } if ( m_hViewPosition.Get() ) { if ( pPlayer->GetActiveWeapon() ) { pPlayer->GetActiveWeapon()->Holster(); } if ( !m_hViewPositionMover ) { // Make an invisible info target entity for us to attach the view to, // and move it to the desired view position. m_hViewPositionMover = CreateEntityByName( "env_laserdot" ); m_hViewPositionMover->SetAbsAngles( pPlayer->EyeAngles() ); pPlayer->SetViewEntity( m_hViewPositionMover ); } // Blend to the target position over time. float flCurTime = (gpGlobals->curtime - m_flStartTime); float flBlendPerc = clamp( flCurTime / 2.0, 0, 1 ); // Figure out the current view position Vector vecCurEye; VectorLerp( pPlayer->EyePosition(), m_hViewPosition.Get()->GetAbsOrigin(), flBlendPerc, vecCurEye ); m_hViewPositionMover->SetAbsOrigin( vecCurEye ); SetNextThink( gpGlobals->curtime, s_pCommentaryUpdateViewThink ); } }
bool C_AR2Explosion::SimulateAndRender(Particle *pBaseParticle, ParticleDraw *pDraw, float &sortKey) { AR2ExplosionParticle* pParticle = (AR2ExplosionParticle*)pBaseParticle; float dt = pDraw->GetTimeDelta(); if (dt > 0.05) dt = 0.05; // yuck, air resistance function craps out at less then 20fps // Update its lifetime. pParticle->m_Lifetime += dt; // pDraw->GetTimeDelta(); if(pParticle->m_Lifetime > pParticle->m_Dwell) { // faded to nothing.... return false; } // Spin the thing pParticle->m_Roll += pParticle->m_RollSpeed * pDraw->GetTimeDelta(); // delayed? if(pParticle->m_Lifetime < 0.0f) { // not alive yet return true; } // Draw. float lifetimePercent = ( pParticle->m_Lifetime - AR2_DUST_FADE_IN_TIME ) / pParticle->m_Dwell; // FIXME: base color should be a dirty version of the material color Vector color = g_AR2DustColor1 * (1.0 - lifetimePercent) + g_AR2DustColor2 * lifetimePercent; Vector tPos; TransformParticle(m_pParticleMgr->GetModelView(), pParticle->m_Pos, tPos); // sortKey = tPos.z; float alpha; if ( pParticle->m_Lifetime < AR2_DUST_FADE_IN_TIME ) { alpha = AR2_DUST_ALPHA * ( pParticle->m_Lifetime / AR2_DUST_FADE_IN_TIME ); } else { alpha = AR2_DUST_ALPHA * ( 1.0f - lifetimePercent ); } alpha *= GetAlphaDistanceFade( tPos, 50, 150 ); RenderParticle_ColorSizeAngle( pDraw, tPos, color, alpha, pParticle->m_Dist, // size based on how far it's traveled pParticle->m_Roll); // Move it (this comes after rendering to make it clear that moving the particle here won't change // its rendering for this frame since m_TransformedPos has already been set). pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * dt; // keep track of distance traveled pParticle->m_Dist = pParticle->m_Dist + pParticle->m_Velocity.Length() * dt; // Dampen velocity. float dist = pParticle->m_Velocity.Length() * dt; float r = dist * dist; // FIXME: this is a really screwy air-resistance function.... pParticle->m_Velocity = pParticle->m_Velocity * (100 / (100 + r )); // dampen roll static float dtime; static float decay; if (dtime != dt) { dtime = dt; decay = ExponentialDecay( 0.3, 1.0, dtime ); } if (fabs(pParticle->m_RollSpeed) > 0.2) pParticle->m_RollSpeed = pParticle->m_RollSpeed * decay; return true; }