Finally, got it working. Below is my classes if somebody would like to see them.
Very much unoptimized indeed! Probably a bunch of bugs as well.
There is most likely better ways of doing it!
But it works, and speed isn’t an issue in my case (even if it takes forever for my class to find a distance that is more than a few meters away
)
from pandac.PandaModules import *
class PNode:
def __init__(self, g,h, pos, parent ):
self.g = g
self.h = h
self.pos = pos
self.f = self.g + self.h
self.parent = parent
def sortPNode( x,y ):
return int(x.f-y.f)
class Path:
def __init__(self, startp, endp, gsize, osize ):
self.startp = startp
self.endp = endp
self.gsize = gsize
self.osize = osize
def visited( self,pos ):
for n in self.open:
if n.pos == pos:
return True
return False
def findInOpen( self,pos ):
index = 0
for n in self.open:
if n.pos == pos:
return n,index
index+=1
return None,None
def calculate(self):
self.open = []
self.closed = []
self.startn = PNode(0,0,self.startp,None)
self.open.append( self.startn )
while len(self.open) > 0:
current = self.open.pop(0)
self.closed.append(current)
if (current.pos - self.endp).length() < self.gsize*1.5: # Are we there yet?
fp = []
while current.parent != None:
fp.insert( 0,current.pos )
current = current.parent
fp.append( self.endp )
return fp
for x in range(-1,2):
for y in range(-1,2):
for z in range(-1,2):
self.examinePos(current, x,y,z)
# We were unable to find a path
return None
def examinePos(self, current, xo,yo,zo ):
if xo == 0 and yo == 0 and zo == 0: return
cost = 10
if (xo!=0 or yo!=0 or zo!=0) and (xo == yo or yo == zo or zo == xo): cost = 15
np = current.pos+Vec3(self.gsize*xo,self.gsize*yo,self.gsize*zo)
if not self.visited(np) and self.walkable( np, self.osize ):
heur = int(abs(self.endp[0]-np[0]) + abs(self.endp[1]-np[1]) + abs(self.endp[2]-np[2]))*10
on,index = self.findInOpen( np )
if not on:
self.open.append( PNode(current.g+cost,heur,np,current) )
self.open.sort(sortPNode)
else:
if on.g > current.g+cost:
self.open[index] = PNode(current.g+cost,heur,np,current)
self.open.sort(sortPNode)
def walkable( self, spot, size ):
self.cs = CollisionSphere( spot[0],spot[1],spot[2], size)
self.cnp = render.attachNewNode(CollisionNode("TmpCollNode"))
self.cnp.node().addSolid(self.cs)
self.cnp.node().setCollideMask(BitMask32.allOff())
self.cnp.node().setCollideMask(BitMask32.bit(20))
self.queue = CollisionHandlerQueue()
self.traverser = CollisionTraverser('TmpTraverser')
self.traverser.addCollider(self.cnp, self.queue)
self.traverser.traverse(render)
self.cnp.removeNode()
if self.queue.getNumEntries() > 0:
return False
return True
Small usage tutorial:
# Each node is 1 unit away, and the object passing through has 0.5 units in radius
planner = Path( Vec3(0,0,0), Vec3(4,5,2), 1, 0.5 )
path = planner.calculate()
# Unless path is None, we have a list of positions to travel through...
movseq = Sequence(name="MovePlayer")
for n in path:
movseq.append( player.node.posInterval(0.25,n) )
movseq.start()
Please note that the code is ripped out of my current object and untested here.
Next on the todo list: Make calculate spawn a task that plans the path a few steps at a time so the game doesn’t freeze. 
And later I will see if I can come up with some code to remove unnecessary nodes in the path. (only have start, end and corner points)
EDIT: updated it. It should be a bit quicker now. (Still very slow over large areas)