private void ClipPoly(Polygon shape, Vect n, double distance) { Body body = shape.Body; int count = shape.Count; var clipped = new List <Vect>(count); for (int i = 0, j = count - 1; i < count; j = i, i++) { Vect a = body.LocalToWorld(shape.GetVertex(j)); double a_dist = a.Dot(n) - distance; if (a_dist < 0.0) { clipped.Add(a); } Vect b = body.LocalToWorld(shape.GetVertex(i)); double b_dist = b.Dot(n) - distance; if (a_dist * b_dist < 0.0) { double t = Math.Abs(a_dist) / (Math.Abs(a_dist) + Math.Abs(b_dist)); clipped.Add(a.Lerp(b, t)); } } Vect centroid = Polygon.CentroidForPoly(clipped); double mass = Polygon.AreaForPoly(clipped, 0.0f) * Density; double moment = Polygon.MomentForPolygon(mass, clipped, -centroid, 0.0f); var new_body = new Body(mass, moment); space.AddBody(new_body); new_body.Position = centroid; new_body.Velocity = body.GetVelocityAtWorldPoint(centroid); new_body.AngularVelocity = body.AngularVelocity; var transform = Transform.CreateTranslation(-centroid); Shape new_shape = new Polygon(new_body, clipped, transform, 0.0); space.AddShape(new_shape); new_shape.Friction = shape.Friction; }
public override void Update(double dt) { // turn the control body based on the angle relative to the actual body Vect mouseDelta = ChipmunkDemoGame.ChipmunkDemoMouse - tankBody.Position; double turn = tankBody.Rotation.Unrotate(mouseDelta).ToAngle(); tankControlBody.Angle = tankBody.Angle - turn; // drive the tank towards the mouse if (ChipmunkDemoGame.ChipmunkDemoMouse.Near(tankBody.Position, 30.0)) { tankControlBody.Velocity = Vect.Zero; } else { double direction = mouseDelta.Dot(tankBody.Rotation) > 0.0 ? 1.0 : -1.0; tankControlBody.Velocity = tankBody.Rotation.Rotate(new Vect(30.0 * direction, 0.0f)); } base.Update(dt); }
private void SliceShapePostStep(Space space, object s, object c) { var context = (SliceContext)c; var shape = (Polygon)s; Vect a = context.A; Vect b = context.B; // Clipping plane normal and distance. Vect diff = b - a; Vect n = diff.Perpendicurlar.Normalize(); double dist = a.Dot(n); ClipPoly(shape, n, dist); ClipPoly(shape, -n, -dist); Body body = shape.Body; space.RemoveShape(shape); space.RemoveBody(body); shape.Free(); body.Free(); }