Nous allons créer une balle physique et un plancher physique. Puis, une simulation physique est utilisée pour faire tomber le ballon sur le sol

Mise en place de la visualisation

La balle et le sol sont visualisées en utilisant JOGL (Java OpenGL) :

import java.awt.event.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import javax.swing.*;
import com.sun.opengl.util.*;
public class FallingBallDemo 
{
    public FallingBallDemo()
    {
        JFrame testFrame = new JFrame("Falling Ball Demo");
        testFrame.setSize( 500, 500);

        GLCanvas canvas = new GLCanvas( new GLCapabilities() );
        canvas.addGLEventListener(new TestRenderer());
        final Animator animator = new Animator( canvas);
        testFrame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
              animator.stop();
              System.exit(0);
            }
          });
        testFrame.add( canvas );
        testFrame.setVisible(true);
        animator.start();        
    }

    public static void main(String args[])
    {
        new FallingBallDemo();
    }

    class TestRenderer implements GLEventListener
    {
        private GL              gl;
        private GLUquadric quadratic;
        private GLU glu;
        private float spherePos[] = new float[3];

        public void init(GLAutoDrawable drawable)
        {
            glu = new GLU();
            quadratic = glu.gluNewQuadric();
            glu.gluQuadricNormals(quadratic, GLU.GLU_SMOOTH);  
            glu.gluQuadricTexture(quadratic, true);        
        }

        public void display(GLAutoDrawable drawable)
        {
            collision.collide(space);
            collision.applyContacts();
            world.step();

            gl = drawable.getGL();
            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
            gl.glLoadIdentity();

            gl.glTranslatef(0, -0.5f, 1f);        

            //draw ground
            gl.glColor3f(1.0f, 1.0f, 1.0f );
            gl.glBegin( GL.GL_QUADS );
                gl.glVertex3f( -1f, 0.0f,  1f );
                gl.glVertex3f(  1f, 0.0f,  1f );
                gl.glVertex3f(  1f, -0.02f, -1f );
                gl.glVertex3f( -1f, -0.02f, -1f );
            gl.glEnd();

            //draw sphere
            gl.glTranslatef(spherePos[0], spherePos[1], spherePos[2]);            
            gl.glColor3f(1.0f, 0.0f, 0.0f );
            glu.gluSphere(quadratic, 0.1f, 25, 25);        
        }


        public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) 
        {
        }

        public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) 
        {
        }
    }
}

Cela dessine un carré blanc, agissant comme un plancher sur un plan situé dans le plan ZX et une balle rouge avec un rayon de 0.1, située à (0,0,0).

Mise en place d'ODE et la modélisation du monde physique

Premièrement, nous allons avoir besoin de certaines variables pour modéliser le monde physique. Leur utilisation sera expliquée plus tard.

public class FallingBallDemo 
{
    private Body sphere;
    private World world;
    private HashSpace space;
    private JavaCollision collision;
    public FallingBallDemo()
    {
        setupODE();
        ...

Maintenant, nous allons initialiser ODEJava et créer un monde avec gravité tournée vers le bas.

private void setupODE()
{
  Odejava.init();
  world = new World();
  world.setGravity(0f, -0.2f, 0f);

Mise en place du modèle de collisions avec un coefficient de friction de Coulomb par défaut pour toutes les surfaces :

  collision = new JavaCollision(world);
  collision.setSurfaceMu(1f)

Création d'une sphère de rayon 0,1 et 0,01 de masse et définition de sa position de départ ainsi que sa vitesse linéaire. La sphère contient une description de sa masse et une géométrie de la collision. La géométrie de collision est une sphère de rayon 0,1. Le constructeur utilisé ici établit la tension d'inertie de ce volume pour la forme définie par la géométrie de collision avec une densité uniforme de 1.

  sphere = new Body("sphere",world, new GeomSphere(0.1f));
  sphere.setPosition(-1f,2.5f,0f);
  sphere.setLinearVel(0.2f,0,0);

Ensuite, nous allons mettre en place le plancher. Les 3 premiers rééls dans le constructeur définissent la normale du plan, ou en d'autres termes, les coefficients a, b et c de l'équation du plan a * x + b * y + c * z = d. Le 4ème flottant est d dans cette équation du plan. Un plan positionné sur les axes X et Z est créé comme suit:

  GeomPlane groundGeom = new GeomPlane (0f, 1f, 0f, 0f);

Les géométries de collision de nos objets physiques sont désormais rassemblés dans un objet appelé un espace.

  space = new HashSpace();        
  space.add(groundGeom);
  space.addBodyGeoms(sphere);
}

Nettoyage

Avant d'arrêter l'application, le moteur ODE doit être correctement fermé :

public FallingBallDemo()
{ 
  ...
  animator.stop();
  cleanupOde();
  System.exit(0); 
  ...
  private void cleanupOde() 
  {
    space.delete();
    collision.delete();
    world.delete();
    Ode.dCloseODE();
  }
  ...

Déplacement de la balle

Dans cette démo, la simulation physique est effectuée chaque trame. D'abord nous appelons la détection des collisions et lui laissons gérer tous les contacts de collision. Ensuite, nous ferons une étape de simulation et puis tout simplement nous lirons la position de la sphère physique pour l'utiliser lors de la traduction visuelle.

public void display(GLAutoDrawable drawable)
{
  collision.collide(space);
  collision.applyContacts();
  world.step();
  sphere.getPosition(spherePos);
  ...
}

La fin

C'est tout. Vous devriez maintenant voir la balle se déplaçant vers la droite et de tomber sur le plancher.

Code source pour cet exemple : Attach:FallingBallDemo.java