29 #include "../../idlib/precompiled.h"
33 #include "../Game_local.h"
35 #define CACHETYPE_AREA 1
36 #define CACHETYPE_PORTAL 2
38 #define MAX_ROUTING_CACHE_MEMORY (2*1024*1024)
40 #define LEDGE_TRAVELTIME_PANALTY 250
89 dist = ( end -
start ).Length();
92 dist *= 100.0f / 100.0f;
94 dist *= 100.0f / 150.0f;
96 dist *= 100.0f / 300.0f;
110 int n,
i,
j, numReach, numRevReach,
t, maxt;
160 bytePtr += j *
sizeof(
unsigned short );
312 int numAreaCache, numPortalCache;
313 int totalAreaCacheMemory, totalPortalCacheMemory;
315 numAreaCache = numPortalCache = 0;
316 totalAreaCacheMemory = totalPortalCacheMemory = 0;
320 totalAreaCacheMemory +=
sizeof(
idRoutingCache ) + cache->
size * (
sizeof(
unsigned short ) +
sizeof(
byte ));
323 totalPortalCacheMemory +=
sizeof(
idRoutingCache ) + cache->
size * (
sizeof(
unsigned short ) +
sizeof(
byte ));
327 gameLocal.
Printf(
"%6d area cache (%d KB)\n", numAreaCache, totalAreaCacheMemory >> 10 );
328 gameLocal.
Printf(
"%6d portal cache (%d KB)\n", numPortalCache, totalPortalCacheMemory >> 10 );
344 if ( clusterNum > 0 ) {
362 assert( areaNum > 0 && areaNum < file->GetNumAreas() );
379 assert( areaNum > 0 && areaNum < file->GetNumAreas() );
398 bool foundClusterPortal =
false;
400 while( nodeNum != 0 ) {
409 foundClusterPortal |=
true;
427 return foundClusterPortal;
458 while( nodeNum != 0 ) {
489 for ( i = 0; i < obstacle->
areas.
Num(); i++ ) {
495 for ( rev_reach = area->
rev_reach; rev_reach; rev_reach = rev_reach->
rev_next ) {
507 for ( reach = area->
reach; reach; reach = reach->
next ) {
681 if ( --reachabilityNum < 0 ) {
694 int side, areaCluster;
697 if ( areaCluster > 0 ) {
712 int i, nextAreaNum, cluster, badTravelFlags, clusterAreaNum, numReachableAreas;
714 idRoutingUpdate *updateListStart, *updateListEnd, *curUpdate, *nextUpdate;
723 if ( clusterAreaNum >= numReachableAreas ) {
729 memset( startAreaTravelTimes, 0,
sizeof( startAreaTravelTimes ) );
738 updateListStart = curUpdate;
739 updateListEnd = curUpdate;
742 while( updateListStart ) {
744 curUpdate = updateListStart;
745 if ( curUpdate->
next ) {
749 updateListEnd =
NULL;
751 updateListStart = curUpdate->
next;
774 if ( cluster > 0 && cluster != areaCache->
cluster ) {
780 if ( clusterAreaNum >= numReachableAreas ) {
795 nextUpdate->
areaNum = nextAreaNum;
800 if ( badTravelFlags &
TFL_FLY ) {
809 nextUpdate->
prev = updateListEnd;
810 if ( updateListEnd ) {
811 updateListEnd->
next = nextUpdate;
814 updateListStart = nextUpdate;
816 updateListEnd = nextUpdate;
838 for ( cache = clusterCache; cache; cache = cache->
next ) {
852 cache->
next = clusterCache;
853 if ( clusterCache ) {
854 clusterCache->
prev = cache;
869 int i, portalNum, clusterAreaNum;
874 idRoutingUpdate *updateListStart, *updateListEnd, *curUpdate, *nextUpdate;
884 updateListStart = curUpdate;
885 updateListEnd = curUpdate;
888 while( updateListStart ) {
890 curUpdate = updateListStart;
892 if ( curUpdate->
next ) {
896 updateListEnd =
NULL;
898 updateListStart = curUpdate->
next;
940 nextUpdate->
prev = updateListEnd;
941 if ( updateListEnd ) {
942 updateListEnd->
next = nextUpdate;
945 updateListStart = nextUpdate;
947 updateListEnd = nextUpdate;
995 int clusterNum, goalClusterNum, portalNum,
i, clusterAreaNum;
996 unsigned short int t, bestTime;
1009 if ( areaNum == goalAreaNum ) {
1014 gameLocal.
Printf(
"RouteToGoalArea: areaNum %d out of range\n", areaNum );
1018 gameLocal.
Printf(
"RouteToGoalArea: goalAreaNum %d out of range\n", goalAreaNum );
1030 if ( clusterNum < 0 ) {
1032 if ( goalClusterNum < 0 ) {
1035 goalClusterNum = portal->
clusters[0];
1048 if ( goalClusterNum < 0 ) {
1050 if ( portal->
clusters[0] == clusterNum || portal->
clusters[1] == clusterNum) {
1051 goalClusterNum = clusterNum;
1056 if ( clusterNum > 0 && goalClusterNum > 0 && clusterNum == goalClusterNum ) {
1059 if ( clusterCache->
travelTimes[clusterAreaNum] ) {
1064 clusterCache =
NULL;
1068 clusterCache =
NULL;
1075 if ( goalClusterNum < 0 ) {
1078 goalClusterNum = portal->
clusters[0];
1093 for ( i = 0; i < cluster->
numPortals; i++ ) {
1111 if ( clusterCache ) {
1129 if ( !bestTime || t < bestTime ) {
1140 travelTime = bestTime;
1158 if ( !
RouteToGoalArea( areaNum, origin, goalAreaNum, travelFlags, travelTime, &reach ) ) {
1170 int i,
j, k, badTravelFlags, nextAreaNum, bestAreaNum;
1171 unsigned short t, bestTravelTime;
1172 idRoutingUpdate *updateListStart, *updateListEnd, *curUpdate, *nextUpdate;
1176 float targetDist, dist;
1178 if (
file ==
NULL || areaNum <= 0 ) {
1185 if ( callback.
TestArea(
this, areaNum ) ) {
1192 for ( k = 0; k < numObstacles; k++ ) {
1197 badTravelFlags = ~travelFlags;
1200 targetDist = (target - origin).Length();
1206 curUpdate->
start = origin;
1209 updateListStart = curUpdate;
1210 updateListEnd = curUpdate;
1216 while ( updateListStart ) {
1218 curUpdate = updateListStart;
1219 if ( curUpdate->
next ) {
1223 updateListEnd =
NULL;
1225 updateListStart = curUpdate->
next;
1230 if ( bestTravelTime && curUpdate->
tmpTravelTime >= bestTravelTime ) {
1255 v1 = reach->
end - curUpdate->
start;
1257 v2 = target - curUpdate->
start;
1258 p = curUpdate->
start + (v2 *
v1) * v1;
1261 for ( j = 0; j < 3; j++ ) {
1262 if ( (p[j] > curUpdate->
start[j] + 0.1f && p[j] > reach->
end[j] + 0.1f) ||
1263 (p[
j] < curUpdate->
start[
j] - 0.1f && p[
j] < reach->
end[
j] - 0.1f) ) {
1268 dist = (target -
p).Length();
1270 dist = (target - reach->
end).Length();
1274 if ( dist < targetDist ) {
1275 t += ( targetDist - dist ) * 10;
1279 if ( bestTravelTime && t >= bestTravelTime ) {
1289 for ( k = 0; k < numObstacles; k++ ) {
1291 if ( obstacles[k].expAbsBounds.LineIntersection( curUpdate->
start, reach->
end ) ) {
1295 if ( k < numObstacles ) {
1301 nextUpdate->
areaNum = nextAreaNum;
1306 if ( badTravelFlags &
TFL_FLY ) {
1315 nextUpdate->
prev = updateListEnd;
1316 if ( updateListEnd ) {
1317 updateListEnd->
next = nextUpdate;
1319 updateListStart = nextUpdate;
1321 updateListEnd = nextUpdate;
1331 if ( !bestTravelTime || t < bestTravelTime ) {
1342 if ( bestAreaNum ) {
idRoutingCache * GetPortalRoutingCache(int clusterNum, int areaNum, int travelFlags) const
void ShutdownRoutingCache(void)
unsigned short maxAreaTravelTime
#define LEDGE_TRAVELTIME_PANALTY
const idAASSettings & GetSettings(void) const
unsigned short * goalAreaTravelTimes
assert(prefInfo.fullscreenBtn)
void Printf(const char *fmt,...) const id_attribute((format(printf
idReachability * rev_next
bool SetAreaState_r(int nodeNum, const idBounds &bounds, const int areaContents, bool disabled)
void DeletePortalCache(void)
idList< idRoutingObstacle * > obstacleList
const aasPortal_t & GetPortal(int index)
void void void void void Error(const char *fmt,...) const id_attribute((format(printf
void RoutingStats(void) const
unsigned char * reachabilities
idRoutingCache * cacheListEnd
idReachability * GetAreaReachability(int areaNum, int reachabilityNum) const
const aasCluster_t & GetCluster(int index) const
idRoutingCache * cacheListStart
GLuint GLuint GLsizei GLenum type
void SetObstacleState(const idRoutingObstacle *obstacle, bool enable)
idRoutingUpdate * portalUpdate
#define AREA_REACHABLE_FLY
void GetBoundsAreas_r(int nodeNum, const idBounds &bounds, idList< int > &areas) const
virtual void VPCALL Memset(void *dst, const int val, const int count)=0
void ShutdownRouting(void)
idBounds boundingBoxes[MAX_AAS_BOUNDING_BOXES]
idRoutingUpdate * areaUpdate
unsigned short * areaTravelTimes
idRoutingCache * time_prev
int GetNumPortals(void) const
unsigned short startTravelTime
void SetupRoutingCache(void)
void SetAreaTravelFlag(int index, int flag)
GLfloat GLfloat GLfloat v2
void CalculateAreaTravelTimes(void)
unsigned short travelTime
virtual void RemoveAllObstacles(void)
static int FtoiFast(float f)
const aasNode_t & GetNode(int index) const
virtual aasHandle_t AddObstacle(const idBounds &bounds)
unsigned short * travelTimes
virtual bool RouteToGoalArea(int areaNum, const idVec3 origin, int goalAreaNum, int travelFlags, int &travelTime, idReachability **reach) const
unsigned short * areaTravelTimes
unsigned short tmpTravelTime
#define MAX_REACH_PER_AREA
int GetNumAreas(void) const
virtual void RemoveObstacle(const aasHandle_t handle)
virtual bool FindNearestGoal(aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback) const
void UpdatePortalRoutingCache(idRoutingCache *portalCache) const
unsigned short * areaTravelTimes
void SetPortalMaxTravelTime(int index, int time)
const aasIndex_t & GetPortalIndex(int index) const
int Append(const type &obj)
GLdouble GLdouble GLdouble r
bool LineIntersection(const idVec3 &start, const idVec3 &end) const
idReachability * rev_reach
void RemoveAreaTravelFlag(int index, int flag)
#define AREA_REACHABLE_WALK
bool RemoveIndex(int index)
idRoutingCache * time_next
void RemoveRoutingCacheUsingArea(int areaNum)
void UnlinkCache(idRoutingCache *cache) const
idRoutingCache *** areaCacheIndex
void UpdateAreaRoutingCache(idRoutingCache *areaCache) const
#define MAX_ROUTING_CACHE_MEMORY
void * Mem_ClearedAlloc(const int size)
unsigned short AreaTravelTime(int areaNum, const idVec3 &start, const idVec3 &end) const
void EnableArea(int areaNum)
void * Mem_Alloc(const int size)
void DeleteClusterCache(int clusterNum)
const idPlane & GetPlane(int index) const
virtual bool TestArea(const class idAAS *aas, int areaNum)=0
void DeleteOldestCache(void) const
int PlaneSide(const idPlane &plane, const float epsilon=ON_EPSILON) const
int GetNumClusters(void) const
void LinkCache(idRoutingCache *cache) const
const aasArea_t & GetArea(int index)
void DeleteAreaTravelTimes(void)
bool ContainsPoint(const idVec3 &p) const
void DisableArea(int areaNum)
virtual bool SetAreaState(const idBounds &bounds, const int areaContents, bool disabled)
idRoutingCache * GetAreaRoutingCache(int clusterNum, int areaNum, int travelFlags) const
int ClusterAreaNum(int clusterNum, int areaNum) const
virtual idVec3 AreaCenter(int areaNum) const
idRoutingCache ** portalCacheIndex
idSIMDProcessor * SIMDProcessor
virtual int TravelTimeToGoalArea(int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags) const