Hi, my name is Leandro.
My friends and I are developing a 3D game using Panda 3D. We are having some problems with the collisions. We use a sphere around our main character and activate the collision with geometry. The problem is that the main character is also a geometry, so the sphere collides with him and ruins everything.
Does anybody know how to fix it, or another way to detect collisions?
By the way, how many triangles has the panda model that we use at the tutorial? How many polygons the engine can handle with?
Panda does support collision tests against visible geometry, but this is only supported halfheartedly. The preferred way to test collisions is to use special collision solids modeled into the scene for this purpose. The artist who lays out the scene is then responsible for laying out the main walls of each room and putting spheres and tubes around smaller objects.
I donāt know whether the MAX converter supports Pandaās tags to identify collision geometry, but it is fully supported by the Maya and MultiGen converters.
If you still decide youād rather test collisions against visible geometry, one trick is to put all the collidable geometry under a common node that is parented to render, and write your own collisionloop task (replacing the one in ShowBase.py) that starts the traversal at that node, rather than at render.
Iām still having troubles with collisions. Iāve tried to use the masks, but it isnāt working. Here is the code: there are two models, panda and panda2. Iāve created the collisions spheres and the collision nodes. Then, iāve created the masks and applied to the nodes. Finally, iāve created the pusher and the traverser. Iām not using the collision against all geometry.
It should have given you a warning message, something like:
:collide(error): CollisionHandlerPusher doesnāt know about render/panda2/chPanda2, disabling.
Note that the above solution may not do what you wantāIām not sure exactly what it is that you do want. The addCollider() calls above will set up the pusher so that if one of the pandas tries to walk into something, e.g. the other panda, it will set the position of self.panda to a place outside of that something. But if you have another task resetting the position every frame (e.g. a LerpInterval), you may not see the pusher having any effect, since its efforts will be undone by your other task.
To play nicely with the collision handler, you need to set up a callback event handler on the collision event, and stop whatever it is thatās trying to move the panda in the case when a collision is detected and do something else instead. Or, you can write a custom task that moves the panda by a certain delta each frame, instead of using something like a LerpInterval.
You can call messenger.toggleVerbose() to watch all the messages go by; some of them will be about the detected collisions, so you can see the sorts of events you can listen for if you need to.
Another comment: if you are using the driveInterface to move the panda around directly from user inputs, the addCollider call would be something like this:
Note that if only one of your Pandas is moved around by user inputs and the other one just walks around under program control, you donāt need to add the second one to the collision traverser or create a pusher for itāany CollisionNode in the scene graph can serve as an obstacle for the object thatās actively responding to collisions.
First of all, thank you so much for your help. The collisions are working!
I have another question for you, but first I will explain exactly what Iām trying to do. Iām developing a RPG with PANDA3D. I will put the characters into a map, or dungeon and I want them to collide with the scenario and characters. First Iāve tried the collision with all geometry but
the character was colliding with his own collide sphere. Then Iāve tried the bitMask and now itās working.
The question is:
The āpusherā makes the target to go back but I donāt want it. I just want to keep the target in place and stop the characters movement so they cannot pass through the target. I donāt want my characters pushing the walls, right? How can I do this?
Hello David,
my name is mauro and Iām one of Leandroās friend that are developing the 3D RPG using PANDA3D.
Iāll try to explain a little better what we are trying to do:
weāre developing this game with a 3rd person view, so that you can see the character you control.
We need to have this main character colliding with all the geometry(like when we use setCollideGeom(1)).
but whe we try to use this, the colision solid collides with the main character too. so we need to have the sphere to collide with everything except the main character model.
Thanks a lot for your help
Mauro
The CollisionHandlerPusher is probably the right choice in this case. It pushes back on the thing which is registered with the CollisionTraverser, which in this case would be your character. By āpushing backā I mean that it pushes back in the right amount to cancel your characterās forward motion, thus stopping your character from going through walls.
Used properly, the pusher will not push the walls out of their proper place. If you are observing the walls being moved, it means that you must have created a CollisionHandlerPusher for the walls themselves, which you donāt need to doāyou only need the pusher for the object which is actually moving.
It sounds like you are doing the right thing with the CollideMaskāattempting to use collide-with-geometry to detect the walls is probably a bad idea.
does it means that we need to put colision solids all over the enviroment?
since weāre making an engine, itāll be very unreasonableā¦
sorry to keep bothering you, itās just that this is the last point we need to do in our RPG engine.
could you give us an exemplo (python) how we do that?
anothe question, why whe the collide with geometry is on, the shpere doesnāt collide with the floor?
You should be putting collision solids all over the environment. Itās not any more work than putting in visible polygons, which you are already doing.
Even if you did not have this requirement in Panda, it is almost always a good idea to create separate geometry, different from the geometry that is to be rendered, for the purposes of testing collisions. This is because the needs of collision tests are inherently different than the needs of rendering. Collision tests are generally performed against a much lower-resolution model than the one that you create for rendering.
You would normally create collision polygons in the modeling package, at the same time you create the visible polygons. What program are you using to define your levels?
I donāt know why youāre not colliding with the floor when you have visible geometry collisions on.
Hi David,
Iām not sure if I understood that part⦠, see if we are making it right:
Weāre making the 3D Models on 3D MAX, nothing special, only some movements (I donāt know about the visible/collidable geometry stuff you said)
Then we have 2 option :
make a collision sphere on the main character to make it collide with the other collisions spheres (by the way, the sphere is the only solid that actually collides). In this I should put the collision solids all over the place, on the building of the scenary, on the objects like trees and rocksā¦
2)make a collision sphere near the main character adn turn collide with geometry on. the only problem is that in this mode we canāt put the sphere āaroundā the main character, or heāll ācollide with himselfā, so we had to put o the front of him. but then he would collide with the other member of the party (who he wasnāt supposed to collide).
so the best choice, would be the first, since we can decide which object will collide with tha main character. but it will demand a lot more work to put the collision solid all around the scenario (to make things worse, the only collision solid working is the sphere).
is that right? we donāt have anyway to ādisableā collide with some of the objects in the collide with geometry mode?
by the way, do you have any idea why the collisionplan or the collision tube donāt work like the sphere?
I think your analysis is correct. Between options (1) and (2) I recommend option (1) as the more efficient choice. However, to make option (2) easier I have just checked in changes to Panda to support using the CollideMask on GeomNodes, so you can now have collide-with-geom enabled and only collide with some geometry, not all geometry. (It will be some time until the changes I have made are available in the CMU distribution; you will need to get the latest code from CVS and build Panda from source if you want this change sooner.)
To generate collision solids in the modeling package, you need to be able to insert the code { barrier } within a entry that is intended to represent invisible collision polygons, rather than visible polygons. I donāt know if there is a way to do this with the 3DSMax converter; I suspect there is not (but our CMU friends may be able to tell me otherwise). If there is not, you may need to edit the egg file and do this by hand. You can also use { sphere } to create a CollisionSphere.
It is true that the only CollisionSolid type that actually collides with other CollisionSolids is the CollisionSphere, so you can only put a sphere around your avatar. This is because we have implemented only the sphere-polygon, sphere-plane, sphere-sphere, and sphere-tube intersection tests. If you want to put (say) a CollisionTube around your avatar, you would need the tube-polygon, tube-plane, tube-sphere, and tube-tube intersection tests as well. If youād like to implement these, Iād be happy to incorporate your work into Panda. But for the most part, we have found that a sphere around the avatar is sufficient.
does adding the < objectType > { barrier } code to an object automatically make it a collision solid or would i have to set a specific bitmask if i want to collide with it?
The < objectType > { barrier } flag makes an object a CollisionSolidāspecifically, it turns it into a series of CollisionPolygons. There are also other object types that make it into a sphere or a tube or whatever.
You might still need to set a particular bitmask on it if you donāt want it to have the default bitmask (and you can also do this in the egg file with, e.g., collide-mask { 0x01 }), but you donāt need to do this in order to collide with it.