AI Libraries for Panda3D

Thanks for the response NNair :slight_smile:

I’m gonna need to think about the stairs problem once I get into PandaAI (or try to design levels and story in such a way that NPCs don’t need to walk stairs, haha ;D). It’s cool that it’s possible to switch meshes as needed though.

Still, you’ve mentioned it’s 2d “for now”, and that gives me hope :slight_smile:.

As for Recast and Detour - that’s understandable. I’m still impressed that you were able to get all this working on time.

Thanks again

Trying to execute the .bat file in OS X.5 Terminal I get:

/Applications/Panda3D/1.7.0/bin/BuildDLL.bat
Cannot locate the root of the panda tree

I would still like to know if I could adapt this to zero g physics? I.e., where a spaceship can’t just get slower but has to turn around and counter-accelerate? How much work is that?

The BuildDLL batch file is for Windows only. You shouldn’t attempt to run .bat files on OSX.

Hypnos has posted a Makefile for OSX somewhere back in the post. Use that.
Alternatively, you can use the latest daily build of Panda3D, it includes PandAI support:
discourse.panda3d.org/viewtopic.php?t=8002
(Note that the current buildbot OSX build needs a small .bash_profile hack to work.)

Don’t know what that is. If I have to install XCode for this it won’t happen.

What’s the hack? And how do I install this? Downloaded the runtime build, it’s just a 2 MB .pkg. What do I have to do?

You’ll want to install the SDK build, not the runtime. The dmg you’ll download contains a package, you can just double-click it to launch the installer.

The hack is to put this in /Users/yourusername/.bash_profile:

export DYLD_LIBRARY_PATH=/Developer/Panda3D/lib/:$DYLD_LIBRARY_PATH

Alright, thx.

Do I have to put this into .bash_profile additionally or replacing something?

And the buildbot thing … Yeah only forum people know about this, not the average beginner. But what exactly is a runtime and what a SDK build? For me as a layman SDK says: install XCode and hack it yourself. Right now it says build 14 failed (BIG RED SIGN = STAY AWAY). File name has a 12 in it. I guess it’s save then. Is it?

Just put it additionally, after you have installed the snapshot build. The installer will automatically remove the 1.6.x cruft from .bash_profile.

Yeah, the latest download link is always safe. The red sign just is a notifier that the latest build failed, in this case just because there is some trouble with the build machine.

The difference between the SDK and Runtime is explained here:
panda3d.org/download.php

i know this is the wrong place to mention this. But i’d suggest that the “Snapshot Builds” could go under the SDK category. Because even if a enduser wants to use a snapshot build he should be (more) aware that it’s not something to be used as a regular user.

Hm, that would be a bit weird because there are also snapshots of the runtime at the buildbot page. It offers both choices, just like download.php does.

ARGH when I try the RR sample from the PandaAI site I get:

Yeah, when I included it in the official build, I altered the way it is imported. Import from “panda3d.ai” rather than “libpandaai” in your code.

Trying the Roaming Ralph sample I get this crash:

pastebin.com/m76d19255

In Terminal I get this error:

The fish demo works, only this error on first startup, at second try no errors:

That fish demo gives me the creeps, here got this lovely music and cute orange fish and then you hook 'em :confused:

all samples work fine for me with current CVS build, after changing the import to panda3d.ai, of course.

Well, we did get some of that feedback :slight_smile:. I guess in the end we just decided to stick with it…was kinda funny in a weird evil way :wink:

Just been looking at this stuff - looks like its going to be really useful. I have a bunch of questions about the path finding though, followed by some observations:

  1. Earlier in this thread it is stated that the path finding is 2D. Is this because its runtime code is limited to 2D, or, as I suspect, because the navimesh generation tool is limited to 2D? i.e. if you were to generate your own mesh you could circumvent this limitation.

  2. What is the format of the navimesh .csv file?

  3. You have to load a navimesh for each character - is there caching involved to prevent duplication of data? With a lot of characters it could be a real problem to store a large navimesh for each.

  4. Is there any way of removing obstacles from the path finding?

Also, some comments:

Why isn’t there a separate navimesh class? Right now you have to add obstacles for every character you have, which is irritating and inefficient - having several characters share a single navimesh to which you apply the obstacles would make rather more sense.

You also seem to be lacking an interface to create a navimesh in code - for instance a game that makes its world out of tiles using some kind of random level generation would need to take per-tile navigation information and stitch it together - there is no way of doing that with the current system.

Thanks for checking out our project lethe! Here are the answers to your specific questions and concerns,

The pathfinding system that we have implemented is 2D. This is because the A* that we have implemented does not check for neighbor nodes in 3D space. It is limited to the nodes in the 2D mesh that is generated. In other words even if you were to create your own 3D mesh, the A* wouldn’t handle it currently. However, you can combine our pathfinding system and the Roaming Ralph example to make pathfinding work on uneven terrain. The limitation here is that since the mesh nodes don’t currently track the height information, they are not accounted for while finding optimal path using A*.

A snapshot of the navmesh.csv is given below,

Grid Size - size of the mesh.

NULL - specifies if a node exists or not.
0 - exists
1 - does not exist.

Node Type - specifies if it is the main node or the neighbor node.
0 - main node.
1 - neighbor node.

GridX - row index
GridY - col index

Length - length of each cell.
Width - width of each cell.
Height - currently overwritten as 0 since height info is not used.

PosX, PosY, PosZ - position of the node in the cell.

Currently there is no caching involved. We needed an instance of the navmesh for each AI character since we wanted to dynamically avoid other AI characters during pathfinding. However, the concern you have raised was one of ours too but due to time constraints we couldn’t create an option for caching the navmesh.

So the way the pathfinding system understands obstacles that have been added dynamically during runtime is by first calculating the area of the obstacle and then setting a property of all the nodes which fall within the area to ‘false’ or non-traversable. Now, removing the obstacle would simply mean setting all those nodes to ‘true’ or traversable. Unfortunately we don’t have a function that is exposed in python that would allow you to do this. With a little coding in C++ this can be easily done. We are planning to do this in a future release.

The answer to this is pretty much point 3.

The navmesh generation tool that we have created requires egg files as input. It creates the navmesh based off the triangles data from them. So if a game created the world during runtime based off random level generation it would still need to be exported out into an egg file and then parsed through the mesh generation tool. If you go through our navmesh generation tutorials you will have a clearer picture on why we cannot do it with the existing system. Creating a completely automated mesh generation system was out of our project scope.

Thank you very much for all the feedback and concerns you brought forward. There were some more features and improvements we wanted to add to the AI libraries, some of which you have already mentioned, however, since the span of this project was only a semester we had to cut them down. In a future release we hope to accomplish some of them at least. Also, we are hoping that the community will be interested in contributing to the AI library as well. Let us know if you have further questions.

This project is very cool and a needed addition to Panda. The C implementation alone will be a huge performance saver.

I worked on an A* implementation a long time ago but gave up- python’s just too slow. At the time, I imported an image then sampled the image for the data regarding the obstacles and walls (an image map). White was a clear node, black was impassable. Greyscale tones were increased time per node (like a sand pit or similar).

That part of the system worked pretty well. I see the advantages of a separate mesh, but I also see that in some situations this image map may have some advantages- for example, new obstacles and walls can be added to the imagemap in the script and A* would then have no issues with the dynamic problem. Any thoughts on a dual import system for the A* grid?

Second item:

This may be too specific- but in my game AI I found the need to have a ‘dodge’ behavior- In my game the NPCs can avoid you but you fire at them in line of sight. That means that when they avoid you, they set themselves up in a vector that moves away from you but this also lines them up perfectly to be shot down. The dodge behavior makes them run at 90 degrees so that they are a moving target in line of sight. In my game, the dodge behavior is activated if they get hit, lasts for a few seconds and then they re-adquire whatever they were doing before.

Thanks :slight_smile:

A dual import system would be great! We did have some time constraints then and so didn’t venture too much into multiple import systems. Basically, our A* works on the mesh from the navmesh.csv file, so if you would like to modify the code for your own implementation it shouldn’t be too difficult looking at the way we have done it.

You would need to go into the C++ code of it though and change some of our pathfinding and mesh generation classes. The mesh generatpr right now parses an EGG file so you could make it parse an image map I guess.

The implementation of our dynamic A* is not too different from what you talk about. We are updating a grid and there is functionality to add static obstacles to the mesh. Though we might be looking to optimize it a bit more in the future.

‘Dodge’ sounds like a cool behavior to have :slight_smile:…We could look into adding it in or maybe someone else could in the future.

Thanks.

I tried to use the pathfinding via navmesh and it failed.
I finally created a 3x3 plane mesh in blender, converted it as described in your tutorial. the collision plane was 3x3 as well and the face in the center was erased.

When i run this following happens: My character is in the upper face (0,1). It now should move to face at the left hand side (1,0). Now it first move to the face down at the left hand side (2,0) and then up to (1,0). Then destination is reached.
But then the character first crossed the obstacle in the center (1,1) and even has not used the shortest path which should be from up side to left side (0,1)->(1,0) and should definitely be found by A*. Similar behavior is on other source and destination points.
But when you wanted to go to the center face (1,1) it says, that destination is not found. Same when you start in this face. Then message came that source is not found. So there is definitely an obstacle.

This is content of csv file:

Grid Size,3
NULL,NodeType,GridX,GridY,Length,Width,Height,PosX,PosY,PosZ
0,0,0,0,22.8739,21.1888,0,-22.8731,22.1094,0.0393925
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
0,1,1,0,21.5476,21.1889,0,-22.8731,-22.7725,0.0393925
0,1,1,1,22.8739,21.8285,0,22.7108,22.1094,0.0393925
0,1,0,1,22.8739,24.0753,0,-0.24105,22.1094,0.0393925
0,0,1,0,21.5476,21.1889,0,-22.8731,-22.7725,0.0393925
0,1,0,1,22.8739,24.0753,0,-0.24105,22.1094,0.0393925
0,1,0,0,22.8739,21.1888,0,-22.8731,22.1094,0.0393925
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
0,1,2,0,22.6711,21.1889,0,-22.8731,-0.66315,0.0393925
0,1,2,1,21.5476,21.8285,0,22.7108,-22.7725,0.0393925
0,1,1,1,22.8739,21.8285,0,22.7108,22.1094,0.0393925
0,0,2,0,22.6711,21.1889,0,-22.8731,-0.66315,0.0393925
0,1,1,1,22.8739,21.8285,0,22.7108,22.1094,0.0393925
0,1,1,0,21.5476,21.1889,0,-22.8731,-22.7725,0.0393925
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
0,1,2,1,21.5476,21.8285,0,22.7108,-22.7725,0.0393925
0,0,0,1,22.8739,24.0753,0,-0.24105,22.1094,0.0393925
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
0,1,0,0,22.8739,21.1888,0,-22.8731,22.1094,0.0393925
0,1,1,0,21.5476,21.1889,0,-22.8731,-22.7725,0.0393925
0,1,1,1,22.8739,21.8285,0,22.7108,22.1094,0.0393925
0,1,1,2,22.6711,21.8285,0,22.7108,-0.66315,0.0393925
0,1,0,2,21.5476,24.0753,0,-0.24105,-22.7725,0.0393925
0,0,1,1,22.8739,21.8285,0,22.7108,22.1094,0.0393925
0,1,0,2,21.5476,24.0753,0,-0.24105,-22.7725,0.0393925
0,1,0,1,22.8739,24.0753,0,-0.24105,22.1094,0.0393925
0,1,0,0,22.8739,21.1888,0,-22.8731,22.1094,0.0393925
0,1,1,0,21.5476,21.1889,0,-22.8731,-22.7725,0.0393925
0,1,2,0,22.6711,21.1889,0,-22.8731,-0.66315,0.0393925
0,1,2,1,21.5476,21.8285,0,22.7108,-22.7725,0.0393925
0,1,2,2,22.6711,24.0753,0,-0.24105,-0.66315,0.0393925
0,1,1,2,22.6711,21.8285,0,22.7108,-0.66315,0.0393925
0,0,2,1,21.5476,21.8285,0,22.7108,-22.7725,0.0393925
0,1,1,2,22.6711,21.8285,0,22.7108,-0.66315,0.0393925
0,1,1,1,22.8739,21.8285,0,22.7108,22.1094,0.0393925
0,1,1,0,21.5476,21.1889,0,-22.8731,-22.7725,0.0393925
0,1,2,0,22.6711,21.1889,0,-22.8731,-0.66315,0.0393925
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
0,1,2,2,22.6711,24.0753,0,-0.24105,-0.66315,0.0393925
0,0,0,2,21.5476,24.0753,0,-0.24105,-22.7725,0.0393925
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
0,1,0,1,22.8739,24.0753,0,-0.24105,22.1094,0.0393925
0,1,1,1,22.8739,21.8285,0,22.7108,22.1094,0.0393925
0,1,1,2,22.6711,21.8285,0,22.7108,-0.66315,0.0393925
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
0,0,1,2,22.6711,21.8285,0,22.7108,-0.66315,0.0393925
1,1,0,0,0,0,0,0,0,0
0,1,0,2,21.5476,24.0753,0,-0.24105,-22.7725,0.0393925
0,1,0,1,22.8739,24.0753,0,-0.24105,22.1094,0.0393925
0,1,1,1,22.8739,21.8285,0,22.7108,22.1094,0.0393925
0,1,2,1,21.5476,21.8285,0,22.7108,-22.7725,0.0393925
0,1,2,2,22.6711,24.0753,0,-0.24105,-0.66315,0.0393925
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
0,0,2,2,22.6711,24.0753,0,-0.24105,-0.66315,0.0393925
1,1,0,0,0,0,0,0,0,0
0,1,1,2,22.6711,21.8285,0,22.7108,-0.66315,0.0393925
0,1,1,1,22.8739,21.8285,0,22.7108,22.1094,0.0393925
0,1,2,1,21.5476,21.8285,0,22.7108,-22.7725,0.0393925
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0
1,1,0,0,0,0,0,0,0,0

Hello peerpanda,

So looking at the .csv file, I can see that the 1,1 position is definitely traversable and not an obstacle. So I am guessing the navmesh.csv has not been generated properly.

This confuses me though. Did you use the same navmesh.csv file as given above when you got this result?

I shall look into it further and post further comments. Let me know if you made any other progress or encountered more problems. Thanks!