319 lines
9.3 KiB
C++
319 lines
9.3 KiB
C++
//=============================================================================
|
|
// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
|
|
//
|
|
// File: roadmanager.h
|
|
//
|
|
// Description: Blahblahblah
|
|
//
|
|
// History: 26/06/2002 + Created -- Cary Brisebois (based on TBJ's work)
|
|
//
|
|
//=============================================================================
|
|
|
|
#ifndef ROADMANAGER_H
|
|
#define ROADMANAGER_H
|
|
|
|
//========================================
|
|
// Nested Includes
|
|
//========================================
|
|
#include <render/culling/swaparray.h>
|
|
|
|
//========================================
|
|
// Forward References
|
|
//========================================
|
|
class Road;
|
|
class Intersection;
|
|
class RoadSegmentData;
|
|
class RoadSegment;
|
|
class Lane;
|
|
|
|
class RoadRenderTest;
|
|
|
|
static const float NEAR_INFINITY = 100000.0f;
|
|
|
|
//=============================================================================
|
|
//
|
|
// Synopsis: Blahblahblah
|
|
//
|
|
//=============================================================================
|
|
|
|
class RoadManager
|
|
{
|
|
public:
|
|
enum { STARTUP = false, SHUTDOWN = true };
|
|
|
|
static const float AGAINST_TRAFFIC_COST_MULTIPLIER;
|
|
|
|
struct ShortestRoad
|
|
{
|
|
Road* road;
|
|
bool isOutRoad;
|
|
float cost;
|
|
};
|
|
struct NodeData
|
|
{
|
|
Intersection* destIn;
|
|
ShortestRoad* roadToIn;
|
|
ShortestRoad* roadJustBeforeIn;
|
|
float dist; // total distance to the destination intersection
|
|
};
|
|
struct BigIntersection
|
|
{
|
|
Intersection* in;
|
|
SwapArray<NodeData> routesWithMultiplier;
|
|
SwapArray<NodeData> routesNoMultiplier;
|
|
};
|
|
enum ElementType
|
|
{
|
|
ET_INTERSECTION, // Intersection*
|
|
ET_NORMALROAD // Road*
|
|
};
|
|
struct PathElement
|
|
{
|
|
ElementType type;
|
|
void* elem;
|
|
bool operator==( const PathElement& right ) const
|
|
{
|
|
return(elem==right.elem);
|
|
}
|
|
bool operator!=( const PathElement& right ) const
|
|
{
|
|
return(elem!=right.elem);
|
|
}
|
|
};
|
|
|
|
|
|
static RoadManager* GetInstance();
|
|
static void Destroy();
|
|
|
|
//---------------Initialization
|
|
void Init( bool shutdown );
|
|
|
|
void InitializeRoadMemory( unsigned int numRoads );
|
|
void InitializeIntersectionMemory( unsigned int numIntersections );
|
|
void InitializeRoadSegmentDataMemory( unsigned int numSegments );
|
|
void InitializeRoadSegmentMemory( unsigned int numRoadSegments );
|
|
|
|
void DumpRoadSegmentDataMemory();
|
|
|
|
Road* GetFreeRoadMemory( );
|
|
Intersection* GetFreeIntersectionMemory( );
|
|
RoadSegmentData* GetFreeRoadSegmentDataMemory( );
|
|
RoadSegment* GetFreeRoadSegmentMemory( );
|
|
|
|
void AddRoad( Road* pRoad );
|
|
void AddIntersection( Intersection* pIntersection );
|
|
void AddRoadSegmentData( RoadSegmentData* pRoadSegmentData );
|
|
void AddRoadSegment( RoadSegment* pRoadSegment );
|
|
|
|
int GetMaxPathElements();
|
|
|
|
void CreateRoadNetwork( void );
|
|
|
|
|
|
//---------------Data Aquisition
|
|
Intersection* FindIntersection( const char* name );
|
|
Intersection* FindIntersection( tUID name );
|
|
Intersection* FindIntersection( rmt::Vector& point );
|
|
|
|
Intersection* FindIntersection( int iIndex );
|
|
|
|
int GetNumIntersectionsUsed( );
|
|
unsigned int GetNumRoads( );
|
|
|
|
bool FindRoad( const rmt::Vector& point,
|
|
const Road** ppRoad,
|
|
RoadSegment** ppOutRoadSegment,
|
|
int& segmentIndex,
|
|
float& in,
|
|
float& lateral,
|
|
bool considerShortCuts=true ) const;
|
|
|
|
static bool FindClosestPointOnRoad( const Road* pRoad,
|
|
const rmt::Vector& pos,
|
|
rmt::Vector& closestPos,
|
|
float& closestDist,
|
|
int& segmentIndex );
|
|
|
|
static float DetermineRoadT( RoadSegment* seg, float segT );
|
|
static float DetermineSegmentT( const rmt::Vector& pos, RoadSegment* seg );
|
|
|
|
|
|
|
|
RoadSegmentData* FindRoadSegmentData( const char* name );
|
|
RoadSegmentData* FindRoadSegmentData( tUID name );
|
|
|
|
RoadRenderTest* GetRoadRenderTest();
|
|
|
|
// fully pathfind from source to target, returning float distance
|
|
float FindPathElementsBetween(
|
|
bool useMultiplier, // IN: direction-biased?
|
|
PathElement& sourceElem, // IN: starting element
|
|
float sourceT, // IN: used only if sourceElem is a road
|
|
const rmt::Vector& sourcePos, // IN: used only if sourceElem is an intersection
|
|
PathElement& targetElem, // IN: terminating element
|
|
float targetT, // IN: used only if targetElem is a road
|
|
const rmt::Vector& targetPos, // IN: used only if targetElem is an intersection
|
|
SwapArray<PathElement>& elems ); // OUT: accumulate roads or intersections
|
|
|
|
enum PathfindingOption
|
|
{
|
|
PO_SEARCH_SHORTCUTS = 1 << 0, // whether or not to take into account shortcut roads
|
|
PO_SEARCH_ROADS = 1 << 1, // whether or not to search for roads
|
|
PO_SEARCH_INTERSECTIONS = 1 << 2, // whether or not to search for intersections
|
|
|
|
NUM_POS = ( PO_SEARCH_SHORTCUTS |
|
|
PO_SEARCH_ROADS |
|
|
PO_SEARCH_INTERSECTIONS )
|
|
};
|
|
|
|
typedef char PathfindingOptions;
|
|
|
|
// search roads and intersections for whichever's closest, given a position
|
|
void FindClosestPathElement(
|
|
const rmt::Vector& pos, // IN: search center
|
|
float searchRadius, // IN: search radius
|
|
PathfindingOptions options, // IN: search options
|
|
PathElement& closestElem, // OUT: closest element (road or intersection)
|
|
RoadSegment*& closestRoadSeg, // OUT: if closest element is road, this is closest seg
|
|
float& closestRoadSegT, // OUT: if closest element is road, this is segment t value
|
|
float& closestRoadT ); // OUT: if closest element is road, this is road's t value
|
|
|
|
enum ErrorValue
|
|
{
|
|
DEAD_END,
|
|
STILL_LOOKING,
|
|
FOUND_TARGET,
|
|
FOUND_BIGINTERSECTION,
|
|
UNEXPECTED
|
|
};
|
|
struct DistErrMap
|
|
{
|
|
int ID;
|
|
ErrorValue errVal;
|
|
float dist;
|
|
};
|
|
|
|
float FindDistToTargetInOneDirection(
|
|
bool useMultiplier,
|
|
Intersection* targetInt,
|
|
Intersection* currInt,
|
|
Intersection* lastInt,
|
|
ShortestRoad* shortestRoadFromLastInt,
|
|
SwapArray<PathElement>& elems,
|
|
ShortestRoad*& firstShortRoad, // needed for traversal dist from src road to srcInt
|
|
ShortestRoad*& lastShortRoad, // needed for traversal dist from targetInt to target road
|
|
ErrorValue& errVal );
|
|
|
|
void TraverseRoads(
|
|
bool useMultiplier,
|
|
Intersection* targetInt,
|
|
Intersection* currInt,
|
|
Intersection* lastInt,
|
|
SwapArray<PathElement>& elems,
|
|
ErrorValue& errVal );
|
|
|
|
|
|
|
|
private:
|
|
|
|
static RoadManager* mInstance;
|
|
|
|
Road* mRoads;
|
|
unsigned int mNumRoads;
|
|
unsigned int mNumRoadsUsed;
|
|
|
|
Intersection* mIntersections;
|
|
unsigned int mNumIntersections;
|
|
unsigned int mNumIntersectionsUsed;
|
|
|
|
struct DijkstraNode
|
|
{
|
|
struct AdjacencyData
|
|
{
|
|
DijkstraNode* adjacentNode;
|
|
ShortestRoad* shortestRoadThere;
|
|
};
|
|
|
|
Intersection* in;
|
|
float distToSrc;
|
|
DijkstraNode* predecessor;
|
|
ShortestRoad* shortestRoadFromPred;
|
|
bool addedToS;
|
|
SwapArray<AdjacencyData> adjacents;
|
|
|
|
DijkstraNode()
|
|
{
|
|
in = NULL;
|
|
|
|
distToSrc = NEAR_INFINITY;
|
|
predecessor = NULL;
|
|
shortestRoadFromPred = NULL;
|
|
addedToS = false;
|
|
}
|
|
|
|
~DijkstraNode()
|
|
{
|
|
in = NULL;
|
|
adjacents.Clear();
|
|
|
|
distToSrc = NEAR_INFINITY;
|
|
predecessor = NULL;
|
|
shortestRoadFromPred = NULL;
|
|
addedToS = false;
|
|
}
|
|
|
|
void Init( float dist, DijkstraNode* pred )
|
|
{
|
|
distToSrc = dist;
|
|
predecessor = pred;
|
|
|
|
shortestRoadFromPred = NULL;
|
|
addedToS = false;
|
|
}
|
|
};
|
|
SwapArray<BigIntersection*> mBigIntersections;
|
|
void PopulateConnectivityData( bool useMultiplier, Intersection* intersections, int numInts );
|
|
void VisitAll( SwapArray<DijkstraNode>& nodes );
|
|
|
|
RoadSegmentData* mRoadSegmentData;
|
|
unsigned int mNumRoadSegmentData;
|
|
unsigned int mNumRoadSegmentDataUsed;
|
|
|
|
RoadSegment** mRoadSegments; // dynamically allocated array of pointers to RoadSegments
|
|
unsigned int mNumRoadSegments;
|
|
unsigned int mNumRoadSegmentsUsed;
|
|
/*
|
|
TransformRoadSegment** mRoadSegments;
|
|
unsigned int mNumRoadSegments;
|
|
unsigned int mNumRoadSegmentsUsed;
|
|
*/
|
|
|
|
RoadRenderTest* mRender;
|
|
|
|
float GetTraversalDistance( ShortestRoad* fromRoad, ShortestRoad* toRoad );
|
|
|
|
|
|
//Singleton
|
|
RoadManager();
|
|
virtual ~RoadManager();
|
|
|
|
//Prevent wasteful constructor creation.
|
|
RoadManager( const RoadManager& roadmanager );
|
|
RoadManager& operator=( const RoadManager& roadmanager );
|
|
};
|
|
|
|
inline unsigned int RoadManager::GetNumRoads()
|
|
{
|
|
return mNumRoadsUsed;
|
|
}
|
|
inline int RoadManager::GetNumIntersectionsUsed()
|
|
{
|
|
return mNumIntersectionsUsed;
|
|
}
|
|
inline RoadRenderTest* RoadManager::GetRoadRenderTest()
|
|
{
|
|
return mRender;
|
|
}
|
|
|
|
#endif //ROADMANAGER_H
|