169 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //
 | |
| // Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
 | |
| //
 | |
| // This software is provided 'as-is', without any express or implied
 | |
| // warranty.  In no event will the authors be held liable for any damages
 | |
| // arising from the use of this software.
 | |
| // Permission is granted to anyone to use this software for any purpose,
 | |
| // including commercial applications, and to alter it and redistribute it
 | |
| // freely, subject to the following restrictions:
 | |
| // 1. The origin of this software must not be misrepresented; you must not
 | |
| //    claim that you wrote the original software. If you use this software
 | |
| //    in a product, an acknowledgment in the product documentation would be
 | |
| //    appreciated but is not required.
 | |
| // 2. Altered source versions must be plainly marked as such, and must not be
 | |
| //    misrepresented as being the original software.
 | |
| // 3. This notice may not be removed or altered from any source distribution.
 | |
| //
 | |
| 
 | |
| #ifndef DETOURNODE_H
 | |
| #define DETOURNODE_H
 | |
| 
 | |
| #include "DetourNavMesh.h"
 | |
| 
 | |
| enum dtNodeFlags
 | |
| {
 | |
| 	DT_NODE_OPEN = 0x01,
 | |
| 	DT_NODE_CLOSED = 0x02,
 | |
| 	DT_NODE_PARENT_DETACHED = 0x04, // parent of the node is not adjacent. Found using raycast.
 | |
| };
 | |
| 
 | |
| typedef unsigned short dtNodeIndex;
 | |
| static const dtNodeIndex DT_NULL_IDX = (dtNodeIndex)~0;
 | |
| 
 | |
| static const int DT_NODE_PARENT_BITS = 24;
 | |
| static const int DT_NODE_STATE_BITS = 2;
 | |
| struct dtNode
 | |
| {
 | |
| 	float pos[3];								///< Position of the node.
 | |
| 	float cost;									///< Cost from previous node to current node.
 | |
| 	float total;								///< Cost up to the node.
 | |
| 	unsigned int pidx : DT_NODE_PARENT_BITS;	///< Index to parent node.
 | |
| 	unsigned int state : DT_NODE_STATE_BITS;	///< extra state information. A polyRef can have multiple nodes with different extra info. see DT_MAX_STATES_PER_NODE
 | |
| 	unsigned int flags : 3;						///< Node flags. A combination of dtNodeFlags.
 | |
| 	dtPolyRef id;								///< Polygon ref the node corresponds to.
 | |
| };
 | |
| 
 | |
| static const int DT_MAX_STATES_PER_NODE = 1 << DT_NODE_STATE_BITS;	// number of extra states per node. See dtNode::state
 | |
| 
 | |
| class dtNodePool
 | |
| {
 | |
| public:
 | |
| 	dtNodePool(int maxNodes, int hashSize);
 | |
| 	~dtNodePool();
 | |
| 	void clear();
 | |
| 
 | |
| 	// Get a dtNode by ref and extra state information. If there is none then - allocate
 | |
| 	// There can be more than one node for the same polyRef but with different extra state information
 | |
| 	dtNode* getNode(dtPolyRef id, unsigned char state=0);	
 | |
| 	dtNode* findNode(dtPolyRef id, unsigned char state);
 | |
| 	unsigned int findNodes(dtPolyRef id, dtNode** nodes, const int maxNodes);
 | |
| 
 | |
| 	inline unsigned int getNodeIdx(const dtNode* node) const
 | |
| 	{
 | |
| 		if (!node) return 0;
 | |
| 		return (unsigned int)(node - m_nodes) + 1;
 | |
| 	}
 | |
| 
 | |
| 	inline dtNode* getNodeAtIdx(unsigned int idx)
 | |
| 	{
 | |
| 		if (!idx) return 0;
 | |
| 		return &m_nodes[idx - 1];
 | |
| 	}
 | |
| 
 | |
| 	inline const dtNode* getNodeAtIdx(unsigned int idx) const
 | |
| 	{
 | |
| 		if (!idx) return 0;
 | |
| 		return &m_nodes[idx - 1];
 | |
| 	}
 | |
| 	
 | |
| 	inline int getMemUsed() const
 | |
| 	{
 | |
| 		return sizeof(*this) +
 | |
| 			sizeof(dtNode)*m_maxNodes +
 | |
| 			sizeof(dtNodeIndex)*m_maxNodes +
 | |
| 			sizeof(dtNodeIndex)*m_hashSize;
 | |
| 	}
 | |
| 	
 | |
| 	inline int getMaxNodes() const { return m_maxNodes; }
 | |
| 	
 | |
| 	inline int getHashSize() const { return m_hashSize; }
 | |
| 	inline dtNodeIndex getFirst(int bucket) const { return m_first[bucket]; }
 | |
| 	inline dtNodeIndex getNext(int i) const { return m_next[i]; }
 | |
| 	inline int getNodeCount() const { return m_nodeCount; }
 | |
| 	
 | |
| private:
 | |
| 	// Explicitly disabled copy constructor and copy assignment operator.
 | |
| 	dtNodePool(const dtNodePool&);
 | |
| 	dtNodePool& operator=(const dtNodePool&);
 | |
| 	
 | |
| 	dtNode* m_nodes;
 | |
| 	dtNodeIndex* m_first;
 | |
| 	dtNodeIndex* m_next;
 | |
| 	const int m_maxNodes;
 | |
| 	const int m_hashSize;
 | |
| 	int m_nodeCount;
 | |
| };
 | |
| 
 | |
| class dtNodeQueue
 | |
| {
 | |
| public:
 | |
| 	dtNodeQueue(int n);
 | |
| 	~dtNodeQueue();
 | |
| 	
 | |
| 	inline void clear() { m_size = 0; }
 | |
| 	
 | |
| 	inline dtNode* top() { return m_heap[0]; }
 | |
| 	
 | |
| 	inline dtNode* pop()
 | |
| 	{
 | |
| 		dtNode* result = m_heap[0];
 | |
| 		m_size--;
 | |
| 		trickleDown(0, m_heap[m_size]);
 | |
| 		return result;
 | |
| 	}
 | |
| 	
 | |
| 	inline void push(dtNode* node)
 | |
| 	{
 | |
| 		m_size++;
 | |
| 		bubbleUp(m_size-1, node);
 | |
| 	}
 | |
| 	
 | |
| 	inline void modify(dtNode* node)
 | |
| 	{
 | |
| 		for (int i = 0; i < m_size; ++i)
 | |
| 		{
 | |
| 			if (m_heap[i] == node)
 | |
| 			{
 | |
| 				bubbleUp(i, node);
 | |
| 				return;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	inline bool empty() const { return m_size == 0; }
 | |
| 	
 | |
| 	inline int getMemUsed() const
 | |
| 	{
 | |
| 		return sizeof(*this) +
 | |
| 		sizeof(dtNode*) * (m_capacity + 1);
 | |
| 	}
 | |
| 	
 | |
| 	inline int getCapacity() const { return m_capacity; }
 | |
| 	
 | |
| private:
 | |
| 	// Explicitly disabled copy constructor and copy assignment operator.
 | |
| 	dtNodeQueue(const dtNodeQueue&);
 | |
| 	dtNodeQueue& operator=(const dtNodeQueue&);
 | |
| 
 | |
| 	void bubbleUp(int i, dtNode* node);
 | |
| 	void trickleDown(int i, dtNode* node);
 | |
| 	
 | |
| 	dtNode** m_heap;
 | |
| 	const int m_capacity;
 | |
| 	int m_size;
 | |
| };		
 | |
| 
 | |
| 
 | |
| #endif // DETOURNODE_H
 |