mirror of
https://github.com/tribes2/engine.git
synced 2026-01-20 03:34:48 +00:00
118 lines
3.4 KiB
C++
118 lines
3.4 KiB
C++
//-----------------------------------------------------------------------------
|
|
// V12 Engine
|
|
//
|
|
// Copyright (c) 2001 GarageGames.Com
|
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "ai/graph.h"
|
|
|
|
static void cantFind(const Point3F& P)
|
|
{
|
|
Con::printf("Can't find node near (%f %f %f)", P.x, P.y, P.z);
|
|
}
|
|
|
|
// See if the given player can get from point A to point B.
|
|
bool NavigationGraph::testPlayerCanReach(Point3F A, Point3F B, const F32* ratings)
|
|
{
|
|
Vector<S32> indexList;
|
|
bool success = false;
|
|
GraphSearch * searcher = getMainSearcher();
|
|
|
|
if (GraphNode * src = closestNode(A))
|
|
{
|
|
if (GraphNode * dst = closestNode(B))
|
|
{
|
|
searcher->setAStar(true);
|
|
searcher->performSearch(src, dst);
|
|
searcher->setRatings(ratings);
|
|
success = searcher->getPathIndices(indexList);
|
|
}
|
|
else
|
|
cantFind(B);
|
|
}
|
|
else
|
|
cantFind(A);
|
|
|
|
return success;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
F32 NavigationGraph::performTests(S32 count, bool enableAStar)
|
|
{
|
|
// Seed off count - so test happens same for same count.
|
|
MRandomR250 rand(count);
|
|
S64 dijkstraIters = 0;
|
|
S64 relaxCount = 0;
|
|
U32 numSearchesDone = 0;
|
|
Vector<S32> indexList;
|
|
|
|
// Get our searcher-
|
|
GraphSearch * searcher = getMainSearcher();
|
|
|
|
// Perform random path searches. numNodes() ignores transients.
|
|
while (--count >= 0)
|
|
{
|
|
if (GraphNode * src = mNodeList[(rand.randI()&0xFFFFFFF) % numNodes()])
|
|
{
|
|
if (GraphNode * dst = mNodeList[(rand.randI()&0xFFFFFFF) % numNodes()])
|
|
{
|
|
numSearchesDone++;
|
|
searcher->setAStar(enableAStar);
|
|
dijkstraIters += searcher->performSearch(src, dst);
|
|
relaxCount += searcher->relaxCount();
|
|
searcher->getPathIndices(indexList);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (numSearchesDone)
|
|
{
|
|
if (relaxCount)
|
|
{
|
|
F64 relaxAverage = F64(relaxCount) / F64(numSearchesDone);
|
|
Con::printf("Average edge relaxations = %f", F32(relaxAverage));
|
|
}
|
|
return F32(F64(dijkstraIters) / F64(numSearchesDone));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
// Flag (for render) those nodes having LOS from the given closest point. We check
|
|
// in and out radii, and the condition is what we compare to. Used for testing.
|
|
void NavigationGraph::markNodesInSight(const Point3F& from, F32 in, F32 out, U32 cond)
|
|
{
|
|
if (!validLOSXref())
|
|
{
|
|
warning("markNodesInSight() called without valid XRef table");
|
|
return;
|
|
}
|
|
|
|
if (GraphNode * src = closestNode(from))
|
|
{
|
|
S32 srcInd = src->getIndex();
|
|
for (S32 i = 0; i < mNonTransient.size(); i++)
|
|
{
|
|
GraphNode * cur = mNonTransient[i];
|
|
F32 dist = (from - cur->location()).len();
|
|
S32 curInd = cur->getIndex();
|
|
bool markIt = false;
|
|
|
|
if (dist > in && dist < out && curInd != srcInd)
|
|
markIt = (mLOSTable->value(srcInd, curInd) == cond);
|
|
|
|
if (markIt)
|
|
cur->set(GraphNode::Render0);
|
|
else
|
|
cur->clear(GraphNode::Render0);
|
|
}
|
|
}
|
|
else
|
|
warning("markNodesInSight() couldn't find closest node");
|
|
}
|
|
|