29 #include "../../idlib/precompiled.h"
32 #include "../Game_local.h"
103 d0 = plane1.
x * node->
pos.
x + plane1.
y * node->
pos.
y + plane1.
z;
108 d2 = plane2.
x * start.
x + plane2.
y * start.
y + plane2.
z;
109 d3 = plane2.
x * end.
x + plane2.
y * end.
y + plane2.
z;
128 for ( i = 0; i < numObstacles; i++ ) {
131 if ( point.
x < bounds[0].
x || point.
y < bounds[0].
y || point.
x > bounds[1].
x || point.
y > bounds[1].
y ) {
135 if ( !obstacles[i].winding.PointInside( point, 0.1f ) ) {
151 int i,
j, k,
n, bestObstacle, bestEdgeNum, queueStart, queueEnd, edgeNums[2];
152 float d, bestd,
scale[2];
156 bool *obstacleVisited;
167 if ( bestObstacle == -1 ) {
176 d = plane.
x * point.
x + plane.
y * point.
y + plane.
z;
183 if ( obstacles[bestObstacle].entity ==
NULL ) {
192 *obstacle = bestObstacle;
195 *edgeNum = bestEdgeNum;
200 queue = (
int *) _alloca( numObstacles *
sizeof( queue[0] ) );
201 obstacleVisited = (
bool *) _alloca( numObstacles *
sizeof( obstacleVisited[0] ) );
205 queue[0] = bestObstacle;
207 memset( obstacleVisited, 0, numObstacles *
sizeof( obstacleVisited[0] ) );
208 obstacleVisited[bestObstacle] =
true;
211 for ( i = queue[0]; queueStart < queueEnd; i = queue[++queueStart] ) {
215 for ( j = 0; j < numObstacles; j++ ) {
217 if ( obstacleVisited[j] ) {
221 if ( obstacles[j].bounds[0].
x > obstacles[i].bounds[1].
x || obstacles[j].bounds[0].
y > obstacles[i].bounds[1].
y ||
222 obstacles[j].bounds[1].
x < obstacles[i].bounds[0].
x || obstacles[j].bounds[1].
y < obstacles[i].bounds[0].
y ) {
226 queue[queueEnd++] =
j;
227 obstacleVisited[
j] =
true;
234 if ( !w2.
RayIntersection( w1[k], dir, scale[0], scale[1], edgeNums ) ) {
237 for ( n = 0; n < 2; n++ ) {
238 newPoint = w1[k] + scale[
n] *
dir;
240 d = ( newPoint - point ).LengthSqr();
243 bestPoint = newPoint;
244 bestEdgeNum = edgeNums[
n];
255 *obstacle = bestObstacle;
258 *edgeNum = bestEdgeNum;
273 float dist, scale1, scale2;
285 for ( i = 0; i < numObstacles; i++ ) {
286 if ( i == skipObstacle ) {
289 if ( bounds[0].
x > obstacles[i].bounds[1].
x || bounds[0].
y > obstacles[i].bounds[1].
y ||
290 bounds[1].
x < obstacles[i].bounds[0].
x || bounds[1].
y < obstacles[i].bounds[0].
y ) {
293 if ( obstacles[i].winding.RayIntersection( startPos, delta, scale1, scale2, edgeNums ) ) {
294 if ( scale1 < blockingScale && scale1 * dist > -0.01
f && scale2 * dist > 0.01
f ) {
295 blockingScale = scale1;
296 blockingObstacle =
i;
297 blockingEdgeNum = edgeNums[0];
301 return ( blockingScale < 1.0
f );
310 int i,
j, numListedClipModels, numObstacles, numVerts, clipMask, blockingObstacle, blockingEdgeNum;
311 int wallEdges[
MAX_AAS_WALL_EDGES], numWallEdges, verts[2], lastVerts[2], nextVerts[2];
312 float stepHeight, headHeight, blockingScale,
min,
max;
314 idVec2 expBounds[2], edgeDir, edgeNormal, nextEdgeDir, nextEdgeNormal, lastEdgeNormal;
324 seekDelta = seekPos - startPos;
332 clipBounds[0] = clipBounds[1] = startPos;
340 for ( i = 0; i < numListedClipModels && numObstacles <
MAX_OBSTACLES; i++ ) {
341 clipModel = clipModelList[
i];
348 if ( obEnt->
IsType( idActor::Type ) ) {
351 if ( ( obPhys == physics ) || ( obEnt == ignore ) || ( obEnt->
health <= 0 ) ) {
360 if ( v1 * v2 > 0.0
f ) {
365 }
else if ( obEnt->
IsType( idMoveable::Type ) ) {
374 if ( max < stepHeight || min > headHeight ) {
386 for ( j = 0; j < numVerts; j++ ) {
391 for ( j = 0; j < numVerts; j++ ) {
392 silVerts[
j].
z = startPos.z;
394 for ( j = 0; j < numVerts; j++ ) {
406 if ( numObstacles == 0 ) {
412 if ( !
GetFirstBlockingObstacle( obstacles, numObstacles, -1, startPos.ToVec2(), seekDelta.
ToVec2(), blockingScale, blockingObstacle, blockingEdgeNum ) ) {
419 float halfBoundsSize = ( expBounds[ 1 ].
x - expBounds[ 0 ].
x ) * 0.5
f;
424 lastVerts[0] = lastVerts[1] = 0;
425 lastEdgeNormal.
Zero();
426 nextVerts[0] = nextVerts[1] = 0;
427 for ( i = 0; i < numWallEdges && numObstacles <
MAX_OBSTACLES; i++ ) {
428 aas->
GetEdge( wallEdges[i], start, end );
432 edgeNormal.
x = edgeDir.
y;
433 edgeNormal.
y = -edgeDir.
x;
434 if ( i < numWallEdges-1 ) {
435 aas->
GetEdge( wallEdges[i+1], nextStart, nextEnd );
439 nextEdgeNormal.
x = nextEdgeDir.
y;
440 nextEdgeNormal.
y = -nextEdgeDir.
x;
449 if ( lastVerts[1] == verts[0] ) {
450 obstacle.
winding[2] -= lastEdgeNormal * halfBoundsSize;
452 obstacle.
winding[1] -= edgeDir;
454 if ( verts[1] == nextVerts[0] ) {
455 obstacle.
winding[3] -= nextEdgeNormal * halfBoundsSize;
457 obstacle.
winding[0] += edgeDir;
462 memcpy( lastVerts, verts,
sizeof( lastVerts ) );
463 lastEdgeNormal = edgeNormal;
469 for ( i = 0; i < numObstacles; i++ ) {
473 silVerts[
j].
z = startPos.z;
496 pathNodeAllocator.
Free( node );
509 for ( node = root; node; node = node->
next ) {
510 for ( i = 0; i < 2; i++ ) {
538 edgeNum = ( node->
edgeNum + node->
dir ) % numPoints;
543 node->
edgeNum = ( node->
edgeNum + numPoints + ( 2 * node->
dir - 1 ) ) % numPoints;
550 seekDelta = seekPos - node->
pos;
551 facing = ( ( 2 * node->
dir - 1 ) * ( node->
delta.
x * seekDelta.
y - node->
delta.
y * seekDelta.
x ) ) >= 0.0
f;
593 int blockingEdgeNum, blockingObstacle, obstaclePoints, bestNumNodes =
MAX_OBSTACLE_PATH;
599 root = pathNodeAllocator.
Alloc();
601 root->
pos = startPos;
605 pathNodeQueue.
Add( root );
609 treeQueue.
Add( node );
612 if ( node->
numNodes > bestNumNodes * 2 ) {
630 node->
delta *= blockingScale;
657 child->
edgeNum = blockingEdgeNum;
660 pathNodeQueue.
Add( child );
673 if ( node->
numNodes < bestNumNodes ) {
681 child->
edgeNum = ( node->
edgeNum + obstaclePoints + ( 2 * node->
dir - 1 ) ) % obstaclePoints;
684 pathNodeQueue.
Add( child );
705 node->
dist = ( seekPos - node->
pos ).LengthSqr();
716 for ( n = node;
n; n = n->
parent ) {
720 if ( n->
dist < bestDist ) {
727 for ( i = 0; i < 2; i++ ) {
734 for ( lastNode = bestNode, node = bestNode->
parent; node; lastNode = node, node = node->
parent ) {
750 int i, numPathPoints, edgeNums[2];
752 idVec2 curPos, curDelta, bounds[2];
753 float scale1, scale2, curLength;
755 optimizedPath[0] = root->
pos;
758 for ( nextNode = curNode = root; curNode != leafNode; curNode = nextNode ) {
760 for ( nextNode = leafNode; nextNode->
parent != curNode; nextNode = nextNode->
parent ) {
767 curPos = curNode->
pos;
768 curDelta = nextNode->
pos - curPos;
769 curLength = curDelta.
Length();
778 for ( i = 0; i < numObstacles; i++ ) {
779 if ( bounds[0].
x > obstacles[i].bounds[1].
x || bounds[0].
y > obstacles[i].bounds[1].
y ||
780 bounds[1].
x < obstacles[i].bounds[0].
x || bounds[1].
y < obstacles[i].bounds[0].
y ) {
783 if ( obstacles[i].winding.RayIntersection( curPos, curDelta, scale1, scale2, edgeNums ) ) {
784 if ( scale1 >= 0.0
f && scale1 <= 1.0
f && ( i != nextNode->
obstacle || scale1 * curLength < curLength - 0.5f ) ) {
787 if ( scale2 >= 0.0
f && scale2 <= 1.0
f && ( i != nextNode->
obstacle || scale2 * curLength < curLength - 0.5f ) ) {
792 if ( i >= numObstacles ) {
798 optimizedPath[numPathPoints++] = nextNode->
pos;
801 return numPathPoints;
815 for ( i = 0; i < numPathPoints-1; i++ ) {
816 pathLength += ( optimizedPath[i+1] - optimizedPath[
i] ).LengthFast();
820 if ( curDir * ( optimizedPath[1] - optimizedPath[0] ) < 0.0f ) {
821 pathLength += 100.0f;
834 int i, numPathPoints, bestNumPathPoints;
837 float pathLength, bestPathLength;
838 bool pathToGoalExists, optimizedPathCalculated;
843 pathToGoalExists =
false;
844 optimizedPathCalculated =
false;
847 bestNumPathPoints = 0;
853 pathToGoalExists |= ( node->
dist < 0.1f );
855 if ( node->
dist <= bestNode->
dist ) {
859 if ( !optimizedPathCalculated ) {
860 bestNumPathPoints =
OptimizePath( root, bestNode, obstacles, numObstacles, optimizedPath );
861 bestPathLength =
PathLength( optimizedPath, bestNumPathPoints, curDir.
ToVec2() );
862 seekPos.
ToVec2() = optimizedPath[1];
865 numPathPoints =
OptimizePath( root, node, obstacles, numObstacles, optimizedPath );
868 if ( pathLength < bestPathLength ) {
870 bestNumPathPoints = numPathPoints;
871 bestPathLength = pathLength;
872 seekPos.
ToVec2() = optimizedPath[1];
874 optimizedPathCalculated =
true;
879 optimizedPathCalculated =
false;
888 for ( lastNode = node, node = node->
parent; node; lastNode = node, node = node->
parent ) {
897 if ( !pathToGoalExists ) {
899 }
else if ( !optimizedPathCalculated ) {
900 OptimizePath( root, bestNode, obstacles, numObstacles, optimizedPath );
901 seekPos.
ToVec2() = optimizedPath[1];
906 start.
z = end.
z = height + 4.0f;
907 numPathPoints =
OptimizePath( root, bestNode, obstacles, numObstacles, optimizedPath );
908 for ( i = 0; i < numPathPoints-1; i++ ) {
909 start.
ToVec2() = optimizedPath[
i];
910 end.
ToVec2() = optimizedPath[i+1];
915 return pathToGoalExists;
926 int numObstacles, areaNum, insideObstacle;
931 bool pathToGoalExists;
945 bounds[0] = -bounds[1];
957 if ( insideObstacle != -1 ) {
963 if ( insideObstacle != -1 ) {
991 return pathToGoalExists;
1036 memset( &trace, 0,
sizeof( trace ) );
1058 aas->
Trace( aasTrace, start, end );
1063 if ( clipTrace.
fraction >= 1.0f ) {
1071 if ( stopEvent & SE_ENTER_LEDGE_AREA ) {
1084 if ( stopEvent & SE_ENTER_OBSTACLE ) {
1121 int i,
j, step, numFrames, curFrameTime;
1122 idVec3 delta, curStart, curEnd, curVelocity, lastEnd, stepUp, tmpStart;
1123 idVec3 gravity, gravityDir, invGravityDir;
1124 float maxStepHeight, minFloorCos;
1135 gravityDir =
idVec3( 0, 0, -1 );
1136 invGravityDir =
idVec3( 0, 0, 1 );
1137 maxStepHeight = 14.0f;
1149 curVelocity = velocity;
1151 numFrames = ( totalTime + frameTime - 1 ) / frameTime;
1152 curFrameTime = frameTime;
1153 for ( i = 0; i < numFrames; i++ ) {
1155 if ( i == numFrames-1 ) {
1156 curFrameTime = totalTime - i * curFrameTime;
1159 delta = curVelocity * curFrameTime * 0.001f;
1167 idVec3 lineStart = curStart;
1170 for ( step = 0; step < 3; step++ ) {
1172 curEnd = curStart + delta;
1173 if (
PathTrace( ent, aas, curStart, curEnd, stopEvent, trace, path ) ) {
1181 curEnd = tmpStart - stepUp;
1182 if (
PathTrace( ent, aas, tmpStart, curEnd, stopEvent, trace, path ) ) {
1187 if ( (lastEnd - start).LengthSqr() > (trace.
endPos -
start).LengthSqr() - 0.1f ||
1188 ( trace.
normal * invGravityDir ) < minFloorCos ) {
1209 if ( trace.
fraction >= 1.0f || ( trace.
normal * invGravityDir ) > minFloorCos ) {
1218 stepUp = invGravityDir * maxStepHeight;
1219 if (
PathTrace( ent, aas, curStart, curStart + stepUp, stopEvent, trace, path ) ) {
1239 if ( (curVelocity - gravityDir * curVelocity * gravityDir ) *
1240 (velocity - gravityDir * velocity * gravityDir) < 0.0
f ) {
1249 if ( j >= MAX_FRAME_SLIDE ) {
1258 curVelocity += gravity * frameTime * 0.001f;
1296 float x,
y,
a,
b,
c, d, sqrtd, inva,
p[2];
1299 y = end[2] - start[2];
1301 a = 4.0f * y * y + 4.0f * x *
x;
1302 b = -4.0f * speed * speed - 4.0f * y * gravity;
1303 c = gravity * gravity;
1305 d = b * b - 4.0f * a *
c;
1306 if ( d <= 0.0
f || a == 0.0
f ) {
1311 p[0] = ( - b + sqrtd ) * inva;
1312 p[1] = ( - b - sqrtd ) * inva;
1314 for ( i = 0; i < 2; i++ ) {
1315 if ( p[i] <= 0.0
f ) {
1319 bal[
n].
angle = atan2( 0.5
f * ( 2.0
f * y * p[i] - gravity ) / d, d * x );
1320 bal[
n].
time = x / ( cos( bal[n].angle ) * speed );
1335 static float HeightForTrajectory(
const idVec3 &start,
float zVel,
float gravity ) {
1340 maxHeight = start.
z - 0.5f * gravity * ( t *
t );
1350 bool idAI::TestTrajectory(
const idVec3 &start,
const idVec3 &end,
float zVel,
float gravity,
float time,
float max_height,
const idClipModel *clip,
int clipmask,
const idEntity *ignore,
const idEntity *targetEntity,
int drawtime ) {
1352 float maxHeight,
t, t2;
1359 maxHeight = start.
z - 0.5f * gravity * ( t *
t );
1361 t =
idMath::Sqrt( ( maxHeight - end.
z ) / ( 0.5f * -gravity ) );
1369 t2 = ( time -
t ) * 0.5
f;
1371 points[1].
z = start.
z + t2 * zVel + 0.5f * gravity * t2 * t2;
1375 points[2].
z = start.
z + t2 * zVel + 0.5f * gravity * t2 * t2;
1377 t2 = time - t * 0.5f;
1379 points[3].
z = start.
z + t2 * zVel + 0.5f * gravity * t2 * t2;
1385 points[1].
z = start.
z + t2 * zVel + 0.5f * gravity * t2 * t2;
1389 points[numSegments] =
end;
1392 for ( i = 0; i < numSegments; i++ ) {
1398 for ( i = 0; i < numSegments; i++ ) {
1399 if ( points[i].
z > max_height ) {
1406 for ( i = 0; i < numSegments; i++ ) {
1439 bool idAI::PredictTrajectory(
const idVec3 &firePos,
const idVec3 &target,
float projectileSpeed,
const idVec3 &projGravity,
const idClipModel *clip,
int clipmask,
float max_height,
const idEntity *ignore,
const idEntity *targetEntity,
int drawtime,
idVec3 &aimDir ) {
1441 float zVel,
a,
t, pitch,
s,
c;
1452 aimDir = target - firePos;
1458 if ( projectileSpeed <= 0.0
f || projGravity ==
vec3_origin ) {
1460 aimDir = target - firePos;
1475 n = Ballistics( firePos, target, projectileSpeed, projGravity[2], ballistics );
1478 aimDir = target - firePos;
1485 if ( ballistics[1].angle < ballistics[0].angle ) {
1487 t = ballistics[0].
time; ballistics[0].
time = ballistics[1].
time; ballistics[1].
time =
t;
1492 for ( i = 0; i <
n; i++ ) {
1493 pitch =
DEG2RAD( ballistics[i].angle );
1495 dir[
i] = target - firePos;
1500 zVel = projectileSpeed * dir[
i].
z;
1503 t = ballistics[
i].
time / 100.0f;
1507 for ( j = 1; j < 100; j++ ) {
1508 pos += velocity *
t;
1509 velocity += projGravity *
t;
1515 if (
TestTrajectory( firePos, target, zVel, projGravity[2], ballistics[i].time, firePos.z + max_height, clip, clipmask, ignore, targetEntity, drawtime ) ) {
virtual const idVec3 & GetOrigin(int id=0) const =0
int ClipModelsTouchingBounds(const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount) const
idEntity * GetEntity(void) const
int GetObstacles(const idPhysics *physics, const idAAS *aas, const idEntity *ignore, int areaNum, const idVec3 &startPos, const idVec3 &seekPos, obstacle_t *obstacles, int maxObstacles, idBounds &clipBounds)
GLsizei const GLfloat * points
static const float INFINITY
assert(prefInfo.fullscreenBtn)
void DrawPathTree(const pathNode_t *root, const float height)
virtual const idVec3 & GetGravityNormal(void) const =0
const idVec3 & Normal(void) const
idMat3 mat3_identity(idVec3(1, 0, 0), idVec3(0, 1, 0), idVec3(0, 0, 1))
virtual int GetClipMask(int id=-1) const =0
bool FindOptimalPath(const pathNode_t *root, const obstacle_t *obstacles, int numObstacles, const float height, const idVec3 &curDir, idVec3 &seekPos)
virtual void DebugArrow(const idVec4 &color, const idVec3 &start, const idVec3 &end, int size, const int lifetime=0)=0
void Expand(const float d)
struct ballistics_s ballistics_t
const int MAX_FRAME_SLIDE
bool GetPathNodeDelta(pathNode_t *node, const obstacle_t *obstacles, const idVec2 &seekPos, bool blocked)
idEntity * startPosObstacle
idCVar ai_showObstacleAvoidance("ai_showObstacleAvoidance","0", CVAR_GAME|CVAR_INTEGER,"draws obstacle avoidance information for monsters. if 2, draws obstacles for player, as well", 0, 2, idCmdSystem::ArgCompletion_Integer< 0, 2 >)
GLenum GLenum GLenum GLenum GLenum scale
bool IsType(const idTypeInfo &c) const
struct pathNode_s * children[2]
const float CLIP_BOUNDS_EPSILON
const idMat3 & GetAxis(void) const
bool PathTrace(const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &end, int stopEvent, struct pathTrace_s &trace, predictedPath_t &path)
const int MAX_AAS_WALL_EDGES
idBlockAlloc< pathNode_t, 128 > pathNodeAllocator
idEntity * seekPosObstacle
virtual const idVec3 & GetLinearVelocity(int id=0) const =0
static float Sqrt(float x)
static bool TestTrajectory(const idVec3 &start, const idVec3 &end, float zVel, float gravity, float time, float max_height, const idClipModel *clip, int clipmask, const idEntity *ignore, const idEntity *targetEntity, int drawtime)
static bool FindPathAroundObstacles(const idPhysics *physics, const idAAS *aas, const idEntity *ignore, const idVec3 &startPos, const idVec3 &seekPos, obstaclePath_t &path)
static bool PredictPath(const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &velocity, int totalTime, int frameTime, int stopEvent, predictedPath_t &path)
const idVec3 & GetOrigin(void) const
virtual int AreaFlags(int areaNum) const =0
virtual int PointReachableAreaNum(const idVec3 &origin, const idBounds &bounds, const int areaFlags) const =0
#define AREA_REACHABLE_FLY
idCVar ai_debugTrajectory("ai_debugTrajectory","0", CVAR_GAME|CVAR_BOOL,"draws trajectory tests for monsters")
virtual int GetWallEdges(int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges) const =0
idBounds boundingBoxes[MAX_AAS_BOUNDING_BOXES]
#define MASK_MONSTERSOLID
static void SinCos(float a, float &s, float &c)
const idVec2 & ToVec2(void) const
struct pathNode_s pathNode_t
void void void Warning(const char *fmt,...) const id_attribute((format(printf
virtual const idBounds & GetBounds(int id=-1) const =0
pathNode_t * BuildPathTree(const obstacle_t *obstacles, int numObstacles, const idBounds &clipBounds, const idVec2 &startPos, const idVec2 &seekPos, obstaclePath_t &path)
virtual void GetEdge(int edgeNum, idVec3 &start, idVec3 &end) const =0
bool AddPoint(const idVec3 &v)
GLfloat GLfloat GLfloat v2
idBounds Translate(const idVec3 &translation) const
idVec3 seekPosOutsideObstacles
void FreePathTree_r(pathNode_t *node)
#define FLOATSIGNBITSET(f)
idPhysics * GetPhysics(void) const
virtual void DebugLine(const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifetime=0, const bool depthTest=false)=0
GLubyte GLubyte GLubyte GLubyte w
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
int GetParallelProjectionSilhouetteVerts(const idVec3 &projectionDir, idVec3 silVerts[6]) const
const idVec3 DEFAULT_GRAVITY_VEC3(0, 0,-DEFAULT_GRAVITY)
static float Fabs(float f)
int PointInsideObstacle(const obstacle_t *obstacles, const int numObstacles, const idVec2 &point)
virtual int AreaTravelFlags(int areaNum) const =0
const idBounds & GetBounds(void) const
float PathLength(idVec2 optimizedPath[MAX_OBSTACLE_PATH], int numPathPoints, const idVec2 &curDir)
const idEntity * blockingEntity
bool IsTraceModel(void) const
virtual bool Trace(aasTrace_t &trace, const idVec3 &start, const idVec3 &end) const =0
static idVec3 Plane2DFromPoints(const idVec2 &start, const idVec2 &end, const bool normalize=false)
const idEntity * blockingEntity
void ExpandForAxialBox(const idVec2 bounds[2])
int GetNumPoints(void) const
const float PUSH_OUTSIDE_OBSTACLES
struct obstacle_s obstacle_t
struct pathTrace_s pathTrace_t
int GetAllocCount(void) const
void PrunePathTree(pathNode_t *root, const idVec2 &seekPos)
static float InvSqrt(float x)
float LengthSqr(void) const
GLubyte GLubyte GLubyte a
int OptimizePath(const pathNode_t *root, const pathNode_t *leafNode, const obstacle_t *obstacles, int numObstacles, idVec2 optimizedPath[MAX_OBSTACLE_PATH])
idBounds Expand(const float d) const
virtual idClipModel * GetClipModel(int id=0) const =0
GLenum GLsizei GLsizei height
bool LineIntersectsPath(const idVec2 &start, const idVec2 &end, const pathNode_t *node)
bool RayIntersection(const idVec2 &start, const idVec2 &dir, float &scale1, float &scale2, int *edgeNums=NULL) const
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
idEntity * entities[MAX_GENTITIES]
idEntity * GetTraceEntity(const trace_t &trace) const
virtual const idPlane & GetPlane(int planeNum) const =0
virtual void GetEdgeVertexNumbers(int edgeNum, int verts[2]) const =0
void ProjectOntoPlane(const idVec3 &normal, const float overBounce=1.0f)
static bool PredictTrajectory(const idVec3 &firePos, const idVec3 &target, float projectileSpeed, const idVec3 &projGravity, const idClipModel *clip, int clipmask, float max_height, const idEntity *ignore, const idEntity *targetEntity, int drawtime, idVec3 &aimDir)
void GetBounds(idVec2 bounds[2]) const
idVec3 startPosOutsideObstacles
struct pathNode_s * parent
#define FLOATSIGNBITNOTSET(f)
virtual void SortWallEdges(int *edges, int numEdges) const =0
#define AREA_REACHABLE_WALK
virtual const idAASSettings * GetSettings(void) const =0
bool IntersectsBounds(const idBounds &a) const
static void FreeObstacleAvoidanceNodes(void)
virtual const idBounds & GetAbsBounds(int id=-1) const =0
idCVar ai_debugMove("ai_debugMove","0", CVAR_GAME|CVAR_BOOL,"draws movement information for monsters")
static float AngleNormalize180(float angle)
void GetPointOutsideObstacles(const obstacle_t *obstacles, const int numObstacles, idVec2 &point, int *obstacle, int *edgeNum)
const int MAX_OBSTACLE_PATH
bool GetFirstBlockingObstacle(const obstacle_t *obstacles, int numObstacles, int skipObstacle, const idVec2 &startPos, const idVec2 &delta, float &blockingScale, int &blockingObstacle, int &blockingEdgeNum)
void AddPoint(const idVec2 &point)
void AxisProjection(const idVec3 &dir, float &min, float &max) const
void TranslationEntities(trace_t &results, const idVec3 &start, const idVec3 &end, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity)
const idBounds & GetAbsBounds(void) const
idBounds & ExpandSelf(const float d)
virtual void PushPointIntoAreaNum(int areaNum, idVec3 &origin) const =0
virtual void DebugBounds(const idVec4 &color, const idBounds &bounds, const idVec3 &org=vec3_origin, const int lifetime=0)=0
idRenderWorld * gameRenderWorld
bool Translation(trace_t &results, const idVec3 &start, const idVec3 &end, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity)
const float MAX_OBSTACLE_RADIUS
float LengthSqr(void) const
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1