177 lines
5.7 KiB
C++
177 lines
5.7 KiB
C++
//========= 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<CircleObstacles_t> 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
|