mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-07 17:29:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: "Force-field" obstacle avoidance & steering
|
||||
//
|
||||
// @Note (toml 06-18-02): Currently only controls direction. Ultimately could
|
||||
// also incorporate body facing (yaw), speed, and translational/rotational
|
||||
// acceleration.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef AI_MOVESOLVER_H
|
||||
#define AI_MOVESOLVER_H
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utlvector.h"
|
||||
#include "ai_obstacle_type.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline float NormalizeAngle( float angle )
|
||||
{
|
||||
if ( angle < 0.0 )
|
||||
angle += 360.0;
|
||||
else if ( angle >= 360.0 )
|
||||
angle -= 360.0;
|
||||
return angle;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ENUMERATIONS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// STRUCTURES
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------
|
||||
// AI_Arc_t
|
||||
//
|
||||
// Purpose: Represents an arc.
|
||||
//
|
||||
//-------------------------------------
|
||||
struct AI_Arc_t
|
||||
{
|
||||
AI_Arc_t()
|
||||
: center( 0 ),
|
||||
span( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
// Set by center and span
|
||||
void Set( float newCenter, float newSpan );
|
||||
|
||||
// Set by the right and left extremes (coordinates run counter clockwise)
|
||||
void SetByLimits( float yawRight, float yawLeft );
|
||||
|
||||
// Center of the arc (as "yaw")
|
||||
float center;
|
||||
|
||||
// Span of the arc (in degrees)
|
||||
float span;
|
||||
};
|
||||
|
||||
//-------------------------------------
|
||||
// AI_MoveSuggestion_t
|
||||
//
|
||||
// Purpose: Suggests a possible move/avoidance, with a range of acceptable alternatives
|
||||
//
|
||||
// @Note (toml 06-20-02): this probably will eventually want to incorporate facing and
|
||||
// destination of the motivating goal.
|
||||
//
|
||||
//-------------------------------------
|
||||
|
||||
enum AI_MoveSuggestionFlags_t
|
||||
{
|
||||
AIMS_FAVOR_LEFT = 0x01,
|
||||
AIMS_FAVOR_RIGHT = 0x02
|
||||
};
|
||||
|
||||
//-----------------
|
||||
|
||||
struct AI_MoveSuggestion_t
|
||||
{
|
||||
AI_MoveSuggestion_t();
|
||||
AI_MoveSuggestion_t( AI_MoveSuggType_t newType, float newWeight, float newDir, float newSpan, CBaseEntity *pEntity = NULL );
|
||||
AI_MoveSuggestion_t( AI_MoveSuggType_t newType, float newWeight, const AI_Arc_t &arc, CBaseEntity *pEntity = NULL );
|
||||
|
||||
void Set( AI_MoveSuggType_t newType, float newWeight, float newDir, float newSpan, CBaseEntity *pEntity = NULL );
|
||||
void Set( AI_MoveSuggType_t newType, float newWeight, const AI_Arc_t &arc, CBaseEntity *pEntity = NULL );
|
||||
|
||||
//---------------------------------
|
||||
|
||||
// The kind of suggestion
|
||||
AI_MoveSuggType_t type;
|
||||
|
||||
// The unadjusted weight of the suggestion [0..1], although [-1..1] within the solver
|
||||
float weight;
|
||||
|
||||
// The desired direction to move/avoid
|
||||
AI_Arc_t arc;
|
||||
|
||||
// The causing entity, if any
|
||||
EHANDLE hObstacleEntity;
|
||||
|
||||
// Flags
|
||||
unsigned flags;
|
||||
|
||||
};
|
||||
|
||||
//-----------------
|
||||
|
||||
typedef CUtlVector<AI_MoveSuggestion_t> CAI_MoveSuggestions;
|
||||
|
||||
//-------------------------------------
|
||||
// AI_MoveSolution_t
|
||||
//
|
||||
// Purpose: The result of resolving suggestions
|
||||
//
|
||||
// @Note (toml 06-18-02): Currently, this is a very dopey little structure.
|
||||
// However, it will probably eventually incorporate much of the info
|
||||
// passed or calculated piecemeal between Move...() and Move...Execute()
|
||||
// functions. Once suggestions incorprate more information, the solution
|
||||
// may want to include a copy of the winning suggestion, so that the
|
||||
// caller need retain less state. If this is not the case, reduce it to just
|
||||
// a yaw.
|
||||
//
|
||||
//-------------------------------------
|
||||
struct AI_MoveSolution_t
|
||||
{
|
||||
AI_MoveSolution_t()
|
||||
: dir(0)
|
||||
{
|
||||
}
|
||||
|
||||
// The direction to move
|
||||
float dir;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class CAI_MoveSolver
|
||||
//
|
||||
// Purpose: Given a set of precalculated "regulations" (typically negative),
|
||||
// and a set of instantaneous suggestions (usually positive)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CAI_MoveSolver
|
||||
{
|
||||
public:
|
||||
CAI_MoveSolver();
|
||||
|
||||
//---------------------------------
|
||||
// Purpose: A regulation is a suggestion that is kept around as a rule until
|
||||
// cleared. They are generally negative suggestions.
|
||||
//---------------------------------
|
||||
void AddRegulation( const AI_MoveSuggestion_t &suggestion );
|
||||
void AddRegulations( const AI_MoveSuggestion_t *pSuggestion, int nSuggestions );
|
||||
|
||||
bool HaveRegulations() const;
|
||||
void ClearRegulations();
|
||||
|
||||
//---------------------------------
|
||||
// Purpose: Solve the move, picking the best direction from a set of suggestions,
|
||||
// after applying the regulations
|
||||
//---------------------------------
|
||||
bool Solve( const AI_MoveSuggestion_t *pSuggestions, int nSuggestions, AI_MoveSolution_t *pResult );
|
||||
bool Solve( const AI_MoveSuggestion_t &suggestion, AI_MoveSolution_t *pResult );
|
||||
|
||||
//---------------------------------
|
||||
bool HaveRegulationForObstacle( CBaseEntity *pEntity);
|
||||
|
||||
//---------------------------------
|
||||
// Visualization
|
||||
void VisualizeRegulations( const Vector& origin );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
REGS_RESERVE = 8,
|
||||
};
|
||||
|
||||
//---------------------------------
|
||||
void NormalizeSuggestions( AI_MoveSuggestion_t *pBegin, AI_MoveSuggestion_t *pEnd );
|
||||
|
||||
//---------------------------------
|
||||
CAI_MoveSuggestions m_Regulations;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// AI_Arc_t inline methods
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void AI_Arc_t::Set( float newCenter, float newSpan )
|
||||
{
|
||||
center = NormalizeAngle( newCenter );
|
||||
span = NormalizeAngle( newSpan );
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline void AI_Arc_t::SetByLimits( float yawRight, float yawLeft )
|
||||
{
|
||||
// Yaw runs counter-clockwise
|
||||
span = yawLeft - yawRight;
|
||||
|
||||
if ( span < 0 )
|
||||
span += 360;
|
||||
|
||||
center = yawRight + span * 0.5;
|
||||
|
||||
if ( center >= 360 )
|
||||
center -= 360;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// AI_MoveSuggestion_t inline methods
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void AI_MoveSuggestion_t::Set( AI_MoveSuggType_t newType, float newWeight, float newDir, float newSpan, CBaseEntity *pEntity )
|
||||
{
|
||||
type = newType;
|
||||
weight = newWeight;
|
||||
hObstacleEntity = pEntity;
|
||||
flags = 0;
|
||||
|
||||
arc.Set( newDir, newSpan );
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline AI_MoveSuggestion_t::AI_MoveSuggestion_t()
|
||||
: type( AIMS_INVALID ),
|
||||
weight( 0 ),
|
||||
flags( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline AI_MoveSuggestion_t::AI_MoveSuggestion_t( AI_MoveSuggType_t newType, float newWeight, float newDir, float newSpan, CBaseEntity *pEntity )
|
||||
{
|
||||
Set( newType, newWeight, newDir, newSpan, pEntity );
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline AI_MoveSuggestion_t::AI_MoveSuggestion_t( AI_MoveSuggType_t newType, float newWeight, const AI_Arc_t &arc, CBaseEntity *pEntity )
|
||||
{
|
||||
Set( newType, newWeight, arc.center, arc.span, pEntity );
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline void AI_MoveSuggestion_t::Set( AI_MoveSuggType_t newType, float newWeight, const AI_Arc_t &arc, CBaseEntity *pEntity )
|
||||
{
|
||||
Set( newType, newWeight, arc.center, arc.span, pEntity );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CAI_MoveSolver inline methods
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline CAI_MoveSolver::CAI_MoveSolver()
|
||||
{
|
||||
m_Regulations.EnsureCapacity( REGS_RESERVE );
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline void CAI_MoveSolver::AddRegulation( const AI_MoveSuggestion_t &suggestion )
|
||||
{
|
||||
m_Regulations.AddToTail( suggestion );
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline void CAI_MoveSolver::AddRegulations( const AI_MoveSuggestion_t *pSuggestions, int nSuggestions )
|
||||
{
|
||||
for (int i = 0; i < nSuggestions; ++i)
|
||||
{
|
||||
m_Regulations.AddToTail( pSuggestions[i] );
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline bool CAI_MoveSolver::HaveRegulations() const
|
||||
{
|
||||
return (m_Regulations.Count() > 0);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline void CAI_MoveSolver::ClearRegulations()
|
||||
{
|
||||
m_Regulations.RemoveAll();
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
inline bool CAI_MoveSolver::Solve( const AI_MoveSuggestion_t &suggestion, AI_MoveSolution_t *pResult)
|
||||
{
|
||||
return Solve( &suggestion, 1, pResult);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
#endif // AI_MOVESOLVER_H
|
||||
Reference in New Issue
Block a user