Character physics and first person

I"m trying to do a 1st person CameraNode attached to a DynamicPhysicsNode similar to the format described in the thread:

http://www.jmonkeyengine.com/jmeforum/index.php?topic=2060.0

Now for players, NPC’s, and monsters I don’t want the DynamicPhysicsNode really to experience any angular momentum except for what is put on them but inputs or AI.  The method described in the linked thread for keeping the character upright would be a start for this except that it uses a syncToGraphical() method that I’m fairly sure is no longer a valid solution.  So for starters I was wondering if there is a good way to limit JME physics to only controlling the forces on a DynamicPhysicsNode and allowing me to always keep my character vertical and manually adjust the other rotation.  The alternative I suppose would be to represent the character as a StaticPhysicsNode so it can still interact with DynamicPhysicsNodes and implement gravity and jumping in my own fashion.  Thanks in advance for your help.

After many hours of work I came up with a preliminary solution:


public void beforeStep(PhysicsSpace space, float time) {
            
            Vector3f xaxis = man.getLocalRotation().mult(new Vector3f(1,0,0f));
            Vector3f desiredy = new Vector3f(0,1,0);
            Vector3f desiredz = xaxis.cross(desiredy).normalize();
            Vector3f desiredx = desiredy.cross(desiredz).normalize();
            Quaternion q = new Quaternion();
            q.fromAxes(desiredx, desiredy, desiredz);
            float[] angles = man.getLocalRotation().inverse().mult(q).toAngles(null);
            man.setAngularVelocity(new Vector3f(angles[0], angles[1], angles[2]));

}


now I'm not positive that I should use Angular Velocity in this way.  I think it's possible that I should multiply that velocity vector by 1f/time and then set it back to zero in the afterStep function just to make sure that every physics step results in it being vertical.  Also I'm pretty sure this code is fairly processor-intensive and I was wondering if anyone had a more efficient solution.

To solve this nicely you'd need a special constraint in the physics engine itself. Which would mean to write native code for ODE in this case… but the solution you came up with is ok, I guess. You will probably get some jitter and large forces, if you node rotates near a static physics node or two of those velocity controlled nodes collide, but if that's ok for you, it'll be fine.



This kind of problem (negating special forces or restricting some rotation/translation axes) was discussed several times on this board (just cannot find it currently ). Maybe you can find some of the discussions.

You're right about the weird forces, the jittering actually didn't happen, but when I try to walk into a cliff I get flung into space with a very large force.  I tried to look for similar posts before I started this thread and I'm sorry that I failed earlier.  Searching for "restriction" led me in the right direction though, I'll take a look into the deeper workings of ODE and ODEJava, unfortunately the odejava site is down right now.  If I decide it's too complex for me I may go back and just use static nodes for characters and implement some simple physics and environment collision in my own manner for characters.

The odejava.org site has no info which would be useful for you anyways. You could have a look into making custom joints for ODE (ode.org) though. But if you never set up a larger c++/jni/java app or hesitate to program in c I would not recommend that, as you would need to recompile the native libraries of odejava (and ode).



Another possibility I wrote about here lately is to use a PhysicsPicker-like joint combination to control the character, maybe that’s an option for you as well.

I had already been thinking about using joints especially since I realized that a cylinder "unicycling" on a sphere moved much more smoothly than surface-motion allows.  What works well for me is to joint the cylinder to a dynamicPhysicsNode underneath the ground on a translational axis and then attaching the same cylinder to a sphere underneath it using a rotational axis, the axis of which I change depending on which direction it needs to roll for movement.  Everything is working really slick now, thanks a bunch.