Hey guys, this is about the Flash version of Box2d. I asked this in the flash forum but have gotten no replies there. I'm kind of up shit creek if I can't find a fix for this and would really love some advice.
The bug is:
If I connect two long rectangles with a revolute joint and then power the joint to squeeze the boxes against a circle (like using a pair of scissors to cut a golf-ball say) then Box2d crashes.
I've made up a quick demo of the bug. Note that if you simply turn up the position iterations in this demo it will stop crashing. In my real project turning up the iterations reduces crashes but does not eliminate them.
Thanks to anyone who can help me out.
Here is the flash develop project for the demo:
[url]colinnorthway.com/Box2dCrashTest.zip[/url]
And here is the pertinent source file:
Code:
package
{
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Dynamics.Joints.*;
import Box2D.Dynamics.Contacts.*;
import Box2D.Common.*;
import Box2D.Common.Math.*;
import Main;
import flash.utils.getTimer
import flash.display.*;
/**
* ...
* @author Colin Northway
*/
public class CrashTest extends Sprite
{
public var m_world:b2World;
public var m_velocityIterations:int = 10;
public var m_positionIterations:int = 10;
public var m_timeStep:Number = 1.0/30.0;
public var m_physScale:Number = 30;
// Sprite to draw in to
public var m_sprite:Sprite;
public function CrashTest()
{
m_sprite = new Sprite();
addChild(m_sprite);
m_sprite.graphics.beginFill(0xFF0000);
//m_sprite.graphics.drawCircle(0, 0, 100);
// Define the gravity vector
var gravity:b2Vec2 = new b2Vec2(0.0, 30.0);
// Allow bodies to sleep
var doSleep:Boolean = true;
// Construct a world object
m_world = new b2World(gravity, doSleep);
m_world.SetWarmStarting(true);
// set debug draw
var dbgDraw:b2DebugDraw = new b2DebugDraw();
//var dbgSprite:Sprite = new Sprite();
//m_sprite.addChild(dbgSprite);
dbgDraw.SetSprite(m_sprite);
dbgDraw.SetDrawScale(30.0);
dbgDraw.SetFillAlpha(0.3);
dbgDraw.SetLineThickness(1.0);
dbgDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
m_world.SetDebugDraw(dbgDraw);
var polyShape:b2PolygonShape;
var bodyDef:b2BodyDef;
var body:b2Body;
var fixtureDef:b2FixtureDef;
var circleShape:b2CircleShape;
//the static circle
circleShape = new b2CircleShape(2);
bodyDef = new b2BodyDef();
bodyDef.position = new b2Vec2(8, 9);
bodyDef.type = b2Body.b2_staticBody;
body = m_world.CreateBody(bodyDef);
fixtureDef = new b2FixtureDef();
fixtureDef.shape = circleShape;
fixtureDef.friction = 1;
body.CreateFixture(fixtureDef);
//the horizontal bar
polyShape = new b2PolygonShape();
polyShape.SetAsBox(5,8/30);
bodyDef = new b2BodyDef();
bodyDef.position = new b2Vec2(12, 5);
bodyDef.type = b2Body.b2_dynamicBody;
var bar1:b2Body = m_world.CreateBody(bodyDef);
fixtureDef = new b2FixtureDef();
fixtureDef.density = 1;
fixtureDef.friction = 1;
fixtureDef.shape = polyShape;
bar1.CreateFixture(fixtureDef)
//the vertical bar
polyShape = new b2PolygonShape();
polyShape.SetAsBox(5, 8/30);
bodyDef = new b2BodyDef();
bodyDef.position = new b2Vec2(5, 12);
bodyDef.angle = Math.PI / 2;
bodyDef.type = b2Body.b2_dynamicBody;
var bar2:b2Body = m_world.CreateBody(bodyDef);
fixtureDef = new b2FixtureDef();
fixtureDef.density = 1;
fixtureDef.friction = 1;
fixtureDef.shape = polyShape;
bar2.CreateFixture(fixtureDef)
//the "body" circle
circleShape = new b2CircleShape(2);
bodyDef = new b2BodyDef();
bodyDef.position = new b2Vec2(5, 5);
bodyDef.angle = Math.PI / 2;
bodyDef.type = b2Body.b2_dynamicBody;
var square:b2Body = m_world.CreateBody(bodyDef);
fixtureDef = new b2FixtureDef();
fixtureDef.density = 1;
fixtureDef.shape = circleShape;
square.CreateFixture(fixtureDef);
var speed:Number = 2;
//the joints to articulate them
var jointDef:b2RevoluteJointDef;
jointDef = new b2RevoluteJointDef();
jointDef.Initialize(bar1, square, new b2Vec2(7, 5));
jointDef.enableMotor = true;
jointDef.maxMotorTorque = 1600;
jointDef.collideConnected = false;
_joint1 = m_world.CreateJoint(jointDef) as b2RevoluteJoint;
jointDef= new b2RevoluteJointDef();
jointDef.Initialize(bar2, square, new b2Vec2(5, 7));
jointDef.enableMotor = true;
jointDef.maxMotorTorque = 1600;
jointDef.collideConnected = false;
_joint2 = m_world.CreateJoint(jointDef) as b2RevoluteJoint
}
protected var _joint1:b2RevoluteJoint;
protected var _joint2:b2RevoluteJoint;
protected function turnOnJoints():void
{
_joint1.SetMotorSpeed(-2.5);
_joint2.SetMotorSpeed(3.5);
}
protected var count:int = 50;
public function update():void {
count--;
if ( count < 0 ) {
turnOnJoints();
}
// Update physics
var physStart:uint = getTimer();
m_world.Step(m_timeStep, 7, 3);
m_world.ClearForces();
// Render
m_world.DrawDebugData();
}
}
}