public void ShatterCell(cpPolyShape shape, cpVect cell, int cell_i, int cell_j, ref WorleyContex context) { // printf("cell %dx%d: (% 5.2f, % 5.2f)\n", cell_i, cell_j, cell.x, cell.y); cpBody body = shape.body; // cpShapeGetBody(shape); cpVect[] ping = new cpVect[MAX_VERTEXES_PER_VORONOI]; // cpVect[ (cpVect*)alloca( * sizeof(cpVect)); cpVect[] pong = new cpVect[MAX_VERTEXES_PER_VORONOI]; //(cpVect*)alloca(MAX_VERTEXES_PER_VORONOI * sizeof(cpVect)); int count = shape.Count; // cpPolyShapeGetCount(); count = (count > MAX_VERTEXES_PER_VORONOI ? MAX_VERTEXES_PER_VORONOI : count); for (int i = 0; i < count; i++) { ping[i] = body.LocalToWorld(shape.GetVert(i)); } cpPointQueryInfo info = null; for (int i = 0; i < context.width; i++) { for (int j = 0; j < context.height; j++) { if ( !(i == cell_i && j == cell_j) && shape.PointQuery(cell, ref info) < 0 ) { count = ClipCell(shape, cell, i, j, context, ping, pong, count); for (int u = 0; u < pong.Length; u++) { if (pong[u] != null) { ping[u] = new cpVect(pong[u]); } } } } } cpVect centroid = cp.CentroidForPoly(count, ping); float mass = cp.AreaForPoly(count, ping, 0) * DENSITY; float moment = cp.MomentForPoly(mass, count, ping, cpVect.cpvneg(centroid), 0); cpBody new_body = space.AddBody(new cpBody(mass, moment)); new_body.SetPosition(centroid); new_body.SetPosition(centroid); new_body.SetVelocity(body.GetVelocityAtLocalPoint(centroid)); new_body.SetAngularVelocity(body.GetAngularVelocity()); cpTransform transform = cpTransform.Translate(cpVect.cpvneg(centroid)); cpShape new_shape = space.AddShape(new cpPolyShape(new_body, count, ping, transform, 0)); // Copy whatever properties you have set on the original shape that are important new_shape.SetFriction(shape.GetFriction()); }
static public cpSpace BouncyTerrainCircles_500(cpSpace space) { //cpSpace space = BENCH_SPACE_NEW(); SetSubTitle("BouncyTerrainCircles 500"); space.SetIterations(10); cpVect offset = new cpVect(-320, -240); for (int i = 0; i < (bouncy_terrain_verts.Length - 1); i++) { cpVect a = bouncy_terrain_verts[i], b = bouncy_terrain_verts[i + 1]; cpShape shape = space.AddShape(new cpSegmentShape(space.GetStaticBody(), cpVect.cpvadd(a, offset), cpVect.cpvadd(b, offset), 0.0f)); shape.SetElasticity(1.0f); } for (int i = 0; i < 500; i++) { float radius = 5.0f; float mass = radius * radius; cpBody body = space.AddBody(new cpBody(mass, cp.MomentForCircle(mass, 0.0f, radius, cpVect.Zero))); body.SetPosition(cpVect.cpvadd(cpVect.cpvmult(cp.frand_unit_circle(), 130.0f), cpVect.Zero)); body.SetVelocity(cpVect.cpvmult(cp.frand_unit_circle(), 50.0f)); cpShape shape = space.AddShape(new cpCircleShape(body, radius, cpVect.Zero)); shape.SetElasticity(1.0f); } return(space); }
public void ClipPoly(cpSpace space, cpShape shp, cpVect n, float dist) { cpPolyShape shape = (cpPolyShape)shp; cpBody body = shape.GetBody(); int count = shape.Count; int clippedCount = 0; cpVect[] clipped = new cpVect[count + 1]; for (int i = 0, j = count - 1; i < count; j = i, i++) { cpVect a = body.LocalToWorld(shape.GetVert(j)); float a_dist = cpVect.cpvdot(a, n) - dist; if (a_dist < 0) { clipped[clippedCount] = a; clippedCount++; } cpVect b = body.LocalToWorld(shape.GetVert(i)); float b_dist = cpVect.cpvdot(b, n) - dist; if (a_dist * b_dist < 0) { float t = cp.cpfabs(a_dist) / (cp.cpfabs(a_dist) + cp.cpfabs(b_dist)); clipped[clippedCount] = cpVect.cpvlerp(a, b, t); clippedCount++; } } cpVect centroid = cp.CentroidForPoly(clippedCount, clipped); float mass = cp.AreaForPoly(clippedCount, clipped, 0) * DENSITY; float moment = cp.MomentForPoly(mass, clippedCount, clipped, cpVect.cpvneg(centroid), 0); cpBody new_body = space.AddBody(new cpBody(mass, moment)); new_body.SetPosition(centroid); new_body.SetVelocity(body.GetVelocityAtWorldPoint(centroid)); new_body.SetAngularVelocity(body.GetAngularVelocity()); cpTransform transform = cpTransform.Translate(cpVect.cpvneg(centroid)); cpShape new_shape = space.AddShape(new cpPolyShape(new_body, clippedCount, clipped, transform, 0)); // Copy whatever properties you have set on the original shape that are important new_shape.SetFriction(shape.GetFriction()); }
static cpSpace NoCollide(cpSpace space) { space.SetIterations(10); var handler = space.AddCollisionHandler(2, 2); //, (a, s, o) => NoCollide_begin(a, s, o), null, null, null); handler.beginFunc = NoCollide_begin; float radius = 4.5f; var staticBody = space.GetStaticBody(); space.AddShape(new cpSegmentShape(staticBody, new cpVect(-330 - radius, -250 - radius), new cpVect(330 + radius, -250 - radius), 0.0f)).SetElasticity(1.0f); space.AddShape(new cpSegmentShape(staticBody, new cpVect(330 + radius, 250 + radius), new cpVect(330 + radius, -250 - radius), 0.0f)).SetElasticity(1.0f); space.AddShape(new cpSegmentShape(staticBody, new cpVect(330 + radius, 250 + radius), new cpVect(-330 - radius, 250 + radius), 0.0f)).SetElasticity(1.0f); space.AddShape(new cpSegmentShape(staticBody, new cpVect(-330 - radius, -250 - radius), new cpVect(-330 - radius, 250 + radius), 0.0f)).SetElasticity(1.0f); for (int x = -320; x <= 320; x += 20) { for (int y = -240; y <= 240; y += 20) { space.AddShape(new cpCircleShape(staticBody, radius, new cpVect(x, y))); } } for (int y = 10 - 240; y <= 240; y += 40) { float mass = 7.0f; cpBody body = space.AddBody(new cpBody(mass, cp.MomentForCircle(mass, 0.0f, radius, cpVect.Zero))); body.SetPosition(new cpVect(-320.0f, y)); body.SetVelocity(new cpVect(100.0f, 0.0f)); cpShape shape = space.AddShape(new cpCircleShape(body, radius, cpVect.Zero)); shape.SetElasticity(1.0f); shape.SetCollisionType(2); } for (int x = 30 - 320; x <= 320; x += 40) { float mass = 7.0f; cpBody body = space.AddBody(new cpBody(mass, cp.MomentForCircle(mass, 0.0f, radius, cpVect.Zero))); body.SetPosition(new cpVect(x, -240.0f)); body.SetVelocity(new cpVect(0.0f, 100.0f)); cpShape shape = space.AddShape(new cpCircleShape(body, radius, cpVect.Zero)); shape.SetElasticity(1.0f); shape.SetCollisionType(2); } return(space); }
void add_box() { const float size = 10; const float mass = 1; cpVect[] verts = new cpVect[] { new cpVect(-size, -size), new cpVect(-size, size), new cpVect(size, size), new cpVect(size, -size) }; float radius = cpVect.cpvlength(new cpVect(size, size)); cpVect pos = rand_pos(radius); cpBody body = space.AddBody(new cpBody(mass, cp.MomentForPoly(mass, 4, verts, cpVect.Zero, 0.0f))); body.SetVelocityUpdateFunc( (s, f1, f2) => planetGravityVelocityFunc(body, s, f1, f2) ); body.SetPosition(pos); // Set the box's velocity to put it into a circular orbit from its // starting position. float r = cpVect.cpvlength(pos); float v = cp.cpfsqrt(gravityStrength / r) / r; body.SetVelocity(cpVect.cpvmult(cpVect.cpvperp(pos), v)); // Set the box's angular velocity to match its orbital period and // align its initial angle with its position. body.SetAngularVelocity(v); body.SetAngle(cp.cpfatan2(pos.y, pos.x)); cpShape shape = space.AddShape(new cpPolyShape(body, 4, verts, cpTransform.Identity, 0.0f)); //cpTransformIdentity shape.SetElasticity(0); shape.SetFriction(0.7f); }
static public cpSpace BouncyTerrainHexagons_500(cpSpace space) { SetSubTitle("BouncyTerrainHexagons 500"); //cpSpace space = BENCH_SPACE_NEW(); space.SetIterations(10); cpVect offset = new cpVect(-320, -240); for (int i = 0; i < (bouncy_terrain_verts.Length - 1); i++) { cpVect a = bouncy_terrain_verts[i], b = bouncy_terrain_verts[i + 1]; cpShape shape = space.AddShape(new cpSegmentShape(space.GetStaticBody(), cpVect.cpvadd(a, offset), cpVect.cpvadd(b, offset), 0.0f)); shape.SetElasticity(1.0f); } float radius = 5.0f; cpVect[] hexagon = new cpVect[6]; for (int i = 0; i < 6; i++) { float angle = -(float)Math.PI * 2.0f * i / 6.0f; hexagon[i] = cpVect.cpvmult(cpVect.cpv(cp.cpfcos(angle), cp.cpfsin(angle)), radius - bevel); } for (int i = 0; i < 500; i++) { float mass = radius * radius; cpBody body = space.AddBody(new cpBody(mass, cp.MomentForPoly(mass, 6, hexagon, cpVect.Zero, 0.0f))); body.SetPosition(cpVect.cpvadd(cpVect.cpvmult(cp.frand_unit_circle(), 130.0f), cpVect.Zero)); body.SetVelocity(cpVect.cpvmult(cp.frand_unit_circle(), 50.0f)); cpShape shape = space.AddShape(new cpPolyShape(body, 6, hexagon, cpTransform.Identity, bevel)); shape.SetElasticity(1.0f); } return(space); }
public override void Update(float dt) { base.Update(dt); float coef = (2.0f + ChipmunkDemoKeyboard.y) / 3.0f; float rate = ChipmunkDemoKeyboard.x * 30.0f * coef; motor.SetRate(rate); motor.SetMaxForce(rate > 0 ? 1000000.0f : 0.0f); space.Step(dt); for (int i = 0; i < numBalls; i++) { cpBody ball = balls[i]; cpVect pos = ball.GetPosition(); if (pos.x > 320.0f) { ball.SetVelocity(cpVect.Zero); ball.SetPosition(new cpVect(-224.0f, 200.0f)); } } }
public override void OnEnter() { base.OnEnter(); space.SetIterations(30); space.SetGravity(new cpVect(0, -500)); space.SetSleepTimeThreshold(0.5f); space.SetCollisionSlop(0.5f); var staticBody = space.GetStaticBody(); // Create segments around the edge of the screen. var shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, -240), new cpVect(-320, 240), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(320, -240), new cpVect(320, 240), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, -240), new cpVect(320, -240), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, 240), new cpVect(320, 240), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); { // Add the edges of the bucket var bb = new cpBB(-300, -200, 100, 0); var radius = 5.0f; shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(bb.l, bb.b), new cpVect(bb.l, bb.t), radius)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(bb.r, bb.b), new cpVect(bb.r, bb.t), radius)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(bb.l, bb.b), new cpVect(bb.r, bb.b), radius)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); // Add the sensor for the water. shape = space.AddShape(cpPolyShape.BoxShape2(staticBody, bb, 0.0f)); shape.SetSensor(true); shape.SetCollisionType(1); } { float width = 200.0f; float height = 50.0f; float mass = 0.3f * FLUID_DENSITY * width * height; var moment = cp.MomentForBox(mass, width, height); cpBody body = space.AddBody(new cpBody(mass, moment)); body.SetPosition(new cpVect(-50, -100)); body.SetVelocity(new cpVect(0, -100)); body.SetAngularVelocity(1); shape = space.AddShape(cpPolyShape.BoxShape(body, width, height, 0.0f)); shape.SetFriction(0.8f); } { float width = 40.0f; float height = width * 2; float mass = 0.3f * FLUID_DENSITY * width * height; float moment = cp.MomentForBox(mass, width, height); cpBody body = space.AddBody(new cpBody(mass, moment)); body.SetPosition(new cpVect(-200, -50)); body.SetVelocity(new cpVect(0, -100)); body.SetAngularVelocity(1); shape = space.AddShape(cpPolyShape.BoxShape(body, width, height, 0.0f)); shape.SetFriction(0.8f); } cpCollisionHandler handler = space.AddCollisionHandler(1, 0); handler.preSolveFunc = waterPreSolve; Schedule(); }