public override void OnEnter() { base.OnEnter(); space.SetIterations(30); space.SetGravity(new cpVect(0, -500)); space.SetSleepTimeThreshold(0.5f); space.SetCollisionSlop(0.5f); cpBody body, staticBody = space.GetStaticBody(); // Create segments around the edge of the screen. //this.addFloor(); this.shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, -240), new cpVect(320, -240), 0f)) as cpSegmentShape; this.shape.SetFriction(1.0f); this.shape.SetElasticity(0.6f); this.shape.SetFilter(NOT_GRABBABLE_FILTER); var width = 50; var height = 70; var mass = width * height * DENSITY; var moment = cp.MomentForBox(mass, width, height); body = space.AddBody(new cpBody(mass, moment)); body.SetPosition(new cpVect(0, 0)); this.shape = space.AddShape(cpPolyShape.BoxShape(body, width, height, 0.0f)); this.shape.SetFriction(0.6f); Schedule(); }
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); }
static public cpSpace ComplexTerrainCircles_1000(cpSpace space) { space.SetIterations(10); space.SetGravity(new cpVect(0, -100)); space.SetCollisionSlop(0.5f); cpVect offset = new cpVect(-320, -240); for (int i = 0; i < (complex_terrain_verts.Length - 1); i++) { cpVect a = complex_terrain_verts[i], b = complex_terrain_verts[i + 1]; space.AddShape(new cpSegmentShape(space.GetStaticBody(), cpVect.cpvadd(a, offset), cpVect.cpvadd(b, offset), 0.0f)); } for (int i = 0; i < 1000; 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(), 180.0f), new cpVect(0.0f, 300.0f))); cpShape shape = space.AddShape(new cpCircleShape(body, radius, cpVect.Zero)); shape.SetElasticity(0.0f); shape.SetFriction(0.0f); } return(space); }
cpShapeFree(cpShape shape) { if(shape){ cpShapeDestroy(shape); cpfree(shape); } }
public void remove(cpShape shape) { if (shape == null) { return; } var it = _shapes.Find((s) => s == shape); if (it != null) { _shapes.Remove(it); CCPhysicsShapeInfo tmp; if (_map.TryGetValue(shape, out tmp)) { _map.Remove(shape); } } //auto it = std::find(_shapes.begin(), _shapes.end(), shape); //if (it != _shapes.end()) //{ // _shapes.erase(it); // auto mit = _map.find(shape); // if (mit != _map.end()) _map.erase(mit); // cpShapeFree(shape); //} }
cpShapeInit(cpShape shape, cpShapeClass klass, cpBody body) { shape.klass = klass; shape.hashid = cpShapeIDCounter; cpShapeIDCounter++; shape.body = body; shape.sensor = 0; shape.e = 0.0f; shape.u = 0.0f; shape.surface_v = cpvzero; shape.collision_type = 0; shape.group = CP_NO_GROUP; shape.layers = CP_ALL_LAYERS; shape.data = null; shape.space = null; shape.next = null; shape.prev = null; return shape; }
public override void Update(float dt) { base.Update(dt); if (CCMouse.Instance.rightclick) { cpPointQueryInfo info = null; cpShape nearest = space.PointQueryNearest(CCMouse.Instance.Position, 0.0f, GRAB_FILTER, ref info); if (nearest != null) { cpBody body = nearest.GetBody(); // cpShapeGetBody(); if (body.bodyType == cpBodyType.STATIC) { body.SetBodyType(cpBodyType.DYNAMIC); body.SetMass(pentagon_mass); body.SetMoment(pentagon_moment); } else if (body.bodyType == cpBodyType.DYNAMIC) { body.SetBodyType(cpBodyType.STATIC); } } } space.EachBody(eachBody, null); space.Step(dt); }
arbiterSetEql(cpShape shapes, cpArbiter arb) { cpShape a = shapes[0]; cpShape b = shapes[1]; return ((a == arb.a && b == arb.b) || (b == arb.a && a == arb.b)); }
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()); }
circle2circle(cpShape shape1, cpShape shape2, cpContact arr) { cpCircleShape circ1 = (cpCircleShape )shape1; //TODO cpCircleShape circ2 = (cpCircleShape )shape2; return circle2circleQuery(circ1.tc, circ2.tc, circ1.r, circ2.r, arr); }
public override void OnEnter() { base.OnEnter(); space.SetIterations(30); space.SetGravity(new cpVect(0f, -300f)); space.SetCollisionSlop(0.5f); space.SetSleepTimeThreshold(1.0f); cpBody body, staticBody = space.GetStaticBody(); // Create segments around the edge of the screen. shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320f, -240f), new cpVect(-320f, 240f), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(320f, -240f), new cpVect(320f, 240f), 0.0f)); shape.SetElasticity(1f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320f, -240f), new cpVect(320f, -240f), 0.0f)); shape.SetElasticity(1f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); //RAMP scaleStaticBody = space.AddBody(cpBody.NewStatic()); shape = space.AddShape(new cpSegmentShape(scaleStaticBody, new cpVect(-240, -180), new cpVect(-140, -180), 4.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); if (!isTest) { // add some boxes to stack on the scale for (int i = 0; i < 5; i++) { body = space.AddBody(new cpBody(1.0f, cp.MomentForBox(1.0f, 30.0f, 30.0f))); body.SetPosition(new cpVect(0f, i * 32f - 220f)); shape = space.AddShape(cpPolyShape.BoxShape(body, 30.0f, 30.0f, 0.0f)); shape.SetElasticity(0.0f); shape.SetFriction(0.8f); } } //Add a ball that we'll track which objects are beneath it. float radius = 15.0f; ballBody = space.AddBody(new cpBody(10.0f, cp.MomentForCircle(10.0f, 0.0f, radius, cpVect.Zero))); ballBody.SetPosition(new cpVect(120, -240 + radius + 5)); shape = space.AddShape(new cpCircleShape(ballBody, radius, cpVect.Zero)); shape.SetElasticity(0.0f); shape.SetFriction(0.9f); Schedule(); }
public override void OnEnter() { base.OnEnter(); space.SetIterations(5); space.SetDamping(0.1f); float mass = 1.0f; { float size = 100.0f; cpBody body = space.AddBody(new cpBody(mass, cp.MomentForBox(mass, size, size))); body.SetPosition(new cpVect(100.0f, 50.0f)); shape1 = space.AddShape(cpPolyShape.BoxShape(body, size, size, 0.0f)); //shape1.SetGroup(1); } { float size = 100.0f; cpBody body = space.AddBody(new cpBody(mass, cp.MomentForBox(mass, size, size))); body.SetPosition(new cpVect(120.0f, -40.0f)); body.SetAngle(1e-2f); shape2 = space.AddShape(cpPolyShape.BoxShape(body, size, size, 0.0f)); //shape2.SetGroup(1); } Schedule(); }
public static void QueryPointFunc(cpShape shape, float distance, CCPoint point, ref CCPointQueryCallbackInfo info) { CCPhysicsShapeInfo it; cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it)); continues = info.func(info.world, it.getShape(), info.data); }
public static void GetShapesAtPointFunc(cpShape shape, float distance, CCPoint point, ref List <CCPhysicsShape> arr) { CCPhysicsShapeInfo it; cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it)); arr.Add(it.getShape()); // (it.second.getShape()); }
public static void QueryPointFunc(cpShape shape, float distance, CCPoint point, ref CCPointQueryCallbackInfo info) { CCPhysicsShapeInfo it; cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it)); Continues = info.Function(info.World, it.Shape, info.Data); }
public void DrawShape(cpShape shape) { cpBody body = shape.body; cpColor color = cp.GetShapeColor(shape);; // ColorForBody(body); switch (shape.shapeType) { case cpShapeType.Circle: { cpCircleShape circle = (cpCircleShape)shape; if ((Flags & cpDrawFlags.BB) == cpDrawFlags.BB || (Flags & cpDrawFlags.All) == cpDrawFlags.All) { Draw(circle.bb); } if ((Flags & cpDrawFlags.Shapes) == cpDrawFlags.Shapes || (Flags & cpDrawFlags.All) == cpDrawFlags.All) { Draw(circle, color); } } break; case cpShapeType.Segment: { cpSegmentShape seg = (cpSegmentShape)shape; if ((Flags & cpDrawFlags.BB) == cpDrawFlags.BB || (Flags & cpDrawFlags.All) == cpDrawFlags.All) { Draw(seg.bb); } if ((Flags & cpDrawFlags.Shapes) == cpDrawFlags.Shapes || (Flags & cpDrawFlags.All) == cpDrawFlags.All) { Draw(seg, color); } } break; case cpShapeType.Polygon: { cpPolyShape poly = (cpPolyShape)shape; if ((Flags & cpDrawFlags.BB) == cpDrawFlags.BB || (Flags & cpDrawFlags.All) == cpDrawFlags.All) { Draw(poly.bb); } if ((Flags & cpDrawFlags.Shapes) == cpDrawFlags.Shapes || (Flags & cpDrawFlags.All) == cpDrawFlags.All) { Draw(poly, color); } } break; default: cp.AssertHard(false, "Bad assertion in DrawShape()"); break; } }
PointQuery(ref PointQueryContext context, cpShape shape, object data) { if( !(shape.group && context.group == shape.group) && (context.layers & shape.layers) && cpShapePointQuery(shape, context.point) ){ context.func(shape, context.data); } }
public override float CalculateDefaultMoment() { cpShape shape = _info.GetShapes().FirstOrDefault(); return(_mass == cp.Infinity ? cp.Infinity : cp.MomentForCircle(_mass, 0, (shape as cpCircleShape).GetRadius(), (shape as cpCircleShape).GetOffset() )); }
public void Add(cpShape shape) { if (shape == null) { return; } shape.SetFilter(new cpShapeFilter(_group, cp.ALL_CATEGORIES, cp.ALL_CATEGORIES)); _shapes.Add(shape); Map.Add(shape, this); }
public static void QueryRectCallbackFunc(cpShape shape, CCRectQueryCallbackInfo info) { CCPhysicsShapeInfo it; cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it)); if (!continues) { return; } continues = info.func(info.world, it.getShape(), info.data); }
static public void add_circle(cpSpace space, int index, float radius) { float mass = radius * radius / 25.0f; cpBody body = space.AddBody(new cpBody(mass, cp.MomentForCircle(mass, 0.0f, radius, cpVect.Zero))); // cpBody body = cpSpaceAddBody(space, cpBodyInit(&bodies[i], mass, cpMomentForCircle(mass, 0.0f, radius, cpVect.Zero))); body.SetPosition(cpVect.cpvmult(cp.frand_unit_circle(), 180.0f)); cpShape shape = space.AddShape(new cpCircleShape(body, radius, cpVect.Zero)); // cpShape shape = cpSpaceAddShape(space, cpCircleShapeInit(&circles[i], body, radius, cpVect.Zero)); shape.SetElasticity(0.0f); shape.SetFriction(0.9f); }
public static void QueryRectCallbackFunc(cpShape shape, CCRectQueryCallbackInfo info) { CCPhysicsShapeInfo it; cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it)); if (!Continues) { return; } Continues = info.Function(info.World, it.Shape, info.Data); }
int ClipCell(cpShape shape, cpVect center, int i, int j, WorleyContex context, cpVect[] verts, cpVect[] clipped, int count) { cpVect other = WorleyPoint(i, j, ref context); // printf(" other %dx%d: (% 5.2f, % 5.2f) ", i, j, other.x, other.y); cpPointQueryInfo queryInfo = null; if (shape.PointQuery(other, ref queryInfo) > 0.0f) { for (int x = 0; x < count; x++) { clipped[x] = new cpVect(verts[x]); } return(count); } else { // printf("clipped\n"); } cpVect n = cpVect.cpvsub(other, center); float dist = cpVect.cpvdot(n, cpVect.cpvlerp(center, other, 0.5f)); int clipped_count = 0; for (j = 0, i = count - 1; j < count; i = j, j++) { cpVect a = verts[i]; float a_dist = cpVect.cpvdot(a, n) - dist; if (a_dist <= 0.0f) { clipped[clipped_count] = a; clipped_count++; } cpVect b = verts[j]; float b_dist = cpVect.cpvdot(b, n) - dist; if (a_dist * b_dist < 0.0f) { float t = cp.cpfabs(a_dist) / (cp.cpfabs(a_dist) + cp.cpfabs(b_dist)); clipped[clipped_count] = cpVect.cpvlerp(a, b, t); clipped_count++; } } return(clipped_count); }
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); }
public cpBody add_ball(cpSpace space, cpVect pos) { cpBody body = space.AddBody(new cpBody(1.0f, cp.MomentForCircle(1.0f, 30, 0, cpVect.Zero))); body.SetPosition(pos); cpShape shape = space.AddShape(new cpCircleShape(body, 30, cpVect.Zero)); shape.SetElasticity(0.0f); shape.SetFriction(0.5f); return(body); }
cpBody add_box(float size, float mass) { float radius = cpVect.cpvlength(new cpVect(size, size)); cpBody body = space.AddBody(new cpBody(mass, cp.MomentForBox(mass, size, size))); body.SetPosition(new cpVect((float)CCRandom.Float_0_1() * (640 - 2 * radius) - (320 - radius), (float)CCRandom.Float_0_1() * (480 - 2 * radius) - (240 - radius))); cpShape shape = space.AddShape(cpPolyShape.BoxShape(body, size, size, 0)); shape.SetElasticity(0); shape.SetFriction(0.7f); return(body); }
public override void OnEnter() { base.OnEnter(); space.SetIterations(30); space.SetGravity(new cpVect(0, -300)); space.SetSleepTimeThreshold(0.5f); space.SetCollisionSlop(0.5f); cpShape shape = space.AddShape(new cpSegmentShape(space.GetStaticBody(), new cpVect(-600, -240), new cpVect(600, -240), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); // Add the dominoes. var n = 7; for (var i = 0; i < n; i++) { for (var j = 0; j < (n - i); j++) { var offset = new cpVect((j - (n - 1 - i) * 0.5f) * 1.5f * HEIGHT, (i + 0.5f) * (HEIGHT + 2 * WIDTH) - WIDTH - 240); add_domino(offset, false); add_domino(cpVect.cpvadd(offset, new cpVect(0, (HEIGHT + WIDTH) / 2)), true); if (j == 0) { add_domino(cpVect.cpvadd(offset, new cpVect(0.5f * (WIDTH - HEIGHT), HEIGHT + WIDTH)), false); } if (j != n - i - 1) { add_domino(cpVect.cpvadd(offset, new cpVect(HEIGHT * 0.75f, (HEIGHT + 3 * WIDTH) / 2)), true); } else { add_domino(cpVect.cpvadd(offset, new cpVect(0.5f * (HEIGHT - WIDTH), HEIGHT + WIDTH)), false); } } } Schedule(); }
public override void Update(float dt) { base.Update(dt); if (CCMouse.Instance.rightclick) { QUERY_START = CCMouse.Instance.Position; } start = QUERY_START; end = CCMouse.Instance.Position; float radius = 10; segInfo = null; m_debugDraw.DrawSegment(start, end, 1, cpColor.Green); shapeInfo = this.space.SegmentQueryFirst(start, end, radius, cpShape.FILTER_ALL, ref segInfo); if (shapeInfo != null) { font.Text = string.Format("Segment Query: Dist({0}) Normal({1},{2})", segInfo.alpha * cpVect.cpvdist(start, end), segInfo.normal.x, segInfo.normal.y); } else { font.Text = string.Format("Segment Query (None)"); } nearestInfo = null; space.PointQueryNearest(CCMouse.Instance.Position, 100, cpShape.FILTER_ALL, ref nearestInfo); if (nearestInfo != null) { // Draw a grey line to the closest shape. m_debugDraw.Draw(CCMouse.Instance.Position, new cpColor(127, 127, 127, 255)); m_debugDraw.DrawSegment(CCMouse.Instance.Position, nearestInfo.point, 1, new cpColor(127, 127, 127, 255)); // Draw a red bounding box around the shape under the mouse. if (nearestInfo.distance < 0) { m_debugDraw.Draw(nearestInfo.shape.bb, cpColor.Red); } } space.Step(dt); }
public void SliceShapePostStep(cpSpace space, cpShape shape, SliceContext context) { cpVect a = context.a; cpVect b = context.b; // Clipping plane normal and distance. cpVect n = cpVect.cpvnormalize(cpVect.cpvperp(cpVect.cpvsub(b, a))); float dist = cpVect.cpvdot(a, n); ClipPoly(space, shape, n, dist); ClipPoly(space, shape, cpVect.cpvneg(n), -dist); cpBody body = shape.GetBody(); space.RemoveShape(shape); space.RemoveBody(body); }
public void SliceQuery(cpShape shape, float t, cpVect n, SliceContext context) { cpVect a = context.a; cpVect b = context.b; // Check that the slice was complete by checking that the endpoints aren't in the sliced shape. cpPointQueryInfo inf1 = null; cpPointQueryInfo inf2 = null; if (shape.PointQuery(a, ref inf1) > 0 && shape.PointQuery(b, ref inf2) > 0) { // Can't modify the space during a query. // Must make a post-step callback to do the actual slicing. context.space.AddPostStepCallback( (s, o1, o2) => SliceShapePostStep(s, (cpShape)o1, (SliceContext)o2), shape, context); } }
public void Remove(cpShape shape) { if (shape == null) { return; } var it = _shapes.Find((s) => s == shape); if (it != null) { _shapes.Remove(it); CCPhysicsShapeInfo tmp; if (_map.TryGetValue(shape, out tmp)) { _map.Remove(shape); } } }
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 void Main(string[] args) { cpSpace space = new cpSpace(); space.SetGravity(new cpVect(0, -100)); cpShape shape = cpShape.NewSegment(space.StaticBody, new cpVect(-20, 5), new cpVect(20, -5), 0); shape.SetFriction(1); space.AddShape(shape); double radius = 5; double mass = 1; double moment = cpUtil.MomentForCircle(mass, 0, radius, cpVect.Zero); cpBody ballBody = new cpBody(mass, moment); space.AddBody(ballBody); ballBody.Position = new cpVect(0, 15); cpShape ballShape = cpShape.NewCircle(ballBody, radius, cpVect.Zero); space.AddShape(ballShape); ballShape.SetFriction(0.7); double timeStep = 1 / 60d; for (double time = 0; time < 2; time += timeStep) { cpVect pos = ballBody.Position; cpVect vel = ballBody.Velocity; Console.WriteLine("Time is {0:F2}. ballBody is at ({1:F2}, {2:F2}). It's velocity is ({3:F2}, {4:F2})", time, pos.X, pos.Y, vel.X, vel.Y ); space.Step(timeStep); } Console.ReadKey(); }
/** return physics shape that contains the point. */ public CCPhysicsShape GetShape(CCPoint point) { cpShape shape = null; this._info.getSpace().PointQuery( PhysicsHelper.CCPointToCpVect(point), 0, new cpShapeFilter(cp.NO_GROUP, cp.ALL_LAYERS, cp.ALL_LAYERS), (s, v1, f, v2, o) => { shape = s; }, null); if (shape == null) { return(null); } CCPhysicsShapeInfo dev; if (CCPhysicsShapeInfo.Map.TryGetValue(shape, out dev)) { return(dev.getShape()); } return(null); }
poly2poly(cpShape shape1, cpShape shape2, cpContact arr) { cpPolyShape poly1 = (cpPolyShape )shape1; cpPolyShape poly2 = (cpPolyShape )shape2; double min1; int mini1 = findMSA(poly2, poly1.tPlanes, poly1.numVerts, &min1); if(mini1 == -1) return 0; double min2; int mini2 = findMSA(poly1, poly2.tPlanes, poly2.numVerts, &min2); if(mini2 == -1) return 0; // There is overlap, find the penetrating verts if(min1 > min2) return findVerts(arr, poly1, poly2, poly1.tPlanes[mini1].n, min1); else return findVerts(arr, poly1, poly2, cpvneg(poly2.tPlanes[mini2].n), min2); }
cpShapeUpdate(cpShape shape, cpVect pos, cpVect rot) { return (shape.bb = shape.klass.cacheData(shape, pos, rot)); }
cpSegmentShapeSetNeighbors(cpShape shape, cpVect prev, cpVect next) { // cpAssertHard(shape.klass == &cpSegmentShapeClass, "Shape is not a segment shape."); cpSegmentShape seg = (cpSegmentShape )shape; seg.a_tangent = cpVect.Sub(prev, seg.a); seg.b_tangent = cpVect.Sub(next, seg.b); }
cpShapeCacheBB(cpShape shape) { cpBody body = shape.body; return cpShapeUpdate(shape, body.p, body.rot); }
cpCircleShapeSetRadius(cpShape shape, double radius) { // cpAssertHard(shape.klass == &cpCircleShapeClass, "Shape is not a circle shape."); cpCircleShape circle = (cpCircleShape )shape; circle.r = radius; }
cpShapeDestroy(cpShape shape) { if(shape.klass && shape.klass.destroy) shape.klass.destroy(shape); }
cpShapeSegmentQuery(cpShape shape, cpVect a, cpVect b, ref cpSegmentQueryInfo info){ cpSegmentQueryInfo blank = new cpSegmentQueryInfo() {null, 0.0f, cpvzero}; info = blank; cpNearestPointQueryInfo nearest; shape.klass.nearestPointQuery(shape, a, &nearest); if(nearest.d <= 0.0){ info.shape = shape; info.t = 0.0; info.n = cpvnormalize(cpVect.Sub(a, nearest.p)); } else { shape.klass.segmentQuery(shape, a, b, info); } return (info.shape != null); }
seg2seg(cpShape shape1, cpShape shape2, cpContact* con) { cpSegmentShape* seg1 = (cpSegmentShape )shape1; cpSegmentShape* seg2 = (cpSegmentShape )shape2; cpVect v1 = cpVect.Sub(seg1.tb, seg1.ta); cpVect v2 = cpVect.Sub(seg2.tb, seg2.ta); double v1lsq = cpVect.LengthSQ(v1); double v2lsq = cpVect.LengthSQ(v2); // project seg2 onto seg1 cpVect p1a = cpvproject(cpVect.Sub(seg2.ta, seg1.ta), v1); cpVect p1b = cpvproject(cpVect.Sub(seg2.tb, seg1.ta), v1); // project seg1 onto seg2 cpVect p2a = cpvproject(cpVect.Sub(seg1.ta, seg2.ta), v2); cpVect p2b = cpvproject(cpVect.Sub(seg1.tb, seg2.ta), v2); // clamp projections to segment endcaps if (cpVect.Dot(p1a, v1) < 0.0f) p1a = cpvzero; else if (cpVect.Dot(p1a, v1) > 0.0f && cpVect.LengthSQ(p1a) > v1lsq) p1a = v1; if (cpVect.Dot(p1b, v1) < 0.0f) p1b = cpvzero; else if (cpVect.Dot(p1b, v1) > 0.0f && cpVect.LengthSQ(p1b) > v1lsq) p1b = v1; if (cpVect.Dot(p2a, v2) < 0.0f) p2a = cpvzero; else if (cpVect.Dot(p2a, v2) > 0.0f && cpVect.LengthSQ(p2a) > v2lsq) p2a = v2; if (cpVect.Dot(p2b, v2) < 0.0f) p2b = cpvzero; else if (cpVect.Dot(p2b, v2) > 0.0f && cpVect.LengthSQ(p2b) > v2lsq) p2b = v2; p1a = cpVect.Add(p1a, seg1.ta); p1b = cpVect.Add(p1b, seg1.ta); p2a = cpVect.Add(p2a, seg2.ta); p2b = cpVect.Add(p2b, seg2.ta); int num = 0; if (!circle2circleQuery(p1a, p2a, seg1.r, seg2.r, nextContactPoint(con, &num))) --num; if (!circle2circleQuery(p1b, p2b, seg1.r, seg2.r, nextContactPoint(con, &num))) --num; if (!circle2circleQuery(p1a, p2b, seg1.r, seg2.r, nextContactPoint(con, &num))) --num; if (!circle2circleQuery(p1b, p2a, seg1.r, seg2.r, nextContactPoint(con, &num))) --num; return num; }
seg2poly(cpShape shape1, cpShape shape2, cpContact arr) { cpSegmentShape seg = (cpSegmentShape )shape1; cpPolyShape poly = (cpPolyShape )shape2; cpSplittingPlane planes = poly.tPlanes; double segD = cpVect.Dot(seg.tn, seg.ta); double minNorm = cpPolyShapeValueOnAxis(poly, seg.tn, segD) - seg.r; double minNeg = cpPolyShapeValueOnAxis(poly, cpvneg(seg.tn), -segD) - seg.r; if(minNeg > 0.0f || minNorm > 0.0f) return 0; int mini = 0; double poly_min = segValueOnAxis(seg, planes.n, planes.d); if(poly_min > 0.0f) return 0; for(int i=0; i<poly.numVerts; i++){ double dist = segValueOnAxis(seg, planes[i].n, planes[i].d); if(dist > 0.0f){ return 0; } else if(dist > poly_min){ poly_min = dist; mini = i; } } int num = 0; cpVect poly_n = cpvneg(planes[mini].n); cpVect va = cpVect.Add(seg.ta, cpVect.Multiply(poly_n, seg.r)); cpVect vb = cpVect.Add(seg.tb, cpVect.Multiply(poly_n, seg.r)); if(cpPolyShapeContainsVert(poly, va)) cpContactInit(nextContactPoint(arr, &num), va, poly_n, poly_min, CP_HASH_PAIR(seg.shape.hashid, 0)); if(cpPolyShapeContainsVert(poly, vb)) cpContactInit(nextContactPoint(arr, &num), vb, poly_n, poly_min, CP_HASH_PAIR(seg.shape.hashid, 1)); // doubleing point precision problems here. // This will have to do for now. // poly_min -= cp_collision_slop; // TODO is this needed anymore? if(minNorm >= poly_min || minNeg >= poly_min) { if(minNorm > minNeg) findPointsBehindSeg(arr, &num, seg, poly, minNorm, 1.0f); else findPointsBehindSeg(arr, &num, seg, poly, minNeg, -1.0f); } // If no other collision points are found, try colliding endpoints. if(num == 0){ cpVect poly_a = poly.tVerts[mini]; cpVect poly_b = poly.tVerts[(mini + 1)%poly.numVerts]; if(circle2circleQuery(seg.ta, poly_a, seg.r, 0.0f, arr)) return 1; if(circle2circleQuery(seg.tb, poly_a, seg.r, 0.0f, arr)) return 1; if(circle2circleQuery(seg.ta, poly_b, seg.r, 0.0f, arr)) return 1; if(circle2circleQuery(seg.tb, poly_b, seg.r, 0.0f, arr)) return 1; } return num; }
cpSegmentShapeSetRadius(cpShape shape, double radius) { // cpAssertHard(shape.klass == &cpSegmentShapeClass, "Shape is not a segment shape."); cpSegmentShape seg = (cpSegmentShape )shape; seg.r = radius; }
cpBodyRemoveShape(cpBody body, cpShape shape) { cpShape prev = shape.prev; cpShape next = shape.next; if(prev){ prev.next = next; } else { body.shapeList = next; } if(next){ next.prev = prev; } shape.prev = null; shape.next = null; }
cpPolyShapeSetVerts(cpShape shape, int numVerts, cpVect[] verts, cpVect offset) { // cpAssertHard(shape.klass == &polyClass, "Shape is not a poly shape."); cpPolyShapeDestroy((cpPolyShape)shape); setUpVerts((cpPolyShape)shape, numVerts, verts, offset); }
cpPolyShapeGetVert(cpShape shape, int idx) { // cpAssertHard(shape.klass == &polyClass, "Shape is not a poly shape."); // cpAssertHard(0 <= idx && idx < cpPolyShapeGetNumVerts(shape), "Index out of range."); return ((cpPolyShape)shape).verts[idx]; }
cpPolyShapeGetNumVerts(cpShape shape) { // cpAssertHard(shape.klass == &polyClass, "Shape is not a poly shape."); return ((cpPolyShape)shape).numVerts; }
circle2poly(cpShape shape1, cpShape shape2, cpContact con) { cpCircleShape circ = (cpCircleShape )shape1; cpPolyShape poly = (cpPolyShape )shape2; cpSplittingPlane planes = poly.tPlanes; int mini = 0; double min = cpSplittingPlaneCompare(planes[0], circ.tc) - circ.r; for(int i=0; i<poly.numVerts; i++){ double dist = cpSplittingPlaneCompare(planes[i], circ.tc) - circ.r; if(dist > 0.0f){ return 0; } else if(dist > min) { min = dist; mini = i; } } cpVect n = planes[mini].n; cpVect a = poly.tVerts[mini]; cpVect b = poly.tVerts[(mini + 1)%poly.numVerts]; double dta = cpVect.CrossProduct(n, a); double dtb = cpVect.CrossProduct(n, b); double dt = cpVect.CrossProduct(n, circ.tc); if(dt < dtb){ return circle2circleQuery(circ.tc, b, circ.r, 0.0f, con); } else if(dt < dta) { cpContactInit( con, cpVect.Sub(circ.tc, cpVect.Multiply(n, circ.r + min/2.0f)), cpvneg(n), min, 0 ); return 1; } else { return circle2circleQuery(circ.tc, a, circ.r, 0.0f, con); } }
cpSegmentShapeSetEndpoints(cpShape shape, cpVect a, cpVect b) { // cpAssertHard(shape.klass == &cpSegmentShapeClass, "Shape is not a segment shape."); cpSegmentShape seg = (cpSegmentShape )shape; seg.a = a; seg.b = b; seg.n = cpvperp(cpvnormalize(cpVect.Sub(b, a))); }
circleSegmentQuery(cpShape shape, cpVect center, double r, cpVect a, cpVect b, cpSegmentQueryInfo info) { cpVect da = cpVect.Sub(a, center); cpVect db = cpVect.Sub(b, center); double qa = cpVect.Dot(da, da) - 2.0f*cpVect.Dot(da, db) + cpVect.Dot(db, db); double qb = -2.0f*cpVect.Dot(da, da) + 2.0f*cpVect.Dot(da, db); double qc = cpVect.Dot(da, da) - r*r; double det = qb*qb - 4.0f*qa*qc; if(det >= 0.0f){ double t = (-qb - System.Math.Sqrt(det))/(2.0f*qa); if(0.0f<= t && t <= 1.0f){ info.shape = shape; info.t = t; info.n = cpvnormalize(cpvlerp(da, db, t)); } } }
cpCircleShapeSetOffset(cpShape shape, cpVect offset) { // cpAssertHard(shape.klass == &cpCircleShapeClass, "Shape is not a circle shape."); cpCircleShape circle = (cpCircleShape )shape; circle.c = offset; }
// function to get the estimated velocity of a shape for the cpBBTree. static cpVect shapeVelocityFunc(cpShape shape){return shape.body.v;}
cpShapeSetBody(cpShape shape, cpBody body) { // cpAssertHard(!cpShapeActive(shape), "You cannot change the body on an active shape. You must remove the shape from the space before changing the body."); shape.body = body; }
cpBodyAddShape(cpBody body, cpShape shape) { cpShape next = body.shapeList; if(next) next.prev = shape; shape.next = next; body.shapeList = shape; }
cpShapeNearestPointQuery(cpShape shape, cpVect p, ref cpNearestPointQueryInfo info) { cpNearestPointQueryInfo blank = new cpNearestPointQueryInfo() {null, cpvzero, double.PositiveInfinity}; info = blank; shape.klass.nearestPointQuery(shape, p, info); return info.d; }
public SupportContext(cpShape shape1, cpShape shape2, Func<cpShape, cpVect, SupportPoint> func1, Func<cpShape, cpVect, SupportPoint> func2) { this.shape1 = shape1; this.shape2 = shape2; this.func1 = func1; this.func2 = func2; }
cpShapePointQuery(cpShape shape, cpVect p){ cpNearestPointQueryInfo info = new cpNearestPointQueryInfo() { null, cpvzero, double.PositiveInfinity }; cpShapeNearestPointQuery(shape, p, ref info); return (info.d < 0.0f); }