Beispiel #1
0
/**
 ****************************************************************************************************
	\fn			void UpdateAIDestinationTo( UINT8 &i_u8Index, const UINT8 &i_u8NodeID )
	\brief		Update destination for this AI
	\param		i_u8Index index of entity in AI entity
	\param		i_u8NodeID destination node ID
	\return		NONE
 ****************************************************************************************************
*/
void GameEngine::AI::UpdateAIDestinationTo( const UINT8 &i_u8Index, const UINT8 &i_u8NodeID )
{
	FUNCTION_START;

	if( AIEntityDatabase->at(i_u8Index)->m_AIState != E_AI_STATE_DEACTIVATE )
		AbortAI( i_u8Index );

	if( i_u8Index < AIEntityDatabase->size() )
	{
		UINT32 u32ClosestNodeID = Utilities::MAX_UINT32;
		D3DXVECTOR3 entityPosition( AIEntityDatabase->at(i_u8Index)->m_entity->m_v3Position.X(),
			AIEntityDatabase->at(i_u8Index)->m_entity->m_v3Position.Y(),
			AIEntityDatabase->at(i_u8Index)->m_entity->m_v3Position.Z() );

		FindClosestNodeIDFromPosition( entityPosition, u32ClosestNodeID );
		if( u32ClosestNodeID < wayPointList->size() )
		{
			AIEntityDatabase->at(i_u8Index)->m_u32TargetNodeID = u32ClosestNodeID;
			AIEntityDatabase->at(i_u8Index)->m_AIState = E_AI_STATE_GO_TO_TARGET_NODE;
			FindOptimalPath( u32ClosestNodeID, i_u8NodeID, *(AIEntityDatabase->at(i_u8Index)->m_optimalPath) );
		}
	}

	FUNCTION_FINISH;
}
Beispiel #2
0
/*
============
idAI::FindPathAroundObstacles

  Finds a path around dynamic obstacles using a path tree with clockwise and counter clockwise edge walks.
============
*/
bool idAI::FindPathAroundObstacles( const idPhysics *physics, const idAAS *aas, const idEntity *ignore, const idVec3 &startPos, const idVec3 &seekPos, obstaclePath_t &path ) {
	int numObstacles, areaNum, insideObstacle;
	obstacle_t obstacles[MAX_OBSTACLES];
	idBounds clipBounds;
	idBounds bounds;
	pathNode_t *root;
	bool pathToGoalExists;
	path.seekPos = seekPos;
	path.firstObstacle = NULL;
	path.startPosOutsideObstacles = startPos;
	path.startPosObstacle = NULL;
	path.seekPosOutsideObstacles = seekPos;
	path.seekPosObstacle = NULL;
	if( !aas ) {
		return true;
	}
	bounds[1] = aas->GetSettings()->boundingBoxes[0][1];
	bounds[0] = -bounds[1];
	bounds[1].z = 32.0f;
	// get the AAS area number and a valid point inside that area
	areaNum = aas->PointReachableAreaNum( path.startPosOutsideObstacles, bounds, ( AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ) );
	aas->PushPointIntoAreaNum( areaNum, path.startPosOutsideObstacles );
	// get all the nearby obstacles
	numObstacles = GetObstacles( physics, aas, ignore, areaNum, path.startPosOutsideObstacles, path.seekPosOutsideObstacles, obstacles, MAX_OBSTACLES, clipBounds );
	// get a source position outside the obstacles
	GetPointOutsideObstacles( obstacles, numObstacles, path.startPosOutsideObstacles.ToVec2(), &insideObstacle, NULL );
	if( insideObstacle != -1 ) {
		path.startPosObstacle = obstacles[insideObstacle].entity;
	}
	// get a goal position outside the obstacles
	GetPointOutsideObstacles( obstacles, numObstacles, path.seekPosOutsideObstacles.ToVec2(), &insideObstacle, NULL );
	if( insideObstacle != -1 ) {
		path.seekPosObstacle = obstacles[insideObstacle].entity;
	}
	// if start and destination are pushed to the same point, we don't have a path around the obstacle
	if( ( path.seekPosOutsideObstacles.ToVec2() - path.startPosOutsideObstacles.ToVec2() ).LengthSqr() < Square( 1.0f ) ) {
		if( ( seekPos.ToVec2() - startPos.ToVec2() ).LengthSqr() > Square( 2.0f ) ) {
			return false;
		}
	}
	// build a path tree
	root = BuildPathTree( obstacles, numObstacles, clipBounds, path.startPosOutsideObstacles.ToVec2(), path.seekPosOutsideObstacles.ToVec2(), path );
	// draw the path tree
	if( ai_showObstacleAvoidance.GetBool() ) {
		DrawPathTree( root, physics->GetOrigin().z );
	}
	// prune the tree
	PrunePathTree( root, path.seekPosOutsideObstacles.ToVec2() );
	// find the optimal path
	pathToGoalExists = FindOptimalPath( root, obstacles, numObstacles, physics->GetOrigin().z, physics->GetLinearVelocity(), path.seekPos );
	// free the tree
	FreePathTree_r( root );
	return pathToGoalExists;
}
Beispiel #3
0
/**
 ****************************************************************************************************
	\fn			float FindSquaredDistanceToNodeID( const D3DXVECTOR3 &i_vCurrPosition, const UINT32 &i_u32NodeID )
	\brief		Find squared distance from position to node ID
	\param		*i_vCurrPosition current entity position
	\param		i_u32NodeID the node ID
	\return		float
	\retval		Squared distance to the given node
 ****************************************************************************************************
*/
float GameEngine::AI::FindDistanceToNodeID( const D3DXVECTOR3 &i_vCurrPosition, const UINT32 &i_u32NodeID )
{
	UINT32 u32ClosestNodeID;
	float returnDistance = 0.0f;

	FUNCTION_START;

	FindClosestNodeIDFromPosition( i_vCurrPosition, u32ClosestNodeID );
	if( u32ClosestNodeID < wayPointList->size() )
	{
		D3DXVECTOR3 distance;
		distance = wayPointList->at(u32ClosestNodeID).centre - i_vCurrPosition;
		returnDistance = D3DXVec3Length( &distance );

		std::deque<UINT32> path;
		bool bResult = FindOptimalPath( u32ClosestNodeID, i_u32NodeID, path );

		if( bResult )
		{
			std::deque<UINT32>::const_iterator pathIter = path.begin();
			for( ; pathIter != path.end(); ++pathIter )
			{
				D3DXVECTOR3 startPoint = wayPointList->find((*pathIter))->second.centre;
				D3DXVECTOR3 endPoint = startPoint;
				++pathIter;
				if( pathIter != path.end() )
					endPoint = wayPointList->find((*pathIter))->second.centre;
				--pathIter;
				distance = endPoint - startPoint;
				returnDistance += D3DXVec3Length( &distance );
			}
		}
	}

	FUNCTION_FINISH;
	return returnDistance;
}