|
|
//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef AI_PLANE_SOLVER_H
#define AI_PLANE_SOLVER_H
#ifdef _WIN32
#pragma once
#endif
#include "utlvector.h"
#include "ai_movesolver.h"
#include "ehandle.h"
#include "mathlib/vector.h"
#include "simtimer.h"
#include "ai_navtype.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class Vector2D; class CBaseEntity; struct edict_t; class CAI_BaseNPC; class CAI_Motor; class CAI_Navigator; struct AILocalMoveGoal_t; struct AIMoveTrace_t;
//-------------------------------------
enum AI_SuggestorResult_t { SR_NONE, SR_OK, SR_FAIL };
DECLARE_POINTER_HANDLE( Obstacle_t ); #define OBSTACLE_INVALID ( (Obstacle_t)0 )
class CAI_PlaneSolver { public: // constructor
CAI_PlaneSolver( CAI_BaseNPC *pNpc ); // Attempt to find a valid move direction for the specifed goal
bool Solve( const AILocalMoveGoal_t &goal, float distClear, Vector *pSolution );
float CalcProbeDist( float speed ); // Flush any cached results (e.g., hull changed, results not valid)
void Reset(); void AddObstacle( const Vector &pos, float radius, CBaseEntity *pEntity = NULL, AI_MoveSuggType_t type = AIMST_AVOID_OBJECT ); bool HaveObstacles() { return ( m_Obstacles.Count() != 0 ) || ( s_GlobalObstacles.Count() != 0 ); }
static Obstacle_t AddGlobalObstacle( const Vector &pos, float radius, CBaseEntity *pEntity = NULL, AI_MoveSuggType_t type = AIMST_AVOID_OBJECT ); static void RemoveGlobalObstacle( Obstacle_t hObstacle ); static void RemoveGlobalObstacles( void ); static bool IsSegmentBlockedByGlobalObstacles( const Vector &vecStart, const Vector &vecEnd );
private: enum { DEGREES_POSITIVE_ARC = 270, DEGREES_POSITIVE_ARC_CLOSE_OBSTRUCTION = 340, NUM_PROBES = 5 };
struct CircleObstacles_t { CircleObstacles_t( const Vector ¢er, float radius, CBaseEntity *pEntity, AI_MoveSuggType_t type ) : center(center), radius(radius), hEntity(pEntity), type(type) { }
Vector center; float radius; AI_MoveSuggType_t type; EHANDLE hEntity; };
// How far ahead does the ground solver look (seconds)
float GetLookaheadTime() { return 1.0; }
// --------------------------------
// For debugging purposes
void VisualizeRegulations(); void VisualizeSolution( const Vector &vecGoal, const Vector& vecActual );
// --------------------------------
bool MoveLimit( Navigation_t navType, const Vector &target, bool ignoreTransients, bool fCheckStep, AIMoveTrace_t *pMoveTrace ); bool MoveLimit( Navigation_t navType, const Vector &target, bool ignoreTransients, bool fCheckStep, int contents, AIMoveTrace_t *pMoveTrace );
//-----------------------------------------------------------------------------
// Adjust the solution for fliers
//-----------------------------------------------------------------------------
void AdjustSolutionForFliers( const AILocalMoveGoal_t &goal, float flSolutionYaw, Vector *pSolution );
// --------------------------------
// Convenience accessors
CAI_BaseNPC * GetNpc(); CAI_Motor * GetMotor(); const Vector & GetLocalOrigin();
// --------------------------------
void GenerateObstacleNpcs( const AILocalMoveGoal_t &goal, float probeDist ); AI_SuggestorResult_t GenerateObstacleSuggestions( const AILocalMoveGoal_t &goal, const AIMoveTrace_t &directTrace, float distClear, float probeDist, float degreesToProbe, int nProbes ); AI_SuggestorResult_t GenerateObstacleSuggestion( const AILocalMoveGoal_t &goal, float yawScanCenter, float probeDist, float spanPerProbe, int probeOffset ); void GenerateSuggestionFromTrace( const AILocalMoveGoal_t &goal, const AIMoveTrace_t &moveTrace, float probeDist, float arcCenter, float arcSpan, int probeOffset ); bool GenerateCircleObstacleSuggestions( const AILocalMoveGoal_t &moveGoal, float probeDist );
void CalcYawsFromOffset( float yawScanCenter, float spanPerProbe, int probeOffset, float *pYawTest, float *pYawCenter ); float CalculateRegulationWeight( const AIMoveTrace_t &moveTrace, float pctBlockedt ); float AdjustRegulationWeight( CBaseEntity *pEntity, float weight ); unsigned ComputeTurnBiasFlags( const AILocalMoveGoal_t &goal, const AIMoveTrace_t &directTrace );
bool RunMoveSolver( const AILocalMoveGoal_t &goal, const AIMoveTrace_t &directTrace, float degreesPositiveArc, bool fDeterOscillation, Vector *pResult ); bool DetectUnsolvable( const AILocalMoveGoal_t &goal ); bool GenerateCircleObstacleSuggestion( const CircleObstacles_t &obstacle, const AILocalMoveGoal_t &moveGoal, float probeDist, const Vector& npcLoc, float radiusNpc );
// --------------------------------
CAI_BaseNPC * m_pNpc;
Vector m_PrevTarget; bool m_fSolvedPrev; float m_PrevSolution; Vector m_PrevSolutionVector; float m_ClosestHaveBeenToCurrent; float m_TimeLastProgress;
bool m_fCannotSolveCurrent; CSimTimer m_RefreshSamplesTimer; // --------------------------------
CUtlVector<CircleObstacles_t> m_Obstacles; static CUtlFixedLinkedList<CircleObstacles_t> s_GlobalObstacles; // --------------------------------
CAI_MoveSolver m_Solver; }; //-------------------------------------
inline void CAI_PlaneSolver::Reset() { m_RefreshSamplesTimer.Force();
m_fSolvedPrev = false; m_PrevTarget.Init( FLT_MAX, FLT_MAX, FLT_MAX ), m_PrevSolution = 0; m_ClosestHaveBeenToCurrent = FLT_MAX; m_TimeLastProgress = FLT_MAX; m_fCannotSolveCurrent = false; } //=============================================================================
#endif // AI_PLANE_SOLVER_H
|