rese DtNode in DtNodePool

This commit is contained in:
ikpil 2024-02-05 00:45:16 +09:00 committed by Ikpil
parent 73bb475ef7
commit 3ce4f59002
3 changed files with 42 additions and 21 deletions

View File

@ -31,14 +31,17 @@ namespace DotRecast.Detour
/// < Add a vertex at every polygon edge crossing. /// < Add a vertex at every polygon edge crossing.
protected readonly DtNavMesh m_nav; protected readonly DtNavMesh m_nav;
protected readonly DtNodePool m_tinyNodePool;
protected readonly DtNodePool m_nodePool; protected readonly DtNodePool m_nodePool;
protected readonly DtNodeQueue m_openList; protected readonly DtNodeQueue m_openList;
protected DtQueryData m_query; protected DtQueryData m_query;
/// < Sliced query state. /// < Sliced query state.
public DtNavMeshQuery(DtNavMesh nav) public DtNavMeshQuery(DtNavMesh nav)
{ {
m_nav = nav; m_nav = nav;
m_tinyNodePool = new DtNodePool();
m_nodePool = new DtNodePool(); m_nodePool = new DtNodePool();
m_openList = new DtNodeQueue(); m_openList = new DtNodeQueue();
} }
@ -1799,9 +1802,9 @@ namespace DotRecast.Detour
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
} }
DtNodePool tinyNodePool = new DtNodePool(); m_tinyNodePool.Clear();
DtNode startNode = tinyNodePool.GetNode(startRef); DtNode startNode = m_tinyNodePool.GetNode(startRef);
startNode.pidx = 0; startNode.pidx = 0;
startNode.cost = 0; startNode.cost = 0;
startNode.total = 0; startNode.total = 0;
@ -1906,7 +1909,7 @@ namespace DotRecast.Detour
{ {
for (int k = 0; k < nneis; ++k) for (int k = 0; k < nneis; ++k)
{ {
DtNode neighbourNode = tinyNodePool.GetNode(neis[k]); DtNode neighbourNode = m_tinyNodePool.GetNode(neis[k]);
// Skip if already visited. // Skip if already visited.
if ((neighbourNode.flags & DtNodeFlags.DT_NODE_CLOSED) != 0) if ((neighbourNode.flags & DtNodeFlags.DT_NODE_CLOSED) != 0)
{ {
@ -1924,7 +1927,7 @@ namespace DotRecast.Detour
} }
// Mark as the node as visited and push to queue. // Mark as the node as visited and push to queue.
neighbourNode.pidx = tinyNodePool.GetNodeIdx(curNode); neighbourNode.pidx = m_tinyNodePool.GetNodeIdx(curNode);
neighbourNode.flags |= DtNodeFlags.DT_NODE_CLOSED; neighbourNode.flags |= DtNodeFlags.DT_NODE_CLOSED;
stack.AddLast(neighbourNode); stack.AddLast(neighbourNode);
} }
@ -1939,8 +1942,8 @@ namespace DotRecast.Detour
DtNode node = bestNode; DtNode node = bestNode;
do do
{ {
DtNode next = tinyNodePool.GetNodeAtIdx(node.pidx); DtNode next = m_tinyNodePool.GetNodeAtIdx(node.pidx);
node.pidx = tinyNodePool.GetNodeIdx(prev); node.pidx = m_tinyNodePool.GetNodeIdx(prev);
prev = node; prev = node;
node = next; node = next;
} while (node != null); } while (node != null);
@ -1950,7 +1953,7 @@ namespace DotRecast.Detour
do do
{ {
visited.Add(node.id); visited.Add(node.id);
node = tinyNodePool.GetNodeAtIdx(node.pidx); node = m_tinyNodePool.GetNodeAtIdx(node.pidx);
} while (node != null); } while (node != null);
} }
@ -2856,9 +2859,9 @@ namespace DotRecast.Detour
resultRef.Clear(); resultRef.Clear();
resultParent.Clear(); resultParent.Clear();
DtNodePool tinyNodePool = new DtNodePool(); m_tinyNodePool.Clear();
DtNode startNode = tinyNodePool.GetNode(startRef); DtNode startNode = m_tinyNodePool.GetNode(startRef);
startNode.pidx = 0; startNode.pidx = 0;
startNode.id = startRef; startNode.id = startRef;
startNode.flags = DtNodeFlags.DT_NODE_CLOSED; startNode.flags = DtNodeFlags.DT_NODE_CLOSED;
@ -2894,7 +2897,7 @@ namespace DotRecast.Detour
continue; continue;
} }
DtNode neighbourNode = tinyNodePool.GetNode(neighbourRef); DtNode neighbourNode = m_tinyNodePool.GetNode(neighbourRef);
// Skip visited. // Skip visited.
if ((neighbourNode.flags & DtNodeFlags.DT_NODE_CLOSED) != 0) if ((neighbourNode.flags & DtNodeFlags.DT_NODE_CLOSED) != 0)
{ {
@ -2934,7 +2937,7 @@ namespace DotRecast.Detour
// Mark node visited, this is done before the overlap test so that // Mark node visited, this is done before the overlap test so that
// we will not visit the poly again if the test fails. // we will not visit the poly again if the test fails.
neighbourNode.flags |= DtNodeFlags.DT_NODE_CLOSED; neighbourNode.flags |= DtNodeFlags.DT_NODE_CLOSED;
neighbourNode.pidx = tinyNodePool.GetNodeIdx(curNode); neighbourNode.pidx = m_tinyNodePool.GetNodeIdx(curNode);
// Check that the polygon does not collide with existing polygons. // Check that the polygon does not collide with existing polygons.

View File

@ -25,7 +25,7 @@ namespace DotRecast.Detour
{ {
public class DtNode public class DtNode
{ {
public readonly int index; public readonly int ptr;
public RcVec3f pos; // Position of the node. public RcVec3f pos; // Position of the node.
public float cost; // Cost from previous node to current node. public float cost; // Cost from previous node to current node.
@ -36,9 +36,9 @@ namespace DotRecast.Detour
public long id; // Polygon ref the node corresponds to. public long id; // Polygon ref the node corresponds to.
public List<long> shortcut; // Shortcut found by raycast. public List<long> shortcut; // Shortcut found by raycast.
public DtNode(int index) public DtNode(int ptr)
{ {
this.index = index; this.ptr = ptr;
} }
public static int ComparisonNodeTotal(DtNode a, DtNode b) public static int ComparisonNodeTotal(DtNode a, DtNode b)

View File

@ -25,6 +25,8 @@ namespace DotRecast.Detour
public class DtNodePool public class DtNodePool
{ {
private readonly Dictionary<long, List<DtNode>> m_map; private readonly Dictionary<long, List<DtNode>> m_map;
private int m_nodeCount;
private readonly List<DtNode> m_nodes; private readonly List<DtNode> m_nodes;
public DtNodePool() public DtNodePool()
@ -35,8 +37,8 @@ namespace DotRecast.Detour
public void Clear() public void Clear()
{ {
m_nodes.Clear();
m_map.Clear(); m_map.Clear();
m_nodeCount = 0;
} }
public int FindNodes(long id, out List<DtNode> nodes) public int FindNodes(long id, out List<DtNode> nodes)
@ -52,7 +54,7 @@ namespace DotRecast.Detour
public DtNode FindNode(long id) public DtNode FindNode(long id)
{ {
var hasNode = m_map.TryGetValue(id, out var nodes); m_map.TryGetValue(id, out var nodes);
if (nodes != null && 0 != nodes.Count) if (nodes != null && 0 != nodes.Count)
{ {
return nodes[0]; return nodes[0];
@ -63,7 +65,7 @@ namespace DotRecast.Detour
public DtNode GetNode(long id, int state) public DtNode GetNode(long id, int state)
{ {
var hasNode = m_map.TryGetValue(id, out var nodes); m_map.TryGetValue(id, out var nodes);
if (nodes != null) if (nodes != null)
{ {
foreach (DtNode node in nodes) foreach (DtNode node in nodes)
@ -85,10 +87,22 @@ namespace DotRecast.Detour
private DtNode Create(long id, int state, List<DtNode> nodes) private DtNode Create(long id, int state, List<DtNode> nodes)
{ {
DtNode node = new DtNode(m_nodes.Count + 1); if (m_nodes.Count <= m_nodeCount)
{
var newNode = new DtNode(m_nodeCount);
m_nodes.Add(newNode);
}
int i = m_nodeCount;
m_nodeCount++;
var node = m_nodes[i];
node.pidx = 0;
node.cost = 0;
node.total = 0;
node.id = id; node.id = id;
node.state = state; node.state = state;
m_nodes.Add(node); node.flags = 0;
node.shortcut = null;
nodes.Add(node); nodes.Add(node);
return node; return node;
@ -96,12 +110,16 @@ namespace DotRecast.Detour
public int GetNodeIdx(DtNode node) public int GetNodeIdx(DtNode node)
{ {
return node != null ? node.index : 0; return node != null
? node.ptr + 1
: 0;
} }
public DtNode GetNodeAtIdx(int idx) public DtNode GetNodeAtIdx(int idx)
{ {
return idx != 0 ? m_nodes[idx - 1] : null; return idx != 0
? m_nodes[idx - 1]
: null;
} }
public DtNode GetNode(long refs) public DtNode GetNode(long refs)