Replace beam search with breadth-first search
parent
3405c038c9
commit
d9f3078396
|
@ -49,9 +49,10 @@ const float FLY_DEF_HEIGHT = 50.0f; // default flying height
|
||||||
// Settings that define goto() accuracy:
|
// Settings that define goto() accuracy:
|
||||||
const float BM_DIM_STEP = 5.0f; // Size of one pixel on the bitmap. Setting 5 means that 5x5 square (in game units) will be represented by 1 px on the bitmap. Decreasing this value will make a bigger bitmap, and may increase accuracy. TODO: Check how it actually impacts goto() accuracy
|
const float BM_DIM_STEP = 5.0f; // Size of one pixel on the bitmap. Setting 5 means that 5x5 square (in game units) will be represented by 1 px on the bitmap. Decreasing this value will make a bigger bitmap, and may increase accuracy. TODO: Check how it actually impacts goto() accuracy
|
||||||
const float BEAM_ACCURACY = 5.0f; // higher value = more accurate, but slower
|
const float BEAM_ACCURACY = 5.0f; // higher value = more accurate, but slower
|
||||||
const float SAFETY_MARGIN = 0.5f; // Smallest distance between two objects. Smaller = less "no route to destination", but higher probability of collisions between objects.
|
const float SAFETY_MARGIN = 1.5f; // Smallest distance between two objects. Smaller = less "no route to destination", but higher probability of collisions between objects.
|
||||||
// Changing SAFETY_MARGIN (old value was 4.0f) seems to have fixed many issues with goto(). TODO: maybe we could make it even smaller? Did changing it introduce any new bugs?
|
// Changing SAFETY_MARGIN (old value was 4.0f) seems to have fixed many issues with goto(). TODO: maybe we could make it even smaller? Did changing it introduce any new bugs?
|
||||||
|
|
||||||
|
const int NB_ITER = 2000; // Maximum number of iterations you have the right to make before temporarily interrupt in order not to lower the framerate.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,7 +127,7 @@ bool CTaskGoto::EventProcess(const Event &event)
|
||||||
if (a || b)
|
if (a || b)
|
||||||
{
|
{
|
||||||
Gfx::Color c = Gfx::Color(0.0f, 0.0f, 0.0f, 1.0f);
|
Gfx::Color c = Gfx::Color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
if (b) c = Gfx::Color(0.0f, 0.0f, 1.0f, 1.0f);
|
if (b) c = Gfx::Color(0.0f, 1.0f, 1.0f, 1.0f);
|
||||||
debugImage->SetPixel(Math::IntPoint(x, y), c);
|
debugImage->SetPixel(Math::IntPoint(x, y), c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1688,6 +1689,8 @@ void CTaskGoto::BeamInit()
|
||||||
m_bmIter[i] = -1;
|
m_bmIter[i] = -1;
|
||||||
}
|
}
|
||||||
m_bmStep = 0;
|
m_bmStep = 0;
|
||||||
|
m_bfsQueueBegin = 0;
|
||||||
|
m_bfsQueueEnd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates points and passes to go from start to goal.
|
// Calculates points and passes to go from start to goal.
|
||||||
|
@ -1701,138 +1704,166 @@ void CTaskGoto::BeamInit()
|
||||||
Error CTaskGoto::BeamSearch(const Math::Vector &start, const Math::Vector &goal,
|
Error CTaskGoto::BeamSearch(const Math::Vector &start, const Math::Vector &goal,
|
||||||
float goalRadius)
|
float goalRadius)
|
||||||
{
|
{
|
||||||
float step, len;
|
|
||||||
int nbIter;
|
|
||||||
|
|
||||||
m_bmStep ++;
|
m_bmStep ++;
|
||||||
|
|
||||||
len = Math::DistanceProjected(start, goal);
|
// Relative postion and distance to neighbors.
|
||||||
step = len/BEAM_ACCURACY;
|
static const int dXs[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
|
||||||
if ( step < BM_DIM_STEP*2.1f ) step = BM_DIM_STEP*2.1f;
|
static const int dYs[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
|
||||||
if ( step > 20.0f ) step = 20.0f;
|
// static const float dDist[8] = {M_SQRT2, 1.0f, M_SQRT2, 1.0f, 1.0f, M_SQRT2, 1.0f, M_SQRT2};
|
||||||
nbIter = 200; // in order not to lower the framerate
|
static const int32_t dDist[8] = {7, 5, 7, 5, 5, 7, 5, 7};
|
||||||
m_bmIterCounter = 0;
|
|
||||||
return BeamExplore(start, start, goal, goalRadius, 165.0f*Math::PI/180.0f, 22, step, 0, nbIter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// prevPos: previous position
|
const int startX = static_cast<int>((start.x+1600.0f)/BM_DIM_STEP);
|
||||||
// curPos: current position
|
const int startY = static_cast<int>((start.z+1600.0f)/BM_DIM_STEP);
|
||||||
// goalPos: position that seeks to achieve
|
const int goalX = static_cast<int>((goal.x+1600.0f)/BM_DIM_STEP);
|
||||||
// angle: angle to the goal we explores
|
const int goalY = static_cast<int>((goal.z+1600.0f)/BM_DIM_STEP);
|
||||||
// nbDiv: number of subdivisions being done with angle
|
|
||||||
// step length of a step
|
|
||||||
// i number of recursions made
|
|
||||||
// nbIter maximum number of iterations you have the right to make before temporarily interrupt
|
|
||||||
|
|
||||||
Error CTaskGoto::BeamExplore(const Math::Vector &prevPos, const Math::Vector &curPos,
|
if (m_bfsQueueEnd == 0) // New search
|
||||||
const Math::Vector &goalPos, float goalRadius,
|
|
||||||
float angle, int nbDiv, float step,
|
|
||||||
int i, int nbIter)
|
|
||||||
{
|
|
||||||
Math::Vector newPos;
|
|
||||||
Error ret;
|
|
||||||
int iDiv, iClear, iLar;
|
|
||||||
|
|
||||||
iLar = 0;
|
|
||||||
if ( i >= MAXPOINTS ) return ERR_GOTO_ITER; // too many recursions
|
|
||||||
|
|
||||||
m_bmTotal = i;
|
|
||||||
|
|
||||||
if ( m_bmIter[i] == -1 )
|
|
||||||
{
|
{
|
||||||
m_bmIter[i] = 0;
|
if (startX == goalX && startY == goalY)
|
||||||
|
|
||||||
if ( i == 0 )
|
|
||||||
{
|
{
|
||||||
m_bmPoints[i] = curPos;
|
m_bmPoints[0] = start;
|
||||||
|
m_bmPoints[1] = goal;
|
||||||
|
m_bmTotal = 1;
|
||||||
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
else
|
// Enqueue the goal node
|
||||||
|
if ( goalX >= 0 && goalX < m_bmSize &&
|
||||||
|
goalY >= 0 && goalY < m_bmSize )
|
||||||
{
|
{
|
||||||
if ( !BitmapTestLine(prevPos, curPos, angle/nbDiv, true) ) return ERR_GOTO_IMPOSSIBLE;
|
const int indexInMap = goalY * m_bmSize + goalX;
|
||||||
|
m_bfsDistances[indexInMap] = 0.0;
|
||||||
|
m_bfsQueue[m_bfsQueueEnd++] = indexInMap;
|
||||||
|
BitmapSetDot(1, goalX, goalY); // Mark as enqueued
|
||||||
|
}
|
||||||
|
|
||||||
m_bmPoints[i] = curPos;
|
// Enqueue nodes around the goal
|
||||||
|
if (goalRadius > 0.0f)
|
||||||
if ( Math::DistanceProjected(curPos, goalPos)-goalRadius <= step )
|
{
|
||||||
|
const int minX = std::max(0, static_cast<int>((goal.x-goalRadius+1600.0f)/BM_DIM_STEP));
|
||||||
|
const int minY = std::max(0, static_cast<int>((goal.z-goalRadius+1600.0f)/BM_DIM_STEP));
|
||||||
|
const int maxX = std::min(m_bmSize-1, static_cast<int>((goal.x+goalRadius+1600.0f)/BM_DIM_STEP));
|
||||||
|
const int maxY = std::min(m_bmSize-1, static_cast<int>((goal.z+goalRadius+1600.0f)/BM_DIM_STEP));
|
||||||
|
for (int y = minY; y <= maxY; ++y)
|
||||||
{
|
{
|
||||||
if ( goalRadius == 0.0f )
|
for (int x = minX; x <= maxX; ++x)
|
||||||
{
|
{
|
||||||
newPos = goalPos;
|
float floatX = (x + 0.5f) * BM_DIM_STEP - 1600.0f;
|
||||||
}
|
float floatY = (y + 0.5f) * BM_DIM_STEP - 1600.0f;
|
||||||
else
|
if (std::hypot(floatX-goal.x, floatY-goal.z) <= goalRadius &&
|
||||||
{
|
BitmapTestDotIsVisitable(x, y) &&
|
||||||
newPos = BeamPoint(curPos, goalPos, 0, Math::DistanceProjected(curPos, goalPos)-goalRadius);
|
!BitmapTestDot(1, x, y))
|
||||||
}
|
{
|
||||||
if ( BitmapTestLine(curPos, newPos, angle/nbDiv, false) )
|
const int indexInMap = y * m_bmSize + x;
|
||||||
{
|
m_bfsDistances[indexInMap] = 0.0;
|
||||||
m_bmPoints[i+1] = newPos;
|
m_bfsQueue[m_bfsQueueEnd++] = indexInMap;
|
||||||
m_bmTotal = i+1;
|
BitmapSetDot(1, x, y); // Mark as enqueued
|
||||||
return ERR_OK;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( iLar >= m_bmIter[i] )
|
m_bmIterCounter = 0;
|
||||||
|
|
||||||
|
while (m_bfsQueueBegin != m_bfsQueueEnd)
|
||||||
{
|
{
|
||||||
newPos = BeamPoint(curPos, goalPos, 0, step);
|
// Pop a node from the queue
|
||||||
ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter);
|
const uint32_t indexInMap = m_bfsQueue[m_bfsQueueBegin++];
|
||||||
if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret;
|
const int x = indexInMap % m_bmSize;
|
||||||
m_bmIter[i] = iLar+1;
|
const int y = indexInMap / m_bmSize;
|
||||||
for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1;
|
const int32_t distance = m_bfsDistances[indexInMap];
|
||||||
|
|
||||||
|
if (x == startX && y == startY)
|
||||||
|
{
|
||||||
|
// We have reached the start.
|
||||||
|
// Follow decreasing distances to find the path.
|
||||||
|
m_bmPoints[0] = start;
|
||||||
|
int btX = x;
|
||||||
|
int btY = y;
|
||||||
|
for (m_bmTotal = 1; m_bmTotal < MAXPOINTS; ++m_bmTotal)
|
||||||
|
{
|
||||||
|
int bestX = -1;
|
||||||
|
int bestY = -1;
|
||||||
|
int32_t bestDistance = std::numeric_limits<int32_t>::max();
|
||||||
|
for (int i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
const int nX = btX + dXs[i];
|
||||||
|
const int nY = btY + dYs[i];
|
||||||
|
if (!BitmapTestDot(1, nX, nY)) continue;
|
||||||
|
const int32_t nDistance = m_bfsDistances[nY * m_bmSize + nX];
|
||||||
|
if (nDistance < bestDistance)
|
||||||
|
{
|
||||||
|
bestX = nX;
|
||||||
|
bestY = nY;
|
||||||
|
bestDistance = nDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestX == -1)
|
||||||
|
{
|
||||||
|
GetLogger()->Error("Failed to find node parent\n");
|
||||||
|
return ERR_GOTO_ITER;
|
||||||
|
}
|
||||||
|
btX = bestX;
|
||||||
|
btY = bestY;
|
||||||
|
if (btX == goalX && btY == goalY)
|
||||||
|
{
|
||||||
|
m_bmPoints[m_bmTotal] = goal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_bmPoints[m_bmTotal].x = (btX + 0.5f) * BM_DIM_STEP - 1600.f;
|
||||||
|
m_bmPoints[m_bmTotal].z = (btY + 0.5f) * BM_DIM_STEP - 1600.f;
|
||||||
|
|
||||||
|
if (bestDistance == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// std::reverse(m_bmPoints, m_bmPoints + m_bmTotal);
|
||||||
|
|
||||||
|
GetLogger()->Info("Found path to goal with %d nodes\n", m_bmTotal + 1);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand the node
|
||||||
|
for (int i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
const int nX = x + dXs[i];
|
||||||
|
const int nY = y + dYs[i];
|
||||||
|
if (BitmapTestDotIsVisitable(nX, nY))
|
||||||
|
{
|
||||||
|
if (BitmapTestDot(1, nX, nY))
|
||||||
|
{
|
||||||
|
// We have seen this node before.
|
||||||
|
// Update distance without adding it to the queue.
|
||||||
|
const int neighborIndexInMap = nY * m_bmSize + nX;
|
||||||
|
m_bfsDistances[neighborIndexInMap] = std::min(
|
||||||
|
m_bfsDistances[neighborIndexInMap],
|
||||||
|
distance + dDist[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Enqueue this neighbor
|
||||||
|
const int neighborIndexInMap = nY * m_bmSize + nX;
|
||||||
|
m_bfsDistances[neighborIndexInMap] = distance + dDist[i];
|
||||||
|
m_bfsQueue[m_bfsQueueEnd++] = neighborIndexInMap;
|
||||||
|
BitmapSetDot(1, nX, nY); // Mark as enqueued
|
||||||
|
if (m_bfsQueueEnd > m_bmSize * m_bmSize)
|
||||||
|
{
|
||||||
|
GetLogger()->Error("Queue is full\n");
|
||||||
|
return ERR_GOTO_ITER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit the number of iterations per frame.
|
||||||
m_bmIterCounter ++;
|
m_bmIterCounter ++;
|
||||||
if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE;
|
if ( m_bmIterCounter >= NB_ITER ) return ERR_CONTINUE;
|
||||||
}
|
|
||||||
iLar ++;
|
|
||||||
|
|
||||||
for ( iDiv=1 ; iDiv<=nbDiv ; iDiv++ )
|
|
||||||
{
|
|
||||||
if ( iLar >= m_bmIter[i] )
|
|
||||||
{
|
|
||||||
newPos = BeamPoint(curPos, goalPos, angle*iDiv/nbDiv, step);
|
|
||||||
ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter);
|
|
||||||
if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret;
|
|
||||||
m_bmIter[i] = iLar+1;
|
|
||||||
for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1;
|
|
||||||
m_bmIterCounter ++;
|
|
||||||
if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE;
|
|
||||||
}
|
|
||||||
iLar ++;
|
|
||||||
|
|
||||||
if ( iLar >= m_bmIter[i] )
|
|
||||||
{
|
|
||||||
newPos = BeamPoint(curPos, goalPos, -angle*iDiv/nbDiv, step);
|
|
||||||
ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter);
|
|
||||||
if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret;
|
|
||||||
m_bmIter[i] = iLar+1;
|
|
||||||
for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1;
|
|
||||||
m_bmIterCounter ++;
|
|
||||||
if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE;
|
|
||||||
}
|
|
||||||
iLar ++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERR_GOTO_IMPOSSIBLE;
|
return ERR_GOTO_IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is a right "start-goal". Calculates the point located at the distance "step"
|
|
||||||
// from the point "start" and an angle "angle" with the right.
|
|
||||||
|
|
||||||
Math::Vector CTaskGoto::BeamPoint(const Math::Vector &startPoint,
|
|
||||||
const Math::Vector &goalPoint,
|
|
||||||
float angle, float step)
|
|
||||||
{
|
|
||||||
Math::Vector resPoint;
|
|
||||||
float goalAngle;
|
|
||||||
|
|
||||||
goalAngle = Math::RotateAngle(goalPoint.x-startPoint.x, goalPoint.z-startPoint.z);
|
|
||||||
|
|
||||||
resPoint.x = startPoint.x + cosf(goalAngle+angle)*step;
|
|
||||||
resPoint.z = startPoint.z + sinf(goalAngle+angle)*step;
|
|
||||||
resPoint.y = 0.0f;
|
|
||||||
|
|
||||||
return resPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests if a path along a straight line is possible.
|
// Tests if a path along a straight line is possible.
|
||||||
|
|
||||||
bool CTaskGoto::BitmapTestLine(const Math::Vector &start, const Math::Vector &goal,
|
bool CTaskGoto::BitmapTestLine(const Math::Vector &start, const Math::Vector &goal,
|
||||||
|
@ -2094,10 +2125,11 @@ void CTaskGoto::BitmapTerrain(int minx, int miny, int maxx, int maxy)
|
||||||
|
|
||||||
bool CTaskGoto::BitmapOpen()
|
bool CTaskGoto::BitmapOpen()
|
||||||
{
|
{
|
||||||
BitmapClose();
|
|
||||||
|
|
||||||
m_bmSize = static_cast<int>(3200.0f/BM_DIM_STEP);
|
m_bmSize = static_cast<int>(3200.0f/BM_DIM_STEP);
|
||||||
m_bmArray = MakeUniqueArray<unsigned char>(m_bmSize*m_bmSize/8*2);
|
if (m_bmArray.get() == nullptr) m_bmArray = MakeUniqueArray<unsigned char>(m_bmSize*m_bmSize/8*2);
|
||||||
|
memset(m_bmArray.get(), 0, m_bmSize*m_bmSize/8*2);
|
||||||
|
if (m_bfsDistances.get() == nullptr) m_bfsDistances = MakeUniqueArray<int32_t>(m_bmSize*m_bmSize);
|
||||||
|
if (m_bfsQueue.get() == nullptr) m_bfsQueue = MakeUniqueArray<uint32_t>(m_bmSize*m_bmSize);
|
||||||
m_bmChanged = true;
|
m_bmChanged = true;
|
||||||
|
|
||||||
m_bmOffset = m_bmSize/2;
|
m_bmOffset = m_bmSize/2;
|
||||||
|
@ -2204,3 +2236,17 @@ bool CTaskGoto::BitmapTestDot(int rank, int x, int y)
|
||||||
|
|
||||||
return m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] & (1<<x%8);
|
return m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] & (1<<x%8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CTaskGoto::BitmapTestDotIsVisitable(int x, int y)
|
||||||
|
{
|
||||||
|
if ( x < 0 || x >= m_bmSize ||
|
||||||
|
y < 0 || y >= m_bmSize ) return false;
|
||||||
|
|
||||||
|
if ( x < m_bmMinX || x > m_bmMaxX ||
|
||||||
|
y < m_bmMinY || y > m_bmMaxY )
|
||||||
|
{
|
||||||
|
BitmapTerrain(x-10,y-10, x+10,y+10); // remade a layer
|
||||||
|
}
|
||||||
|
|
||||||
|
return !(m_bmArray[m_bmLine*y + x/8] & (1<<x%8));
|
||||||
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct Point;
|
||||||
|
|
||||||
class CObject;
|
class CObject;
|
||||||
|
|
||||||
const int MAXPOINTS = 500;
|
const int MAXPOINTS = 50000;
|
||||||
|
|
||||||
|
|
||||||
enum TaskGotoGoal
|
enum TaskGotoGoal
|
||||||
|
@ -103,8 +103,6 @@ protected:
|
||||||
void BeamStart();
|
void BeamStart();
|
||||||
void BeamInit();
|
void BeamInit();
|
||||||
Error BeamSearch(const Math::Vector &start, const Math::Vector &goal, float goalRadius);
|
Error BeamSearch(const Math::Vector &start, const Math::Vector &goal, float goalRadius);
|
||||||
Error BeamExplore(const Math::Vector &prevPos, const Math::Vector &curPos, const Math::Vector &goalPos, float goalRadius, float angle, int nbDiv, float step, int i, int nbIter);
|
|
||||||
Math::Vector BeamPoint(const Math::Vector &startPoint, const Math::Vector &goalPoint, float angle, float step);
|
|
||||||
|
|
||||||
bool BitmapTestLine(const Math::Vector &start, const Math::Vector &goal, float stepAngle, bool bSecond);
|
bool BitmapTestLine(const Math::Vector &start, const Math::Vector &goal, float stepAngle, bool bSecond);
|
||||||
void BitmapObject();
|
void BitmapObject();
|
||||||
|
@ -117,6 +115,7 @@ protected:
|
||||||
void BitmapSetDot(int rank, int x, int y);
|
void BitmapSetDot(int rank, int x, int y);
|
||||||
void BitmapClearDot(int rank, int x, int y);
|
void BitmapClearDot(int rank, int x, int y);
|
||||||
bool BitmapTestDot(int rank, int x, int y);
|
bool BitmapTestDot(int rank, int x, int y);
|
||||||
|
bool BitmapTestDotIsVisitable(int x, int y);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Math::Vector m_goal;
|
Math::Vector m_goal;
|
||||||
|
@ -141,10 +140,14 @@ protected:
|
||||||
int m_bmSize = 0; // width or height of the table
|
int m_bmSize = 0; // width or height of the table
|
||||||
int m_bmOffset = 0; // m_bmSize/2
|
int m_bmOffset = 0; // m_bmSize/2
|
||||||
int m_bmLine = 0; // increment line m_bmSize/8
|
int m_bmLine = 0; // increment line m_bmSize/8
|
||||||
std::unique_ptr<unsigned char[]> m_bmArray; // bit table
|
std::unique_ptr<unsigned char[]> m_bmArray; // Bit table
|
||||||
|
std::unique_ptr<int32_t[]> m_bfsDistances; // Distances to the goal for breadth-first search.
|
||||||
|
std::unique_ptr<uint32_t[]> m_bfsQueue; // Nodes in the queue. Stored as indices.
|
||||||
|
int m_bfsQueueBegin = 0; // Front of the queue. This is the next node to be expanded.
|
||||||
|
int m_bfsQueueEnd = 0; // Back of the queue. This is where nodes are inserted.
|
||||||
int m_bmMinX = 0, m_bmMinY = 0;
|
int m_bmMinX = 0, m_bmMinY = 0;
|
||||||
int m_bmMaxX = 0, m_bmMaxY = 0;
|
int m_bmMaxX = 0, m_bmMaxY = 0;
|
||||||
int m_bmTotal = 0; // number of points in m_bmPoints
|
int m_bmTotal = 0; // index of final point in m_bmPoints
|
||||||
int m_bmIndex = 0; // index in m_bmPoints
|
int m_bmIndex = 0; // index in m_bmPoints
|
||||||
Math::Vector m_bmPoints[MAXPOINTS+2];
|
Math::Vector m_bmPoints[MAXPOINTS+2];
|
||||||
signed char m_bmIter[MAXPOINTS+2] = {};
|
signed char m_bmIter[MAXPOINTS+2] = {};
|
||||||
|
|
Loading…
Reference in New Issue