//============================================================================= // 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 //======================================== // 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 routesWithMultiplier; SwapArray 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& 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& 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& 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 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 mBigIntersections; void PopulateConnectivityData( bool useMultiplier, Intersection* intersections, int numInts ); void VisitAll( SwapArray& 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