29 #include "../../../idlib/precompiled.h"
36 #define INSIDEUNITS 2.0f
37 #define INSIDEUNITS_WALKEND 0.5f
38 #define INSIDEUNITS_WALKSTART 0.1f
39 #define INSIDEUNITS_SWIMEND 0.5f
40 #define INSIDEUNITS_FLYEND 0.5f
41 #define INSIDEUNITS_WATERJUMP 15.0f
54 for ( reach = area->
reach; reach; reach = reach->
next ) {
109 int i, faceNum, otherAreaNum;
116 for ( i = 0; i < area->
numFaces; i++ ) {
122 if ( otherAreaNum == 0 ) {
153 int i, faceNum, otherAreaNum;
164 for ( i = 0; i < area->
numFaces; i++ ) {
170 if ( otherAreaNum == 0 ) {
205 int i, k,
l, m,
n, faceNum, face1Num, face2Num, otherAreaNum, edge1Num, edge2Num;
216 for ( i = 0; i < area->
numFaces; i++ ) {
227 for ( k = 0; k < area->
numFaces; k++ ) {
234 for ( l = 0; l < otherArea->
numFaces; l++ ) {
242 for ( m = 0; m < face1->
numEdges; m++ ) {
244 for ( n = 0; n < face2->
numEdges; n++ ) {
246 if ( edge1Num == edge2Num ) {
254 if ( m < face1->numEdges ) {
258 if ( l < otherArea->numFaces ) {
262 if ( k < area->numFaces ) {
268 reach->
edgeNum = abs( edge1Num );
288 int i,
j, k,
l, edge1Num, edge2Num, areas[10];
289 int floor_bestArea1FloorEdgeNum, floor_bestArea2FloorEdgeNum, floor_foundReach;
290 int water_bestArea1FloorEdgeNum, water_bestArea2FloorEdgeNum, water_foundReach;
291 int side1, faceSide1, floorFace1Num;
292 float dist, dist1, dist2, diff, invGravityDot, orthogonalDot;
293 float x1,
x2, x3, x4,
y1,
y2, y3, y4, tmp,
y;
294 float length, floor_bestLength, water_bestLength, floor_bestDist, water_bestDist;
295 idVec3 v1,
v2,
v3, v4, tmpv, p1area1, p1area2, p2area1, p2area2;
297 idVec3 floor_bestStart, floor_bestEnd, floor_bestNormal;
298 idVec3 water_bestStart, water_bestEnd, water_bestNormal;
302 aasFace_t *floorFace1, *floorFace2, *floor_bestFace1, *water_bestFace1;
323 for ( i = 0; i < 2; i++ ) {
324 if ( area1->
bounds[0][i] > area2->
bounds[1][i] + 2.0f ) {
327 if ( area1->
bounds[1][i] < area2->
bounds[0][i] - 2.0f ) {
332 floor_foundReach =
false;
333 floor_bestDist = 99999;
334 floor_bestLength = 0;
335 floor_bestArea2FloorEdgeNum = 0;
337 water_foundReach =
false;
338 water_bestDist = 99999;
339 water_bestLength = 0;
340 water_bestArea2FloorEdgeNum = 0;
342 for ( i = 0; i < area1->
numFaces; i++ ) {
344 faceSide1 = floorFace1Num < 0;
345 floorFace1 = &
file->
faces[abs(floorFace1Num)];
365 for ( k = 0; k < floorFace1->
numEdges; k++ ) {
367 side1 = (edge1Num < 0);
371 side1 = (side1 == faceSide1);
373 edge1Num = abs(edge1Num);
386 for ( j = 0; j < area2->
numFaces; j++ ) {
393 for ( l = 0; l < floorFace2->
numEdges; l++ ) {
400 diff = normal * v3 - dist;
401 if ( diff < -0.2f || diff > 0.2
f ) {
404 diff = normal * v4 - dist;
405 if ( diff < -0.2f || diff > 0.2f ) {
415 orthogonalDot = orthogonal * orthogonal;
423 x1 = (v1 * orthogonal) / orthogonalDot;
424 x2 = (v2 * orthogonal) / orthogonalDot;
425 x3 = (v3 * orthogonal) / orthogonalDot;
426 x4 = (v4 * orthogonal) / orthogonalDot;
429 tmp = x1; x1 =
x2; x2 = tmp;
430 tmp =
y1; y1 =
y2; y2 = tmp;
431 tmpv =
v1; v1 =
v2; v2 = tmpv;
434 tmp = x3; x3 = x4; x4 = tmp;
435 tmp = y3; y3 = y4; y4 = tmp;
436 tmpv =
v3; v3 = v4; v4 = tmpv;
439 if ( x2 <= x3 || x4 <= x1 ) {
443 if ( (x1 - 0.5f < x3 && x4 < x2 + 0.5f) && (x3 - 0.5f < x1 && x2 < x4 + 0.5f) ) {
453 if ( x1 > x3 - 0.1f && x1 < x3 + 0.1f ) {
458 else if ( x1 < x3 ) {
459 y = y1 + (x3 - x1) * (y2 - y1) / (x2 - x1);
466 y = y3 + (x1 - x3) * (y4 - y3) / (x4 - x3);
473 if ( x2 > x4 - 0.1f && x2 < x4 + 0.1f ) {
478 else if ( x2 < x4 ) {
479 y = y3 + (x2 - x3) * (y4 - y3) / (x4 - x3);
486 y = y1 + (x4 - x1) * (y2 - y1) / (x2 - x1);
495 if ( dist1 > dist2 - 1.0f && dist1 < dist2 + 1.0f ) {
497 start = ( p1area1 + p2area1 ) * 0.5f;
498 end = ( p1area2 + p2area2 ) * 0.5f;
500 else if (dist1 < dist2) {
512 length = (p2area2 - p1area2).Length();
516 if ( dist < floor_bestDist ||
519 (dist < floor_bestDist + 1.0f && length > floor_bestLength) ) {
520 floor_bestDist = dist;
521 floor_bestLength =
length;
522 floor_foundReach =
true;
523 floor_bestArea1FloorEdgeNum = edge1Num;
524 floor_bestArea2FloorEdgeNum = edge2Num;
525 floor_bestFace1 = floorFace1;
526 floor_bestStart =
start;
527 floor_bestNormal = normal;
533 if ( dist < water_bestDist ||
536 (dist < water_bestDist + 1.0f && length > water_bestLength) ) {
537 water_bestDist = dist;
538 water_bestLength =
length;
539 water_foundReach =
true;
540 water_bestArea1FloorEdgeNum = edge1Num;
541 water_bestArea2FloorEdgeNum = edge2Num;
542 water_bestFace1 = floorFace1;
543 water_bestStart =
start;
544 water_bestNormal = normal;
571 if ( floor_foundReach ) {
574 if ( floor_bestDist >= 0 && floor_bestDist < file->settings.maxStepHeight ) {
582 walkReach->
edgeNum = abs( floor_bestArea1FloorEdgeNum );
610 if ( water_foundReach ) {
612 testPoint = water_bestEnd -
INSIDEUNITS * water_bestNormal;
618 if ( water_bestDist < file->settings.maxWaterJumpHeight + 24 ) {
626 waterJumpReach->
start = water_bestStart;
628 waterJumpReach->
edgeNum = abs( floor_bestArea1FloorEdgeNum );
654 if ( floor_foundReach ) {
656 if ( floor_bestDist > 0 && floor_bestDist < file->settings.maxBarrierHeight ) {
658 if ( !water_foundReach || (floor_bestDist - water_bestDist < 16) ) {
668 barrierJumpReach->
edgeNum = abs( floor_bestArea1FloorEdgeNum );
698 if ( floor_foundReach ) {
699 if ( floor_bestDist < 0 ) {
708 walkReach->
edgeNum = abs( floor_bestArea1FloorEdgeNum );
717 start = floor_bestEnd;
718 start[2] = floor_bestStart[2];
722 trace.
maxAreas =
sizeof(areas) /
sizeof(
int);
729 for (i = 0; i < trace.
numAreas; i++) {
740 walkOffLedgeReach->
start = floor_bestStart;
741 walkOffLedgeReach->
end = floor_bestEnd;
742 walkOffLedgeReach->
edgeNum = abs( floor_bestArea1FloorEdgeNum );
761 int i,
j, faceNum, edgeNum, side, reachAreaNum,
p, areas[10];
776 for ( i = 0; i < area->
numFaces; i++ ) {
785 for ( j = 0; j < face->
numEdges; j++ ) {
805 mid = ( v1 +
v2 ) * 0.5
f;
809 trace.
maxAreas =
sizeof(areas) /
sizeof(
int);
813 if ( !reachAreaNum || reachAreaNum == areaNum ) {
826 for ( p = 0; p < trace.
numAreas; p++ ) {
841 reach->
edgeNum = abs( edgeNum );
854 int i, numReachableAreas;
856 numReachableAreas = 0;
857 for ( i = 1; i < file->
areas.Num(); i++ ) {
869 common->
Printf(
"%6d reachable areas\n", numReachableAreas );
878 int i,
j, lastPercent, percent;
891 for ( i = 1; i < file->
areas.Num(); i++ ) {
902 for ( i = 1; i < file->
areas.Num(); i++ ) {
908 for ( j = 0; j < file->
areas.Num(); j++ ) {
913 if ( !( file->
areas[j].flags & AREA_REACHABLE_WALK ) ) {
927 percent = 100 * i / file->
areas.Num();
928 if ( percent > lastPercent ) {
930 lastPercent = percent;
935 for ( i = 1; i < file->
areas.Num(); i++ ) {
virtual idVec3 FaceCenter(int faceNum) const
#define INSIDEUNITS_WALKSTART
const idAASSettings & GetSettings(void) const
const idVec3 & Normal(void) const
bool allowSwimReachabilities
bool Build(const idMapFile *mapFile, idAASFileLocal *file)
const idMapFile * mapFile
#define INSIDEUNITS_WATERJUMP
#define INSIDEUNITS_SWIMEND
#define AREA_REACHABLE_FLY
idVec3 Cross(const idVec3 &a) const
void Reachability_Swim(int areaNum)
idList< aasIndex_t > faceIndex
idList< aasIndex_t > edgeIndex
GLfloat GLfloat GLfloat v2
unsigned short travelTime
bool AreaIsClusterPortal(int areaNum)
idList< aasFace_t > faces
static float Fabs(float f)
#define INTSIGNBITNOTSET(i)
void FlagReachableAreas(idAASFileLocal *file)
bool allowFlyReachabilities
virtual idVec3 EdgeCenter(int edgeNum) const
void LinkReversedReachability(void)
#define INSIDEUNITS_WALKEND
bool Reachability_Step_Barrier_WaterJump_WalkOffLedge(int fromAreaNum, int toAreaNum)
virtual void Printf(const char *fmt,...) id_attribute((format(printf
GLdouble GLdouble GLdouble y2
#define AREACONTENTS_WATER
bool ReachabilityExists(int fromAreaNum, int toAreaNum)
void Reachability_Fly(int areaNum)
GLfloat GLfloat GLfloat GLfloat v3
void Reachability_WalkOffLedge(int areaNum)
idList< aasEdge_t > edges
idList< aasVertex_t > vertices
#define AREA_REACHABLE_WALK
virtual bool Trace(aasTrace_t &trace, const idVec3 &start, const idVec3 &end) const
#define INSIDEUNITS_FLYEND
idList< aasArea_t > areas
GLsizei const GLcharARB const GLint * length
bool CanSwimInArea(int areaNum)
void Reachability_EqualFloorHeight(int areaNum)
void AddReachabilityToArea(idReachability *reach, int areaNum)
bool AreaHasFloor(int areaNum)
void DeleteReachabilities(void)
#define AREACONTENTS_CLUSTERPORTAL