Custom Physics Control (Listeners and Physics Tick) Help Needed

Hey guys!

So, I’m relatively new to JME3, and I’ve gone through all the basic tutorials. I’m hitting up more advanced topics one at a time by slowing adding features to a simple little game for practice. As you might imagine, I need to do a custom physics control that will be added to certain projectiles. These projectiles will NOT apply normal physics when colliding with another object. Instead, they will be destroyed (which I’m not sure how to handle entirely) and apply a specific force to the object hit at the hit location. I’ve been playing around and browsing the Javadoc and tutorials on physics listeners and the physics tick, and I’m really not sure what I need to do. At first I thought I just needed to use the listener to check for collision, determine which object needs the force applied to it, and apply the force; BUT, the javadoc and tutorial mention that if I want to apply a force, I need to do it in the Pre-physics tick phase or else it may get skipped. Then I saw that I could also apply an impulse that didn’t have that constraint.

A little more background on the current APP: I have a first person character control implemented and the character can run and jump around the environment and also sprint. the environment is procedurally generated by randomly scattering RigidBodyControl blocks of varying sizes. Basically, I want the player to be able to “shoot” a projectile and when it hits a block, the block will have a force/impulse applied at the hit location. I DO NOT WANT IT TO BE A HIT-SCAN MECHANIC. I want a projectile. Also, the projectile should not be affected by gravity. I would prefer the projectile to travel on a straight line.

Ultimately, how should I handle this situation? I know I need a physics listener, but would it be wiser to use a custom Ghost control or custom rigid body control? Should I use impulses or forces? How should I go about accessing the physics tick and do I need to? How should I handle the projectile’s destruction after the collision (should I do it in the control?)?

Thanks for the advice/help in advance. Sorry that I asked a lot of questions.

Since your projectile will essentially ignore physics but you want the collision detection I’d say, use a ghost control and move it yourself. In the collision callback you figure out what spatial you hit (probably by setting some user data on the spatials or something, there are different ways to do it).

When you detect a collision you put the collision data in some “common” thread safe list, example by using offer in a linked deque.

Then you have a separate physics listener that in the prePhysicsTick looks through the list (e.g. poll in linked deque) and applies the impulse or force.

Thanks Johan, that makes a ton of sense actually. So, then how would I go about deleting the ghost controlled projectile after saving the collision data? Also, and I forgot to mention this in my first post, what is the second parameter of the applyImpulse method exactly (rel_pos)?

My assumption is that I can just delete it immediately after saving the collision data prior to exiting the callback block, but I wasn’t sure if that was allowed. I didn’t know if you were allowed to modify the scenegraph that heavily during collisions.

Thanks again!

Physics happen in the physics thread. Scene graph changes must happen in the “render” thread. The rule of thumb (with exceptions ofc) is that anything physics must only be done in prePhysicsTick, scenegraph changes must only be done in controls (or similar methods in SimpleApp).

One way to modify the scene graph even if you are in the prePhysics listener is to enqueue the changes to the scene graph. Like described here:

If you are going the other way, i.e. inside a Control want to change some physics you have to invent another system (there is no physics-enqueue that I know of). So maybe from the scene graph thread put some data in a thread safe work list, then from a prePhysics listener read the list of “work to do” and perform the changes.
You could even make a list of Callables and then you’d have your own enqueue.

For your other question, I don’t know, I guess it’s where on the object to apply the impulse.