Table of contents
Recommended Resources
Programming Game AI by Example - Resource Page
Seek and Flee
Using a physics engine
Author:' Van'
Discussion: Computing course correction (steering)
Discussion: Solving for rotation difference with quaternions
Also see: Ogre wiki on Newton Game Dynamics
We use the 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:
void SetThrust(float Scalar) { float mMaxEngineThrust = 400.00; float mThrustToUse = mScalar * mMaxEngineThrust; ..// make call to physics engine } // SetThrust
Here are the Seek() and Flee() functions. These functions solve for a torque scalar.
//------------------------------- 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
Alias: AI_Agent_Control