Here’s my vertex processing code, It’s mostly ripped straight from the manual.

I extract all the edges, and then use them to form “nodes” which are basically triangular areas in the mesh. The edges then link the nodes together, forming a graph which I can traverse with A*.

```
def _processNode(self, node):
geomNodeCollection = node.findAllMatches('**/+GeomNode')
for nodePath in geomNodeCollection:
geomNode = nodePath.node()
self._processGeomNode(geomNode)
for edge in self.edges:
if len(edge.nodes) <= 1:
# This edge isn't between two nodes, so we don't need to worry about it when pathfinding.
# But we still need it for determining which node an agent is in.
edge.navigable = False
def _processGeomNode(self, geomNode):
for i in range(geomNode.getNumGeoms()):
geom = geomNode.getGeom(i)
state = geomNode.getGeomState(i)
self._processGeom(geom)
def _processGeom(self, geom):
vdata = geom.getVertexData()
for i in range(geom.getNumPrimitives()):
prim = geom.getPrimitive(i)
self._processPrimitive(prim, vdata)
def _processPrimitive(self, prim, vdata):
vertex = GeomVertexReader(vdata, "vertex")
prim = prim.decompose()
def getVertex(index):
vi = prim.getVertex(index)
vertex.setRow(vi)
return vertex.getData3f()
for p in range(prim.getNumPrimitives()):
s = prim.getPrimitiveStart(p)
e = prim.getPrimitiveEnd(p)
for i in range(s, e):
v = getVertex(i)
if i + 1 >= e:
break
v2 = getVertex(i + 1)
edge1 = self.addEdge(v, v2)
if i + 2 >= e:
break
v3 = getVertex(i + 2)
edge2 = self.addEdge(v2, v3)
edge3 = self.addEdge(v3, v)
self.nodes.append(NavNode(edge1, edge2, edge3))
```

To determine which node an agent is in, I just do a dot product from the agent’s position to the center of each of the three edges. If all three dot products are positive (or negative, I can’t remember), the agent must be inside the node. I do some other stuff for vertical testing as well. It’s all in the A3P repository.