コード例 #1
0
//-----------------------------------------------------------------------------
// Purpose: Calculate our body lean based on our delta velocity
//-----------------------------------------------------------------------------
void CAI_PassengerBehaviorZombie::CalculateBodyLean( void )
{
	// Calculate our lateral displacement from a perfectly centered start
	float flLateralDisp = SimpleSplineRemapVal( m_vehicleState.m_vecLastAngles.z, 100.0f, -100.0f, -1.0f, 1.0f );
	flLateralDisp = clamp( flLateralDisp, -1.0f, 1.0f );

	// FIXME: Framerate dependant!
	m_flLastLateralLean = ( m_flLastLateralLean * 0.2f ) + ( flLateralDisp * 0.8f );

	// Factor in a "stun" if the zombie was moved too far off course
	if ( fabs( m_flLastLateralLean ) > 0.75f )
	{
		SuppressAttack( 0.5f );
	}

	// Calc our vertical displacement
	float flVerticalDisp = SimpleSplineRemapVal( m_vehicleState.m_vecDeltaVelocity.z, -50.0f, 50.0f, -1.0f, 1.0f );
	flVerticalDisp = clamp( flVerticalDisp, -1.0f, 1.0f );

	// FIXME: Framerate dependant!
	m_flLastVerticalLean = ( m_flLastVerticalLean * 0.75f ) + ( flVerticalDisp * 0.25f );
	
	// Set these parameters
	GetOuter()->SetPoseParameter( "lean_lateral", m_flLastLateralLean );
	GetOuter()->SetPoseParameter( "lean_vertical", m_flLastVerticalLean );
}
コード例 #2
0
void CGrabController::ComputeMaxSpeed( CBaseEntity *pEntity, IPhysicsObject *pPhysics )
{
	m_shadow.maxSpeed = 1000;
	m_shadow.maxAngular = DEFAULT_MAX_ANGULAR;

	// Compute total mass...
	float flMass = PhysGetEntityMass( pEntity );
	float flMaxMass = playerpickup_maxmass.GetFloat();
	if ( flMass <= flMaxMass )
		return;

	float flLerpFactor = clamp( flMass, flMaxMass, 500.0f );
	flLerpFactor = SimpleSplineRemapVal( flLerpFactor, flMaxMass, 500.0f, 0.0f, 1.0f );

	float invMass = pPhysics->GetInvMass();
	float invInertia = pPhysics->GetInvInertia().Length();

	float invMaxMass = 1.0f / MAX_MASS;
	float ratio = invMaxMass / invMass;
	invMass = invMaxMass;
	invInertia *= ratio;

	float maxSpeed = invMass * MASS_SPEED_SCALE * 200;
	float maxAngular = invInertia * MASS_SPEED_SCALE * 360;

	m_shadow.maxSpeed = Lerp( flLerpFactor, m_shadow.maxSpeed, maxSpeed );
	m_shadow.maxAngular = Lerp( flLerpFactor, m_shadow.maxAngular, maxAngular );
}
コード例 #3
0
void CEnvHeadcrabCanister::TestForCollisionsAgainstWorld( const Vector &vecEndPosition )
{
	// Splash damage!
	// Iterate on all entities in the vicinity.
	float flDamageRadius = m_flDamageRadius;
	float flDamage = m_flDamage;

	CBaseEntity *pEntity;
	for ( CEntitySphereQuery sphere( vecEndPosition, flDamageRadius ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
	{
		if ( pEntity == this )
			continue;

		if ( !pEntity->IsSolid() )
			continue;

		// Get distance to object and use it as a scale value.
		Vector vecSegment;
		VectorSubtract( pEntity->GetAbsOrigin(), vecEndPosition, vecSegment ); 
		float flDistance = VectorNormalize( vecSegment );

		float flFactor = 1.0f / ( flDamageRadius * (INNER_RADIUS_FRACTION - 1) );
		flFactor *= flFactor;
		float flScale = flDistance - flDamageRadius;
		flScale *= flScale * flFactor;
		if ( flScale > 1.0f ) 
		{ 
			flScale = 1.0f; 
		}
		
		// Check for a physics object and apply force!
		Vector vecForceDir = vecSegment;
		IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
		if ( pPhysObject )
		{
			// Send it flying!!!
			float flMass = PhysGetEntityMass( pEntity );
			vecForceDir *= flMass * 750 * flScale;
			pPhysObject->ApplyForceCenter( vecForceDir );
		}

		if ( pEntity->m_takedamage && ( m_flDamage != 0.0f ) )
		{
			CTakeDamageInfo info( this, this, flDamage * flScale, DMG_BLAST );
			CalculateExplosiveDamageForce( &info, vecSegment, pEntity->GetAbsOrigin() );
			pEntity->TakeDamage( info );
		}

		if ( pEntity->IsPlayer() && !(static_cast<CBasePlayer*>(pEntity)->IsInAVehicle()) )
		{
			if (vecSegment.z < 0.1f)
			{
				vecSegment.z = 0.1f;
				VectorNormalize( vecSegment );					
			}
			float flAmount = SimpleSplineRemapVal( flScale, 0.0f, 1.0f, 250.0f, 1000.0f );
			pEntity->ApplyAbsVelocityImpulse( vecSegment * flAmount );
		}
	}
}
コード例 #4
0
void C_PropCoreBall::ApplyBoneMatrixTransform( matrix3x4_t& transform )
{
	BaseClass::ApplyBoneMatrixTransform( transform );

	float flVal[3] = { m_flTargetScale[0], m_flTargetScale[1], m_flTargetScale[2] };
	float *flTargetScale[3] = { &m_flTargetScale[0], &m_flTargetScale[1], &m_flTargetScale[2] };
	float flScale[3] = { m_flScaleX, m_flScaleY, m_flScaleZ };
	float flLerpTime[3] = { m_flLerpTimeX, m_flLerpTimeY, m_flLerpTimeZ };
	float flGoalTime[3] = { m_flGoalTimeX, m_flGoalTimeY, m_flGoalTimeZ };
	bool *bRunning[3] = { &m_bRunningScale[0], &m_bRunningScale[1], &m_bRunningScale[2] };
		
	for ( int i = 0; i < 3; i++ )
	{
		if ( *flTargetScale[i] != flScale[i] )
		{
			float deltaTime = (float)( gpGlobals->curtime - flGoalTime[i]) / flLerpTime[i];
			float flRemapVal = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, *flTargetScale[i], flScale[i] );

			*bRunning[i] = true;

			if ( deltaTime >= 1.0f )
			{
				*flTargetScale[i] = flScale[i];
				*bRunning[i] = false;
			}

			flVal[i] = flRemapVal;
			m_flCurrentScale[i] = flVal[i];
		}
	}

	VectorScale( transform[0], flVal[0], transform[0] );
	VectorScale( transform[1], flVal[1], transform[1] );
	VectorScale( transform[2], flVal[2], transform[2] );
}
コード例 #5
0
// Find our interpolated value at the given point in time
float CInterpolatedValue::Interp( float curTime )
{
	switch( m_nInterpType )
	{
	case INTERP_LINEAR:
		{
			if ( curTime >= m_flEndTime )
				return m_flEndValue;

			if ( curTime <= m_flStartTime )
				return m_flStartValue;

			return RemapVal( curTime, m_flStartTime, m_flEndTime, m_flStartValue, m_flEndValue );
		}

	case INTERP_SPLINE:
		{
			if ( curTime >= m_flEndTime )
				return m_flEndValue;

			if ( curTime <= m_flStartTime )
				return m_flStartValue;

			return SimpleSplineRemapVal( curTime, m_flStartTime, m_flEndTime, m_flStartValue, m_flEndValue );
		}
	}

	// NOTENOTE: You managed to pass in a bogus interpolation type!
	Assert(0);
	return -1.0f;
}
コード例 #6
0
//-----------------------------------------------------------------------------
// Purpose: Calculate the FOV for the intro sequence (needed by both server and client)
//-----------------------------------------------------------------------------
float ScriptInfo_CalculateFOV( float flFOVBlendStartTime, float flNextFOVBlendTime, int nFOV, int nNextFOV, bool bSplineRamp )
{
	// Handle the spline case
	if ( bSplineRamp )
	{
		//If we're past the zoom time, just take the new value and stop transitioning
		float deltaTime = (float)( gpGlobals->curtime - flFOVBlendStartTime ) / ( flNextFOVBlendTime - flFOVBlendStartTime );
		if ( deltaTime >= 1.0f )
			return nNextFOV;

		float flResult = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, (float) nFOV, (float) nNextFOV );
		
		// Msg("FOV BLENDING: curtime %.2f    StartedAt %.2f    FinishAt: %.2f\n", gpGlobals->curtime, flFOVBlendStartTime, flNextFOVBlendTime );
		// Msg("			   Perc:   %.2f    Start: %d	End: %d		FOV: %.2f\n", SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, nFOV, nNextFOV ), nFOV, nNextFOV, flResult );
		
		return flResult;
	}
	
	// Common, linear blend
	if ( (flNextFOVBlendTime - flFOVBlendStartTime) != 0 )
	{
		float flResult = RemapValClamped( gpGlobals->curtime, flFOVBlendStartTime, flNextFOVBlendTime, (float) nFOV, (float) nNextFOV );
		
		// Msg("FOV BLENDING: curtime %.2f    StartedAt %.2f    FinishAt: %.2f\n", gpGlobals->curtime, flFOVBlendStartTime, flNextFOVBlendTime );
		// Msg("			   Perc:   %.2f    Start: %d	End: %d		FOV: %.2f\n", RemapValClamped( gpGlobals->curtime, flFOVBlendStartTime, flNextFOVBlendTime, 0.0, 1.0 ), nFOV, nNextFOV, flResult );
		
		return flResult;
	}

	
	// Msg("FOV BLENDING: JUMPED TO NEXT FOV (%d)\n", nNextFOV );
	return nNextFOV;
}
コード例 #7
0
void CSDKGameMovement::SetProneEyeOffset( float proneFraction )
{
	Vector vecPropViewOffset = VEC_PRONE_VIEW;
	Vector vecStandViewOffset = GetPlayerViewOffset( player->m_Local.m_bDucked || m_pSDKPlayer->m_bUnProneToDuck );

	Vector temp = player->GetViewOffset();
	temp.z = SimpleSplineRemapVal( proneFraction, 1.0, 0.0, vecPropViewOffset.z, vecStandViewOffset.z );

	player->SetViewOffset( temp );
}
コード例 #8
0
void CAI_Spotlight::UpdateSpotlightDirection( void )
{
	if ( !m_hSpotlight )
	{
		CreateSpotlightEntities();
	}

	// Compute the current beam direction
	Vector vTargetDir;
	VectorSubtract( m_vSpotlightTargetPos, m_hSpotlight->GetAbsStartPos(), vTargetDir ); 
	VectorNormalize(vTargetDir);
	ConstrainToCone( &vTargetDir );

	// Compute the amount to rotate
	float flDot = DotProduct( vTargetDir, m_vSpotlightDir );
	flDot = clamp( flDot, -1.0f, 1.0f );
	float flAngle = AngleNormalize( RAD2DEG( acos( flDot ) ) );
	float flClampedAngle = clamp( flAngle, 0.0f, 45.0f );
	float flBeamTurnRate = SimpleSplineRemapVal( flClampedAngle, 0.0f, 45.0f, 10.0f, 45.0f );
	if ( fabs(flAngle) > flBeamTurnRate * gpGlobals->frametime )
	{
		flAngle = flBeamTurnRate * gpGlobals->frametime;
	}

	// Compute the rotation axis
	Vector vecRotationAxis;
	CrossProduct( m_vSpotlightDir, vTargetDir, vecRotationAxis );
	if ( VectorNormalize( vecRotationAxis ) < 1e-3 )
	{
		vecRotationAxis.Init( 0, 0, 1 );
	}

	// Compute the actual rotation amount, using quat slerp blending
	Quaternion desiredQuat, resultQuat;
	AxisAngleQuaternion( vecRotationAxis, flAngle, desiredQuat );
	QuaternionSlerp( m_vAngularVelocity, desiredQuat, QUAT_BLEND_FACTOR, resultQuat );
	m_vAngularVelocity = resultQuat;

	// If we're really close, and we're not moving very quickly, slam.
	float flActualRotation = AngleNormalize( RAD2DEG(2 * acos(m_vAngularVelocity.w)) );
	if (( flActualRotation < 1e-3 ) && (flAngle < 1e-3 ))
	{
		m_vSpotlightDir = vTargetDir;
		m_vAngularVelocity.Init( 0, 0, 0, 1 );
		return;
	}

	// Update the desired direction
	matrix3x4_t rot;
	Vector vecNewDir;
	QuaternionMatrix( m_vAngularVelocity, rot );
	VectorRotate( m_vSpotlightDir, rot, vecNewDir );
	m_vSpotlightDir = vecNewDir;
	VectorNormalize(m_vSpotlightDir);
}
コード例 #9
0
ファイル: c_entitydissolve.cpp プロジェクト: Yosam02/game
//-----------------------------------------------------------------------------
// Sparks!
//-----------------------------------------------------------------------------
void C_EntityDissolve::DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] )
{
	if ( m_flNextSparkTime > gpGlobals->curtime )
		return;

	float dt = m_flStartTime + m_flFadeOutStart - gpGlobals->curtime;
	dt = clamp( dt, 0.0f, m_flFadeOutStart );
	
	float flNextTime;
	if (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL)
	{
		flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 2.0f * TICK_INTERVAL, 0.4f );
	}
	else
	{
		// m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT);
		flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 0.3f, 1.0f );
	}

	m_flNextSparkTime = gpGlobals->curtime + flNextTime;

	// Send out beams around us
	int iNumBeamsAround = 2;
	int iNumRandomBeams = 1;
	int iTotalBeams = iNumBeamsAround + iNumRandomBeams;
	float flYawOffset = RandomFloat(0,360);
	for ( int i = 0; i < iTotalBeams; i++ )
	{
		int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 );
		mstudiobbox_t *pBox = set->pHitbox(nHitbox);

		float flActualYawOffset = 0;
		bool bRandom = ( i >= iNumBeamsAround );
		if ( !bRandom )
		{
			flActualYawOffset = anglemod( flYawOffset + ((360 / iTotalBeams) * i) );
		}

		BuildTeslaEffect( pBox, *hitboxbones[pBox->bone], bRandom, flActualYawOffset );
	}
}
コード例 #10
0
ファイル: RagdollBoogie.cpp プロジェクト: EspyEspurr/game
//-----------------------------------------------------------------------------
// Purpose: Burn targets around us
//-----------------------------------------------------------------------------
void CRagdollBoogie::BoogieThink( void )
{
	CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( GetMoveParent() );
	if ( !pRagdoll )
	{
		UTIL_Remove( this );
		return;
	}

	float flMagnitude = m_flMagnitude;
	if ( m_flBoogieLength != 0 )
	{
		float dt = gpGlobals->curtime - m_flStartTime;
		if ( dt >= m_flBoogieLength )
		{
			// Don't remove while suppressed... this helps if we try to start another boogie
			if ( m_nSuppressionCount == 0 )
			{
				UTIL_Remove( this );
			}
			SetThink( NULL );
			return;
		}

		if ( dt < 0 )
		{
			SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) );
			return;
		}

		flMagnitude = SimpleSplineRemapVal( dt, 0.0f, m_flBoogieLength, m_flMagnitude, 0.0f ); 
	}

#ifndef _XBOX
	if ( m_nSuppressionCount == 0 )
	{
		ragdoll_t *pRagdollPhys = pRagdoll->GetRagdoll( );
		for ( int j = 0; j < pRagdollPhys->listCount; ++j )
		{
			float flMass = pRagdollPhys->list[j].pObject->GetMass();
			float flForce = m_flMagnitude * flMass;

			Vector vecForce;
			vecForce = RandomVector( -flForce, flForce );
			pRagdollPhys->list[j].pObject->ApplyForceCenter( vecForce ); 
		}
	}
#endif // !_XBOX

	SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) );
}
コード例 #11
0
void CBaseHelicopter::DoWashPushOnAirboat( CBaseEntity *pAirboat, 
	const Vector &vecWashToAirboat, float flWashAmount )
{
	// For the airboat, simply produce a small roll and a push outwards.
	// But don't produce a roll if we're too rolled in that direction already.
	
	// Get the actual up direction vector
	Vector vecUp;
	pAirboat->GetVectors( NULL, NULL, &vecUp );
	if ( vecUp.z < MAX_AIRBOAT_ROLL_COSANGLE )
		return;

	// Compute roll direction so that we get pushed down on the side where the rotor wash is.
	Vector vecRollNormal;
	CrossProduct( vecWashToAirboat, Vector( 0, 0, 1 ), vecRollNormal );

	// Project it into the plane of the roll normal
	VectorMA( vecUp, -DotProduct( vecUp, vecRollNormal ), vecRollNormal, vecUp );
	VectorNormalize( vecUp );

	// Compute a vector which is the max direction we can roll given the roll constraint
	Vector vecExtremeUp;
	VMatrix rot;
	MatrixBuildRotationAboutAxis( rot, vecRollNormal, MAX_AIRBOAT_ROLL_ANGLE );
	MatrixGetColumn( rot, 2, &vecExtremeUp );

	// Find the angle between how vertical we are and how vertical we should be
	float flCosDelta = DotProduct( vecExtremeUp, vecUp );
	float flDelta = acos(flCosDelta) * 180.0f / M_PI;
	flDelta = clamp( flDelta, 0.0f, MAX_AIRBOAT_ROLL_ANGLE );
	flDelta = SimpleSplineRemapVal( flDelta, 0.0f, MAX_AIRBOAT_ROLL_ANGLE, 0.0f, 1.0f );

	float flForce = 12.0f * flWashAmount * flDelta;

	Vector vecWashOrigin;
	Vector vecForce;
	VectorMultiply( Vector( 0, 0, -1 ), flForce, vecForce );
	VectorMA( pAirboat->GetAbsOrigin(), -200.0f, vecWashToAirboat, vecWashOrigin );

	pAirboat->VPhysicsTakeDamage( CTakeDamageInfo( this, this, vecForce, vecWashOrigin, flWashAmount, DMG_BLAST ) );
}
コード例 #12
0
//-----------------------------------------------------------------------------
// Purpose: 
// Output : float
//-----------------------------------------------------------------------------
float C_BaseHLPlayer::GetZoom( void )
{
	float fFOV = m_flZoomEnd;

	//See if we need to lerp the values
	if ( ( m_flZoomStart != m_flZoomEnd ) && ( m_flZoomRate > 0.0f ) )
	{
		float deltaTime = (float)( gpGlobals->curtime - m_flZoomStartTime ) / m_flZoomRate;

		if ( deltaTime >= 1.0f )
		{
			//If we're past the zoom time, just take the new value and stop lerping
			fFOV = m_flZoomStart = m_flZoomEnd;
		}
		else
		{
			fFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_flZoomStart, m_flZoomEnd );
		}
	}

	return fFOV;
}
コード例 #13
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_ScriptIntro::CalculateFOV( void )
{
	// Calculate the FOV
	if ( m_flNextFOVBlendTime >= gpGlobals->curtime )
	{
		if ( m_bAlternateFOV == true )
		{
			float deltaTime = (float)( gpGlobals->curtime - m_flFOVBlendStartTime ) / ( m_flNextFOVBlendTime - m_flFOVBlendStartTime );

			if ( deltaTime >= 1.0f )
			{
				//If we're past the zoom time, just take the new value and stop transitioning
				m_IntroData.m_playerViewFOV = m_iNextFOV;
			}
			else
			{
				m_IntroData.m_playerViewFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_iFOVAtStartBlend, m_iNextFOV );
			}
		}
		else
		{
			if ( (m_flNextFOVBlendTime - m_flFOVBlendStartTime) != 0 )
			{
				m_IntroData.m_playerViewFOV = RemapValClamped( gpGlobals->curtime, m_flFOVBlendStartTime, m_flNextFOVBlendTime, m_iFOVAtStartBlend, m_iNextFOV );

				//Msg("FOV BLENDING: curtime %.2f    StartedAt %.2f    FinishAt: %.2f\n", gpGlobals->curtime, m_flFOVBlendStartTime, m_flNextFOVBlendTime );
				//Msg("			   Perc:   %.2f    Start: %d	End: %d		FOV: %.2f\n", RemapValClamped( gpGlobals->curtime, m_flFOVBlendStartTime, m_flNextFOVBlendTime, 0.0, 1.0 ), m_iFOVAtStartBlend, m_iNextFOV, m_IntroData.m_playerViewFOV );
			}
			else
			{
				//Msg("FOV BLENDING: JUMPED TO NEXT FOV (%d)\n", m_iNextFOV );
				m_IntroData.m_playerViewFOV = m_iNextFOV;
			}
		}
	}
}
コード例 #14
0
//-----------------------------------------------------------------------------
// Purpose: Do the headlight
//-----------------------------------------------------------------------------
void CFlashlightEffect::UpdateLightNew(const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp )
{
	VPROF_BUDGET( "CFlashlightEffect::UpdateLightNew", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING );

	FlashlightState_t state;

	// We will lock some of the flashlight params if player is on a ladder, to prevent oscillations due to the trace-rays
	bool bPlayerOnLadder = ( C_BasePlayer::GetLocalPlayer()->GetMoveType() == MOVETYPE_LADDER );

	const float flEpsilon = 0.1f;			// Offset flashlight position along vecUp
	const float flDistCutoff = 128.0f;
	const float flDistDrag = 0.2;

	CTraceFilterSkipPlayerAndViewModel traceFilter;
	float flOffsetY = r_flashlightoffsety.GetFloat();

	if( r_swingflashlight.GetBool() )
	{
		// This projects the view direction backwards, attempting to raise the vertical
		// offset of the flashlight, but only when the player is looking down.
		Vector vecSwingLight = vecPos + vecForward * -12.0f;
		if( vecSwingLight.z > vecPos.z )
		{
			flOffsetY += (vecSwingLight.z - vecPos.z);
		}
	}

	Vector vOrigin = vecPos + flOffsetY * vecUp;

	// Not on ladder...trace a hull
	if ( !bPlayerOnLadder ) 
	{
		trace_t pmOriginTrace;
		UTIL_TraceHull( vecPos, vOrigin, Vector(-4, -4, -4), Vector(4, 4, 4), MASK_SOLID & ~(CONTENTS_HITBOX), &traceFilter, &pmOriginTrace );

		if ( pmOriginTrace.DidHit() )
		{
			vOrigin = vecPos;
		}
	}
	else // on ladder...skip the above hull trace
	{
		vOrigin = vecPos;
	}

	// Now do a trace along the flashlight direction to ensure there is nothing within range to pull back from
	int iMask = MASK_OPAQUE_AND_NPCS;
	iMask &= ~CONTENTS_HITBOX;
	iMask |= CONTENTS_WINDOW;

	// VR SOURCE - Use weap angle forward vector here
	
	Vector vTarget;

	/*if ( VR_Controller()->initialized() && VR_Controller()->hasWeaponTracking() ) 
	{
		vTarget = vecPos + 
	} 
	else 
	{*/
		vTarget = vecPos + vecForward * r_flashlightfar.GetFloat();
	// }
	

	// Work with these local copies of the basis for the rest of the function
	Vector vDir   = vTarget - vOrigin;
	Vector vRight = vecRight;
	Vector vUp    = vecUp;
	VectorNormalize( vDir   );
	VectorNormalize( vRight );
	VectorNormalize( vUp    );

	// Orthonormalize the basis, since the flashlight texture projection will require this later...
	vUp -= DotProduct( vDir, vUp ) * vDir;
	VectorNormalize( vUp );
	vRight -= DotProduct( vDir, vRight ) * vDir;
	VectorNormalize( vRight );
	vRight -= DotProduct( vUp, vRight ) * vUp;
	VectorNormalize( vRight );

	AssertFloatEquals( DotProduct( vDir, vRight ), 0.0f, 1e-3 );
	AssertFloatEquals( DotProduct( vDir, vUp    ), 0.0f, 1e-3 );
	AssertFloatEquals( DotProduct( vRight, vUp  ), 0.0f, 1e-3 );

	trace_t pmDirectionTrace;
	UTIL_TraceHull( vOrigin, vTarget, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), iMask, &traceFilter, &pmDirectionTrace );

	if ( r_flashlightvisualizetrace.GetBool() == true )
	{
		debugoverlay->AddBoxOverlay( pmDirectionTrace.endpos, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), QAngle( 0, 0, 0 ), 0, 0, 255, 16, 0 );
		debugoverlay->AddLineOverlay( vOrigin, pmDirectionTrace.endpos, 255, 0, 0, false, 0 );
	}

	float flDist = (pmDirectionTrace.endpos - vOrigin).Length();
	if ( flDist < flDistCutoff )
	{
		// We have an intersection with our cutoff range
		// Determine how far to pull back, then trace to see if we are clear
		float flPullBackDist = bPlayerOnLadder ? r_flashlightladderdist.GetFloat() : flDistCutoff - flDist;	// Fixed pull-back distance if on ladder
		m_flDistMod = Lerp( flDistDrag, m_flDistMod, flPullBackDist );
		
		if ( !bPlayerOnLadder )
		{
			trace_t pmBackTrace;
			UTIL_TraceHull( vOrigin, vOrigin - vDir*(flPullBackDist-flEpsilon), Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), iMask, &traceFilter, &pmBackTrace );
			if( pmBackTrace.DidHit() )
			{
				// We have an intersection behind us as well, so limit our m_flDistMod
				float flMaxDist = (pmBackTrace.endpos - vOrigin).Length() - flEpsilon;
				if( m_flDistMod > flMaxDist )
					m_flDistMod = flMaxDist;
			}
		}
	}
	else
	{
		m_flDistMod = Lerp( flDistDrag, m_flDistMod, 0.0f );
	}
	vOrigin = vOrigin - vDir * m_flDistMod;

	state.m_vecLightOrigin = vOrigin;

	BasisToQuaternion( vDir, vRight, vUp, state.m_quatOrientation );

	state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat();

	bool bFlicker = false;

#ifdef HL2_EPISODIC
	C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
	if ( pPlayer )
	{
		float flBatteryPower = ( pPlayer->m_HL2Local.m_flFlashBattery >= 0.0f ) ? ( pPlayer->m_HL2Local.m_flFlashBattery ) : pPlayer->m_HL2Local.m_flSuitPower;
		if ( flBatteryPower <= 10.0f )
		{
			float flScale;
			if ( flBatteryPower >= 0.0f )
			{	
				flScale = ( flBatteryPower <= 4.5f ) ? SimpleSplineRemapVal( flBatteryPower, 4.5f, 0.0f, 1.0f, 0.0f ) : 1.0f;
			}
			else
			{
				flScale = SimpleSplineRemapVal( flBatteryPower, 10.0f, 4.8f, 1.0f, 0.0f );
			}
			
			flScale = clamp( flScale, 0.0f, 1.0f );

			if ( flScale < 0.35f )
			{
				float flFlicker = cosf( gpGlobals->curtime * 6.0f ) * sinf( gpGlobals->curtime * 15.0f );
				
				if ( flFlicker > 0.25f && flFlicker < 0.75f )
				{
					// On
					state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale;
				}
				else
				{
					// Off
					state.m_fLinearAtten = 0.0f;
				}
			}
			else
			{
				float flNoise = cosf( gpGlobals->curtime * 7.0f ) * sinf( gpGlobals->curtime * 25.0f );
				state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale + 1.5f * flNoise;
			}

			state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );
			state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );
			
			bFlicker = true;
		}
	}
#endif // HL2_EPISODIC

	if ( bFlicker == false )
	{
		state.m_fLinearAtten = r_flashlightlinear.GetFloat();
		state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat();
		state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat();
	}

	state.m_fConstantAtten = r_flashlightconstant.GetFloat();
	state.m_Color[0] = 1.0f;
	state.m_Color[1] = 1.0f;
	state.m_Color[2] = 1.0f;
	state.m_Color[3] = r_flashlightambient.GetFloat();
	state.m_NearZ = r_flashlightnear.GetFloat() + m_flDistMod;	// Push near plane out so that we don't clip the world when the flashlight pulls back 
	state.m_FarZ = r_flashlightfar.GetFloat();
	state.m_bEnableShadows = r_flashlightdepthtexture.GetBool();
	state.m_flShadowMapResolution = r_flashlightdepthres.GetInt();

	state.m_pSpotlightTexture = m_FlashlightTexture;
	state.m_nSpotlightTextureFrame = 0;

	state.m_flShadowAtten = r_flashlightshadowatten.GetFloat();
	state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat();
	state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat();

	if( m_FlashlightHandle == CLIENTSHADOW_INVALID_HANDLE )
	{
		m_FlashlightHandle = g_pClientShadowMgr->CreateFlashlight( state );
	}
	else
	{
		if( !r_flashlightlockposition.GetBool() )
		{
			g_pClientShadowMgr->UpdateFlashlightState( m_FlashlightHandle, state );
		}
	}
	
	g_pClientShadowMgr->UpdateProjectedTexture( m_FlashlightHandle, true );
	
	// Kill the old flashlight method if we have one.
	LightOffOld();

#ifndef NO_TOOLFRAMEWORK
	if ( clienttools->IsInRecordingMode() )
	{
		KeyValues *msg = new KeyValues( "FlashlightState" );
		msg->SetFloat( "time", gpGlobals->curtime );
		msg->SetInt( "entindex", m_nEntIndex );
		msg->SetInt( "flashlightHandle", m_FlashlightHandle );
		msg->SetPtr( "flashlightState", &state );
		ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
		msg->deleteThis();
	}
#endif
}
コード例 #15
0
bool CFlashlightEffect::UpdateDefaultFlashlightState( FlashlightState_t& state, const Vector &vecPos, const Vector &vecForward,
														const Vector &vecRight, const Vector &vecUp, bool castsShadows, bool bTracePlayers )
{
	VPROF_BUDGET( __FUNCTION__, VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING );

	if ( !m_bIsOn )
	{
		//		return;
	}

	if ( ComputeLightPosAndOrientation( vecPos, vecForward, vecRight, vecUp, state.m_vecLightOrigin, state.m_quatOrientation, bTracePlayers ) == false )
	{
		return false;
	}

	state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat();

	bool bFlicker = false;

#ifdef HL2_EPISODIC
	C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
	if ( pPlayer )
	{
		float flBatteryPower = ( pPlayer->m_HL2Local.m_flFlashBattery >= 0.0f ) ? ( pPlayer->m_HL2Local.m_flFlashBattery ) : pPlayer->m_HL2Local.m_flSuitPower;
		if ( flBatteryPower <= 10.0f )
		{
			float flScale;
			if ( flBatteryPower >= 0.0f )
			{	
				flScale = ( flBatteryPower <= 4.5f ) ? SimpleSplineRemapVal( flBatteryPower, 4.5f, 0.0f, 1.0f, 0.0f ) : 1.0f;
			}
			else
			{
				flScale = SimpleSplineRemapVal( flBatteryPower, 10.0f, 4.8f, 1.0f, 0.0f );
			}

			flScale = clamp( flScale, 0.0f, 1.0f );

			if ( flScale < 0.35f )
			{
				float flFlicker = cosf( gpGlobals->curtime * 6.0f ) * sinf( gpGlobals->curtime * 15.0f );

				if ( flFlicker > 0.25f && flFlicker < 0.75f )
				{
					// On
					state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale;
				}
				else
				{
					// Off
					state.m_fLinearAtten = 0.0f;
				}
			}
			else
			{
				float flNoise = cosf( gpGlobals->curtime * 7.0f ) * sinf( gpGlobals->curtime * 25.0f );
				state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale + 1.5f * flNoise;
			}

			state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );
			state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );

			bFlicker = true;
		}
	}
#endif // HL2_EPISODIC

	if ( bFlicker == false )
	{
		if ( m_flLinearAtten > 0.0f )
		{
			state.m_fLinearAtten = m_flLinearAtten;
		}
		else
		{
			state.m_fLinearAtten = r_flashlightlinear.GetFloat();
		}

		if ( m_flFov > 0.0f )
		{
			state.m_fHorizontalFOVDegrees = m_flFov;
			state.m_fVerticalFOVDegrees = m_flFov;
		}
		else
		{
			state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat();
			state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat();
		}

		if ( m_bMuzzleFlashEnabled )
		{
			state.m_fHorizontalFOVDegrees = state.m_fVerticalFOVDegrees = r_flashlightmuzzleflashfov.GetFloat();
		}
	}

	state.m_fConstantAtten = r_flashlightconstant.GetFloat();
	state.m_Color[0] = 1.0f;
	state.m_Color[1] = 1.0f;
	state.m_Color[2] = 1.0f;
	state.m_Color[3] = r_flashlightambient.GetFloat();

	state.m_NearZ = r_flashlightnear.GetFloat() + r_flashlightnearoffsetscale.GetFloat() * m_flCurrentPullBackDist;		// Optionally push near plane out so that we don't clip the world when the flashlight pulls back 
	if ( m_flFarZ > 0.0f )
	{
		state.m_FarZ = state.m_FarZAtten = m_flFarZ;	// Strictly speaking, these are different, but the game can treat them the same
	}
	else
	{
		state.m_FarZ = state.m_FarZAtten = r_flashlightfar.GetFloat();	// Strictly speaking, these are different, but the game can treat them the same
	}
	state.m_bEnableShadows = castsShadows && r_flashlightdepthtexture.GetBool();
	state.m_flShadowMapResolution = r_flashlightdepthres.GetInt();
	state.m_flShadowFilterSize = 3.0f;

	// uberlight
	state.m_bUberlight = r_flashlightuberlight.GetBool();
	state.m_uberlightState.m_fRoundness = 1.0f;

	if ( m_bMuzzleFlashEnabled )
	{
		state.m_pSpotlightTexture = m_MuzzleFlashTexture;
		state.m_pProjectedMaterial = NULL;
		state.m_Color[0] = m_flMuzzleFlashBrightness;
		state.m_Color[1] = m_flMuzzleFlashBrightness;
		state.m_Color[2] = m_flMuzzleFlashBrightness;
	}
	else
	{
		state.m_pSpotlightTexture = m_FlashlightTexture;
		state.m_pProjectedMaterial = NULL;
	}

	state.m_nSpotlightTextureFrame = 0;

	state.m_flShadowAtten = r_flashlightshadowatten.GetFloat();
	state.m_flShadowSlopeScaleDepthBias = g_pMaterialSystemHardwareConfig->GetShadowSlopeScaleDepthBias();
	state.m_flShadowDepthBias = g_pMaterialSystemHardwareConfig->GetShadowDepthBias();

	state.m_bVolumetric = r_flashlightvolumetrics.GetBool();
	state.m_flAmbientOcclusion = r_flashlightAO.GetFloat();
	
	return true;
}
コード例 #16
0
ファイル: flashlighteffect.cpp プロジェクト: paralin/hl2sdk
//-----------------------------------------------------------------------------
// Purpose: Do the headlight
//-----------------------------------------------------------------------------
void CFlashlightEffect::UpdateLightNew(const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp)
{
	FlashlightState_t state;

	Vector end = vecPos + r_flashlightoffsety.GetFloat() * vecUp;

	trace_t pmEye, pmEyeBack;
	CTraceFilterSkipPlayerAndViewModel traceFilter;

	UTIL_TraceHull( vecPos, end, Vector( -4, -4, -4 ), Vector ( 4, 4, 4 ), MASK_SOLID & ~(CONTENTS_HITBOX), &traceFilter, &pmEye );

	if ( pmEye.fraction != 1.0f )
	{
		end = vecPos;
	}

	int iMask = MASK_OPAQUE_AND_NPCS;
	iMask &= ~CONTENTS_HITBOX;
	iMask |= CONTENTS_WINDOW;

	// Trace a line outward, skipping the player model and the view model.
	//Eye -> EyeForward
	UTIL_TraceHull( end, vecPos + vecForward * r_flashlightfar.GetFloat(), Vector( -4, -4, -4 ), Vector ( 4, 4, 4 ), iMask, &traceFilter, &pmEye );
	UTIL_TraceHull( end, vecPos - vecForward * 128, Vector( -4, -4, -4 ), Vector ( 4, 4, 4 ), iMask, &traceFilter, &pmEyeBack );

	float flDist;
	float flLength = (pmEye.endpos - end).Length();

	if ( flLength <= 128 )
	{
		flDist = ( ( 1.0f - ( flLength / 128 ) ) * 128.0f );
	}
	else
	{
		flDist = 0.0f;
	}


	m_flDistMod = Lerp( 0.3f, m_flDistMod, flDist );

	float flMaxDist = (pmEyeBack.endpos - end).Length();
	if( m_flDistMod > flMaxDist )
		m_flDistMod = flMaxDist;

	Vector vStartPos = end;
	Vector vEndPos = pmEye.endpos;
	Vector vDir = vEndPos - vStartPos;
	
	VectorNormalize( vDir );

	if ( vDir == vec3_origin )
	{
		vDir = vecForward;
	}

	vStartPos = vStartPos - vDir * m_flDistMod;

	if ( r_flashlightvisualizetrace.GetBool() == true )
	{
		debugoverlay->AddBoxOverlay( vEndPos, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), QAngle( 0, 0, 0 ), 0, 0, 255, 16, 0 );
		debugoverlay->AddLineOverlay( vStartPos, vEndPos, 255, 0, 0, false, 0 );
	}

	state.m_vecLightOrigin = vStartPos;
	state.m_vecLightDirection = vDir;

	state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat();

	bool bFlicker = false;

#ifdef HL2_EPISODIC
	
	C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
	if ( pPlayer && pPlayer->m_HL2Local.m_flSuitPower <= 10.0f )
	{
		float flScale = SimpleSplineRemapVal( pPlayer->m_HL2Local.m_flSuitPower, 10.0f, 4.8f, 1.0f, 0.0f );
		flScale = clamp( flScale, 0.0f, 1.0f );

		if ( flScale < 0.35f )
		{
			float flFlicker = cosf( gpGlobals->curtime * 6.0f ) * sinf( gpGlobals->curtime * 15.0f );
			
			if ( flFlicker > 0.25f && flFlicker < 0.75f )
			{
				// On
				state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale;
			}
			else
			{
				// Off
				state.m_fLinearAtten = 0.0f;
			}
		}
		else
		{
			float flNoise = cosf( gpGlobals->curtime * 7.0f ) * sinf( gpGlobals->curtime * 25.0f );
			state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale + 1.5f * flNoise;
		}

		state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );
		state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );
		
		bFlicker = true;
	}

#endif
	
	if ( bFlicker == false )
	{
		state.m_fLinearAtten = r_flashlightlinear.GetFloat();
		state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat();
		state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat();
	}

	state.m_fConstantAtten = r_flashlightconstant.GetFloat();
	state.m_Color.Init( 1.0f, 1.0f, 1.0f );
	state.m_NearZ = r_flashlightnear.GetFloat();
	state.m_FarZ = r_flashlightfar.GetFloat();
	
	if( m_FlashlightHandle == CLIENTSHADOW_INVALID_HANDLE )
	{
		m_FlashlightHandle = g_pClientShadowMgr->CreateFlashlight( state );
	}
	else
	{
		if( !r_flashlightlockposition.GetBool() )
		{
			g_pClientShadowMgr->UpdateFlashlightState( m_FlashlightHandle, state );
		}
	}
	
	g_pClientShadowMgr->UpdateProjectedTexture( m_FlashlightHandle, true );
	
	// Kill the old flashlight method if we have one.
	LightOffOld();
}
コード例 #17
0
//------------------------------------------------------------------------------
// Purpose : 
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CNPC_CombineDropship::Flight( void )
{
	// Only run pose params in some flight states
	bool bRunPoseParams = ( m_iLandState == LANDING_NO || 
							m_iLandState == LANDING_LEVEL_OUT || 
							m_iLandState == LANDING_LIFTOFF ||
							m_iLandState == LANDING_SWOOPING );

	if ( bRunPoseParams )
	{
		if( GetFlags() & FL_ONGROUND )
		{
			//This would be really bad.
			RemoveFlag( FL_ONGROUND );
		}

		// NDebugOverlay::Line(GetLocalOrigin(), GetDesiredPosition(), 0,0,255, true, 0.1);

		Vector deltaPos = GetDesiredPosition() - GetLocalOrigin();

		// calc desired acceleration
		float dt = 1.0f;

		Vector	accel;
		float	accelRate = DROPSHIP_ACCEL_RATE;
		float	maxSpeed = m_flMaxSpeed;

		if ( m_lifeState == LIFE_DYING )
		{
			accelRate *= 5.0;
			maxSpeed *= 5.0;
		}

		float flDist = min( GetAbsVelocity().Length() + accelRate, maxSpeed );

		// Only decelerate to our goal if we're going to hit it
		if ( deltaPos.Length() > flDist * dt )
		{
			float scale = flDist * dt / deltaPos.Length();
			deltaPos = deltaPos * scale;
		}
		
		// If we're swooping, floor it
		if ( m_iLandState == LANDING_SWOOPING )
		{
			VectorNormalize( deltaPos );
			deltaPos *= maxSpeed;
		}
		
		// calc goal linear accel to hit deltaPos in dt time.
		accel.x = 2.0 * (deltaPos.x - GetAbsVelocity().x * dt) / (dt * dt);
		accel.y = 2.0 * (deltaPos.y - GetAbsVelocity().y * dt) / (dt * dt);
		accel.z = 2.0 * (deltaPos.z - GetAbsVelocity().z * dt + 0.5 * 384 * dt * dt) / (dt * dt);
		
		//NDebugOverlay::Line(GetLocalOrigin(), GetLocalOrigin() + deltaPos, 255,0,0, true, 0.1);
		//NDebugOverlay::Line(GetLocalOrigin(), GetLocalOrigin() + accel, 0,255,0, true, 0.1);

		// don't fall faster than 0.2G or climb faster than 2G
		if ( m_iLandState != LANDING_SWOOPING )
		{
			accel.z = clamp( accel.z, 384 * 0.2, 384 * 2.0 );
		}

		Vector forward, right, up;
		GetVectors( &forward, &right, &up );

		Vector goalUp = accel;
		VectorNormalize( goalUp );

		// calc goal orientation to hit linear accel forces
		float goalPitch = RAD2DEG( asin( DotProduct( forward, goalUp ) ) );
		float goalYaw = UTIL_VecToYaw( m_vecDesiredFaceDir );
		float goalRoll = RAD2DEG( asin( DotProduct( right, goalUp ) ) );

		// clamp goal orientations
		goalPitch = clamp( goalPitch, -45, 60 );
		goalRoll = clamp( goalRoll, -45, 45 );

		// calc angular accel needed to hit goal pitch in dt time.
		dt = 0.6;
		QAngle goalAngAccel;
		goalAngAccel.x = 2.0 * (AngleDiff( goalPitch, AngleNormalize( GetLocalAngles().x ) ) - GetLocalAngularVelocity().x * dt) / (dt * dt);
		goalAngAccel.y = 2.0 * (AngleDiff( goalYaw, AngleNormalize( GetLocalAngles().y ) ) - GetLocalAngularVelocity().y * dt) / (dt * dt);
		goalAngAccel.z = 2.0 * (AngleDiff( goalRoll, AngleNormalize( GetLocalAngles().z ) ) - GetLocalAngularVelocity().z * dt) / (dt * dt);

		goalAngAccel.x = clamp( goalAngAccel.x, -300, 300 );
		//goalAngAccel.y = clamp( goalAngAccel.y, -60, 60 );
		goalAngAccel.y = clamp( goalAngAccel.y, -120, 120 );
		goalAngAccel.z = clamp( goalAngAccel.z, -300, 300 );

		// limit angular accel changes to simulate mechanical response times
		dt = 0.1;
		QAngle angAccelAccel;
		angAccelAccel.x = (goalAngAccel.x - m_vecAngAcceleration.x) / dt;
		angAccelAccel.y = (goalAngAccel.y - m_vecAngAcceleration.y) / dt;
		angAccelAccel.z = (goalAngAccel.z - m_vecAngAcceleration.z) / dt;

		angAccelAccel.x = clamp( angAccelAccel.x, -1000, 1000 );
		angAccelAccel.y = clamp( angAccelAccel.y, -1000, 1000 );
		angAccelAccel.z = clamp( angAccelAccel.z, -1000, 1000 );

		m_vecAngAcceleration += angAccelAccel * 0.1;

		// Msg( "pitch %6.1f (%6.1f:%6.1f)  ", goalPitch, GetLocalAngles().x, m_vecAngVelocity.x );
		// Msg( "roll %6.1f (%6.1f:%6.1f) : ", goalRoll, GetLocalAngles().z, m_vecAngVelocity.z );
		// Msg( "%6.1f %6.1f %6.1f  :  ", goalAngAccel.x, goalAngAccel.y, goalAngAccel.z );
		// Msg( "%6.0f %6.0f %6.0f\n", angAccelAccel.x, angAccelAccel.y, angAccelAccel.z );

		ApplySidewaysDrag( right );
		ApplyGeneralDrag();
		
		QAngle angVel = GetLocalAngularVelocity();
		angVel += m_vecAngAcceleration * 0.1;

		//angVel.y = clamp( angVel.y, -60, 60 );
		//angVel.y = clamp( angVel.y, -120, 120 );
		angVel.y = clamp( angVel.y, -120, 120 );

		SetLocalAngularVelocity( angVel );

		m_flForce = m_flForce * 0.8 + (accel.z + fabs( accel.x ) * 0.1 + fabs( accel.y ) * 0.1) * 0.1 * 0.2;

		Vector vecImpulse = m_flForce * up;
		
		if ( m_lifeState == LIFE_DYING )
		{
			vecImpulse.z = -38.4;  // 64ft/sec
		}
		else
		{
			vecImpulse.z -= 38.4;  // 32ft/sec
		}
		
		// Find our acceleration direction
		Vector	vecAccelDir = vecImpulse;
		VectorNormalize( vecAccelDir );

		// Find our current velocity
		Vector	vecVelDir = GetAbsVelocity();
		VectorNormalize( vecVelDir );

		// Level out our plane of movement
		vecAccelDir.z	= 0.0f;
		vecVelDir.z		= 0.0f;
		forward.z		= 0.0f;
		right.z			= 0.0f;

		// Find out how "fast" we're moving in relation to facing and acceleration
		float speed = m_flForce * DotProduct( vecVelDir, vecAccelDir );// * DotProduct( forward, vecVelDir );

		// Use the correct pose params
		char *sBodyAccel;
		char *sBodySway;
		if ( m_hContainer || m_iLandState == LANDING_SWOOPING )
		{
			sBodyAccel = "cargo_body_accel";
			sBodySway = "cargo_body_sway";
			SetPoseParameter( "body_accel", 0 );
			SetPoseParameter( "body_sway", 0 );
		}
		else
		{
			sBodyAccel = "body_accel";
			sBodySway = "body_sway";
			SetPoseParameter( "cargo_body_accel", 0 );
			SetPoseParameter( "cargo_body_sway", 0 );
		}

		// Apply the acceleration blend to the fins
		float finAccelBlend = SimpleSplineRemapVal( speed, -60, 60, -1, 1 );
		float curFinAccel = GetPoseParameter( sBodyAccel );
		
		curFinAccel = UTIL_Approach( finAccelBlend, curFinAccel, 0.5f );

		SetPoseParameter( sBodyAccel, curFinAccel );

		speed = m_flForce * DotProduct( vecVelDir, right );

		// Apply the spin sway to the fins
		float finSwayBlend = SimpleSplineRemapVal( speed, -60, 60, -1, 1 );
		float curFinSway = GetPoseParameter( sBodySway );

		curFinSway = UTIL_Approach( finSwayBlend, curFinSway, 0.5f );
		SetPoseParameter( sBodySway, curFinSway );

		// Add in our velocity pulse for this frame
		ApplyAbsVelocityImpulse( vecImpulse );

		//Msg("FinAccel: %f, Finsway: %f\n", curFinAccel, curFinSway );
	}
	else
	{
		SetPoseParameter( "body_accel", 0 );
		SetPoseParameter( "body_sway", 0 );
		SetPoseParameter( "cargo_body_accel", 0 );
		SetPoseParameter( "cargo_body_sway", 0 );
	}
}