function b2Step(cnt) {
	var stepping = false;
	var timeStep = 1.0/60;
	var iteration = 1;
	world.Step(timeStep, iteration);
	
	if (clearBackground) ctx.clearRect(0, 0, canvasWidth, canvasHeight);
	
	b2DrawWorld(world, ctx);
	world.CleanBodyList	();

	setTimeout('b2Step(' + (cnt || 0) + ')', 10);
}

function b2DrawWorld(world, context) {	
	for (var b = world.m_bodyList; b; b = b.m_next) {
		if (b.IsStatic() && hideStatics) {
		} else {
			for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
				var p = b2DrawShape(s, context);
				if (p > canvasHeight+50) {
					if (hideStatics) world.DestroyBody(b);
				}
			}
		}
	}
}

function b2DrawShape(shape, context) {
	context.strokeStyle = '#333';
	context.fillStyle = '#fff';
	context.beginPath();
	
	var yPos = 0;
	switch (shape.m_type) {
	case b2Shape.e_circleShape:
		{
			var circle = shape;
			var pos = circle.m_position;
			var r = circle.m_radius;
			var segments = 16.0;
			var theta = 0.0;
			var dtheta = 2.0 * Math.PI / segments;
			yPos = pos.y;
			// draw circle
			context.moveTo(pos.x + r, pos.y);
			for (var i = 0; i < segments; i++) {
				var d = new b2Vec2(r * Math.cos(theta), r * Math.sin(theta));
				var v = b2Math.AddVV(pos, d);
				context.lineTo(v.x, v.y);
				theta += dtheta;
			}
			context.lineTo(pos.x + r, pos.y);
	
			context.fill();
		}
		break;
	case b2Shape.e_polyShape:
		{
			var poly = shape;
			var tV = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[0]));
			yPos = tV.y;
			context.moveTo(tV.x, tV.y);
			for (var i = 0; i < poly.m_vertexCount; i++) {
				var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
				context.lineTo(v.x, v.y);
			}
			context.lineTo(tV.x, tV.y);
			context.fill();
			
		}
		break;
	}
	context.stroke();
	return yPos;
}