Friday, February 25, 2005

BoxStack.java

The main class for building a World where boxes are dropping on a flat surface. A SimpleSpace is attached for collision detection. The things to be implemented are HashSpace, box-box and box-plane collisions, and a Dantzig LCP constraint solver.
package simulator;

import javax.vecmath.*;
import java.awt.event.*;
import com.brackeen.javagamebook.input.*;
import java.util.List;
import java.util.LinkedList;


public class BoxStack
extends Simulator {

private class MyObject {
Body
body; // the body

Geom
geom; // geometries representing this body
};

private static final int NUM = 10;
private static final double DENSITY = 5.0;
private static final int MAX_CONTACTS = 4; // maximum number of contact points per body

private static MyObject[] obj;
private static int num = 0;
private static int nextobj = 0;
private static boolean random_pos = true;
private static World world;
private static Geom floor;

private List contactgroup;

protected GameAction fire

=
new GameAction("fire", GameAction.DETECT_INITAL_PRESS_ONLY);

private class BoxStackCollision
extends Collision implements ContactConstants {

public void nearCallback(Geom g1, Geom g2) {

// exit without doing anything if the two bodies are connected by a joint

Body b1 = g1.getBody();
Body b2 = g2.getBody();
if (b1!=null && b2!=null &&
b1.isConnectedExcluding(b2,
"simulator.ContactJoint")) return;

Contact[] contact =
new Contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box

for (int i = 0; i < MAX_CONTACTS; i++) {
contact[i] =
new Contact();
contact[i].surface.mode = Bounce | SoftCFM;
contact[i].surface.mu = Double.POSITIVE_INFINITY;
contact[i].surface.mu2 =
0;
contact[i].surface.bounce =
0.1;
contact[i].surface.bounce_vel =
0.1;
contact[i].surface.soft_cfm =
0.01;
}
int numc = collide(g1, g2, MAX_CONTACTS, contact);
if (numc > 0) {
for (int i = 0; i < numc; i++) {
Joint c =
new ContactJoint(world, contact[i]);
c.attach(b1, b2);
}
}
}
}

public static void main(String[] args) {
new BoxStack().run();
}

public void start() {
inputManager.mapToKey(
fire, KeyEvent.VK_SPACE);
inputManager.mapToMouse(
fire, InputManager.MOUSE_BUTTON_1);

world =
new World();
//space = new SimpleSpace(null);

contactgroup = new LinkedList();
obj =
new MyObject[NUM];
for (int i = 0; i < NUM; i++) {
obj[i] =
new MyObject();
}

world.setGravity(
0, -0.5, 0);
world.setCFM(
1e-5);
world.setAutoDisableFlag(
true);
world.setContactMaxCorrectingVel(
0.1);
world.setContactSurfaceLayer(
0.001);

floor =
new Plane(space, 0, 1, 0, 0);
space.setCollision(
new BoxStackCollision());
}

public void step() {
//floor.setState(Geom.STATE_IDLE);

command();
space.collide();
world.step();
}

public void command() {
int i;
if (fire.isPressed()) {
if (num < NUM) {
i = num;
num++;
}
else {
i = nextobj;
nextobj++;
if (nextobj >= num) {
nextobj =
0;
}
}
obj[i].body =
new Body(world);
double[] sides = new double[3];
for (int k = 0; k < 3; k++) {
sides[k] = Math.random() *
50 + 10;
}

Matrix3d R =
new Matrix3d();
if (random_pos) {
obj[i].body.setPosition(Math.random() *
20 - 100,
Math.random() +
200,
Math.random() *
20 - 200);
R.set(
new AxisAngle4d(Math.random() * 2.0 - 1.0,
Math.random() *
2.0 - 1.0,
Math.random() *
2.0 - 1.0,
Math.random() *
10.0 - 5.0));
}
else {
double maxheight = 0;
for (int k = 0; k < num; k++) {
Vector3d pos = obj[k].body.getPosition();
if (pos.z > maxheight) {
maxheight = pos.z;
}
}
obj[i].body.setPosition(
0, maxheight + 1, 0);
R.set(
new AxisAngle4d(0, 1, 0, Math.random() * 10.0 - 5.0));
}
obj[i].body.setRotation(R);
//dBodySetData (obj[i].body,(void*) i);

Mass m =
new Mass();
m.setBox(DENSITY, sides[
0], sides[1], sides[2]);
obj[i].geom =
new Box(space, sides[0], sides[1], sides[2]);
obj[i].geom.setBody(obj[i].body);
obj[i].body.setMass(m);
}
}
}



Tuesday, February 08, 2005

Resource on the web

The work now has been stuck in HashSpace. The thing that baffles me is how the space is divided with multiple resolutions. Meanwhile, the search for HashSpace revealed some interesting projects:
  • PyODE - Python bindings for ODE
  • Odejava - Java bindings for ODE
Moreover, Odejava is associated with two Java 3D game engine:
  • Xith3D - an open source 3D scenegraph for Java. It is designed to be leaner, more game orientated alternative to the Java3D scenegraph, yet using the same basic scenegraph structure as Java3D.
  • jME - Java gaming engine