Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (777)
Games in Android Showcase (231)
games submitted by our members
Games in WIP (856)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [Odejava] Box won't tip over  (Read 3456 times)
0 Members and 1 Guest are viewing this topic.
Offline Hmm

Senior Newbie





« Posted 2007-05-13 19:46:20 »

Hi,

I'm new to Odejava (to physics in general).  I have a scene set up which consists of a floor and several walls.  I'm dropping a small cube onto the floor with a random velocity and rotation.

Everything works great, until the cube starts to slow down from the friction.  If the cube was rolling along the ground, and the friction slows it to a stop, it will completely stop, even if it is sitting on the ground at a massive angle (will sit on it's edge instead of a face):



Is there something wrong with the way that I'm setting up my objects?

Worldwide Settings:
1  
2  
3  
4  
5  
6  
physics_JavaCollision.setSurfaceMu(1.0f);
physics_JavaCollision.setSurfaceBounce(0f);
physics_JavaCollision.setSurfaceBounceVel(5000.1f);
physics_JavaCollision.setSurfaceMode(Ode.dContactBounce);
physics_World.setStepInteractions(50);
physics_World.setStepSize(0.05f);


Contact between cube and wall:
1  
2  
3  
physics_Contact.setMode(Ode.dContactBounce | Ode.dContactApprox1);
physics_Contact.setBounce(0.2f);
physics_Contact.setBounceVel(0.01f);


Creating the cube:
1  
2  
3  
4  
5  
this.myBody = new Body(physics_World);
this.myBody.setGeom(new GeomBox(DIAMETER * 2, DIAMETER * 2, DIAMETER * 2));
this.myBody.adjustMass(1.0f);
this.myBody.resetRotationAndForces();
physics_HashSpace.addBodyGeoms(this.myBody);


The floor and walls of the box are simple GeomBoxes which have been added to the world without a Body.

Thanks for any help!  Smiley  More code is available is needed to diagnose the problem.
Offline irrisor

Junior Devvie





« Reply #1 - Posted 2007-05-14 08:24:34 »

sounds like auto-disabled - raise the thresholds for the auto-disable feature
Offline Hmm

Senior Newbie





« Reply #2 - Posted 2007-05-14 17:27:25 »

I've tried adding the following to the creation of my bodies:

1  
2  
this.myBody.setAutoDisable(false);
this.myBody.setAngularVelocityDisableThreshold(5f);


...but it has no effect.  isAutoDisabling() returns false on both the world and the bodies, even before I added that code.

In fact, it is very rare that a box actually lands on a face, the majority of the tie is spent either partly or fully resting on a single edge as shown above, but the physics seem to work fine otherwise.  Would adding a mass to the corner of each box help at all?

Also, here's how I'm positioning my boxes and giving them initial force and spin:
1  
2  
3  
4  
boxObject.translate(-(FIELD_WIDTH / 2f) - CAMERA_BUFFER_SPACE * 0.3f, -(FIELD_HEIGHT * 1.5f), (FIELD_WIDTH * 0.1f));
boxObject.myBody.setForce(500.0f + (float)((Math.random() - 0.5) * 400), 0f, (float)((Math.random() - 0.5) * 600));
boxObject.myBody.setAngularVel(0f, (float)(Math.random() * 2), (float)(Math.random() * 2));
myWorld.addObject(boxObject);


Yet another thing I've noticed: when the boxes are landing on the base and flipping around, it almost looks like there is some kind of force holding it upwards.  Ex. when a box is rolling around in one direction, and is in the position above, something appears to pull it backward back onto it's edge.  In my simulation, the Y axis is reversed (is positive going down).  Could this have something to do with it?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline arne

Senior Devvie




money is the worst drug- we should not let it rule


« Reply #3 - Posted 2007-05-14 19:37:14 »

hmm - could it be, that you've set the mass incorrectly?

This error could happen, if you create your geom, set the position of the geom and then attach a body. The mass of the geom is centered at the origin of the Body's coordinate system. To solve the problem, change your Box' position by modifing the position of the body and not of the geom itself.

:: JOODE :: Xith3d :: OdeJava ::
Offline Hmm

Senior Newbie





« Reply #4 - Posted 2007-05-14 19:52:06 »

Whoops, forgot that the 'boxObject.translate(...);' call that I posted above actually refers to a 3D engine call and not a physics engine call.  It actually refers to this:

1  
2  
3  
4  
5  
public void translate(float x, float y, float z)
{
   this.myBody.setPosition(x, y, z);
   //3D engine stuff...
}


So, putting this together, the code from the creation of the object all the way to it's positioning, relating to mass, position, and rotation, is:
1  
2  
3  
4  
5  
6  
7  
8  
9  
this.myBody = new Body(physics_World);
this.myBody.setGeom(new GeomBox(DIAMETER * 2, DIAMETER * 2, DIAMETER * 2));
this.myBody.adjustMass(1.0f);
this.myBody.resetRotationAndForces();
physics_HashSpace.addBodyGeoms(this.myBody);

this.myBody.setPosition(-(FIELD_WIDTH / 2f) - CAMERA_BUFFER_SPACE * 0.3f, -(FIELD_HEIGHT * 1.5f), (FIELD_WIDTH * 0.1f));
this.myBody.setForce(500.0f + (float)((Math.random() - 0.5) * 400), 0f, (float)((Math.random() - 0.5) * 600));
this.myBody.setAngularVel(0f, (float)(Math.random() * 2), (float)(Math.random() * 2));


Is that the correct way to set the mass?
Offline Hmm

Senior Newbie





« Reply #5 - Posted 2007-05-14 20:01:33 »

Now that you mention it, on closer inspection I can see that the boxes which land perfectly flat always land on the same face, making it look like the mass is to blame.

What kind of function calls should I be looking for which could be upsetting the mass?
Offline Hmm

Senior Newbie





« Reply #6 - Posted 2007-05-16 22:21:50 »

Could it have something to do with the way that I'm displaying the boxes in my 3D engine?

Here's what I do on every step of the physics engine:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
//Get ODEJava's position & rotation
Vector3f myPosition = this.myBody.getPosition();
Matrix3f myRotation = this.myBody.getRotation();

//This function converts the position into something that the 3D renderer can handle, and moves the displayed cube there
moveTo(new SimpleVector(myPosition.x, myPosition.y, myPosition.z));

//Converts the rotation matrix to put into the 3D renderer
this.setRotationMatrix(Matrix3fToMatrix(myRotation));

//Add position history (for telling when the box stops moving)
if (this.previousPositions.size() >= POSITION_HISTORY_DEPTH)
{
   this.previousPositions.removeElementAt(0);
   this.previousPositions.addElement(myPosition);
} else {
   this.previousPositions.push(myPosition);
}


Here's how I'm converting the matrix format:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
protected Matrix Matrix3fToMatrix(Matrix3f input)
{
   //Declare variables
   float[] insertDump = new float[16]; //The array holding the values in the new Matrix
   float[] rowDump = new float[3];     //The array for temporarily holding values from the rows of the Matrix3f
   int targetElement = 0;              //Points to the next location in the insertDump to add data
   
   //Loop through the rows of the Matrix3f
   for (int sourceRow = 0; sourceRow < 3; sourceRow++)
   {
      //Grab the row from the Matrix3f
      input.getRow(sourceRow, rowDump);
     
      //Insert the 3 elements from the Matrix3f into the Matrix.  The fourth element has been initialized to 0.0f.
      insertDump[targetElement] = rowDump[0];
      insertDump[targetElement + 1] = rowDump[1];
      insertDump[targetElement + 2] = rowDump[2];
     
      //Move the target ahead by four spaces
      targetElement += 4;
   }
   
   //The final row consists of { 0.0f, 0.0f, 0.0f, 1.0f }, since this is a rotation matrix
   insertDump[15] = 1.0f;
   
   //Create the new Matrix and load in the values
   Matrix output = new Matrix();
   output.setDump(insertDump);
   
   //Return
   return output;
}


Also, the 3D engine that I'm using has a coordinate system in which the Y-axis is positive going downward, the X-axis is positive going right, and the Z-axis is positive moving into the screen.  Could this be messing up ODE?
Offline Riven
Administrator

« JGO Overlord »


Medals: 1357
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #7 - Posted 2007-05-17 18:14:19 »

Maybe these rather exotic values are to blame:

1  
2  
3  
4  
physics_JavaCollision.setSurfaceMu(1.0f); // try 0.8-0.9
physics_JavaCollision.setSurfaceBounce(0f); // try 0.1
physics_JavaCollision.setSurfaceBounceVel(5000.1f); // try 2.0
physics_JavaCollision.setSurfaceMode(Ode.dContactBounce);

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Hmm

Senior Newbie





« Reply #8 - Posted 2007-05-17 19:23:43 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
   physics_World.setGravity(0.0f, 9.81f, 0.0f);
   physics_JavaCollision = new org.odejava.collision.JavaCollision(physics_World);
   physics_Contact = new org.odejava.collision.Contact(physics_JavaCollision.getContactIntBuffer(), physics_JavaCollision.getContactFloatBuffer());
   environment_IDs = new HashMap();
   physics_JavaCollision.setSurfaceMu(0.8f);
   physics_JavaCollision.setSurfaceBounce(0.1f);
       physics_JavaCollision.setSurfaceBounceVel(2.0f);
   physics_JavaCollision.setSurfaceMode(Ode.dContactBounce);
   physics_World.setStepInteractions(10);
   physics_World.setStepSize(0.05f);


...produced the same results.
Offline Hmm

Senior Newbie





« Reply #9 - Posted 2007-05-20 18:16:05 »

Alright, after a week of debugging I found the answer.  For the record, the 3D engine I was interfacing with was jPCT.

The problem was with the display of the rotation.  My Matrix3fToMatrix() function (see above) was being used to transfer the rotation matrix from OdeJava to jPCT.  Either the OdeJava matrix was wrong, the conversion was wrong, or the engines are incompatible.  Either way, the solution was to use Quaternions.

Here's the function that I used to convert the Quaternion from Body.getQuaternion() to a Matrix for jPCT:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
protected Matrix Quat4fToMatrix(javax.vecmath.Quat4f input)
{
   float[] MatrixDump = new float[16];
   float xx = input.x * input.x;
   float xy = input.x * input.y;
   float xz = input.x * input.z;
   float xw = input.x * input.w;
   float yy = input.y * input.y;
   float yz = input.y * input.z;
   float yw = input.y * input.w;
   float zz = input.z * input.z;
   float zw = input.z * input.w;
   
   MatrixDump[0] = 1 - 2 * ( yy + zz );
   MatrixDump[4] = 2 * ( xy - zw );
   MatrixDump[8] = 2 * ( xz + yw );
   MatrixDump[1] = 2 * ( xy + zw );
   MatrixDump[5] = 1 - 2 * ( xx + zz );
   MatrixDump[9] = 2 * ( yz - xw );
   MatrixDump[2] = 2 * ( xz - yw );
   MatrixDump[6] = 2 * ( yz + xw );
   MatrixDump[10] = 1 - 2 * ( xx + yy );
   MatrixDump[15] = 1;
   
   Matrix buffer = new Matrix();
   buffer.setDump(MatrixDump);
   return buffer;
}


Thanks for all the help guys! Wink
Pages: [1]
  ignore  |  Print  
 
 

 
hadezbladez (330 views)
2018-11-16 13:46:03

hadezbladez (169 views)
2018-11-16 13:41:33

hadezbladez (328 views)
2018-11-16 13:35:35

hadezbladez (78 views)
2018-11-16 13:32:03

EgonOlsen (2168 views)
2018-06-10 19:43:48

EgonOlsen (2195 views)
2018-06-10 19:43:44

EgonOlsen (1372 views)
2018-06-10 19:43:20

DesertCoockie (1998 views)
2018-05-13 18:23:11

nelsongames (1641 views)
2018-04-24 18:15:36

nelsongames (2291 views)
2018-04-24 18:14:32
Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45

Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!