void CSDKPlayerAnimState::ConvergeYawAnglesThroughZero( float flGoalYaw, float flYawRate, float flDeltaTime, float &flCurrentYaw )
{
	float flFadeTurnDegrees = 60;

	float flEyeGoalYaw = AngleDiff(flGoalYaw, m_flEyeYaw);
	float flEyeCurrentYaw = AngleDiff(flCurrentYaw, m_flEyeYaw);

	// Find the yaw delta.
	float flDeltaYaw = flEyeGoalYaw - flEyeCurrentYaw;
	float flDeltaYawAbs = fabs( flDeltaYaw );

	// Always do at least a bit of the turn (1%).
	float flScale = 1.0f;
	flScale = flDeltaYawAbs / flFadeTurnDegrees;
	flScale = clamp( flScale, 0.01f, 1.0f );

	float flYaw = flYawRate * flDeltaTime * flScale;
	if ( flDeltaYawAbs < flYaw )
	{
		flCurrentYaw = flGoalYaw;
	}
	else
	{
		float flSide = ( flDeltaYaw < 0.0f ) ? -1.0f : 1.0f;
		flCurrentYaw += ( flYaw * flSide );
	}

	flCurrentYaw = AngleNormalize( flCurrentYaw );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_PropVehicleDriveable::RestrictView( float *pYawBounds, float *pPitchBounds,
										   float *pRollBounds, QAngle &vecViewAngles )
{
	int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
	Vector vehicleEyeOrigin;
	QAngle vehicleEyeAngles;
	GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );

	// Limit the yaw.
	if ( pYawBounds )
	{
		float flAngleDiff = AngleDiff( vecViewAngles.y, vehicleEyeAngles.y );
		flAngleDiff = clamp( flAngleDiff, pYawBounds[0], pYawBounds[1] );
		vecViewAngles.y = vehicleEyeAngles.y + flAngleDiff;
	}

	// Limit the pitch.
	if ( pPitchBounds )
	{
		float flAngleDiff = AngleDiff( vecViewAngles.x, vehicleEyeAngles.x );
		flAngleDiff = clamp( flAngleDiff, pPitchBounds[0], pPitchBounds[1] );
		vecViewAngles.x = vehicleEyeAngles.x + flAngleDiff;
	}

	// Limit the roll.
	if ( pRollBounds )
	{
		float flAngleDiff = AngleDiff( vecViewAngles.z, vehicleEyeAngles.z );
		flAngleDiff = clamp( flAngleDiff, pRollBounds[0], pRollBounds[1] );
		vecViewAngles.z = vehicleEyeAngles.z + flAngleDiff;
	}
}
示例#3
0
/*! angle_diff(a, b)

	Returns the relative angle in (-180, 180) between
	angle //a// and //b// such that (a + angle_diff(a, b)) = b (mod 360)
*/
int l_angle_diff(lua_State* L)
{
	AngleDiff diff(AngleDiff(lua_tonumber(L, 1)).relative(AngleDiff(lua_tonumber(L, 2))));
	
	lua_pushnumber(L, diff.toDeg());
	
	return 1;
}
void vParticleOperator_WorldRotationForce::Simulate( vParticle *parent )
{
	QAngle cur = MainViewAngles();

	Vector2D force( AngleDiff( cur.y, last.y ), AngleDiff( last.x, cur.x ) );
	force *= GetImpulse( parent ) * vParticle::GetRelativeScale() * str;

	float rainHack = CFrameTimeHelper::GetFrameTime() - (1.0f/60.0f);
	force += force * rainHack * -20.0f;

	last = cur;

	parent->vecVelocity += force;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : pLocalPlayer - 
//			pCmd - 
//-----------------------------------------------------------------------------
void C_PropVehiclePrisonerPod::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
{
	int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
	Vector vehicleEyeOrigin;
	QAngle vehicleEyeAngles;
	GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );

	// Limit the yaw.
	float flAngleDiff = AngleDiff( pCmd->viewangles.y, vehicleEyeAngles.y );
	flAngleDiff = clamp( flAngleDiff, POD_VIEW_YAW_MIN, POD_VIEW_YAW_MAX );
	pCmd->viewangles.y = vehicleEyeAngles.y + flAngleDiff;

	// Limit the pitch -- don't let them look down into the empty pod!
	flAngleDiff = AngleDiff( pCmd->viewangles.x, vehicleEyeAngles.x );
	flAngleDiff = clamp( flAngleDiff, POD_VIEW_PITCH_MIN, POD_VIEW_PITCH_MAX );
	pCmd->viewangles.x = vehicleEyeAngles.x + flAngleDiff;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : pLocalPlayer - 
//			pCmd - 
//-----------------------------------------------------------------------------
void C_PropVehicleChoreoGeneric::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
{
	int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
	Vector vehicleEyeOrigin;
	QAngle vehicleEyeAngles;
	GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );

	// Limit the yaw.
	float flAngleDiff = AngleDiff( pCmd->viewangles.y, vehicleEyeAngles.y );
	flAngleDiff = clamp( flAngleDiff, m_vehicleView.flYawMin, m_vehicleView.flYawMax );
	pCmd->viewangles.y = vehicleEyeAngles.y + flAngleDiff;

	// Limit the pitch -- don't let them look down into the empty pod!
	flAngleDiff = AngleDiff( pCmd->viewangles.x, vehicleEyeAngles.x );
	flAngleDiff = clamp( flAngleDiff, m_vehicleView.flPitchMin, m_vehicleView.flPitchMax );
	pCmd->viewangles.x = vehicleEyeAngles.x + flAngleDiff;
}
void C_QUA_Strider::RestrictView( float *pYawBounds, float *pPitchBounds,
										   float *pRollBounds, QAngle &vecViewAngles )
{
	// Cambiado. Para que el cliente vea.
	//int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
	// Encontrado el bug de los Bones... ahora debemos mirar que hacemos.
	Vector vehicleEyeOrigin;
	QAngle vehicleEyeAngles;
	//GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
	Vector up,forward;
	vehicleEyeOrigin=this->GetAbsOrigin();
	vehicleEyeAngles=this->GetAbsAngles();
	this->GetVectors(&forward,NULL,&up);
	vehicleEyeOrigin+=(forward*120)+(up*-10);

	// NO limitamos el yaw en el Strider, porque si no no vemos nada.
	// Limit the yaw.
	if ( pYawBounds )
	{
		float flAngleDiff = AngleDiff( vecViewAngles.y, vehicleEyeAngles.y );
		flAngleDiff = clamp( flAngleDiff, pYawBounds[0], pYawBounds[1] );
		vecViewAngles.y = vehicleEyeAngles.y + flAngleDiff;
	}

	// Limit the pitch.
	if ( pPitchBounds )
	{
		float flAngleDiff = AngleDiff( vecViewAngles.x, vehicleEyeAngles.x );
		flAngleDiff = clamp( flAngleDiff, pPitchBounds[0], pPitchBounds[1] );
		vecViewAngles.x = vehicleEyeAngles.x + flAngleDiff;
	}

	// Limit the roll.
	if ( pRollBounds )
	{
		float flAngleDiff = AngleDiff( vecViewAngles.z, vehicleEyeAngles.z );
		flAngleDiff = clamp( flAngleDiff, pRollBounds[0], pRollBounds[1] );
		vecViewAngles.z = vehicleEyeAngles.z + flAngleDiff;
	}
}
Real MultiRobot2DCSpace::Distance(const Config& x, const Config& y)
{
  int stride = (allowRotation ? 3 : 2);
  Assert(x.n==stride*(int)robots.size());
  Assert(x.n==y.n);
  int k=0;
  Real d2=0;
  for(size_t i=0;i<robots.size();i++,k+=stride) {
    d2 += Vector2(x(k+0),x(k+1)).distanceSquared(Vector2(y(k+0),y(k+1)));
    d2 += Sqr(angleDistanceWeight)*Sqr(AngleDiff(x(k+2),y(k+2)));
  }
  return Sqrt(d2);
}
//-----------------------------------------------------------------------------
// Clamps the view angles while manning the gun 
//-----------------------------------------------------------------------------
void C_ObjectBaseMannedGun::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
{
#if 0
	// Confine the view to the appropriate yaw range...
	float flAngleDiff = AngleDiff( pCmd->viewangles[YAW], flCenterYaw );

	// Here, we must clamp to the cone...
	if (flAngleDiff < m_Movement.GetMinYaw())
		pCmd->viewangles[YAW] = anglemod(flCenterYaw + m_Movement.GetMinYaw());
	else if (flAngleDiff > m_Movement.GetMaxYaw())
		pCmd->viewangles[YAW] = anglemod(flCenterYaw + m_Movement.GetMaxYaw());
#endif

	// Prevent too much downward looking
	if ( pCmd->viewangles[PITCH] > m_Movement.GetMaxPitch())
	{
		pCmd->viewangles[PITCH] = m_Movement.GetMaxPitch();
	}
}
示例#10
0
bool Aircraft::Step(float FT, sf::Vector2f Wind)
{
    bool Die = false;
    Time += FT;

    const sf::Vector2f &Me = Shape.getPosition();
    TakeoffSound.setPosition(Me.x, Me.y, 0.f);
    FlySound.setPosition(Me.x, Me.y, 0.f);
    LandingSound.setPosition(Me.x, Me.y, 0.f);

    Shape.update(FT);

    float Turning = 0.f;

    switch (State)
    {
        case FlyingIn:
        {
            sf::Vector2f To(400.f, 300.f);
            Shape.setRotation(Angle(Me - To));

            if (P.NumPoints() > 0)
            {
                State = FlyingPath;
            }
            else if (Me.x > 100 && Me.x < 700 && Me.y > 100 && Me.y < 500)
            {
                State = FlyingFree;
                Turning = 0.2f;
            }
            break;
        }
        case FlyingOut:
        {
            sf::Vector2f From(400.f, 300.f);
            Shape.rotate(AngleDiff(Shape.getRotation(), Angle(From - Me)) * FT);

            float Scale = Map(Speed / Template.Speed, 0.f, 1.f, 1.f, 0.9f);
            float ShadowRadius = Radius * Scale;
			sf::Vector2f Shadow = sf::Transform().scale(sf::Vector2f(Scale, Scale), sf::Vector2f(800 / 2, 600 * 0.8f)).transformPoint(Me);

            if ((Me.x < -Radius || Me.x > (800 + Radius) || Me.y < -Radius || Me.y > (600 + Radius)) &&
				(Shadow.x < -ShadowRadius || Shadow.x > (800 + ShadowRadius) || Shadow.y < -ShadowRadius || Shadow.y > (600 + ShadowRadius)))
            {
                Die = true;
            }
            break;
        }
        case FlyingFree:
        {
            float Angle = AngleFix(Shape.getRotation()), AddAngle;
            if ((Me.x < 100 && Angle > 180) ||
                (Me.x > 700 && Angle < 180) ||
                (Me.y < 100 && (Angle > 90 && Angle < 270)) ||
                (Me.y > 500 && (Angle > 270 || Angle < 90)))
            {
                AddAngle = Turn;
                Turning = Turn / 10;
            }
            else if ((Me.x < 100 && Angle <= 180) ||
                     (Me.x > 700 && Angle >= 180) ||
                     (Me.y < 100 && (Angle <= 90 || Angle >= 270)) ||
                     (Me.y > 500 && (Angle <= 270 && Angle >= 90)))
            {
                AddAngle = -Turn;
                Turning = -Turn / 10;
            }
            else
            {
                AddAngle = Turning;
            }

            Angle += AddAngle;
            Shape.setRotation(AngleFix(Angle));

            if (P.NumPoints() > 0)
            {
                State = FlyingPath;
            }
            break;
        }
        case FlyingPath:
        {
            if (P.NumPoints() > 0)
            {
                const sf::Vector2f To = P[0]; // might crash

                if (InRange(Me, To, 5))
                    P.RemovePoint(0);

                float Target = Angle(Me - To);

                Shape.setRotation(Target);

                if (Land &&
                    P.NumPoints() == 0 &&
                    /*Land->OnMe(Me) &&*/
                    P.Highlight
                    /*abs(AngleDiff(GetAngle(), Land->GetAngle())) <= Land->GetTemplate().LandAngle*/)
                {
                    FlySound.stop();
                    LandingSound.play();
                    State = Landing;
                    LandPoint = Me;
                }
                else if (P.NumPoints() == 0)
                {
                    if (Direction == Out &&
                         ((OutDirection == OutUp && To.y < 50) ||
                          (OutDirection == OutDown && To.y > 550) ||
                          (OutDirection == OutLeft && To.x < 50) ||
                          (OutDirection == OutRight && To.x > 750)))
                    {
                        State = FlyingOut;
                    }
                    else
                    {
                        State = FlyingFree;
                    }
                }
            }
            break;
        }
        case Landing:
        {
            sf::Vector2f Runway = Land->GetPos() + PolarToRect(sf::Vector2f(Land->GetLength() * 1.5f, Land->GetAngle()));
            float Dist = Distance(Me, LandPoint);

            Speed = Map(Dist, 0.f, Land->GetLength() * 1.1f, Template.Speed, 0.f);

            if (Land->GetTemplate().Directional)
            {
                Shape.rotate(AngleDiff(Shape.getRotation(), Angle(Me - Runway)) * 3 * FT);
            }

            float Scale = Map2(Dist, 0.f, Land->GetLength() * 1.1f, 1.f, 0.65f);
            Shape.setScale(Scale, Scale);
            Radius = Template.Radius * Scale;

            if (Dist > Land->GetLength())
            {
                Die = true;
            }
            break;
        }
        case TakingOff:
        {
            sf::Vector2f Runway = Land->GetPos() + PolarToRect(sf::Vector2f(Land->GetLength() * 1.5f, Land->GetAngle()));
            float Dist = Distance(Me, Land->GetPos());

            Speed = Map(Dist, 0.f, Land->GetLength() * 1.1f, 10.f, Template.Speed);

            if (Land->GetTemplate().Directional)
            {
                Shape.rotate(AngleDiff(Shape.getRotation(), Angle(Me - Runway)) * 3 * FT);
            }

            float Scale = Map2(Dist, 0.f, Land->GetLength() * 1.1f, 0.65f, 1.f);
            Shape.setScale(Scale, Scale);
            Radius = Template.Radius * Scale;

            if (Dist > Land->GetLength())
            {
                FlySound.play();
                State = FlyingFree;
                Land = 0;
            }
            break;
        }
    }

    Shape.move(PolarToRect(sf::Vector2f(Speed, Shape.getRotation())) * FT);
    Shape.move(Wind * FT * Magnitude(Shape.getScale()) / sqrt(2.f));

    return Die;
}
示例#11
0
//-----------------------------------------------------------------------------
// 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 );
	}
}
//------------------------------------------------------------------------------
// 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 );
	}
}
示例#13
0
void IntegratedStateEstimator::ReadSensors(RobotSensors& sensors)
{
  JointPositionSensor* jp = sensors.GetTypedSensor<JointPositionSensor>();
  JointVelocitySensor* jv = sensors.GetTypedSensor<JointVelocitySensor>();
  if(jv) {
    for(size_t i=0;i<robot.joints.size();i++) {
      if(robot.joints[i].type == RobotJoint::Normal || robot.joints[i].type == RobotJoint::Spin) {
	int link = robot.joints[i].linkIndex;
	dq_predicted[link] = jv->dq[link];
      }
    }
  }
  else if(jp) {
    if(last_dt == 0)
      dq_predicted.setZero();
    else {
      //do finite differencing
      for(size_t i=0;i<robot.joints.size();i++) {
	if(robot.joints[i].type == RobotJoint::Normal) {
	  int link = robot.joints[i].linkIndex;
	  dq_predicted[link] = (jp->q[link] - q_predicted[link])/last_dt;
	}
	else if(robot.joints[i].type == RobotJoint::Spin) {
	  int link = robot.joints[i].linkIndex;
	  dq_predicted[link] = AngleDiff(jp->q[link],q_predicted[link])/last_dt;
	}
      }
    }
  }

  //update joint positions for normal joints
  if(jp) {
    for(size_t i=0;i<robot.joints.size();i++) {
      if(robot.joints[i].type == RobotJoint::Normal || robot.joints[i].type == RobotJoint::Spin) {
	int link = robot.joints[i].linkIndex;
	q_predicted[link] = jp->q[link];
      }
    }
  }

  //use gyro sensors to update q_predicted
  vector<GyroSensor*> gyroSensors;
  sensors.GetTypedSensors(gyroSensors);
  if(!gyroSensors.empty()) {
    robot.UpdateConfig(q_predicted);
    for(size_t j=0;j<gyroSensors.size();j++) {
      int glink = gyroSensors[j]->link;
      int match = -1;
      for(size_t i=0;i<robot.joints.size();i++) {
	if(robot.joints[i].type == RobotJoint::Floating) {
	  if(robot.joints[i].linkIndex == glink) {
	    match = (int)i;
	    break;
	  }
	}
      }
      if(match >= 0) {
	robot.SetJointByOrientation(match,glink,gyroSensors[j]->rotation);
	robot.SetJointVelocityByMoment(match,glink,gyroSensors[j]->angVel,Vector3(Zero));
	vector<int> indices;
	robot.GetJointIndices(match,indices);
	assert(indices.size()==6);
	q_predicted(indices[3]) = robot.q(indices[3]);
	q_predicted(indices[4]) = robot.q(indices[4]);
	q_predicted(indices[5]) = robot.q(indices[5]);
	dq_predicted(indices[3]) = robot.dq(indices[3]);
	dq_predicted(indices[4]) = robot.dq(indices[4]);
	dq_predicted(indices[5]) = robot.dq(indices[5]);
      }
      else {
	fprintf(stderr,"Warning: can't use gyro sensor on a non-floating link %d\n",glink);
      }
    }
  }

  vector<Accelerometer*> accelerometers;
  sensors.GetTypedSensors(accelerometers);
  if(accelerometerFrames.empty()) {
    robot.UpdateConfig(q_predicted);
    //initialize
    accelerometerFrames.resize(accelerometers.size());
    accelerometerVels.resize(accelerometers.size());
    for(size_t i=0;i<accelerometers.size();i++) {
      int alink = accelerometers[i]->link;
      accelerometerFrames[i] = robot.links[alink].T_World*accelerometers[i]->Tsensor;
      robot.GetWorldVelocity(accelerometers[i]->Tsensor.t,alink,robot.dq,accelerometerVels[i].v);
      robot.GetWorldAngularVelocity(alink,robot.dq,accelerometerVels[i].w);
    }
  }

  //advance accelerometers
  if(last_dt > 0.0 && !accelerometers.empty()) {
    fprintf(stderr,"TODO: integrate accelerometers\n");
  }
}
示例#14
0
void AngleInterval::setMinRange(Real a, Real b)
{
  d = AngleDiff(a,b);
  if(d<0) { c=a; d=-d; }
  else  c=b;
}
示例#15
0
Real AngleInterp(Real a, Real b, Real u)
{
  Real d = AngleDiff(b,a);
  Assert(d >= -Pi && d <= Pi);
  return AngleNormalize(a+u*d);
}
//-----------------------------------------------------------------------------
// Purpose: Vehicle dampening shared between server and client
//-----------------------------------------------------------------------------
void SharedVehicleViewSmoothing(CBasePlayer *pPlayer,
                                Vector *pAbsOrigin, QAngle *pAbsAngles,
                                bool bEnterAnimOn, bool bExitAnimOn,
                                const Vector &vecEyeExitEndpoint,
                                ViewSmoothingData_t *pData,
                                float *pFOV )
{
    int eyeAttachmentIndex = pData->pVehicle->LookupAttachment( "vehicle_driver_eyes" );
    matrix3x4_t vehicleEyePosToWorld;
    Vector vehicleEyeOrigin;
    QAngle vehicleEyeAngles;
    pData->pVehicle->GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
    AngleMatrix( vehicleEyeAngles, vehicleEyePosToWorld );

    // Dampen the eye positional change as we drive around.
    *pAbsAngles = pPlayer->EyeAngles();
    if ( r_VehicleViewDampen.GetInt() && pData->bDampenEyePosition )
    {
        CPropVehicleDriveable *pDriveable = assert_cast<CPropVehicleDriveable*>(pData->pVehicle);
        pDriveable->DampenEyePosition( vehicleEyeOrigin, vehicleEyeAngles );
    }

    // Started running an entry or exit anim?
    bool bRunningAnim = ( bEnterAnimOn || bExitAnimOn );
    if ( bRunningAnim && !pData->bWasRunningAnim )
    {
        pData->bRunningEnterExit = true;
        pData->flEnterExitStartTime = gpGlobals->curtime;
        pData->flEnterExitDuration = pData->pVehicle->SequenceDuration( pData->pVehicle->GetSequence() );

#ifdef CLIENT_DLL
        pData->vecOriginSaved = PrevMainViewOrigin();
        pData->vecAnglesSaved = PrevMainViewAngles();
#endif

        // Save our initial angular error, which we will blend out over the length of the animation.
        pData->vecAngleDiffSaved.x = AngleDiff( vehicleEyeAngles.x, pData->vecAnglesSaved.x );
        pData->vecAngleDiffSaved.y = AngleDiff( vehicleEyeAngles.y, pData->vecAnglesSaved.y );
        pData->vecAngleDiffSaved.z = AngleDiff( vehicleEyeAngles.z, pData->vecAnglesSaved.z );

        pData->vecAngleDiffMin = pData->vecAngleDiffSaved;
    }

    pData->bWasRunningAnim = bRunningAnim;

    float frac = 0;
    float flFracFOV = 0;

    // If we're in an enter/exit animation, blend the player's eye angles to the attachment's
    if ( bRunningAnim || pData->bRunningEnterExit )
    {
        *pAbsAngles = vehicleEyeAngles;

        // Forward integrate to determine the elapsed time in this entry/exit anim.
        frac = ( gpGlobals->curtime - pData->flEnterExitStartTime ) / pData->flEnterExitDuration;
        frac = clamp( frac, 0.0f, 1.0f );

        flFracFOV = ( gpGlobals->curtime - pData->flEnterExitStartTime ) / ( pData->flEnterExitDuration * 0.85f );
        flFracFOV = clamp( flFracFOV, 0.0f, 1.0f );

        //Msg("Frac: %f\n", frac );

        if ( frac < 1.0 )
        {
            // Blend to the desired vehicle eye origin
            //Vector vecToView = (vehicleEyeOrigin - PrevMainViewOrigin());
            //vehicleEyeOrigin = PrevMainViewOrigin() + (vecToView * SimpleSpline(frac));
            //debugoverlay->AddBoxOverlay( vehicleEyeOrigin, -Vector(1,1,1), Vector(1,1,1), vec3_angle, 0,255,255, 64, 10 );
        }
        else
        {
            pData->bRunningEnterExit = false;

            // Enter animation has finished, align view with the eye attachment point
            // so they can start mouselooking around.
#if !defined ( HL2MP_DEV_DLL ) && !defined ( HL2MP_DEV_VEHICLE_FIX )
            if ( !bExitAnimOn )
            {
                Vector localEyeOrigin;
                QAngle localEyeAngles;

                pData->pVehicle->GetAttachmentLocal( eyeAttachmentIndex, localEyeOrigin, localEyeAngles );
#ifdef CLIENT_DLL
                engine->SetViewAngles( localEyeAngles );
#endif
            }
#else

#ifdef CLIENT_DLL
            pPlayer = C_BasePlayer::GetLocalPlayer();
#endif
            if ( pPlayer )
            {
                if ( !bExitAnimOn )
                {
                    Vector localEyeOrigin;
                    QAngle localEyeAngles;

                    pData->pVehicle->GetAttachmentLocal( eyeAttachmentIndex, localEyeOrigin, localEyeAngles );
#ifdef CLIENT_DLL
                    engine->SetViewAngles( localEyeAngles );
#endif
                }
            }
#endif
        }
    }

    // Compute the relative rotation between the unperturbed eye attachment + the eye angles
    matrix3x4_t cameraToWorld;
    AngleMatrix( *pAbsAngles, cameraToWorld );

    matrix3x4_t worldToEyePos;
    MatrixInvert( vehicleEyePosToWorld, worldToEyePos );

    matrix3x4_t vehicleCameraToEyePos;
    ConcatTransforms( worldToEyePos, cameraToWorld, vehicleCameraToEyePos );

    // Damp out some of the vehicle motion (neck/head would do this)
    if ( pData->bClampEyeAngles )
    {
        RemapViewAngles( pData, vehicleEyeAngles );
    }

    AngleMatrix( vehicleEyeAngles, vehicleEyeOrigin, vehicleEyePosToWorld );

    // Now treat the relative eye angles as being relative to this new, perturbed view position...
    matrix3x4_t newCameraToWorld;
    ConcatTransforms( vehicleEyePosToWorld, vehicleCameraToEyePos, newCameraToWorld );

    // output new view abs angles
    MatrixAngles( newCameraToWorld, *pAbsAngles );

    // UNDONE: *pOrigin would already be correct in single player if the HandleView() on the server ran after vphysics
    MatrixGetColumn( newCameraToWorld, 3, *pAbsOrigin );

    float flDefaultFOV;
#ifdef CLIENT_DLL
    flDefaultFOV = default_fov.GetFloat();
#else
    flDefaultFOV = pPlayer->GetDefaultFOV();
#endif

    // If we're playing an entry or exit animation...
    if ( bRunningAnim || pData->bRunningEnterExit )
    {
        float flSplineFrac = clamp( SimpleSpline( frac ), 0.f, 1.f );

        // Blend out the error between the player's initial eye angles and the animation's initial
        // eye angles over the duration of the animation.
        QAngle vecAngleDiffBlend = ( ( 1 - flSplineFrac ) * pData->vecAngleDiffSaved );

        // If our current error is less than the error amount that we're blending
        // out, use that. This lets the angles converge as quickly as possible.
        QAngle vecAngleDiffCur;
        vecAngleDiffCur.x = AngleDiff( vehicleEyeAngles.x, pData->vecAnglesSaved.x );
        vecAngleDiffCur.y = AngleDiff( vehicleEyeAngles.y, pData->vecAnglesSaved.y );
        vecAngleDiffCur.z = AngleDiff( vehicleEyeAngles.z, pData->vecAnglesSaved.z );

        // In either case, never increase the error, so track the minimum error and clamp to that.
        for (int i = 0; i < 3; i++)
        {
            if ( fabs(vecAngleDiffCur[i] ) < fabs( pData->vecAngleDiffMin[i] ) )
            {
                pData->vecAngleDiffMin[i] = vecAngleDiffCur[i];
            }

            if ( fabs(vecAngleDiffBlend[i] ) < fabs( pData->vecAngleDiffMin[i] ) )
            {
                pData->vecAngleDiffMin[i] = vecAngleDiffBlend[i];
            }
        }

        // Add the error to the animation's eye angles.
        *pAbsAngles -= pData->vecAngleDiffMin;

        // Use this as the basis for the next error calculation.
        pData->vecAnglesSaved = *pAbsAngles;

        //if ( gpGlobals->frametime )
        //{
        //	Msg("Angle : %.2f %.2f %.2f\n", target.x, target.y, target.z );
        //}
        //Msg("Prev: %.2f %.2f %.2f\n", pData->vecAnglesSaved.x, pData->vecAnglesSaved.y, pData->vecAnglesSaved.z );

        Vector vecAbsOrigin = *pAbsOrigin;

        // If we're exiting, our desired position is the server-sent exit position
        if ( bExitAnimOn )
        {
            //debugoverlay->AddBoxOverlay( vecEyeExitEndpoint, -Vector(1,1,1), Vector(1,1,1), vec3_angle, 255,255,255, 64, 10 );

            // Blend to the exit position
            *pAbsOrigin = Lerp( flSplineFrac, vecAbsOrigin, vecEyeExitEndpoint );

            if ( pFOV != NULL )
            {
                if ( pData->flFOV > flDefaultFOV )
                {
                    *pFOV = Lerp( flFracFOV, pData->flFOV, flDefaultFOV );
                }
            }
        }
        else
        {
            // Blend from our starting position to the desired origin
            *pAbsOrigin = Lerp( flSplineFrac, pData->vecOriginSaved, vecAbsOrigin );

            if ( pFOV != NULL )
            {
                if ( pData->flFOV > flDefaultFOV )
                {
                    *pFOV = Lerp( flFracFOV, flDefaultFOV, pData->flFOV );
                }
            }
        }
    }
    else if ( pFOV != NULL )
    {
        if ( pData->flFOV > flDefaultFOV )
        {
            // Not running an entry/exit anim. Just use the vehicle's FOV.
            *pFOV = pData->flFOV;
        }
    }
}
void C_ASW_Simple_Drone::UpdatePoseParams()
{
	VPROF_BUDGET( "C_ASW_Simple_Drone::UpdatePoseParams", VPROF_BUDGETGROUP_ASW_CLIENT );
	// update pose params based on velocity and our angles

	// calculate the angle difference between our facing and our velocity
	Vector v;
	EstimateAbsVelocity(v);	
	float travel_yaw = anglemod(UTIL_VecToYaw(v));
	float current_yaw = anglemod( GetLocalAngles().y );

	// Draw a green triangle on the ground for the travel yaw
	if (cl_asw_drone_travel_yaw.GetBool())
	{
		float flBaseSize = 10;
		float flHeight = 80;
		Vector vBasePos = GetAbsOrigin() + Vector( 0, 0, 5 );
		QAngle angles( 0, 0, 0 );
		Vector vForward, vRight, vUp;
		angles[YAW] = travel_yaw;
		AngleVectors( angles, &vForward, &vRight, &vUp );
		debugoverlay->AddTriangleOverlay( vBasePos+vRight*flBaseSize/2, vBasePos-vRight*flBaseSize/2, vBasePos+vForward*flHeight, 0, 255, 0, 255, false, 0.01 );		
	}

	// calculate our fraction of full anim velocity
	float speed_fraction = 0;
	float ground_speed = GetRunSpeed();
	if (ground_speed > 0)
		speed_fraction = clamp<float>(
			(v.Length()) / ground_speed,
			0.0f, 1.0f);
	speed_fraction = 1.0f - speed_fraction;

	// smooth out the travel yaw to prevent sudden changes in move_yaw pose parameter
	if (m_flCurrentTravelYaw == -1)
		m_flCurrentTravelYaw = travel_yaw;
	else
	{
		float travel_diff = AngleDiff(m_flCurrentTravelYaw, travel_yaw);
		if (travel_diff < 0)
			travel_diff = -travel_diff;
		travel_diff = clamp<float>(travel_diff, 32.0f, 256.0f);	// alter the yaw by this amount - i.e. faster if the angle is bigger, but clamped
		if (speed_fraction > 0.75f)	// change the angle even quicker if we're moving very slowly
		{
			travel_diff *= (2.0f + ((speed_fraction - 0.75f) * 8.0f));
		}
		if (speed_fraction < 1.0f)	// don't bother adjusting the yaw if we're standing still
			m_flCurrentTravelYaw = AI_ClampYaw( travel_diff * cl_asw_drone_travel_yaw_rate.GetFloat(), m_flCurrentTravelYaw, travel_yaw, gpGlobals->frametime );
		else
			m_flCurrentTravelYaw = travel_yaw;	// if we're standing still, immediately change
		//Msg("travel=%.1f current_travel=%.1f current=%.1f t=%f\n",
			//travel_yaw, m_flCurrentTravelYaw, current_yaw, gpGlobals->curtime);
		travel_yaw = m_flCurrentTravelYaw;
	}

	// set the move_yaw pose parameter
	float diff = AngleDiff(travel_yaw, current_yaw);

	// Draw a green triangle on the ground for the move yaw
	if (cl_asw_drone_travel_yaw.GetBool())
	{
		float flBaseSize = 10;
		float flHeight = 80;
		Vector vBasePos = GetAbsOrigin() + Vector( 0, 0, 5 );
		QAngle angles( 0, 0, 0 );
		Vector vForward, vRight, vUp;
		angles[YAW] = travel_yaw;
		AngleVectors( angles, &vForward, &vRight, &vUp );
		debugoverlay->AddTriangleOverlay( vBasePos+vRight*flBaseSize/2, vBasePos-vRight*flBaseSize/2, vBasePos+vForward*flHeight, 0, 0, 255, 255, false, 0.01 );		

		angles[YAW] = diff;
		AngleVectors( angles, &vForward, &vRight, &vUp );
		debugoverlay->AddTriangleOverlay( vBasePos+vRight*flBaseSize/2, vBasePos-vRight*flBaseSize/2, vBasePos+vForward*flHeight, 255, 0, 0, 255, false, 0.01 );
	}
	
	
	diff = clamp<float>(diff, -180.0f, 180.0f);
	int pose_index = LookupPoseParameter( "move_yaw" );
	if (pose_index >= 0)
	{
		SetPoseParameter(pose_index, diff);
	}
	
	// smooth out our speed fraction to prevent sudden changes to idle_move pose parameter
	//Msg("sf=%f cts=%f gs=%f vl=%f\n", speed_fraction, m_flCurrentTravelSpeed,
		//ground_speed, v.Length());
	if (m_flCurrentTravelSpeed == -1)
	{
		m_flCurrentTravelSpeed = speed_fraction;
	}
	else
	{
		if (m_flCurrentTravelSpeed < speed_fraction)
		{
			m_flCurrentTravelSpeed = clamp<float>(
				m_flCurrentTravelSpeed + gpGlobals->frametime,
				0.0f, speed_fraction);
		}
		else
		{
			m_flCurrentTravelSpeed = clamp<float>(
				m_flCurrentTravelSpeed - gpGlobals->frametime * 3.0f,
				speed_fraction, 1.0f);
		}
		speed_fraction = m_flCurrentTravelSpeed;
	}
	
	// set the idle_move pose parameter
	pose_index = LookupPoseParameter( "idle_move" );
	if (pose_index >= 0)
	{
		SetPoseParameter(pose_index, 100.0f * speed_fraction);
	}
}