History: AI Agent Control
Source of version: 4 (current)
Copy to clipboard
{maketoc}
!!Recommended Resources
[http://www.wordware.com/files/ai|Programming Game AI by Example - Resource Page]
[http://www.ai-junkie.com/books/toc_pgaibe.html|ai-junkie]
!!Seek and Flee
!!!Using a physics engine
__Author__:' ((User:Van|Van))'
__Discussion__: [http://www.ogre3d.org/forums/viewtopic.php?f=2&t=49973|Computing course correction (steering)]
__Discussion__: [http://www.ogre3d.org/forums/viewtopic.php?f=2&t=50083|Solving for rotation difference with quaternions]
Also see: ((OgreNewt|Ogre wiki on Newton Game Dynamics))
We use the [http://www.newtondynamics.com/|newton physics engine]. We utilize the same input controls that humans use. We use a scalar, -1.0 to +1.0 for torque and 0.0 to +1.0 for thrust, to determine how much of the "engine controls" to apply into the physics engine. Therefore it doesn't matter if the the input is keyboard, mouse, joystick or computed (i.e. AI) the input to our physics system is always a scalar that represents the amount power/torque to apply. For example:
{CODE(wrap="1", colors="c++")}void SetThrust(float Scalar)
{
float mMaxEngineThrust = 400.00;
float mThrustToUse = mScalar * mMaxEngineThrust;
..// make call to physics engine
} // SetThrust{CODE}
Here are the __Seek()__ and __Flee()__ functions. These functions solve for a ''torque'' scalar.
{CODE(wrap="1", colors="c++")}
//------------------------------- Seek -----------------------------------
//
// Given a target, this behavior returns a steering force which will
// direct the agent towards the target
//------------------------------------------------------------------------
void Seek(Ogre::Vector3 TargetPosition, Ogre::Quaternion TargetOrientation)
{
Ogre::Vector3 mAgentPosition = mGlobalResource->LocalPlayerObjectScene->getInventoryPosition();
Ogre::Quaternion mAgentOrientation = mGlobalResource->LocalPlayerObjectScene->getInventoryOrientation();
Ogre::Vector3 mVectorToTarget = TargetPosition - mAgentPosition; // A-B = B->A
mAgentPosition.normalise();
mAgentOrientation.normalise();
Ogre::Vector3 mAgentHeading = mAgentOrientation * mAgentPosition;
Ogre::Vector3 mTargetHeading = TargetOrientation * TargetPosition;
mAgentHeading.normalise();
mTargetHeading.normalise();
// Orientation control - Ogre::Vector3::UNIT_Y is common up vector.
Ogre::Vector3 mAgentVO = mAgentOrientation.Inverse() * Ogre::Vector3::UNIT_Y;
Ogre::Vector3 mTargetVO = TargetOrientation * Ogre::Vector3::UNIT_Y;
// Compute new torque scalar (-1.0 to 1.0) based on heading vector to target.
Ogre::Vector3 mSteeringForce = mAgentOrientation.Inverse() * mVectorToTarget;
mSteeringForce.normalise();
float mYaw = mSteeringForce.x;
float mPitch = mSteeringForce.y;
float mRoll = mTargetVO.getRotationTo( mAgentVO ).getRoll().valueRadians();
clsSystemControls::getSingleton().setPitchControl( mPitch );
clsSystemControls::getSingleton().setYawControl( mYaw );
clsSystemControls::getSingleton().setRollControl( mRoll );
} // Seek
//----------------------------- Flee -------------------------------------
//
// Does the opposite of Seek
//------------------------------------------------------------------------
void Flee(Ogre::Vector3 TargetPosition, Ogre::Quaternion TargetOrientation)
{
Ogre::Vector3 mAgentPosition = mGlobalResource->LocalPlayerObjectScene->getInventoryPosition();
Ogre::Quaternion mAgentOrientation = mGlobalResource->LocalPlayerObjectScene->getInventoryOrientation();
Ogre::Vector3 mVectorToTarget = TargetPosition - mAgentPosition; // A-B = B->A
mAgentPosition.normalise();
mAgentOrientation.normalise();
Ogre::Vector3 mAgentHeading = mAgentOrientation * mAgentPosition;
Ogre::Vector3 mTargetHeading = TargetOrientation * TargetPosition;
mAgentHeading.normalise();
mTargetHeading.normalise();
// Orientation control - Ogre::Vector3::UNIT_Y is common up vector.
Ogre::Vector3 mAgentVO = mAgentOrientation.Inverse() * Ogre::Vector3::UNIT_Y;
Ogre::Vector3 mTargetVO = TargetOrientation * Ogre::Vector3::UNIT_Y;
// Compute new torque scalar (-1.0 to 1.0) based on heading vector to target.
Ogre::Vector3 mSteeringForce = mAgentOrientation * mVectorToTarget;
mSteeringForce.normalise();
float mYaw = mSteeringForce.x;
float mPitch = mSteeringForce.y;
float mRoll = mTargetVO.getRotationTo( mAgentVO ).getRoll().valueRadians();
clsSystemControls::getSingleton().setPitchControl( mPitch );
clsSystemControls::getSingleton().setYawControl( mYaw );
clsSystemControls::getSingleton().setRollControl( mRoll );
} // Flee
{CODE}
---
Alias: (alias(AI_Agent_Control))