//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef AI_PLANE_SOLVER_H #define AI_PLANE_SOLVER_H #ifdef _WIN32 #pragma once #endif #include "ai_movesolver.h" #include "ai_navtype.h" #include "ehandle.h" #include "mathlib/vector.h" #include "simtimer.h" #include "utlvector.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 }; 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); } private: enum { DEGREES_POSITIVE_ARC = 270, DEGREES_POSITIVE_ARC_CLOSE_OBSTRUCTION = 340, NUM_PROBES = 5 }; // 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); // -------------------------------- 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; // -------------------------------- 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; }; CUtlVector m_Obstacles; // -------------------------------- 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