2013-12-03 07:31:46 +04:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// nav_node.h
// Navigation Nodes are used when generating a Navigation Mesh by point sampling the map
// Author: Michael S. Booth (mike@turtlerockstudios.com), January 2003
# ifndef _NAV_NODE_H_
# define _NAV_NODE_H_
# include "nav.h"
// If DEBUG_NAV_NODES is true, nav_show_nodes controls drawing node positions, and
// nav_show_node_id allows you to show the IDs of nodes that didn't get used to create areas.
# define DEBUG_NAV_NODES 1
//--------------------------------------------------------------------------------------------------------------
/**
* Navigation Nodes .
* These Nodes encapsulate world locations , and ways to get from one location to an adjacent one .
* Note that these links are not necessarily commutative ( falling off of a ledge , for example ) .
*/
class CNavNode
{
public :
CNavNode ( const Vector & pos , const Vector & normal , CNavNode * parent , bool onDisplacement ) ;
~ CNavNode ( ) ;
static CNavNode * GetNode ( const Vector & pos ) ; ///< return navigation node at the position, or NULL if none exists
static void CleanupGeneration ( ) ;
CNavNode * GetConnectedNode ( NavDirType dir ) const ; ///< get navigation node connected in given direction, or NULL if cant go that way
const Vector * GetPosition ( void ) const ;
const Vector * GetNormal ( void ) const { return & m_normal ; }
unsigned int GetID ( void ) const { return m_id ; }
static CNavNode * GetFirst ( void ) { return m_list ; }
static unsigned int GetListLength ( void ) { return m_listLength ; }
CNavNode * GetNext ( void ) { return m_next ; }
void Draw ( void ) ;
void ConnectTo ( CNavNode * node , NavDirType dir , float obstacleHeight , float flObstacleStartDist , float flObstacleEndDist ) ; ///< create a connection FROM this node TO the given node, in the given direction
CNavNode * GetParent ( void ) const ;
void MarkAsVisited ( NavDirType dir ) ; ///< mark the given direction as having been visited
BOOL HasVisited ( NavDirType dir ) ; ///< return TRUE if the given direction has already been searched
BOOL IsBiLinked ( NavDirType dir ) const ; ///< node is bidirectionally linked to another node in the given direction
BOOL IsClosedCell ( void ) const ; ///< node is the NW corner of a bi-linked quad of nodes
void Cover ( void ) { m_isCovered = true ; } ///< @todo Should pass in area that is covering
BOOL IsCovered ( void ) const { return m_isCovered ; } ///< return true if this node has been covered by an area
void AssignArea ( CNavArea * area ) ; ///< assign the given area to this node
CNavArea * GetArea ( void ) const ; ///< return associated area
void SetAttributes ( int bits ) { m_attributeFlags = bits ; }
int GetAttributes ( void ) const { return m_attributeFlags ; }
float GetGroundHeightAboveNode ( NavCornerType cornerType ) const ; ///< return ground height above node in given corner direction (NUM_CORNERS for highest in any direction)
bool IsBlockedInAnyDirection ( void ) const ; ///< return true if the node is blocked in any direction
bool IsOnDisplacement ( void ) const { return m_isOnDisplacement ; }
private :
CNavNode ( ) { } // constructor used only for hash lookup
friend class CNavMesh ;
bool TestForCrouchArea ( NavCornerType cornerNum , const Vector & mins , const Vector & maxs , float * groundHeightAboveNode ) ;
void CheckCrouch ( void ) ;
Vector m_pos ; ///< position of this node in the world
Vector m_normal ; ///< surface normal at this location
CNavNode * m_to [ NUM_DIRECTIONS ] ; ///< links to north, south, east, and west. NULL if no link
float m_obstacleHeight [ NUM_DIRECTIONS ] ; ///< obstacle height (delta from nav node z position) that must be climbed to reach next node in this direction
float m_obstacleStartDist [ NUM_DIRECTIONS ] ; ///< distance along this direction to reach the beginning of the obstacle
float m_obstacleEndDist [ NUM_DIRECTIONS ] ; ///< distance along this direction to reach the end of the obstacle
unsigned int m_id ; ///< unique ID of this node
int m_attributeFlags ; ///< set of attribute bit flags (see NavAttributeType)
static CNavNode * m_list ; ///< the master list of all nodes for this map
static unsigned int m_listLength ;
static unsigned int m_nextID ;
CNavNode * m_next ; ///< next link in master list
CNavNode * m_nextAtXY ; ///< next link at a particular position
// below are only needed when generating
unsigned char m_visited ; ///< flags for automatic node generation. If direction bit is clear, that direction hasn't been explored yet.
CNavNode * m_parent ; ///< the node prior to this in the search, which we pop back to when this node's search is done (a stack)
bool m_isCovered ; ///< true when this node is "covered" by a CNavArea
CNavArea * m_area ; ///< the area this node is contained within
bool m_isBlocked [ NUM_CORNERS ] ;
bool m_crouch [ NUM_CORNERS ] ;
float m_groundHeightAboveNode [ NUM_CORNERS ] ;
bool m_isOnDisplacement ;
} ;
//--------------------------------------------------------------------------------------------------------------
//
// Inlines
//
inline CNavNode * CNavNode : : GetConnectedNode ( NavDirType dir ) const
{
return m_to [ dir ] ;
}
inline const Vector * CNavNode : : GetPosition ( void ) const
{
return & m_pos ;
}
inline CNavNode * CNavNode : : GetParent ( void ) const
{
return m_parent ;
}
inline void CNavNode : : MarkAsVisited ( NavDirType dir )
{
m_visited | = ( 1 < < dir ) ;
}
inline BOOL CNavNode : : HasVisited ( NavDirType dir )
{
if ( m_visited & ( 1 < < dir ) )
return true ;
return false ;
}
inline void CNavNode : : AssignArea ( CNavArea * area )
{
m_area = area ;
}
inline CNavArea * CNavNode : : GetArea ( void ) const
{
return m_area ;
}
inline bool CNavNode : : IsBlockedInAnyDirection ( void ) const
{
return m_isBlocked [ SOUTH_EAST ] | | m_isBlocked [ SOUTH_WEST ] | | m_isBlocked [ NORTH_EAST ] | | m_isBlocked [ NORTH_WEST ] ;
}
# endif // _NAV_NODE_H_