public override void initTest(bool deserialized) { { { PolygonShape shape = new PolygonShape(); Vec2[] vertices = new Vec2[] {new Vec2(-40, -10), new Vec2(40, -10), new Vec2(40, 0), new Vec2(-40, 0)}; shape.set(vertices, 4); getGroundBody().createFixture(shape, 0.0f); } { PolygonShape shape = new PolygonShape(); Vec2[] vertices = {new Vec2(-40, -1), new Vec2(-20, -1), new Vec2(-20, 20), new Vec2(-40, 30)}; shape.set(vertices, 4); getGroundBody().createFixture(shape, 0.0f); } { PolygonShape shape = new PolygonShape(); Vec2[] vertices = {new Vec2(20, -1), new Vec2(40, -1), new Vec2(40, 30), new Vec2(20, 20)}; shape.set(vertices, 4); getGroundBody().createFixture(shape, 0.0f); } } m_world.setParticleRadius(0.35f); m_world.setParticleDamping(0.2f); { CircleShape shape = new CircleShape(); shape.m_p.set(0, 30); shape.m_radius = 20; ParticleGroupDef pd = new ParticleGroupDef(); pd.flags = ParticleType.b2_waterParticle; pd.shape = shape; m_world.createParticleGroup(pd); } { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; Body body = m_world.createBody(bd); CircleShape shape = new CircleShape(); shape.m_p.set(0, 80); shape.m_radius = 5; body.createFixture(shape, 0.5f); } }
public override void initTest(bool deserialized) { { { PolygonShape shape = new PolygonShape(); Vec2[] vertices = new Vec2[] {new Vec2(-40, -20), new Vec2(40, -20), new Vec2(40, 0), new Vec2(-40, 0)}; shape.set(vertices, 4); getGroundBody().createFixture(shape, 0.0f); } { PolygonShape shape = new PolygonShape(); Vec2[] vertices = new Vec2[] { new Vec2(-40, -20), new Vec2(-20, -20), new Vec2(-20, 60), new Vec2(-40, 60) }; shape.set(vertices, 4); getGroundBody().createFixture(shape, 0.0f); } { PolygonShape shape = new PolygonShape(); Vec2[] vertices = new Vec2[] {new Vec2(20, -20), new Vec2(40, -20), new Vec2(40, 60), new Vec2(20, 60)}; shape.set(vertices, 4); getGroundBody().createFixture(shape, 0.0f); } { PolygonShape shape = new PolygonShape(); Vec2[] vertices = new Vec2[] {new Vec2(-40, 40), new Vec2(40, 40), new Vec2(40, 60), new Vec2(-40, 60)}; shape.set(vertices, 4); getGroundBody().createFixture(shape, 0.0f); } } m_world.setParticleRadius(0.5f); m_lastGroup = null; m_drawing = true; m_groupFlags = 0; }
public override void initTest(bool argDeserialized) { if (argDeserialized) { return; } Body ground = null; { BodyDef bd = new BodyDef(); ground = getWorld().createBody(bd); EdgeShape shape = new EdgeShape(); shape.set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f)); ground.createFixture(shape, 0.0f); } { PolygonShape shape = new PolygonShape(); shape.setAsBox(0.5f, 0.125f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 20.0f; WeldJointDef jd = new WeldJointDef(); Body prevBody = ground; for (int i = 0; i < e_count; ++i) { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(-14.5f + 1.0f*i, 5.0f); Body body = getWorld().createBody(bd); body.createFixture(fd); Vec2 anchor = new Vec2(-15.0f + 1.0f*i, 5.0f); jd.initialize(prevBody, body, anchor); getWorld().createJoint(jd); prevBody = body; } } { PolygonShape shape = new PolygonShape(); shape.setAsBox(1f, 0.125f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 20.0f; WeldJointDef jd = new WeldJointDef(); jd.frequencyHz = 5f; jd.dampingRatio = .7f; Body prevBody = ground; for (int i = 0; i < 3; ++i) { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(-14.0f + 2.0f*i, 15.0f); Body body = getWorld().createBody(bd); body.createFixture(fd); Vec2 anchor = new Vec2(-15.0f + 2.0f*i, 15.0f); jd.initialize(prevBody, body, anchor); getWorld().createJoint(jd); prevBody = body; } } { PolygonShape shape = new PolygonShape(); shape.setAsBox(0.5f, 0.125f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 20.0f; WeldJointDef jd = new WeldJointDef(); Body prevBody = ground; for (int i = 0; i < e_count; ++i) { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(-4.5f + 1.0f*i, 5.0f); Body body = getWorld().createBody(bd); body.createFixture(fd); if (i > 0) { Vec2 anchor = new Vec2(-5.0f + 1.0f*i, 5.0f); jd.initialize(prevBody, body, anchor); getWorld().createJoint(jd); } prevBody = body; } } { PolygonShape shape = new PolygonShape(); shape.setAsBox(0.5f, 0.125f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 20.0f; WeldJointDef jd = new WeldJointDef(); jd.frequencyHz = 8f; jd.dampingRatio = .7f; Body prevBody = ground; for (int i = 0; i < e_count; ++i) { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(5.5f + 1.0f*i, 10.0f); Body body = getWorld().createBody(bd); body.createFixture(fd); if (i > 0) { Vec2 anchor = new Vec2(5.0f + 1.0f*i, 10.0f); jd.initialize(prevBody, body, anchor); getWorld().createJoint(jd); } prevBody = body; } } for (int i = 0; i < 2; ++i) { Vec2[] vertices = new Vec2[3]; vertices[0] = new Vec2(-0.5f, 0.0f); vertices[1] = new Vec2(0.5f, 0.0f); vertices[2] = new Vec2(0.0f, 1.5f); PolygonShape shape = new PolygonShape(); shape.set(vertices, 3); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 1.0f; BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(-8.0f + 8.0f*i, 12.0f); Body body = getWorld().createBody(bd); body.createFixture(fd); } for (int i = 0; i < 2; ++i) { CircleShape shape = new CircleShape(); shape.m_radius = 0.5f; FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 1.0f; BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(-6.0f + 6.0f*i, 10.0f); Body body = getWorld().createBody(bd); body.createFixture(fd); } }
public override void initTest(bool deserialized) { if (deserialized) { return; } getWorld().setGravity(new Vec2(0.0f, 0.0f)); float k_restitution = 0.4f; Body ground; { BodyDef bd = new BodyDef(); bd.position.set(0.0f, 20.0f); ground = getWorld().createBody(bd); EdgeShape shape = new EdgeShape(); FixtureDef sd = new FixtureDef(); sd.shape = shape; sd.density = 0.0f; sd.restitution = k_restitution; // Left vertical shape.set(new Vec2(-20.0f, -20.0f), new Vec2(-20.0f, 20.0f)); ground.createFixture(sd); // Right vertical shape.set(new Vec2(20.0f, -20.0f), new Vec2(20.0f, 20.0f)); ground.createFixture(sd); // Top horizontal shape.set(new Vec2(-20.0f, 20.0f), new Vec2(20.0f, 20.0f)); ground.createFixture(sd); // Bottom horizontal shape.set(new Vec2(-20.0f, -20.0f), new Vec2(20.0f, -20.0f)); ground.createFixture(sd); } { Transform xf1 = new Transform(); xf1.q.set(0.3524f*MathUtils.PI); Rot.mulToOutUnsafe(xf1.q, new Vec2(1.0f, 0.0f), ref xf1.p); Vec2[] vertices = new Vec2[3]; vertices[0] = Transform.mul(xf1, new Vec2(-1.0f, 0.0f)); vertices[1] = Transform.mul(xf1, new Vec2(1.0f, 0.0f)); vertices[2] = Transform.mul(xf1, new Vec2(0.0f, 0.5f)); PolygonShape poly1 = new PolygonShape(); poly1.set(vertices, 3); FixtureDef sd1 = new FixtureDef(); sd1.shape = poly1; sd1.density = 4.0f; Transform xf2 = new Transform(); xf2.q.set(-0.3524f*MathUtils.PI); Rot.mulToOut(xf2.q, new Vec2(-1.0f, 0.0f), ref xf2.p); vertices[0] = Transform.mul(xf2, new Vec2(-1.0f, 0.0f)); vertices[1] = Transform.mul(xf2, new Vec2(1.0f, 0.0f)); vertices[2] = Transform.mul(xf2, new Vec2(0.0f, 0.5f)); PolygonShape poly2 = new PolygonShape(); poly2.set(vertices, 3); FixtureDef sd2 = new FixtureDef(); sd2.shape = poly2; sd2.density = 2.0f; BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.angularDamping = 2.0f; bd.linearDamping = 0.5f; bd.position.set(0.0f, 2.0f); bd.angle = MathUtils.PI; bd.allowSleep = false; m_body = getWorld().createBody(bd); m_body.createFixture(sd1); m_body.createFixture(sd2); } { PolygonShape shape = new PolygonShape(); shape.setAsBox(0.5f, 0.5f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 1.0f; fd.friction = 0.3f; for (int i = 0; i < 10; ++i) { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(0.0f, 5.0f + 1.54f*i); Body body = getWorld().createBody(bd); body.createFixture(fd); float gravity = 10.0f; float I = body.getInertia(); float mass = body.getMass(); // For a circle: I = 0.5 * m * r * r ==> r = sqrt(2 * I / m) float radius = MathUtils.sqrt(2.0f*I/mass); FrictionJointDef jd = new FrictionJointDef(); jd.localAnchorA.setZero(); jd.localAnchorB.setZero(); jd.bodyA = ground; jd.bodyB = body; jd.collideConnected = true; jd.maxForce = mass*gravity; jd.maxTorque = mass*radius*gravity; getWorld().createJoint(jd); } } }
public override void initTest(bool deserialized) { if (deserialized) { return; } // Ground body { EdgeShape shape = new EdgeShape(); shape.set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f)); FixtureDef sd = new FixtureDef(); sd.shape = shape; sd.friction = 0.3f; BodyDef bd = new BodyDef(); Body ground = getWorld().createBody(bd); ground.createFixture(sd); } // Small triangle Vec2[] vertices = new Vec2[3]; vertices[0] = new Vec2(-1.0f, 0.0f); vertices[1] = new Vec2(1.0f, 0.0f); vertices[2] = new Vec2(0.0f, 2.0f); PolygonShape polygon = new PolygonShape(); polygon.set(vertices, 3); FixtureDef triangleShapeDef = new FixtureDef(); triangleShapeDef.shape = polygon; triangleShapeDef.density = 1.0f; triangleShapeDef.filter.groupIndex = k_smallGroup; triangleShapeDef.filter.categoryBits = k_triangleCategory; triangleShapeDef.filter.maskBits = k_triangleMask; BodyDef triangleBodyDef = new BodyDef(); triangleBodyDef.type = BodyType.DYNAMIC; triangleBodyDef.position.set(-5.0f, 2.0f); Body body1 = getWorld().createBody(triangleBodyDef); body1.createFixture(triangleShapeDef); // Large triangle (recycle definitions) vertices[0].mulLocal(2.0f); vertices[1].mulLocal(2.0f); vertices[2].mulLocal(2.0f); polygon.set(vertices, 3); triangleShapeDef.filter.groupIndex = k_largeGroup; triangleBodyDef.position.set(-5.0f, 6.0f); triangleBodyDef.fixedRotation = true; // look at me! Body body2 = getWorld().createBody(triangleBodyDef); body2.createFixture(triangleShapeDef); { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(-5.0f, 10.0f); Body body = getWorld().createBody(bd); PolygonShape p = new PolygonShape(); p.setAsBox(0.5f, 1.0f); body.createFixture(p, 1.0f); PrismaticJointDef jd = new PrismaticJointDef(); jd.bodyA = body2; jd.bodyB = body; jd.enableLimit = true; jd.localAnchorA.set(0.0f, 4.0f); jd.localAnchorB.setZero(); jd.localAxisA.set(0.0f, 1.0f); jd.lowerTranslation = -1.0f; jd.upperTranslation = 1.0f; getWorld().createJoint(jd); } // Small box polygon.setAsBox(1.0f, 0.5f); FixtureDef boxShapeDef = new FixtureDef(); boxShapeDef.shape = polygon; boxShapeDef.density = 1.0f; boxShapeDef.restitution = 0.1f; boxShapeDef.filter.groupIndex = k_smallGroup; boxShapeDef.filter.categoryBits = k_boxCategory; boxShapeDef.filter.maskBits = k_boxMask; BodyDef boxBodyDef = new BodyDef(); boxBodyDef.type = BodyType.DYNAMIC; boxBodyDef.position.set(0.0f, 2.0f); Body body3 = getWorld().createBody(boxBodyDef); body3.createFixture(boxShapeDef); // Large box (recycle definitions) polygon.setAsBox(2.0f, 1.0f); boxShapeDef.filter.groupIndex = k_largeGroup; boxBodyDef.position.set(0.0f, 6.0f); Body body4 = getWorld().createBody(boxBodyDef); body4.createFixture(boxShapeDef); // Small circle CircleShape circle = new CircleShape(); circle.m_radius = 1.0f; FixtureDef circleShapeDef = new FixtureDef(); circleShapeDef.shape = circle; circleShapeDef.density = 1.0f; circleShapeDef.filter.groupIndex = k_smallGroup; circleShapeDef.filter.categoryBits = k_circleCategory; circleShapeDef.filter.maskBits = k_circleMask; BodyDef circleBodyDef = new BodyDef(); circleBodyDef.type = BodyType.DYNAMIC; circleBodyDef.position.set(5.0f, 2.0f); Body body5 = getWorld().createBody(circleBodyDef); body5.createFixture(circleShapeDef); // Large circle circle.m_radius *= 2.0f; circleShapeDef.filter.groupIndex = k_largeGroup; circleBodyDef.position.set(5.0f, 6.0f); Body body6 = getWorld().createBody(circleBodyDef); body6.createFixture(circleShapeDef); }
public override void initTest(bool deserialized) { if (deserialized) { return; } { BodyDef bd = new BodyDef(); bd.position.set(0.0f, 0.0f); Body body = getWorld().createBody(bd); EdgeShape shape = new EdgeShape(); shape.set(new Vec2(50.0f, 0.0f), new Vec2(-50.0f, 0.0f)); body.createFixture(shape, 0.0f); } { CircleShape circle1 = new CircleShape(); circle1.m_radius = 0.5f; circle1.m_p.set(-0.5f, 0.5f); CircleShape circle2 = new CircleShape(); ; circle2.m_radius = 0.5f; circle2.m_p.set(0.5f, 0.5f); for (int i = 0; i < 10; ++i) { float x = MathUtils.randomFloat(-0.1f, 0.1f); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(x + 5.0f, 1.05f + 2.5f*i); bd.angle = MathUtils.randomFloat(-MathUtils.PI, MathUtils.PI); Body body = getWorld().createBody(bd); body.createFixture(circle1, 2.0f); body.createFixture(circle2, 0.0f); } } { PolygonShape polygon1 = new PolygonShape(); polygon1.setAsBox(0.25f, 0.5f); PolygonShape polygon2 = new PolygonShape(); polygon2.setAsBox(0.25f, 0.5f, new Vec2(0.0f, -0.5f), 0.5f*MathUtils.PI); for (int i = 0; i < 10; ++i) { float x = MathUtils.randomFloat(-0.1f, 0.1f); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(x - 5.0f, 1.05f + 2.5f*i); bd.angle = MathUtils.randomFloat(-MathUtils.PI, MathUtils.PI); Body body = getWorld().createBody(bd); body.createFixture(polygon1, 2.0f); body.createFixture(polygon2, 2.0f); } } { Transform xf1 = new Transform(); xf1.q.set(0.3524f*MathUtils.PI); Rot.mulToOut(xf1.q, new Vec2(1.0f, 0.0f), ref xf1.p); Vec2[] vertices = new Vec2[3]; PolygonShape triangle1 = new PolygonShape(); vertices[0] = Transform.mul(xf1, new Vec2(-1.0f, 0.0f)); vertices[1] = Transform.mul(xf1, new Vec2(1.0f, 0.0f)); vertices[2] = Transform.mul(xf1, new Vec2(0.0f, 0.5f)); triangle1.set(vertices, 3); Transform xf2 = new Transform(); xf2.q.set(-0.3524f*MathUtils.PI); Rot.mulToOut(xf2.q, new Vec2(-1.0f, 0.0f), ref xf2.p); PolygonShape triangle2 = new PolygonShape(); vertices[0] = Transform.mul(xf2, new Vec2(-1.0f, 0.0f)); vertices[1] = Transform.mul(xf2, new Vec2(1.0f, 0.0f)); vertices[2] = Transform.mul(xf2, new Vec2(0.0f, 0.5f)); triangle2.set(vertices, 3); for (int i = 0; i < 10; ++i) { float x = MathUtils.randomFloat(-0.1f, 0.1f); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(x, 2.05f + 2.5f*i); bd.angle = 0.0f; Body body = getWorld().createBody(bd); body.createFixture(triangle1, 2.0f); body.createFixture(triangle2, 2.0f); } } { PolygonShape bottom = new PolygonShape(); bottom.setAsBox(1.5f, 0.15f); PolygonShape left = new PolygonShape(); left.setAsBox(0.15f, 2.7f, new Vec2(-1.45f, 2.35f), 0.2f); PolygonShape right = new PolygonShape(); right.setAsBox(0.15f, 2.7f, new Vec2(1.45f, 2.35f), -0.2f); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(0.0f, 2.0f); Body body = getWorld().createBody(bd); body.createFixture(bottom, 4.0f); body.createFixture(left, 4.0f); body.createFixture(right, 4.0f); } }
public override void initTest(bool deserialized) { if (deserialized) { return; } Body ground = null; { BodyDef bd = new BodyDef(); ground = getWorld().createBody(bd); EdgeShape shape = new EdgeShape(); shape.set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f)); ground.createFixture(shape, 0.0f); } { CircleShape shape = new CircleShape(); shape.m_radius = 0.5f; BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; RevoluteJointDef rjd = new RevoluteJointDef(); bd.position.set(-10f, 20.0f); Body body = getWorld().createBody(bd); body.createFixture(shape, 5.0f); float w = 100.0f; body.setAngularVelocity(w); body.setLinearVelocity(new Vec2(-8.0f*w, 0.0f)); rjd.initialize(ground, body, new Vec2(-10.0f, 12.0f)); rjd.motorSpeed = -1.0f*MathUtils.PI; rjd.maxMotorTorque = 10000.0f; rjd.enableMotor = false; rjd.lowerAngle = -0.25f*MathUtils.PI; rjd.upperAngle = 0.5f*MathUtils.PI; rjd.enableLimit = true; rjd.collideConnected = true; m_joint = (RevoluteJoint) getWorld().createJoint(rjd); } { CircleShape circle_shape = new CircleShape(); circle_shape.m_radius = 3.0f; BodyDef circle_bd = new BodyDef(); circle_bd.type = BodyType.DYNAMIC; circle_bd.position.set(5.0f, 30.0f); FixtureDef fd = new FixtureDef(); fd.density = 5.0f; fd.filter.maskBits = 1; fd.shape = circle_shape; Body ball = m_world.createBody(circle_bd); ball.createFixture(fd); PolygonShape polygon_shape = new PolygonShape(); polygon_shape.setAsBox(10.0f, 0.2f, new Vec2(-10.0f, 0.0f), 0.0f); BodyDef polygon_bd = new BodyDef(); polygon_bd.position.set(20.0f, 10.0f); polygon_bd.type = BodyType.DYNAMIC; polygon_bd.bullet = true; Body polygon_body = m_world.createBody(polygon_bd); polygon_body.createFixture(polygon_shape, 2.0f); RevoluteJointDef rjd = new RevoluteJointDef(); rjd.initialize(ground, polygon_body, new Vec2(20.0f, 10.0f)); rjd.lowerAngle = -0.25f*MathUtils.PI; rjd.upperAngle = 0.0f*MathUtils.PI; rjd.enableLimit = true; m_world.createJoint(rjd); } // Tests mass computation of a small object far from the origin { BodyDef bodyDef = new BodyDef(); bodyDef.type = BodyType.DYNAMIC; Body body = m_world.createBody(bodyDef); PolygonShape polyShape = new PolygonShape(); Vec2[] verts = new Vec2[3]; verts[0] = new Vec2(17.63f, 36.31f); verts[1] = new Vec2(17.52f, 36.69f); verts[2] = new Vec2(17.19f, 36.36f); polyShape.set(verts, 3); FixtureDef polyFixtureDef = new FixtureDef(); polyFixtureDef.shape = polyShape; polyFixtureDef.density = 1; body.createFixture(polyFixtureDef); // assertion hits inside here } }
public override void initTest(bool deserialized) { { BodyDef bd = new BodyDef(); Body ground = m_world.createBody(bd); { PolygonShape shape = new PolygonShape(); Vec2[] vertices = new Vec2[] {new Vec2(-40, -10), new Vec2(40, -10), new Vec2(40, 0), new Vec2(-40, 0)}; shape.set(vertices, 4); ground.createFixture(shape, 0.0f); } { PolygonShape shape = new PolygonShape(); Vec2[] vertices = new Vec2[] {new Vec2(-40, -1), new Vec2(-20, -1), new Vec2(-20, 20), new Vec2(-40, 30)}; shape.set(vertices, 4); ground.createFixture(shape, 0.0f); } { PolygonShape shape = new PolygonShape(); Vec2[] vertices = new Vec2[] {new Vec2(20, -1), new Vec2(40, -1), new Vec2(40, 30), new Vec2(20, 20)}; shape.set(vertices, 4); ground.createFixture(shape, 0.0f); } } m_world.setParticleRadius(0.2f); { PolygonShape shape = new PolygonShape(); shape.setAsBox(20, 10, new Vec2(0, 10), 0); ParticleGroupDef pd = new ParticleGroupDef(); pd.flags = flags; pd.shape = shape; m_world.createParticleGroup(pd); } { BodyDef bd = new BodyDef(); bd.type = BodyType.KINEMATIC; Body body = m_world.createBody(bd); circle = body; CircleShape shape = new CircleShape(); shape.m_p.set(0, 5); shape.m_radius = 1; body.createFixture(shape, 0.1f); body.setLinearVelocity(new Vec2(-6, 0.0f)); } { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; Body body = m_world.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(1, 1, new Vec2(-10, 5), 0); body.createFixture(shape, 0.1f); } { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; Body body = m_world.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(1, 1, new Vec2(10, 5), 0.5f); body.createFixture(shape, 0.1f); } { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; Body body = m_world.createBody(bd); EdgeShape shape = new EdgeShape(); shape.set(new Vec2(0, 20), new Vec2(1, 21)); body.createFixture(shape, 0.1f); } { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; Body body = m_world.createBody(bd); EdgeShape shape = new EdgeShape(); shape.set(new Vec2(3, 20), new Vec2(4, 21)); body.createFixture(shape, 0.1f); } { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; Body body = m_world.createBody(bd); EdgeShape shape = new EdgeShape(); shape.set(new Vec2(-3, 21), new Vec2(-2, 20)); body.createFixture(shape, 0.1f); } }
private void createLeg(float s, Vec2 wheelAnchor) { Vec2 p1 = new Vec2(5.4f*s, -6.1f); Vec2 p2 = new Vec2(7.2f*s, -1.2f); Vec2 p3 = new Vec2(4.3f*s, -1.9f); Vec2 p4 = new Vec2(3.1f*s, 0.8f); Vec2 p5 = new Vec2(6.0f*s, 1.5f); Vec2 p6 = new Vec2(2.5f*s, 3.7f); FixtureDef fd1 = new FixtureDef(); FixtureDef fd2 = new FixtureDef(); fd1.filter.groupIndex = -1; fd2.filter.groupIndex = -1; fd1.density = 1.0f; fd2.density = 1.0f; PolygonShape poly1 = new PolygonShape(); PolygonShape poly2 = new PolygonShape(); if (s > 0.0f) { Vec2[] vertices = new Vec2[3]; vertices[0] = p1; vertices[1] = p2; vertices[2] = p3; poly1.set(vertices, 3); vertices[0] = new Vec2(); vertices[1] = p5.sub(p4); vertices[2] = p6.sub(p4); poly2.set(vertices, 3); } else { Vec2[] vertices = new Vec2[3]; vertices[0] = p1; vertices[1] = p3; vertices[2] = p2; poly1.set(vertices, 3); vertices[0] = new Vec2(); vertices[1] = p6.sub(p4); vertices[2] = p5.sub(p4); poly2.set(vertices, 3); } fd1.shape = poly1; fd2.shape = poly2; BodyDef bd1 = new BodyDef(), bd2 = new BodyDef(); bd1.type = BodyType.DYNAMIC; bd2.type = BodyType.DYNAMIC; bd1.position = m_offset; bd2.position = p4.add(m_offset); bd1.angularDamping = 10.0f; bd2.angularDamping = 10.0f; Body body1 = getWorld().createBody(bd1); Body body2 = getWorld().createBody(bd2); body1.createFixture(fd1); body2.createFixture(fd2); DistanceJointDef djd = new DistanceJointDef(); // Using a soft distance constraint can reduce some jitter. // It also makes the structure seem a bit more fluid by // acting like a suspension system. djd.dampingRatio = 0.5f; djd.frequencyHz = 10.0f; djd.initialize(body1, body2, p2.add(m_offset), p5.add(m_offset)); getWorld().createJoint(djd); djd.initialize(body1, body2, p3.add(m_offset), p4.add(m_offset)); getWorld().createJoint(djd); djd.initialize(body1, m_wheel, p3.add(m_offset), wheelAnchor.add(m_offset)); getWorld().createJoint(djd); djd.initialize(body2, m_wheel, p6.add(m_offset), wheelAnchor.add(m_offset)); getWorld().createJoint(djd); RevoluteJointDef rjd = new RevoluteJointDef(); rjd.initialize(body2, m_chassis, p4.add(m_offset)); getWorld().createJoint(rjd); }
public override void initTest(bool deserialized) { if (deserialized) { return; } m_hz = 4.0f; m_zeta = 0.7f; m_speed = 50.0f; Body ground = null; { BodyDef bd = new BodyDef(); ground = m_world.createBody(bd); EdgeShape shape = new EdgeShape(); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 0.0f; fd.friction = 0.6f; shape.set(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f)); ground.createFixture(fd); float[] hs = {0.25f, 1.0f, 4.0f, 0.0f, 0.0f, -1.0f, -2.0f, -2.0f, -1.25f, 0.0f}; float x = 20.0f, y1 = 0.0f, dx = 5.0f; for (int i = 0; i < 10; ++i) { float y2 = hs[i]; shape.set(new Vec2(x, y1), new Vec2(x + dx, y2)); ground.createFixture(fd); y1 = y2; x += dx; } for (int i = 0; i < 10; ++i) { float y2 = hs[i]; shape.set(new Vec2(x, y1), new Vec2(x + dx, y2)); ground.createFixture(fd); y1 = y2; x += dx; } shape.set(new Vec2(x, 0.0f), new Vec2(x + 40.0f, 0.0f)); ground.createFixture(fd); x += 80.0f; shape.set(new Vec2(x, 0.0f), new Vec2(x + 40.0f, 0.0f)); ground.createFixture(fd); x += 40.0f; shape.set(new Vec2(x, 0.0f), new Vec2(x + 10.0f, 5.0f)); ground.createFixture(fd); x += 20.0f; shape.set(new Vec2(x, 0.0f), new Vec2(x + 40.0f, 0.0f)); ground.createFixture(fd); x += 40.0f; shape.set(new Vec2(x, 0.0f), new Vec2(x, 20.0f)); ground.createFixture(fd); } // Teeter { BodyDef bd = new BodyDef(); bd.position.set(140.0f, 1.0f); bd.type = BodyType.DYNAMIC; Body body = m_world.createBody(bd); PolygonShape box = new PolygonShape(); box.setAsBox(10.0f, 0.25f); body.createFixture(box, 1.0f); RevoluteJointDef jd = new RevoluteJointDef(); jd.initialize(ground, body, body.getPosition()); jd.lowerAngle = -8.0f*MathUtils.PI/180.0f; jd.upperAngle = 8.0f*MathUtils.PI/180.0f; jd.enableLimit = true; m_world.createJoint(jd); body.applyAngularImpulse(100.0f); } // Bridge { int N = 20; PolygonShape shape = new PolygonShape(); shape.setAsBox(1.0f, 0.125f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 1.0f; fd.friction = 0.6f; RevoluteJointDef jd = new RevoluteJointDef(); Body prevBody = ground; for (int i = 0; i < N; ++i) { BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(161.0f + 2.0f*i, -0.125f); Body body = m_world.createBody(bd); body.createFixture(fd); Vec2 anchor = new Vec2(160.0f + 2.0f*i, -0.125f); jd.initialize(prevBody, body, anchor); m_world.createJoint(jd); prevBody = body; } Vec2 anchor2 = new Vec2(160.0f + 2.0f*N, -0.125f); jd.initialize(prevBody, ground, anchor2); m_world.createJoint(jd); } // Boxes { PolygonShape box = new PolygonShape(); box.setAsBox(0.5f, 0.5f); Body body = null; BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(230.0f, 0.5f); body = m_world.createBody(bd); body.createFixture(box, 0.5f); bd.position.set(230.0f, 1.5f); body = m_world.createBody(bd); body.createFixture(box, 0.5f); bd.position.set(230.0f, 2.5f); body = m_world.createBody(bd); body.createFixture(box, 0.5f); bd.position.set(230.0f, 3.5f); body = m_world.createBody(bd); body.createFixture(box, 0.5f); bd.position.set(230.0f, 4.5f); body = m_world.createBody(bd); body.createFixture(box, 0.5f); } // Car { PolygonShape chassis = new PolygonShape(); Vec2[] vertices = new Vec2[8]; vertices[0] = new Vec2(-1.5f, -0.5f); vertices[1] = new Vec2(1.5f, -0.5f); vertices[2] = new Vec2(1.5f, 0.0f); vertices[3] = new Vec2(0.0f, 0.9f); vertices[4] = new Vec2(-1.15f, 0.9f); vertices[5] = new Vec2(-1.5f, 0.2f); chassis.set(vertices, 6); CircleShape circle = new CircleShape(); circle.m_radius = 0.4f; BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(0.0f, 1.0f); m_car = m_world.createBody(bd); m_car.createFixture(chassis, 1.0f); FixtureDef fd = new FixtureDef(); fd.shape = circle; fd.density = 1.0f; fd.friction = 0.9f; bd.position.set(-1.0f, 0.35f); m_wheel1 = m_world.createBody(bd); m_wheel1.createFixture(fd); bd.position.set(1.0f, 0.4f); m_wheel2 = m_world.createBody(bd); m_wheel2.createFixture(fd); WheelJointDef jd = new WheelJointDef(); Vec2 axis = new Vec2(0.0f, 1.0f); jd.initialize(m_car, m_wheel1, m_wheel1.getPosition(), axis); jd.motorSpeed = 0.0f; jd.maxMotorTorque = 20.0f; jd.enableMotor = true; jd.frequencyHz = m_hz; jd.dampingRatio = m_zeta; m_spring1 = (WheelJoint) m_world.createJoint(jd); jd.initialize(m_car, m_wheel2, m_wheel2.getPosition(), axis); jd.motorSpeed = 0.0f; jd.maxMotorTorque = 10.0f; jd.enableMotor = false; jd.frequencyHz = m_hz; jd.dampingRatio = m_zeta; m_spring2 = (WheelJoint) m_world.createJoint(jd); } }
public override void initTest(bool deserialized) { if (deserialized) { return; } // Ground body { BodyDef bd = new BodyDef(); Body ground = getWorld().createBody(bd); EdgeShape shape = new EdgeShape(); shape.set(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f)); ground.createFixture(shape, 0.0f); } // Collinear edges // This shows the problematic case where a box shape can hit // an internal vertex. { BodyDef bd = new BodyDef(); Body ground = getWorld().createBody(bd); EdgeShape shape = new EdgeShape(); shape.m_radius = 0.0f; shape.set(new Vec2(-8.0f, 1.0f), new Vec2(-6.0f, 1.0f)); ground.createFixture(shape, 0.0f); shape.set(new Vec2(-6.0f, 1.0f), new Vec2(-4.0f, 1.0f)); ground.createFixture(shape, 0.0f); shape.set(new Vec2(-4.0f, 1.0f), new Vec2(-2.0f, 1.0f)); ground.createFixture(shape, 0.0f); } // Chain shape { BodyDef bd = new BodyDef(); bd.angle = 0.25f*MathUtils.PI; Body ground = getWorld().createBody(bd); Vec2[] vs = new Vec2[4]; vs[0] = new Vec2(5.0f, 7.0f); vs[1] = new Vec2(6.0f, 8.0f); vs[2] = new Vec2(7.0f, 8.0f); vs[3] = new Vec2(8.0f, 7.0f); ChainShape shape = new ChainShape(); shape.createChain(vs, 4); ground.createFixture(shape, 0.0f); } // Square tiles. This shows that adjacency shapes may // have non-smooth collision. There is no solution // to this problem. { BodyDef bd = new BodyDef(); Body ground = getWorld().createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(1.0f, 1.0f, new Vec2(4.0f, 3.0f), 0.0f); ground.createFixture(shape, 0.0f); shape.setAsBox(1.0f, 1.0f, new Vec2(6.0f, 3.0f), 0.0f); ground.createFixture(shape, 0.0f); shape.setAsBox(1.0f, 1.0f, new Vec2(8.0f, 3.0f), 0.0f); ground.createFixture(shape, 0.0f); } // Square made from an edge loop. Collision should be smooth. { BodyDef bd = new BodyDef(); Body ground = m_world.createBody(bd); Vec2[] vs = new Vec2[4]; vs[0] = new Vec2(-1.0f, 3.0f); vs[1] = new Vec2(1.0f, 3.0f); vs[2] = new Vec2(1.0f, 5.0f); vs[3] = new Vec2(-1.0f, 5.0f); ChainShape shape = new ChainShape(); shape.createLoop(vs, 4); ground.createFixture(shape, 0.0f); } // Edge loop. Collision should be smooth. { BodyDef bd = new BodyDef(); bd.position.set(-10.0f, 4.0f); Body ground = getWorld().createBody(bd); Vec2[] vs = new Vec2[10]; vs[0] = new Vec2(0.0f, 0.0f); vs[1] = new Vec2(6.0f, 0.0f); vs[2] = new Vec2(6.0f, 2.0f); vs[3] = new Vec2(4.0f, 1.0f); vs[4] = new Vec2(2.0f, 2.0f); vs[5] = new Vec2(0.0f, 2.0f); vs[6] = new Vec2(-2.0f, 2.0f); vs[7] = new Vec2(-4.0f, 3.0f); vs[8] = new Vec2(-6.0f, 2.0f); vs[9] = new Vec2(-6.0f, 0.0f); ChainShape shape = new ChainShape(); shape.createLoop(vs, 10); ground.createFixture(shape, 0.0f); } // Square character 1 { BodyDef bd = new BodyDef(); bd.position.set(-3.0f, 8.0f); bd.type = BodyType.DYNAMIC; bd.fixedRotation = true; bd.allowSleep = false; Body body = getWorld().createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(0.5f, 0.5f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 20.0f; body.createFixture(fd); } // Square character 2 { BodyDef bd = new BodyDef(); bd.position.set(-5.0f, 5.0f); bd.type = BodyType.DYNAMIC; bd.fixedRotation = true; bd.allowSleep = false; Body body = getWorld().createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(0.25f, 0.25f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 20.0f; body.createFixture(fd); } // Hexagon character { BodyDef bd = new BodyDef(); bd.position.set(-5.0f, 8.0f); bd.type = BodyType.DYNAMIC; bd.fixedRotation = true; bd.allowSleep = false; Body body = getWorld().createBody(bd); float angle = 0.0f; float delta = MathUtils.PI/3.0f; Vec2[] vertices = new Vec2[6]; for (int i = 0; i < 6; ++i) { vertices[i] = new Vec2(0.5f*MathUtils.cos(angle), 0.5f*MathUtils.sin(angle)); angle += delta; } PolygonShape shape = new PolygonShape(); shape.set(vertices, 6); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 20.0f; body.createFixture(fd); } // Circle character { BodyDef bd = new BodyDef(); bd.position.set(3.0f, 5.0f); bd.type = BodyType.DYNAMIC; bd.fixedRotation = true; bd.allowSleep = false; Body body = getWorld().createBody(bd); CircleShape shape = new CircleShape(); shape.m_radius = 0.5f; FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 20.0f; body.createFixture(fd); } // Circle character { BodyDef bd = new BodyDef(); bd.position.set(-7.0f, 6.0f); bd.type = BodyType.DYNAMIC; bd.allowSleep = false; m_character = getWorld().createBody(bd); CircleShape shape = new CircleShape(); shape.m_radius = 0.25f; FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.density = 20.0f; fd.friction = 1; m_character.createFixture(fd); } }
public override void initTest(bool deserialized) { if (deserialized) { return; } // Ground body { EdgeShape shape = new EdgeShape(); shape.set(new Vec2(-50.0f, 0.0f), new Vec2(50.0f, 0.0f)); FixtureDef sd = new FixtureDef(); sd.shape = shape; BodyDef bd = new BodyDef(); Body ground = getWorld().createBody(bd); ground.createFixture(sd); } float xLo = -5.0f, xHi = 5.0f; float yLo = 2.0f, yHi = 35.0f; // Small triangle Vec2[] vertices = new Vec2[3]; vertices[0] = new Vec2(-1.0f, 0.0f); vertices[1] = new Vec2(1.0f, 0.0f); vertices[2] = new Vec2(0.0f, 2.0f); PolygonShape polygon = new PolygonShape(); polygon.set(vertices, 3); FixtureDef triangleShapeDef = new FixtureDef(); triangleShapeDef.shape = polygon; triangleShapeDef.density = 1.0f; BodyDef triangleBodyDef = new BodyDef(); triangleBodyDef.type = BodyType.DYNAMIC; triangleBodyDef.position.set(MathUtils.randomFloat(xLo, xHi), MathUtils.randomFloat(yLo, yHi)); Body body1 = getWorld().createBody(triangleBodyDef); body1.createFixture(triangleShapeDef); // Large triangle (recycle definitions) vertices[0].mulLocal(2.0f); vertices[1].mulLocal(2.0f); vertices[2].mulLocal(2.0f); polygon.set(vertices, 3); triangleBodyDef.position.set(MathUtils.randomFloat(xLo, xHi), MathUtils.randomFloat(yLo, yHi)); Body body2 = getWorld().createBody(triangleBodyDef); body2.createFixture(triangleShapeDef); // Small box polygon.setAsBox(1.0f, 0.5f); FixtureDef boxShapeDef = new FixtureDef(); boxShapeDef.shape = polygon; boxShapeDef.density = 1.0f; BodyDef boxBodyDef = new BodyDef(); boxBodyDef.type = BodyType.DYNAMIC; boxBodyDef.position.set(MathUtils.randomFloat(xLo, xHi), MathUtils.randomFloat(yLo, yHi)); Body body3 = getWorld().createBody(boxBodyDef); body3.createFixture(boxShapeDef); // Large box (recycle definitions) polygon.setAsBox(2.0f, 1.0f); boxBodyDef.position.set(MathUtils.randomFloat(xLo, xHi), MathUtils.randomFloat(yLo, yHi)); Body body4 = getWorld().createBody(boxBodyDef); body4.createFixture(boxShapeDef); // Small circle CircleShape circle = new CircleShape(); circle.m_radius = 1.0f; FixtureDef circleShapeDef = new FixtureDef(); circleShapeDef.shape = circle; circleShapeDef.density = 1.0f; BodyDef circleBodyDef = new BodyDef(); circleBodyDef.type = BodyType.DYNAMIC; circleBodyDef.position.set(MathUtils.randomFloat(xLo, xHi), MathUtils.randomFloat(yLo, yHi)); Body body5 = getWorld().createBody(circleBodyDef); body5.createFixture(circleShapeDef); // Large circle circle.m_radius *= 2.0f; circleBodyDef.position.set(MathUtils.randomFloat(xLo, xHi), MathUtils.randomFloat(yLo, yHi)); Body body6 = getWorld().createBody(circleBodyDef); body6.createFixture(circleShapeDef); }
public override void initTest(bool deserialized) { if (deserialized) { return; } World world = getWorld(); Body ground = null; { BodyDef bd = new BodyDef(); ground = getWorld().createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(5.0f, 100.0f); bd = new BodyDef(); bd.type = BodyType.STATIC; FixtureDef sides = new FixtureDef(); sides.shape = shape; sides.density = 0; sides.friction = 0; sides.restitution = .8f; sides.filter.categoryBits = 4; sides.filter.maskBits = 2; bd.position.set(-10.01f, 50.0f); Body bod = world.createBody(bd); bod.createFixture(sides); bd.position.set(10.01f, 50.0f); bod = world.createBody(bd); bod.createFixture(sides); } // turney { CircleShape cd; FixtureDef fd = new FixtureDef(); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; int numPieces = 5; float radius = 4f; bd.position = new Vec2(0.0f, 25.0f); Body body = getWorld().createBody(bd); for (int i = 0; i < numPieces; i++) { cd = new CircleShape(); cd.m_radius = .5f; fd.shape = cd; fd.density = 25; fd.friction = .1f; fd.restitution = .9f; float xPos = radius*(float) System.Math.Cos(2f*System.Math.PI*(i/(float) (numPieces))); float yPos = radius*(float) System.Math.Sin(2f*System.Math.PI*(i/(float) (numPieces))); cd.m_p.set(xPos, yPos); body.createFixture(fd); } RevoluteJointDef rjd = new RevoluteJointDef(); rjd.initialize(body, getGroundBody(), body.getPosition()); rjd.motorSpeed = MathUtils.PI; rjd.maxMotorTorque = 1000000.0f; rjd.enableMotor = true; getWorld().createJoint(rjd); } { Body prevBody = ground; // Define crank. { PolygonShape shape = new PolygonShape(); shape.setAsBox(0.5f, 2.0f); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(0.0f, 7.0f); Body body = getWorld().createBody(bd); body.createFixture(shape, 2.0f); RevoluteJointDef rjd = new RevoluteJointDef(); rjd.initialize(prevBody, body, new Vec2(0.0f, 5.0f)); rjd.motorSpeed = 1.0f*MathUtils.PI; rjd.maxMotorTorque = 20000; rjd.enableMotor = true; getWorld().createJoint(rjd); prevBody = body; } // Define follower. { PolygonShape shape = new PolygonShape(); shape.setAsBox(0.5f, 4.0f); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(0.0f, 13.0f); Body body = getWorld().createBody(bd); body.createFixture(shape, 2.0f); RevoluteJointDef rjd = new RevoluteJointDef(); rjd.initialize(prevBody, body, new Vec2(0.0f, 9.0f)); rjd.enableMotor = false; getWorld().createJoint(rjd); prevBody = body; } // Define piston { PolygonShape shape = new PolygonShape(); shape.setAsBox(7f, 2f); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(0.0f, 17.0f); Body body = getWorld().createBody(bd); FixtureDef piston = new FixtureDef(); piston.shape = shape; piston.density = 2; piston.filter.categoryBits = 1; piston.filter.maskBits = 2; body.createFixture(piston); body.setBullet(false); RevoluteJointDef rjd = new RevoluteJointDef(); rjd.initialize(prevBody, body, new Vec2(0.0f, 17.0f)); getWorld().createJoint(rjd); PrismaticJointDef pjd = new PrismaticJointDef(); pjd.initialize(ground, body, new Vec2(0.0f, 17.0f), new Vec2(0.0f, 1.0f)); pjd.maxMotorForce = 1000.0f; pjd.enableMotor = true; getWorld().createJoint(pjd); } // Create a payload { PolygonShape sd = new PolygonShape(); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; FixtureDef fixture = new FixtureDef(); Body body; for (int i = 0; i < 100; ++i) { sd.setAsBox(0.4f, 0.3f); bd.position.set(-1.0f, 23.0f + i); bd.bullet = bullet; body = world.createBody(bd); fixture.shape = sd; fixture.density = .1f; fixture.filter.categoryBits = 2; fixture.filter.maskBits = 1 | 4 | 2; body.createFixture(fixture); } CircleShape cd = new CircleShape(); cd.m_radius = 0.36f; for (int i = 0; i < 100; ++i) { bd.position.set(1.0f, 23.0f + i); bd.bullet = bullet; fixture.shape = cd; fixture.density = 2f; fixture.filter.categoryBits = 2; fixture.filter.maskBits = 1 | 4 | 2; body = world.createBody(bd); body.createFixture(fixture); } float angle = 0.0f; float delta = MathUtils.PI/3.0f; Vec2[] vertices = new Vec2[6]; for (int i = 0; i < 6; ++i) { vertices[i] = new Vec2(0.3f*MathUtils.cos(angle), 0.3f*MathUtils.sin(angle)); angle += delta; } PolygonShape shape = new PolygonShape(); shape.set(vertices, 6); for (int i = 0; i < 100; ++i) { bd.position.set(0f, 23.0f + i); bd.type = BodyType.DYNAMIC; bd.fixedRotation = true; bd.bullet = bullet; fixture.shape = shape; fixture.density = 1f; fixture.filter.categoryBits = 2; fixture.filter.maskBits = 1 | 4 | 2; body = world.createBody(bd); body.createFixture(fixture); } } } }