//------------------------------------------------------------------------
bool CVehicleSeatActionRotateTurret::GetRemainingAnglesToAimGoalInDegrees(float &pitch, float &yaw)
{
	// no aim goal set (or it got cleared)?
	if (m_aimGoal.IsZero())
	{
		return false; // have no aim goal
	}

	IVehiclePart* pPitchPart = m_rotations[eVTRT_Pitch].m_pPart;
	IVehiclePart* pYawPart   = m_rotations[eVTRT_Yaw].m_pPart;

	if (!pYawPart)
	{
		pitch = yaw = 0.0f;
		return true;  // have an aim goal
	}

	// aim goal is a world pos. Convert it to vehicle space:
	Vec3 aimGoalLocal = m_pVehicle->GetEntity()->GetWorldTM().GetInverted() * m_aimGoal;

	// direction from yaw part pivot to aim goal
	Vec3 yawPartToAimGoal = aimGoalLocal - pYawPart->GetLocalTM(false).GetTranslation();

	// angles from yaw part to aim goal
	Quat aimDir = Quat::CreateRotationVDir(yawPartToAimGoal.GetNormalizedSafe());
	Ang3 desiredAngles(aimDir);

	if (pPitchPart)
	{
		Ang3 pitchAngles(pPitchPart->GetLocalTM(false));
		pitch = RAD2DEG(desiredAngles.x - pitchAngles.x);
		pitch = fmod(pitch, 360.0f);
	}
	else
	{
		pitch = 0.0f;
	}

	Ang3 yawAngles(pYawPart->GetLocalTM(false));
	yaw = RAD2DEG(desiredAngles.z - yawAngles.z);
	yaw = fmod(yaw, 360.0f);

	return true;  // have an aim goal
}
/*
============
hhPhysics_StaticWeapon::Evaluate
============
*/
bool hhPhysics_StaticWeapon::Evaluate( int timeStepMSec, int endTimeMSec ) {
	if( !selfOwner ) {
		return false;
	}

	idMat3 localAxis;
	idVec3 localOrigin( 0.0f, 0.0f, selfOwner->EyeHeight() );
	idAngles pitchAngles( selfOwner->GetUntransformedViewAngles().pitch, 0.0f, 0.0f );

	if( selfOwner->InVehicle() ) {
		localAxis = pitchAngles.ToMat3();
	} else {
		localAxis = ( pitchAngles + selfOwner->GunTurningOffset() ).ToMat3();
		localOrigin += selfOwner->GunAcceleratingOffset();
		if ( castSelf ) {
			castSelf->MuzzleRise( localOrigin, localAxis );
		}
	}

	SetLocalAxis( localAxis );
	SetLocalOrigin( localOrigin );

	return idPhysics_Static::Evaluate( timeStepMSec, endTimeMSec );
}
示例#3
0
/*
================
sdVehicleIKArms::Update
================
*/
void sdVehicleIKArms::Update( void ) {
	idEntity* vehicleEnt = vehicle;
	if ( !vehicleEnt ) {
		return;
	}

	idVec3 shoulderPos;
	idMat3 temp;

	idAnimator* animator = vehicleEnt->GetAnimator();
	animator->GetJointTransform( ikJoints[ ARM_JOINT_INDEX_SHOULDER ], gameLocal.time, shoulderPos, temp );

	idVec3 shoulderToElbow	= baseJointPositions[ ARM_JOINT_INDEX_ELBOW ] - baseJointPositions[ ARM_JOINT_INDEX_SHOULDER ];
	idVec3 elbowToWrist		= baseJointPositions[ ARM_JOINT_INDEX_WRIST ] - baseJointPositions[ ARM_JOINT_INDEX_ELBOW ];
	idVec3 wristToMuzzle	= baseJointPositions[ ARM_JOINT_INDEX_MUZZLE ] - baseJointPositions[ ARM_JOINT_INDEX_WRIST ];
	idVec3 elbowToMuzzle	= baseJointPositions[ ARM_JOINT_INDEX_MUZZLE ] - baseJointPositions[ ARM_JOINT_INDEX_ELBOW ];

	idMat3 shoulderAxis;
	TransposeMultiply( baseJointAxes[ ARM_JOINT_INDEX_SHOULDER ], temp, shoulderAxis );
	idMat3 transposedShoulderAxis = shoulderAxis.Transpose();

	idPlayer* player = GetPlayer();
	if ( player && requireTophat ) {
		if ( !gameLocal.usercmds[ player->entityNumber ].buttons.btn.tophat ) {
			player = NULL;
		}
	}

	bool changed = false;

	changed |= !oldParentAxis.Compare( temp, 0.005f );

	idAngles newAngles;

	renderView_t* view = player ? player->GetRenderView() : NULL;
	renderEntity_t* renderEnt = vehicleEnt->GetRenderEntity();

	trace_t trace;
	idVec3 modelTarget;
	if( view ) {
		idVec3 end = view->vieworg + ( 8192 * view->viewaxis[ 0 ] );
		gameLocal.clip.TracePoint( CLIP_DEBUG_PARMS trace, view->vieworg, end, CONTENTS_SOLID | CONTENTS_OPAQUE, player );

		modelTarget = trace.endpos;

		modelTarget -= renderEnt->origin;
		modelTarget *= renderEnt->axis.Transpose();

		modelTarget -= shoulderPos;
		modelTarget *= transposedShoulderAxis;

		modelTarget -= shoulderToElbow;
	}


	if ( view ) {
		idVec3 target = modelTarget;

		const idVec3& dir = baseJointAxes[ ARM_JOINT_INDEX_MUZZLE ][ 0 ];
		
		target -= elbowToMuzzle - ( ( dir * elbowToMuzzle ) * dir );
		target *= baseJointAxes[ ARM_JOINT_INDEX_MUZZLE ].Transpose();

		newAngles.yaw = RAD2DEG( atan2( target[ 1 ], target[ 0 ] ) );
	} else {
		newAngles.yaw = 0;
	}

	bool yawChanged = !sdVehiclePosition::ClampAngle( newAngles, jointAngles, clampYaw, 1, 0.1f );
	if ( yawSound != NULL ) {
		yawSound->Update( yawChanged );
	}
	changed |= yawChanged;

	idMat3 yawMat;
	idAngles::YawToMat3( newAngles.yaw, yawMat );

	if ( view ) {
		idVec3 target = modelTarget;

		idVec3 newElbowToWrist	= elbowToWrist * yawMat;
		idVec3 newWristToMuzzle	= wristToMuzzle * yawMat;

		idMat3 muzzleAxis = baseJointAxes[ ARM_JOINT_INDEX_MUZZLE ] * yawMat;

		target -= newElbowToWrist;
		target -= newWristToMuzzle - ( ( muzzleAxis[ 0 ] * newWristToMuzzle ) * muzzleAxis[ 0 ] );
		target *= muzzleAxis.Transpose();

		newAngles.pitch = -RAD2DEG( atan2( target[ 2 ], target[ 0 ] ) );
	} else {
		newAngles.pitch = 0;
	}

	bool pitchChanged = !sdVehiclePosition::ClampAngle( newAngles, jointAngles, clampPitch,	0, 0.1f );
	if ( pitchSound != NULL ) {
		pitchSound->Update( pitchChanged );
	}
	changed |= pitchChanged;

	// configurable pitching axis - to support vertically oriented arms (eg badger, bumblebee)
	// as well as horizontally oriented arms (eg goliath)
	int truePitchAxis = pitchAxis;
	if ( truePitchAxis < 0 ) {
		newAngles.pitch = -newAngles.pitch;
		truePitchAxis = -truePitchAxis;
	}

	idAngles pitchAngles( 0.0f, 0.0f, 0.0f );
	if ( truePitchAxis == 1 ) {					// x-axis
		pitchAngles.roll = newAngles.pitch;
	} else if ( truePitchAxis == 3 ) {			// z-axis
		pitchAngles.yaw = newAngles.pitch;
	} else {									// y-axis
		pitchAngles.pitch = newAngles.pitch;
	}

	idMat3 pitchMat = pitchAngles.ToMat3();

	if( changed ) {
		oldParentAxis = temp;
		jointAngles = newAngles;

		animator->SetJointAxis( ikJoints[ ARM_JOINT_INDEX_ELBOW ], JOINTMOD_WORLD_OVERRIDE, baseJointAxes[ ARM_JOINT_INDEX_ELBOW ] * yawMat * shoulderAxis );
		animator->SetJointAxis( ikJoints[ ARM_JOINT_INDEX_WRIST ], JOINTMOD_WORLD_OVERRIDE, pitchMat * baseJointAxes[ ARM_JOINT_INDEX_WRIST ] * yawMat * shoulderAxis );
	}
}