You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
5.8 KiB
183 lines
5.8 KiB
//===== 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
|