No Torque/Z Translation

Hi, is it possible to turn off Torque for a given DynamicPhysicsNode - so that it never spins when impacting with another physics object?  Or reduce the torque to a single axis (Z)?

Also, is it possible to restrict a DynamicPhysicsNode to only moving along the X and Y axis when colliding with another physics object?



(Imagine Pong, where the ball was actually a square - when it bounced it never rotated, and it only moved along two axis)



I've read in previous posts that this can be done by overwritting/creating a new joint - but I dont know how to go about this.

I've also read that you can set the after step rotational/translation values to 0, but wouldn't it be more efficient/effective to just turn off these calculations altogether?



Has anybody done this before, or could show me how to do it?



Thanks

In the best of all worlds, you'd simply create a Joint with two translational axes and tie it to your object. Unfortunately such joints are not supported by the ODE natives :frowning:



To efficiently support the things, you'd like, one would have to write new ODE joints in C, rebuild the ODEJava natives, and add the support for the new joints to jME Physics 2 :-o

(There already is a patch for an ODE joint restricting the movement of objects to a plan (two axes), but it's not included in the official ODE builds - which ODEJava and thus jME Physics 2 are using).



But I think you should be able to realize it less efficient but more easily this way: Attach an empty DynamicPhysicsNode to a Joint with a single translational axis (e.g. [1,0,0]). Attach an object (DynamicPhysicsNode) that should move in a plane and does not rotate to that empty node with another Joint. The second joint has a single translational axis, too (e.g. [0,1,0]). Give it a shot and tell if this works for you.



Another easy way would be to reset rotation/velocity values each step, yes. But it could increase visual bodypenetration or even cause strange jittering. But you can give it a try, also.

Ok thanks Irrisor.



I've give your first solution a shot initially as it seems less of a bodge. And get back to you with the results.

We need a Physics Wiki really, the core jME wiki is extremely useful and im sure it would stop people like hassling you all day long.



As a side note, is there any intention of ODE officially supporting such joints in the near future?  If there

Doesn't seem like it - maybe some people need to bug them about it on the mailing list :slight_smile:



Regarding a physics wiki: yes, that'd probably be good. Would have little content initially, though, as I don't invest much time on physics and game programming, currently. But I'll have a look what it takes to set one up and post here to ask if more people like the idea.

Well if you get the basics up and running we contribute bits as we come across them, and you can proof them.  :smiley:

Hi irrisor.



I begun experimenting with your propsed Joint method, and encountered a few probs.

You tried to add another axis. Not another joint. You need to add another DynamicPhysicsNode and a Joint:


    (world ---) joint1 ---- dummy node --- joint2 --- your normal node



And yes, you'd have 1000 Joints for 500 objects, plus another 500 dummy objects - that's what I meant with 'inefficient'. It probably wouldn't scale for more than a couple of objects.

Thats less than ideal then  :expressionless:

Still a bit confused about the Joint/Axes usage, if I understood it better id get something into the Wiki.

Add this to TestGenerateGeometry to see what I mean:


        DynamicPhysicsNode dummy = getPhysicsSpace().createDynamicNode();
        Joint joint1 = getPhysicsSpace().createJoint();
        joint1.attach( dummy );
        joint1.createTranslationalAxis().setDirection( new Vector3f( 1, 0, 0 ) );
        Joint joint2 = getPhysicsSpace().createJoint();
        joint2.createTranslationalAxis().setDirection( new Vector3f( 0, 1, 0 ) );
        joint2.attach( dynamicNode, dummy );

Ok I get it now  :stuck_out_tongue: duh!



I've made a few alterations to the previous TestClass I sent over (Lesson4). And some strange behaviour is occurring.



As a side note: I dont think I will use this approach as it seems a bit of a work around on a complex framework for something which could be handled by a few simple calculations - but I thought you should take a look just in case it highlights a problem.



package com;

import java.util.logging.Level;
import com.jme.input.InputHandler;
import com.jme.input.KeyInput;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.math.Vector3f;
import com.jme.util.LoggingSystem;
import com.jmex.physics.*;
import com.jmex.physics.geometry.PhysicsBox;
import com.jmex.physics.util.SimplePhysicsGame;

public class TestRestrictedPhysics extends SimplePhysicsGame {
   private DynamicPhysicsNode dynamicNode, dynamicNode2;
   
   protected void simpleInitGame() {
      DynamicPhysicsNode dummy;
      Joint joint1, joint2;
      
      getPhysicsSpace().setDirectionalGravity(new Vector3f(0, 0, 0));
      
      dynamicNode = getPhysicsSpace().createDynamicNode();
      dynamicNode.createBox( "rolling sphere" );
      dynamicNode.getLocalTranslation().set( -10, 0, 0 );
      rootNode.attachChild( dynamicNode );
      
      dynamicNode2 = getPhysicsSpace().createDynamicNode();
      dynamicNode2.createBox( "rolling sphere" );
      dynamicNode2.getLocalTranslation().set( 0, 0.75f, 0.75f );
      rootNode.attachChild( dynamicNode );
      
      dummy = getPhysicsSpace().createDynamicNode();
      joint1 = getPhysicsSpace().createJoint();
      joint1.attach( dummy );
      joint1.createTranslationalAxis().setDirection( new Vector3f( 1, 0, 0 ) );
      joint2 = getPhysicsSpace().createJoint();
      joint2.createTranslationalAxis().setDirection( new Vector3f( 0, 1, 0 ) );
      joint2.attach( dynamicNode, dummy );
      
      dummy = getPhysicsSpace().createDynamicNode();
      joint1 = getPhysicsSpace().createJoint();
      joint1.attach( dummy );
      joint1.createTranslationalAxis().setDirection( new Vector3f( 1, 0, 0 ) );
      joint2 = getPhysicsSpace().createJoint();
      joint2.createTranslationalAxis().setDirection( new Vector3f( 0, 1, 0 ) );
      joint2.attach( dynamicNode2, dummy );
      
      input.addAction( new MyInputAction(),  InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_SPACE, InputHandler.AXIS_NONE, true );
      input.addAction( new MyInputAction2(),  InputHandler.DEVICE_KEYBOARD, KeyInput.KEY_R, InputHandler.AXIS_NONE, false );
      
      showPhysics = true;
   }
   
   private class MyInputAction extends InputAction {
      
      public void performAction( InputActionEvent evt ) {
         dynamicNode.addForce( new Vector3f( 50, 0, 0 ) );
      }
   }
   
   private class MyInputAction2 extends InputAction {
      
      public void performAction( InputActionEvent evt ) {
         dynamicNode.clearDynamics();
         dynamicNode.getLocalTranslation().set( -10, 0, 0 );
      }
   }
   
   protected void simpleUpdate() {
      if ( dynamicNode.getWorldTranslation().x > 10 ||  dynamicNode.getWorldTranslation().x < -10) {
         dynamicNode.clearDynamics();
         dynamicNode.getLocalTranslation().set( -9, 0, 0 );
      }
      
      if ( dynamicNode2.getWorldTranslation().x > 9 ||  dynamicNode2.getWorldTranslation().x < -9) {
         dynamicNode2.clearDynamics();
         dynamicNode2.getLocalTranslation().set( 0, 0.5f, 0.5f );
      }
   }
   
   public static void main( String[] args ) {
      LoggingSystem.getLogger().setLevel( Level.WARNING );
      new TestRestrictedPhysics().start();
   }
}



Space: addsForce to the left box.
R: resets the left box.

When the boxes collide everything appears to react as it should. But then the box with force (originally the left one) is reset in the update method - for moving to far across the x axis, clearingDynamics doesnt seem to remove the applied force. Also the second box will not reset since adding the joints. And after a few seconds of stopping at the right will propel itself across the negative x axis (left).

Give it a shot, you'll see.

I know this thread is old, but I have the same requirement: objects that move and collide on the x-y plane with no rotation. I tried this same approach (two joints with a dummy node in between) and I couldn't make it work.



One problem is that the dummy node has mass, so it isn't the same as having a single joint with two axes. I suppose I could get around this by making the mass very small.



Another problem is that joints appear to be soft and springy. I watched the joints using PhysicsDebugger.drawPhysics(). If I apply large forces to the node that I want to move, I can see the joints bend and then spring back into place. The more I push the object, the less stable the joints become, to the point where the dummy node seems to jump around the screen at random and make the other node spin around. I tried setting the breaking forces and torques to infinity but still had this problem. I also played around a little bit with the spring constants and damping coefficients but I wasn't able to get this to work.



Ultimately, I found that resetting the translation, rotation and angular velocity every frame worked well enough for my game. I imagine the energy that would have gone into rotation is simply lost this way so the simulation is less accurate and collisions are less bouncy than they should be, but it is nice and stable.



If anyone knows of a better way to do this, I'd still be interested. Thanks in advance.