i know you can use bulletAppState.physicsTick(space, tpf); yourself, but anyway you will need add to Physics Space.
But when i think… you can always create new bulletAppState / physics space (virtual one) and test it there with physicsTick and collisionListener. while new bulletAppState would not be added to appStateManager(or just disabled), then it will not update itself, but only if you do physicsTick
In the documentation there is an article about non-physical collision detection: https://wiki.jmonkeyengine.org/jme3/advanced/collision_and_intersection.html
I guess that in that case I do not need to add the Spatials to bulletAppState right?
At this point I’m only interested in collision detection between spatials and I thought that bullet is needed for that but now I see that maybe not…
Note: not all shape → shape collisions are supported this way and some that are will not always provide useful contact information.
For example, Ray to anything will work… but I think Sphere to Axis-aligned Box will not. Sphere to Sphere should work well enough, I think but JME bounding shapes default to axis-aligned bounding boxes.
So it just depends on what you are really trying to do and how careful you want to be setting up your scene graph. Or you can just try it and see.
I have some use-cases. for example one of them is to check whether Ninja A “Head” geometry was hit by Ninja B “foot” geometry while B is performing the “Sidekick” animation. I’ll be glad if you can point me to some sample code or other documentation about it.
Even the physics engine wouldn’t really support that “out of the box” because it would use capsules for the characters.
You will probably need to deconstruct what you want your hit zones to be and either attach invisible spheres to them or just track them yourself. (Either can be done with attachment nodes for the bones.)
Collision with the spatial is not going to help you because in the scene graph the best you’ll get is bounds to bounds collisions… which in the case you mention would just be two big axis-aligned bounding boxes, one per character.
Why would you have a collision listener per control which will always be notified about every collision everywhere instead of just one global collision listener that figures out how to properly dispatch things?
Edit: in case it wasn’t clear, with your approach if you have 100 objects and 5 of them are colliding then 500 events will be sent around and you’ll ignore most of them.
So you mean I should create just one CollisionRigidBodyControl and attach it to the root Spatial (Ninja A) and one more CollisionRigidBodyControl and attach it to the other Spatial (Ninja B)?
Just want to be clear: I assume Ninja (or Sinbad or whatever) Spatial is made of of some inner geometries and I want to check whether these inner geometries where collided with some other Ninja’s inner geometries.
it shows: extends RigidBodyControl implements PhysicsCollisionListener
and since RigidBodyControl can be attached to many geometries as seen in the above visitor it made me think that listener should be registered per each geometry.
So back to the original question - if I’ll have this single listener, can it detect collision between inner (children) geometries of Ninja A and Ninja B ?
Please see the below video: Two Sinbads collision detection test
I have set: bulletAppState.setDebugEnabled(true);
So I was able to see that the Physics collision shapes are aligned (location+scale) with all geometries. I have also attached one more RigidBodyControl to the root model Spatial:
All of those RigidBodyControls are added to bullet’s physics space.
Now when I move the models it looks fine, I can see that physics controls are moving.
I have also registered ONE collision listener: bulletAppState.getPhysicsSpace().addCollisionListener(new CollisionRigidBodyControl());
Problem is that I’m not getting notifications about geometries collision in my listener…
Things that are not related to your issue but look “silly” in your code:
Probably this is not a control… it definitely should not be a control. It will confuse anyone looking at your code thinking you are trying to add a control as a listener. Just make it a listener. Name it that way. Let the control thing go.
Buggy and redundant. At best, you are about to add the spatial/control to the physics space which will already set this for you. At worst, you forget to add the spatial/control to the physics space but the control incorrectly assumes it has been added.
We don’t see where you do that. Are you sure it is being called? (I assume yes.)
I remember in my own code having to add the listener from the same thread that created the physics space… but JME code doesn’t seem to account for that and I don’t remember anyone else complaining.
Only other thing I can think of is some folks mentioning that an all kinematic scene doesn’t always generate collision events. If all of your objects are 0 mass then make sure they are also kinematic (docs says it’s the default but you can check your objects to see)… and maybe try adding a non-kinematic (mass > 0) object to the scene to see if you get collisions for it.
I thought that this line of code registers the listener and makes it work right away: bulletAppState.getPhysicsSpace().addCollisionListener(new CollisionRigidBodyControl());
OK, I will change the class name but I thought from the documentation that a listener must inherit from either RigidBodyControl or GhostControl:
(from the docs) “…
You need to add the PhysicsCollisionListener to the physics space before collisions will be listened for. Here’s an example of a Physics Control that uses a collision listener. (The example shows a RigidBodyControl, but it can also be GhostControl.) …”
Thanks for taking the time to answer. Is there a good working sample code which I can use as reference?