Created
May 10, 2015 15:32
-
-
Save mucaho/fcbd9bfd1ce3111d518b to your computer and use it in GitHub Desktop.
Calculate checksum for DominoTest using hopefully deterministic JBox2D - see https://github.com/jbox2d/jbox2d/issues/19
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.jbox2d.checksum; | |
import org.jbox2d.collision.shapes.PolygonShape; | |
import org.jbox2d.common.Settings; | |
import org.jbox2d.common.Vec2; | |
import org.jbox2d.dynamics.*; | |
import java.util.concurrent.ScheduledThreadPoolExecutor; | |
import java.util.concurrent.TimeUnit; | |
import java.util.concurrent.atomic.AtomicInteger; | |
public class ChecksumTest implements Runnable { | |
// DISABLE JBOX2D FAST MATH!!! | |
static { | |
Settings.FAST_ABS = false; | |
Settings.FAST_ATAN2 = false; | |
Settings.FAST_CEIL = false; | |
Settings.FAST_FLOOR = false; | |
Settings.FAST_POW = false; | |
Settings.FAST_ROUND = false; | |
Settings.SINCOS_LUT_ENABLED = false; | |
} | |
final float dwidth = .20f; | |
final float dheight = 1.0f; | |
float ddensity;// = 10f; | |
final float dfriction = 0.1f; | |
int baseCount = 25; | |
private World world; | |
private Body groundBody; | |
private Body bullet1; | |
private Body bullet2; | |
public void makeDomino(float x, float y, boolean horizontal, World world) { | |
PolygonShape sd = new PolygonShape(); | |
sd.setAsBox(.5f * dwidth, .5f * dheight); | |
FixtureDef fd = new FixtureDef(); | |
fd.shape = sd; | |
fd.density = ddensity; | |
BodyDef bd = new BodyDef(); | |
bd.type = BodyType.DYNAMIC; | |
fd.friction = dfriction; | |
fd.restitution = 0.65f; | |
bd.position = new Vec2(x, y); | |
bd.angle = horizontal ? (float) (Math.PI / 2.0) : 0f; | |
Body myBody = world.createBody(bd); | |
myBody.createFixture(fd); | |
} | |
public void initWorld() { | |
Vec2 gravity = new Vec2(0, -10f); | |
world = new World(gravity); | |
world.setParticleGravityScale(0.4f); | |
world.setParticleDensity(1.2f); | |
BodyDef bodyDef = new BodyDef(); | |
groundBody = world.createBody(bodyDef); | |
world.setAllowSleep(true); | |
world.setWarmStarting(true); | |
world.setSubStepping(false); | |
world.setContinuousPhysics(true); | |
} | |
public void initTest() { | |
{ // Floor | |
PolygonShape sd = new PolygonShape(); | |
sd.setAsBox(50.0f, 10.0f); | |
BodyDef bd = new BodyDef(); | |
bd.position = new Vec2(0.0f, -10.0f); | |
world.createBody(bd).createFixture(sd, 0f); | |
} | |
{ | |
ddensity = 10f; | |
// Make bullet | |
PolygonShape sd = new PolygonShape(); | |
sd.setAsBox(.7f, .7f); | |
FixtureDef fd = new FixtureDef(); | |
fd.density = 35f; | |
BodyDef bd = new BodyDef(); | |
bd.type = BodyType.DYNAMIC; | |
fd.shape = sd; | |
fd.friction = 0f; | |
fd.restitution = 0.85f; | |
bd.bullet = true; | |
// bd.addShape(sd); | |
bd.position = new Vec2(30f, 50f); | |
bullet1 = world.createBody(bd); | |
bullet1.createFixture(fd); | |
bullet1.setLinearVelocity(new Vec2(-25f, -25f)); | |
bullet1.setAngularVelocity(6.7f); | |
fd.density = 25f; | |
bd.position = new Vec2(-30, 25f); | |
bullet2 = world.createBody(bd); | |
bullet2.createFixture(fd); | |
bullet2.setLinearVelocity(new Vec2(35f, -10f)); | |
bullet2.setAngularVelocity(-8.3f); | |
} | |
{ | |
float currX; | |
// Make base | |
for (int i = 0; i < baseCount; ++i) { | |
currX = i * 1.5f * dheight - (1.5f * dheight * baseCount / 2f); | |
makeDomino(currX, dheight / 2.0f, false, world); | |
makeDomino(currX, dheight + dwidth / 2.0f, true, world); | |
} | |
currX = baseCount * 1.5f * dheight - (1.5f * dheight * baseCount / 2f); | |
// Make 'I's | |
for (int j = 1; j < baseCount; ++j) { | |
if (j > 3) | |
ddensity *= .8f; | |
float currY = dheight * .5f + (dheight + 2f * dwidth) * .99f * j; // y at center of 'I' | |
// structure | |
for (int i = 0; i < baseCount - j; ++i) { | |
currX = i * 1.5f * dheight - (1.5f * dheight * (baseCount - j) / 2f);// + | |
// parent.random(-.05f, | |
// .05f); | |
ddensity *= 2.5f; | |
if (i == 0) { | |
makeDomino(currX - (1.25f * dheight) + .5f * dwidth, currY - dwidth, false, world); | |
} | |
if (i == baseCount - j - 1) { | |
// if (j != 1) //djm: why is this here? it makes it off balance | |
makeDomino(currX + (1.25f * dheight) - .5f * dwidth, currY - dwidth, false, world); | |
} | |
ddensity /= 2.5f; | |
makeDomino(currX, currY, false, world); | |
makeDomino(currX, currY + .5f * (dwidth + dheight), true, world); | |
makeDomino(currX, currY - .5f * (dwidth + dheight), true, world); | |
} | |
} | |
} | |
} | |
@Override | |
public void run() { | |
world.step(1f / 60f, 8, 3); | |
} | |
public int bodyCount() { | |
int count = 0; | |
Body body = world.getBodyList(); | |
while (body != null) { | |
count++; | |
body = body.getNext(); | |
} | |
return count; | |
} | |
public int checksum() { | |
int checkSum = 7; | |
Body body = world.getBodyList(); | |
while (body != null) { | |
checkSum = 31 * checkSum + body.getPosition().hashCode(); | |
checkSum = 31 * checkSum + body.getLinearVelocity().hashCode(); | |
checkSum = 31 * checkSum + Float.floatToIntBits(body.getAngularVelocity()); | |
body = body.getNext(); | |
} | |
return checkSum; | |
} | |
public static void main (String[] args) throws InterruptedException { | |
final ChecksumTest test = new ChecksumTest(); | |
test.initWorld(); | |
test.initTest(); | |
final AtomicInteger steps = new AtomicInteger(0); | |
final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); | |
executor.scheduleAtFixedRate(new Runnable() { | |
@Override | |
public void run() { | |
test.run(); | |
steps.getAndIncrement(); | |
if (steps.get() >= 1000) | |
executor.shutdown(); | |
} | |
}, 0, 16, TimeUnit.MILLISECONDS); | |
executor.awaitTermination(1000 * 16 * 2, TimeUnit.MILLISECONDS); | |
System.out.println("Step count: " + steps.get()); | |
System.out.println("Body count: " + test.bodyCount()); | |
System.out.println("Bullet1 pos: " + test.bullet1.getPosition()); | |
System.out.println("Bullet2 pos: " + test.bullet2.getPosition()); | |
System.out.println("Checksum: " + test.checksum()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment