cpSpaceActivateBody(cpSpace space, cpBody body) { // cpAssertHard(!cpBodyIsRogue(body), "Internal error: Attempting to activate a rogue body."); if(space.locked){ // cpSpaceActivateBody() is called again once the space is unlocked if(!cpArrayContains(space.rousedBodies, body)) cpArrayPush(space.rousedBodies, body); } else { // cpAssertSoft(body.node.root == null && body.node.next == null, "Internal error: Activating body non-null node pointers."); cpArrayPush(space.bodies, body); CP_BODY_FOREACH_SHAPE(body, shape){ cpSpatialIndexRemove(space.staticShapes, shape, shape.hashid); cpSpatialIndexInsert(space.activeShapes, shape, shape.hashid); } CP_BODY_FOREACH_ARBITER(body, arb){ cpBody bodyA = arb.body_a; // Arbiters are shared between two bodies that are always woken up together. // You only want to restore the arbiter once, so bodyA is arbitrarily chosen to own the arbiter. // The edge case is when static bodies are involved as the static bodies never actually sleep. // If the static body is bodyB then all is good. If the static body is bodyA, that can easily be checked. if(body == bodyA || cpBodyIsStatic(bodyA)){ int numContacts = arb.numContacts; cpContact contacts = arb.contacts; // Restore contact values back to the space's contact buffer memory arb.contacts = cpContactBufferGetArray(space); memcpy(arb.contacts, contacts, numContacts*sizeof(cpContact)); cpSpacePushContacts(space, numContacts); // Reinsert the arbiter into the arbiter cache cpShape a = arb.a, *b = arb.b; cpShape shape_pair[] = {a, b};
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; }
cpBodyInit(cpBody body, double m, double i) { body.space = null; body.shapeList = null; body.arbiterList = null; body.constraintList = null; body.velocity_func = cpBodyUpdateVelocity; body.position_func = cpBodyUpdatePosition; cpComponentNode node = new cpComponentNode() {null, null, 0.0f}; body.node = node; body.p = cpvzero; body.v = cpvzero; body.f = cpvzero; body.w = 0.0f; body.t = 0.0f; body.v_bias = cpvzero; body.w_bias = 0.0f; body.v_limit = double.PositiveInfinity; body.w_limit = double.PositiveInfinity; body.data = null; // Setters must be called after full initialization so the sanity checks don't assert on garbage data. cpBodySetMass(body, m); cpBodySetMoment(body, i); cpBodySetAngle(body, 0.0f); return body; }
cpBodyInitStatic(cpBody body) { cpBodyInit(body, double.PositiveInfinity, double.PositiveInfinity); body.node.idleTime = double.PositiveInfinity; return body; }
public override void ApplyImpulse(float dt) { cpBody a = this.a; cpBody b = this.b; cpVect r1 = this.r1; cpVect r2 = this.r2; // compute relative velocity cpVect vr = cp.relative_velocity(a, b, r1, r2); // compute normal impulse cpVect j = cpMat2x2.Transform(this.k, cpVect.cpvsub(this.bias, vr)); cpVect jOld = this.jAcc; this.jAcc = cpVect.cpvclamp(cpVect.cpvadd(this.jAcc, j), this.maxForce * dt); j = cpVect.cpvsub(this.jAcc, jOld); // apply impulse cp.apply_impulses(a, b, this.r1, this.r2, j); }
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(); }
public override void OnEnter() { base.OnEnter(); space.SetIterations(20); planetBody = space.AddBody(cpBody.NewKinematic()); planetBody.SetAngularVelocity(0.2f); for (int i = 0; i < 30; i++) { add_box(); } cpShape shape = space.AddShape(new cpCircleShape(planetBody, 70, cpVect.Zero)); shape.SetElasticity(1); shape.SetFriction(1); shape.SetFilter(NOT_GRABBABLE_FILTER); Schedule(); }
public PhysicObject(UIImage firstText, int radius, cpSpace space, bool isKinematic = false) : base(firstText) { trsf = new cpTransform(); collCount++; physic = new cpBody(rnd.Next(500, 1000), cp.PHYSICS_INFINITY); if (isKinematic) { physic.SetBodyType(cpBodyType.KINEMATIC); } shp = new cpCircleShape(physic, radius, cpVect.Zero); shp.Active(); shp.SetSensor(true); shp.SetCollisionType(1); physic.SetPosition(new cpVect((float)Frame.Location.X, (float)Frame.Location.Y)); if (space != null) { space.AddBody(physic); space.AddShape(shp); this.space = space; } }
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); }
static public cpSpace ComplexTerrainHexagons_1000(cpSpace space) { SetSubTitle("ComplexTerrainHexagons_1000"); 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)); } 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 < 1000; 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(), 180.0f), new cpVect(0.0f, 300.0f))); cpShape shape = space.AddShape(new cpPolyShape(body, 6, hexagon, cpTransform.Identity, bevel)); shape.SetElasticity(0.0f); shape.SetFriction(0.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 PreStep(float dt) { cpBody a = this.a; cpBody b = this.b; this.r1 = cpTransform.Vect(a.transform, cpVect.cpvsub(this.anchorA, a.cog)); this.r2 = cpTransform.Vect(b.transform, cpVect.cpvsub(this.anchorB, b.cog)); cpVect delta = cpVect.cpvsub(cpVect.cpvadd(b.p, this.r2), cpVect.cpvadd(a.p, this.r1)); float dist = cpVect.cpvlength(delta); float pdist = 0.0f; if (dist > this.max) { pdist = dist - this.max; this.n = cpVect.cpvnormalize(delta); } else if (dist < this.min) { pdist = this.min - dist; this.n = cpVect.cpvneg(cpVect.cpvnormalize(delta)); } else { this.n = cpVect.Zero; this.jnAcc = 0.0f; } // calculate mass normal this.nMass = 1.0f / cp.k_scalar(a, b, this.r1, this.r2, this.n); // calculate bias velocity float maxBias = this.maxBias; this.bias = cp.cpfclamp(-cp.bias_coef(this.errorBias, dt) * pdist / dt, -maxBias, maxBias); }
public void SetBody(cpBody body) { _body = body; }
cpBoxShapeInit2(cpPolyShape poly, cpBody body, cpBB box) { cpVect[] verts = new cpVect[] { cpv(box.l, box.b), cpv(box.l, box.t), cpv(box.r, box.t), cpv(box.r, box.b) }; return cpPolyShapeInit(poly, body, 4, verts, cpvzero); }
cpBoxShapeNew2(cpBody body, cpBB box) { return (cpShape)cpBoxShapeInit2(new cpPolyShape(), body, box); }
public static cpShape NewSegment(cpBody body, cpVect a, cpVect b, cpFloat r) { return(new cpShape(cpSegmentShapeNew(body, a, b, r))); }
cpPolyShapeNew(cpBody body, int numVerts, cpVect[] verts, cpVect offset) { return (cpShape)cpPolyShapeInit(new cpPolyShape(), body, numVerts, verts, offset); }
cpBodyApplyForce(cpBody body, cpVect force, cpVect r) { cpBodyActivate(body); body.f = cpVect.Add(body.f, force); body.t += cpVect.CrossProduct(r, force); }
cpBodyUpdatePosition(cpBody body, double dt) { body.p = cpVect.Add(body.p, cpVect.Multiply(cpVect.Add(body.v, body.v_bias), dt)); setAngle(body, body.a + (body.w + body.w_bias)*dt); body.v_bias = cpvzero; body.w_bias = 0.0f; cpBodySanityCheck(body); }
cpBodyEachConstraint(cpBody body, cpBodyConstraintIteratorFunc func, object data) { cpConstraint constraint = body.constraintList; while(constraint){ cpConstraint next = cpConstraintNext(constraint, body); func(body, constraint, data); constraint = next; } }
cpBodyEachArbiter(cpBody body, cpBodyArbiterIteratorFunc func, object data) { cpArbiter arb = body.arbiterList; while(arb){ cpArbiter next = cpArbiterNext(arb, body); arb.swappedColl = (body == arb.body_b); func(body, arb, data); arb = next; } }
cpBodyGetVelAtLocalPoint(cpBody body, cpVect point) { return cpBodyGetVelAtPoint(body, cpvrotate(point, body.rot)); }
cpBodyEachShape(cpBody body, cpBodyShapeIteratorFunc func, object data) { cpShape shape = body.shapeList; while(shape){ cpShape next = shape.next; func(body, shape, data); shape = next; } }
cpBodyGetVelAtWorldPoint(cpBody body, cpVect point) { return cpBodyGetVelAtPoint(body, cpVect.Sub(point, body.p)); }
cpBodyGetVelAtPoint(cpBody body, cpVect r) { return cpVect.Add(body.v, cpVect.Multiply(cpvperp(r), body.w)); }
cpBodyApplyImpulse(cpBody body, cpVect j, cpVect r) { cpBodyActivate(body); apply_impulse(body, j, r); }
public override void OnEnter() { base.OnEnter(); SetSubTitle("Use the mouse to drive the tank, it will follow the cursor."); //Position = new CCPoint(240, 170); space.SetIterations(10); space.SetSleepTimeThreshold(0.5f); cpBody staticBody = space.GetStaticBody(); cpShape shape; // Create segments around the edge of the screen. shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, -240), new cpVect(-320, 240), 0)); shape.SetElasticity(1); shape.SetFriction(1); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(320, -240), new cpVect(320, 240), 0)); shape.SetElasticity(1); shape.SetFriction(1); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, -240), new cpVect(320, -240), 0)); shape.SetElasticity(1); shape.SetFriction(1); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, 240), new cpVect(320, 240), 0)); shape.SetElasticity(1); shape.SetFriction(1); shape.SetFilter(NOT_GRABBABLE_FILTER); for (int i = 0; i < 50; i++) { cpBody body = add_box(20, 1); cpConstraint pivot = space.AddConstraint(new cpPivotJoint(staticBody, body, cpVect.Zero, cpVect.Zero)); pivot.SetMaxBias(0); // disable joint correction pivot.SetMaxForce(1000); // emulate linear friction cpConstraint gear = space.AddConstraint(new cpGearJoint(staticBody, body, 0, 1)); gear.SetMaxBias(0); // disable joint correction gear.SetMaxForce(5000); // emulate linear friction } // We joint the tank to the control body and control the tank indirectly by modifying the control body. tankControlBody = space.AddBody(cpBody.NewKinematic()); tankBody = add_box(30, 10); cpConstraint pivot2 = space.AddConstraint(new cpPivotJoint(tankControlBody, tankBody, cpVect.Zero, cpVect.Zero)); pivot2.SetMaxBias(0); // disable joint correction pivot2.SetMaxForce(10000); // emulate linear friction cpConstraint gears = space.AddConstraint(new cpGearJoint(tankControlBody, tankBody, 0, 1)); gears.SetErrorBias(0); // attempt to fully correct the joint each step gears.SetMaxBias(1.2f); // but limit it's angular correction rate gears.SetMaxForce(5000); // emulate angular friction Schedule(); }
cpBodySetAngle(cpBody body, double angle) { cpBodyActivate(body); setAngle(body, angle); }
public override void OnEnter() { base.OnEnter(); SetSubTitle("Right click to make pentagons static/dynamic."); space.SetIterations(5); space.SetGravity(new cpVect(0, -100)); cpBody body, staticBody = space.GetStaticBody(); cpShape shape; // Vertexes for a triangle shape. cpVect[] tris = new cpVect[] { new cpVect(-15, -15), new cpVect(0, 10), new cpVect(15, -15), }; // Create the static triangles. for (int i = 0; i < 9; i++) { for (int j = 0; j < 6; j++) { float stagger = (j % 2) * 40; cpVect offset = new cpVect(i * 80 - 320 + stagger, j * 70 - 240); shape = space.AddShape(new cpPolyShape(staticBody, 3, tris, cpTransform.Translate(offset), 0)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); } } cpVect[] verts = new cpVect[NUM_VERTS]; for (int i = 0; i < NUM_VERTS; i++) { float angle = -2 * cp.M_PI * i / NUM_VERTS; verts[i] = cpVect.cpv(10 * cp.cpfcos(angle), 10 * cp.cpfsin(angle)); } pentagon_mass = 1; pentagon_moment = cp.MomentForPoly(1.0f, NUM_VERTS, verts, cpVect.Zero, 0.0f); // Add lots of pentagons. for (int i = 0; i < 100; i++) { body = space.AddBody(new cpBody(pentagon_mass, pentagon_moment)); body.SetPosition( new cpVect( RandomHelper.next(-300, 300), RandomHelper.next(350, 1000))); shape = space.AddShape(new cpPolyShape(body, NUM_VERTS, verts, cpTransform.Identity, 0.0f)); shape.SetElasticity(0.0f); shape.SetFriction(0.4f); } Schedule(); }
setAngle(cpBody body, double angle) { body.a = angle;//fmod(a, (double)System.Math.PI*2.0f); body.rot = cpvforangle(angle); cpBodyAssertSane(body); }
public void AddBody(cpBody body) { cpSpaceAddBody(pointer, body); }
void cpBodyDestroy(cpBody body){}
public override void OnEnter() { base.OnEnter(); SetSubTitle("Use the arrow keys to control the machine."); space.SetIterations(20); space.SetGravity(new cpVect(0, -500)); cpBody staticBody = space.GetStaticBody(); cpShape shape; cpVect a, b; shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, 240), new cpVect(320, 240), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); // Create segments around the edge of the screen. 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); float offset = 30.0f; // make chassis float chassis_mass = 2.0f; a = new cpVect(-offset, 0.0f); b = new cpVect(offset, 0.0f); cpBody chassis = space.AddBody(new cpBody(chassis_mass, cp.MomentForSegment(chassis_mass, a, b, 0.0f))); shape = space.AddShape(new cpSegmentShape(chassis, a, b, seg_radius)); shape.SetFilter(new cpShapeFilter(1, cp.ALL_CATEGORIES, cp.ALL_CATEGORIES)); // make crank float crank_mass = 1.0f; float crank_radius = 13.0f; cpBody crank = space.AddBody(new cpBody(crank_mass, cp.MomentForCircle(crank_mass, crank_radius, 0.0f, cpVect.Zero))); shape = space.AddShape(new cpCircleShape(crank, crank_radius, cpVect.Zero)); shape.SetFilter(new cpShapeFilter(1, cp.ALL_CATEGORIES, cp.ALL_CATEGORIES)); space.AddConstraint(new cpPivotJoint(chassis, crank, cpVect.Zero, cpVect.Zero)); float side = 30.0f; int num_legs = 2; for (int i = 0; i < num_legs; i++) { make_leg(side, offset, chassis, crank, cpVect.cpvmult(cpVect.cpvforangle((float)(2 * i + 0) / (float)num_legs * ((float)Math.PI)), crank_radius)); make_leg(side, -offset, chassis, crank, cpVect.cpvmult(cpVect.cpvforangle((float)(2 * i + 1) / (float)num_legs * ((float)Math.PI)), crank_radius)); } motor = space.AddConstraint(new cpSimpleMotor(chassis, crank, 6.0f)); Schedule(); }
cpBodyFree(cpBody body) { if(body){ cpBodyDestroy(body); cpfree(body); } }
cpPolyShapeInit(cpPolyShape poly, cpBody body, int numVerts, cpVect[] verts, cpVect offset) { setUpVerts(poly, numVerts, verts, offset); cpShapeInit((cpShape)poly, &polyClass, body); return poly; }
void AttachHook(cpBody hook, cpBody crate) { hookJoint = space.AddConstraint(new cpPivotJoint(hook, crate, hook.GetPosition())); }
cpBoxShapeInit(cpPolyShape poly, cpBody body, double width, double height) { double hw = width / 2.0f; double hh = height / 2.0f; return cpBoxShapeInit2(poly, body, cpBBNew(-hw, -hh, hw, hh)); }
public override void OnEnter() { base.OnEnter(); SetSubTitle("Control the crane by moving the mouse. Right click to release."); space.SetIterations(30); space.SetGravity(new cpVect(0, -100)); space.SetDamping(0.8f); cpBody staticBody = space.GetStaticBody(); cpShape shape; 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 a body for the dolly. dollyBody = space.AddBody(new cpBody(10, cp.Infinity)); dollyBody.SetPosition(new cpVect(0, 100)); // Add a block so you can see it. space.AddShape(cpPolyShape.BoxShape(dollyBody, 30, 30, 0.0f)); // Add a groove joint for it to move back and forth on. space.AddConstraint(new cpGrooveJoint(staticBody, dollyBody, new cpVect(-250, 100), new cpVect(250, 100), cpVect.Zero)); // Add a pivot joint to act as a servo motor controlling it's position // By updating the anchor points of the pivot joint, you can move the dolly. dollyServo = space.AddConstraint(new cpPivotJoint(staticBody, dollyBody, dollyBody.GetPosition())); // Max force the dolly servo can generate. dollyServo.SetMaxForce(10000); // Max speed of the dolly servo dollyServo.SetMaxBias(100); // You can also change the error bias to control how it slows down. dollyServo.SetErrorBias(0.2f); // Add the crane hook. cpBody hookBody = space.AddBody(new cpBody(1, cp.Infinity)); hookBody.SetPosition(new cpVect(0, 50)); // Add a sensor shape for it. This will be used to figure out when the hook touches a box. shape = space.AddShape(new cpCircleShape(hookBody, 10, cpVect.Zero)); shape.SetSensor(true);// cpTrue); shape.SetCollisionType(((int)COLLISION_TYPES.HOOK_SENSOR)); // Add a slide joint to act as a winch motor // By updating the max length of the joint you can make it pull up the load. winchServo = space.AddConstraint(new cpSlideJoint(dollyBody, hookBody, cpVect.Zero, cpVect.Zero, 0, cp.Infinity)); // Max force the dolly servo can generate. winchServo.SetMaxForce(30000); // Max speed of the dolly servo winchServo.SetMaxBias(60); // TODO: cleanup // Finally a box to play with cpBody boxBody = space.AddBody(new cpBody(30, cp.MomentForBox(30, 50, 50))); boxBody.SetPosition(new cpVect(200, -200)); // Add a block so you can see it. shape = space.AddShape(cpPolyShape.BoxShape(boxBody, 50, 50, 0)); shape.SetFriction(0.7f); shape.SetCollisionType(((int)COLLISION_TYPES.CRATE)); var handler = space.AddCollisionHandler( (int)COLLISION_TYPES.HOOK_SENSOR, (int)COLLISION_TYPES.CRATE); handler.beginFunc = HookCrate; Schedule(); }
cpBoxShapeNew(cpBody body, double width, double height) { return (cpShape)cpBoxShapeInit(new cpPolyShape(), body, width, height); }
public override void OnEnter() { base.OnEnter(); space.SetIterations(30); space.SetGravity(new cpVect(0, -100)); space.SetSleepTimeThreshold(0.5f); cpBody body, staticBody = space.GetStaticBody(); cpShape shape; // Create segments around the edge of the screen. 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); float mass = 1; float width = 20; float height = 30; float spacing = width * 0.3f; // Add lots of boxes. for (int i = 0; i < CHAIN_COUNT; i++) { cpBody prev = null; for (int j = 0; j < LINK_COUNT; j++) { cpVect pos = new cpVect(40 * (i - (CHAIN_COUNT - 1) / 2.0f), 240 - (j + 0.5f) * height - (j + 1) * spacing); body = space.AddBody(new cpBody(mass, cp.MomentForBox(mass, width, height))); body.SetPosition(pos); shape = space.AddShape(new cpSegmentShape(body, new cpVect(0, (height - width) / 2.0f), new cpVect(0, (width - height) / 2.0f), width / 2.0f)); shape.SetFriction(0.8f); float breakingForce = 80000; cpConstraint constraint = null; if (prev == null) { constraint = space.AddConstraint(new cpSlideJoint(body, staticBody, new cpVect(0, height / 2), new cpVect(pos.x, 240), 0, spacing)); } else { constraint = space.AddConstraint(new cpSlideJoint(body, prev, new cpVect(0, height / 2), new cpVect(0, -height / 2), 0, spacing)); } constraint.SetMaxForce(breakingForce); constraint.SetPostSolveFunc(s => BreakableJointPostSolve(constraint)); constraint.SetCollideBodies(false); //cpConstraintSetPostSolveFunc(constraint, BreakableJointPostSolve); prev = body; } } float radius = 15.0f; body = space.AddBody(new cpBody(10.0f, cp.MomentForCircle(10.0f, 0.0f, radius, cpVect.Zero))); body.SetPosition(new cpVect(0, -240 + radius + 5)); body.SetVelocity(new cpVect(0, 300)); shape = space.AddShape(new cpCircleShape(body, 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); //space.defaultHandler. cpCollisionHandler handler = space.AddWildcardHandler(COLLISION_TYPE_ONE_WAY); handler.preSolveFunc = NeverCollide; //space.def SetDefaultCollisionHandler(space, NeverCollide, NULL, NULL, NULL, NULL); { float mass = 1.0f; float length = 100.0f; cpVect a = new cpVect(-length / 2.0f, 0.0f), b = new cpVect(length / 2.0f, 0.0f); cpBody body = space.AddBody(new cpBody(mass, cp.MomentForSegment(mass, a, b, 0.0f))); body.SetPosition(new cpVect(-160.0f, -80.0f)); space.AddShape(new cpSegmentShape(body, a, b, 30.0f)); } { float mass = 1.0f; float length = 100.0f; cpVect a = new cpVect(-length / 2.0f, 0.0f), b = new cpVect(length / 2.0f, 0.0f); cpBody body = space.AddBody(new cpBody(mass, cp.MomentForSegment(mass, a, b, 0.0f))); body.SetPosition(new cpVect(-160.0f, 80.0f)); space.AddShape(new cpSegmentShape(body, a, b, 20.0f)); } { float mass = 1.0f; int NUM_VERTS = 5; cpVect[] verts = new cpVect[NUM_VERTS]; for (int i = 0; i < NUM_VERTS; i++) { float angle = -2 * cp.M_PI * i / NUM_VERTS; verts[i] = new cpVect(40 * cp.cpfcos(angle), 40 * cp.cpfsin(angle)); } cpBody body = space.AddBody(new cpBody(mass, cp.MomentForPoly(mass, NUM_VERTS, verts, cpVect.Zero, 0.0f))); body.SetPosition(new cpVect(-0.0f, -80.0f)); space.AddShape(new cpPolyShape(body, NUM_VERTS, verts, 0.0f)); } { float mass = 1.0f; int NUM_VERTS = 4; cpVect[] verts = new cpVect[NUM_VERTS]; for (int i = 0; i < NUM_VERTS; i++) { float angle = -2 * cp.M_PI * i / NUM_VERTS; verts[i] = new cpVect(60 * cp.cpfcos(angle), 60 * cp.cpfsin(angle)); } cpBody body = space.AddBody(new cpBody(mass, cp.MomentForPoly(mass, NUM_VERTS, verts, cpVect.Zero, 0.0f))); body.SetPosition(new cpVect(-0.0f, 80.0f)); space.AddShape(new cpPolyShape(body, NUM_VERTS, verts, 0)); } { float mass = 1.0f; float r = 60.0f; cpBody body = space.AddBody(new cpBody(mass, cp.Infinity)); body.SetPosition(new cpVect(160, -80)); space.AddShape(new cpCircleShape(body, r, cpVect.Zero)); } { float mass = 1.0f; float r = 40.0f; cpBody body = space.AddBody(new cpBody(mass, cp.Infinity)); body.SetPosition(new cpVect(160, 80)); space.AddShape(new cpCircleShape(body, r, cpVect.Zero)); } Schedule(); }
public override void OnEnter() { base.OnEnter(); SetSubTitle("This unicycle is completely driven and balanced by a single cpSimpleMotor.\nMove the mouse to make the unicycle follow it."); space.SetIterations(30); space.SetGravity(new cpVect(0, -500)); { cpShape shape = null; cpBody staticBody = space.GetStaticBody(); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-3200, -240), new cpVect(3200, -240), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(0, -200), new cpVect(240, -240), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-240, -240), new cpVect(0, -200), 0.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetFilter(NOT_GRABBABLE_FILTER); } { float radius = 20.0f; float mass = 1.0f; float moment = cp.MomentForCircle(mass, 0.0f, radius, cpVect.Zero); wheel_body = space.AddBody(new cpBody(mass, moment)); wheel_body.SetPosition(new cpVect(0.0f, -160.0f + radius)); cpShape shape = space.AddShape(new cpCircleShape(wheel_body, radius, cpVect.Zero)); shape.SetFriction(0.7f); shape.SetFilter(new cpShapeFilter(1, cp.ALL_CATEGORIES, cp.ALL_CATEGORIES)); } { float cog_offset = 30.0f; cpBB bb1 = new cpBB(-5.0f, 0.0f - cog_offset, 5.0f, cog_offset * 1.2f - cog_offset); cpBB bb2 = new cpBB(-25.0f, bb1.t, 25.0f, bb1.t + 10.0f); float mass = 3.0f; float moment = cp.MomentForBox2(mass, bb1) + cp.MomentForBox2(mass, bb2); balance_body = space.AddBody(new cpBody(mass, moment)); balance_body.SetPosition(new cpVect(0.0f, wheel_body.GetPosition().y + cog_offset)); cpShape shape = null; shape = space.AddShape(cpPolyShape.BoxShape2(balance_body, bb1, 0.0f)); shape.SetFriction(1.0f); shape.SetFilter(new cpShapeFilter(1, cp.ALL_CATEGORIES, cp.ALL_CATEGORIES)); shape = space.AddShape(cpPolyShape.BoxShape2(balance_body, bb2, 0.0f)); shape.SetFriction(1.0f); shape.SetFilter(new cpShapeFilter(1, cp.ALL_CATEGORIES, cp.ALL_CATEGORIES)); } cpVect anchorA = balance_body.WorldToLocal(wheel_body.GetPosition()); cpVect groove_a = cpVect.cpvadd(anchorA, new cpVect(0.0f, 30.0f)); cpVect groove_b = cpVect.cpvadd(anchorA, new cpVect(0.0f, -10.0f)); space.AddConstraint(new cpGrooveJoint(balance_body, wheel_body, groove_a, groove_b, cpVect.Zero)); space.AddConstraint(new cpDampedSpring(balance_body, wheel_body, anchorA, cpVect.Zero, 0.0f, 6.0e2f, 30.0f)); motor = space.AddConstraint(new cpSimpleMotor(wheel_body, balance_body, 0.0f)); motor.SetPreSolveFunc((s) => motor_preSolve(motor, s)); { float width = 100.0f; float height = 20.0f; float mass = 3.0f; cpBody boxBody = space.AddBody(new cpBody(mass, cp.MomentForBox(mass, width, height))); boxBody.SetPosition(new cpVect(200, -100)); cpShape shape = space.AddShape(cpPolyShape.BoxShape(boxBody, width, height, 0.0f)); shape.SetFriction(0.7f); } Schedule(); }
unthreadHelper(cpArbiter arb, cpBody body) {
public override void OnEnter() { base.OnEnter(); SetSubTitle("Use the arrow keys to control the machine."); space.SetGravity(new cpVect(0, -600)); cpBody staticBody = space.GetStaticBody(); cpShape shape; // beveling all of the line segments slightly helps prevent things from getting stuck on cracks shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-256, 16), new cpVect(-256, 300), 2.0f)); shape.SetElasticity(0.0f); shape.SetFriction(0.5f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-256, 16), new cpVect(-192, 0), 2.0f)); shape.SetElasticity(0.0f); shape.SetElasticity(0.0f); shape.SetFriction(0.5f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-192, 0), new cpVect(-192, -64), 2.0f)); shape.SetElasticity(0.0f); shape.SetFriction(0.5f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-128, -64), new cpVect(-128, 144), 2.0f)); shape.SetElasticity(0.0f); shape.SetFriction(0.5f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-192, 80), new cpVect(-192, 176), 2.0f)); shape.SetElasticity(0.0f); shape.SetFriction(0.5f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-192, 176), new cpVect(-128, 240), 2.0f)); shape.SetElasticity(0.0f); shape.SetFriction(0.5f); shape.SetFilter(NOT_GRABBABLE_FILTER); shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-128, 144), new cpVect(192, 64), 2.0f)); shape.SetElasticity(0.0f); shape.SetFriction(0.5f); shape.SetFilter(NOT_GRABBABLE_FILTER); cpVect[] verts = new cpVect[] { new cpVect(-30, -80), new cpVect(-30, 80), new cpVect(30, 64), new cpVect(30, -80), }; cpBody plunger = space.AddBody(new cpBody(1.0f, cp.Infinity)); plunger.SetPosition(new cpVect(-160, -80)); shape = space.AddShape(new cpPolyShape(plunger, 4, verts, cpTransform.Identity, 0)); shape.SetElasticity(1.0f); shape.SetFriction(0.5f); shape.SetFilter(new cpShapeFilter(cp.NO_GROUP, 1, 1)); balls = new cpBody[numBalls]; // add balls to hopper for (int i = 0; i < numBalls; i++) { balls[i] = add_ball(space, new cpVect(-224 + i, 80 + 64 * i)); } // add small gear cpBody smallGear = space.AddBody(new cpBody(10.0f, cp.MomentForCircle(10.0f, 80, 0, cpVect.Zero))); smallGear.SetPosition(new cpVect(-160, -160)); smallGear.SetAngle(-cp.M_PI_2); shape = space.AddShape(new cpCircleShape(smallGear, 80.0f, cpVect.Zero)); shape.SetFilter(cpShape.FILTER_NONE); space.AddConstraint(new cpPivotJoint(staticBody, smallGear, new cpVect(-160, -160), cpVect.Zero)); // add big gear cpBody bigGear = space.AddBody(new cpBody(40.0f, cp.MomentForCircle(40.0f, 160, 0, cpVect.Zero))); bigGear.SetPosition(new cpVect(80, -160)); bigGear.SetAngle(cp.M_PI_2); shape = space.AddShape(new cpCircleShape(bigGear, 160.0f, cpVect.Zero)); shape.SetFilter(cpShape.FILTER_NONE); space.AddConstraint(new cpPivotJoint(staticBody, bigGear, new cpVect(80, -160), cpVect.Zero)); // connect the plunger to the small gear. space.AddConstraint(new cpPinJoint(smallGear, plunger, new cpVect(80, 0), new cpVect(0, 0))); // connect the gears. space.AddConstraint(new cpGearJoint(smallGear, bigGear, -cp.M_PI_2, -2.0f)); // feeder mechanism float bottom = -300.0f; float top = 32.0f; cpBody feeder = space.AddBody(new cpBody(1.0f, cp.MomentForSegment(1.0f, new cpVect(-224.0f, bottom), new cpVect(-224.0f, top), 0.0f))); feeder.SetPosition(new cpVect(-224, (bottom + top) / 2.0f)); float len = top - bottom; shape = space.AddShape(new cpSegmentShape(feeder, new cpVect(0.0f, len / 2.0f), new cpVect(0.0f, -len / 2.0f), 20.0f)); shape.SetFilter(GRAB_FILTER); space.AddConstraint(new cpPivotJoint(staticBody, feeder, new cpVect(-224.0f, bottom), new cpVect(0.0f, -len / 2.0f))); cpVect anchr = feeder.WorldToLocal(new cpVect(-224.0f, -160.0f)); space.AddConstraint(new cpPinJoint(feeder, smallGear, anchr, new cpVect(0.0f, 80.0f))); // motorize the second gear motor = space.AddConstraint(new cpSimpleMotor(staticBody, bigGear, 3.0f)); Schedule(); }
public cpBall(cpBody body, float radius, cpVect offset) : base(body, radius, offset) { }
public void ScaleIterator(cpBody body, cpArbiter arb, ref cpVect sum) { sum = cpVect.cpvadd(sum, arb.TotalImpulse()); }
cpSlideJointInit(cpSlideJoint *joint, cpBody a, cpBody b, cpVect anchr1, cpVect anchr2, double min, double max) { cpConstraintInit((cpConstraint )joint, &klass, a, b); joint.anchr1 = anchr1; joint.anchr2 = anchr2; joint.min = min; joint.max = max; joint.jnAcc = 0.0f; return joint; }
cpBodyResetForces(cpBody body) { cpBodyActivate(body); body.f = cpvzero; body.t = 0.0f; }
public CCMouse() { mouseBody = cpBody.NewKinematic(); Position = cpVect.Zero; }
cpBodySetPos(cpBody body, cpVect pos) { cpBodyActivate(body); body.p = pos; cpBodyAssertSane(body); }
public override void OnEnter() { base.OnEnter(); space.SetIterations(10); space.SetGravity(new cpVect(0, -GRAVITY)); // space.sleepTimeThreshold = 1000; cpBody body, staticBody = space.GetStaticBody(); cpShape shape; // Create segments around the edge of the screen. 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); // Set up the player body = space.AddBody(new cpBody(1.0f, cp.Infinity)); body.p = new cpVect(0, -200); body.SetVelocityUpdateFunc( (gravity, damping, dt) => playerUpdateVelocity(body, gravity, damping, dt) ); playerBody = body; shape = space.AddShape(cpPolyShape.BoxShape2(body, new cpBB(-15, -27.5f, 15, 27.5f), 10f)); shape.e = 0.0f; shape.u = 0.0f; shape.type = 1; playerShape = shape; // Add some boxes to jump on for (int i = 0; i < 6; i++) { for (int j = 0; j < 3; j++) { body = space.AddBody(new cpBody(4.0f, cp.Infinity)); body.p = new cpVect(100 + j * 60, -200 + i * 60); shape = space.AddShape(cpPolyShape.BoxShape(body, 50, 50, 0)); shape.e = 0.0f; shape.u = 0.7f; } } Schedule(); }
cpBodyRemoveConstraint(cpBody body, cpConstraint constraint) { body.constraintList = filterConstraints(body.constraintList, body, constraint); }
public cpPivotJoint(cpBody a, cpBody b, cpVect pivot) : this(a, b, (a != null ? a.WorldToLocal(pivot) : pivot), (b != null ? b.WorldToLocal(pivot) : pivot)) { }
cpBodyUpdateVelocity(cpBody body, cpVect gravity, double damping, double dt) { body.v = cpvclamp(cpVect.Add(cpVect.Multiply(body.v, damping), cpVect.Multiply(cpVect.Add(gravity, cpVect.Multiply(body.f, body.m_inv)), dt)), body.v_limit); double w_limit = body.w_limit; body.w = cpfclamp(body.w*damping + body.t*body.i_inv*dt, -w_limit, w_limit); cpBodySanityCheck(body); }
protected override void OnAwake() { base.OnAwake(); Vector2 pos = this.transform.position;//static body(0,0) should add postion , Dynamic use Rigidbody position as parent XRigidbody2D xRigidbody2D = this.GetComponent <XRigidbody2D>(); if (xRigidbody2D != null) { if (xRigidbody2D.mBodyType != cpBodyType.STATIC) { xRigidbody2D.Init(); mRigidbody2D = xRigidbody2D.Rigidbody2D; pos = Vector2.zero; } else { mRigidbody2D = XSpaceManager.Instance.Space.GetStaticBody(); } } else { //静态的,不能移动 mRigidbody2D = XSpaceManager.Instance.Space.GetStaticBody(); } //local Vector2 left, bottom, right, top; Quaternion rotation; switch (mShapeType) { case ColliderType.Segment: float angle = Vector2.Angle(this.mEnd - this.mStart, Vector2.right); rotation = Quaternion.AngleAxis(angle + this.transform.eulerAngles.z, Vector3.forward); left = rotation * new Vector2(this.mStart.x, this.mStart.y - this.mRadius); bottom = rotation * new Vector2(this.mEnd.x, this.mEnd.y - this.mRadius); right = rotation * new Vector2(this.mEnd.x, this.mEnd.y + this.mRadius); top = rotation * new Vector2(this.mStart.x, this.mStart.y + this.mRadius); Vector2 start = (Vector2)pos + (left + top) / 2; Vector2 end = (Vector2)pos + (bottom + right) / 2; mCollider2D = new cpSegmentShape(mRigidbody2D, new cpVect(start.x, start.y) * XSpaceManager.PixelsPerUnit, new cpVect(end.x, end.y) * XSpaceManager.PixelsPerUnit, mRadius * XSpaceManager.PixelsPerUnit); break; case ColliderType.Circle: mCollider2D = new cpCircleShape(mRigidbody2D, mRadius * XSpaceManager.PixelsPerUnit, new cpVect(pos.x + mCenter.x, pos.y + mCenter.y) * XSpaceManager.PixelsPerUnit); break; case ColliderType.Box: mCollider2D = cpPolyShape.BoxShape2(mRigidbody2D, new cpBB((pos.x + mCenter.x - mSize.x * this.transform.localScale.x / 2) * XSpaceManager.PixelsPerUnit, (pos.y + mCenter.y - mSize.y * this.transform.localScale.y / 2) * XSpaceManager.PixelsPerUnit, (pos.x + mCenter.x + mSize.x * this.transform.localScale.x / 2) * XSpaceManager.PixelsPerUnit, (pos.y + mCenter.y + mSize.y * this.transform.localScale.y / 2) * XSpaceManager.PixelsPerUnit), mRadius * XSpaceManager.PixelsPerUnit); break; case ColliderType.Polygon: int count = mVects.Length; cpVect [] vts = new cpVect [mVects.Length]; for (int i = 0; i < count; i++) { vts[i] = cpVect.Zero; vts[i].x = (pos.x + mVects[i].x) * XSpaceManager.PixelsPerUnit; vts[i].y = (pos.y + mVects[i].y) * XSpaceManager.PixelsPerUnit; } mCollider2D = new cpPolyShape(mRigidbody2D, mVects.Length, vts, mRadius * XSpaceManager.PixelsPerUnit); break; //case cpShapeType.NumShapes: // break; } mCollider2D.SetSensor(mTrigger); mCollider2D.SetElasticity(mElasticity); mCollider2D.SetFriction(mFriction); cpShapeFilter filter = new cpShapeFilter(mGroup, (int)mCategory, (int)mMask); mCollider2D.SetFilter(filter); }
public bool waterPreSolve(cpArbiter arb, cpSpace space, object o) { cpShape obj1, obj2; arb.GetShapes(out obj1, out obj2); cpPolyShape water = obj1 as cpPolyShape; cpPolyShape poly = obj2 as cpPolyShape; cpBody body = poly.GetBody(); float level = water.GetBB().t; // cpShapeGetBB().t; int count = poly.Count; //cpPolyShapeGetCount(poly.g); int clippedCount = 0; cpVect[] clipped = new cpVect[10]; for (int i = 0, j = count - 1; i < count; j = i, i++) { cpVect a = body.LocalToWorld(poly.GetVert(j)); cpVect b = body.LocalToWorld(poly.GetVert(i)); if (a.y < level) { clipped[clippedCount] = a; clippedCount++; } float a_level = a.y - level; float b_level = b.y - level; if (a_level * b_level < 0.0f) { float t = cp.cpfabs(a_level) / (cp.cpfabs(a_level) + cp.cpfabs(b_level)); clipped[clippedCount] = cpVect.cpvlerp(a, b, t); clippedCount++; } } // Calculate buoyancy from the clipped polygon area float clippedArea = cp.AreaForPoly(clippedCount, clipped, 0.0f); float displacedMass = clippedArea * FLUID_DENSITY; cpVect centroid = cp.CentroidForPoly(clippedCount, clipped); //ChipmunkDebugDrawPolygon(clippedCount, clipped, 0.0f, RGBAColor(0, 0, 1, 1), RGBAColor(0, 0, 1, 0.1f)); //ChipmunkDebugDrawDot(5, centroid, RGBAColor(0, 0, 1, 1)); float dt = space.GetCurrentTimeStep(); cpVect g = space.GetGravity(); // Apply the buoyancy force as an impulse. body.ApplyImpulseAtWorldPoint(cpVect.cpvmult(g, -displacedMass * dt), centroid); // Apply linear damping for the fluid drag. cpVect v_centroid = body.GetVelocityAtWorldPoint(centroid); float k = k_scalar_body(body, centroid, cpVect.cpvnormalize(v_centroid)); float damping = clippedArea * FLUID_DRAG * FLUID_DENSITY; float v_coef = cp.cpfexp(-damping * dt * k); // linear drag // cpfloat v_coef = 1.0/(1.0 + damping*dt*cpvlength(v_centroid)*k); // quadratic drag body.ApplyImpulseAtWorldPoint(cpVect.cpvmult(cpVect.cpvsub(cpVect.cpvmult(v_centroid, v_coef), v_centroid), 1.0f / k), centroid); // Apply angular damping for the fluid drag. cpVect cog = body.LocalToWorld(body.GetCenterOfGravity()); float w_damping = cp.MomentForPoly(FLUID_DRAG * FLUID_DENSITY * clippedArea, clippedCount, clipped, cpVect.cpvneg(cog), 0.0f); body.SetAngularVelocity(body.GetAngularVelocity() * cp.cpfexp(-w_damping * dt / body.GetMoment())); return(true); }
cpSlideJointNew(cpBody a, cpBody b, cpVect anchr1, cpVect anchr2, double min, double max) { return (cpConstraint )cpSlideJointInit(cpSlideJointAlloc(), a, b, anchr1, anchr2, min, max); }
public override void OnEnter() { base.OnEnter(); Position = new CCPoint(100, 100); space.SetIterations(10); space.SetGravity(new cpVect(0, -100)); space.SetSleepTimeThreshold(0.5f); cpBody staticBody = space.GetStaticBody(); // staticBody; cpShape shape; for (var y = 480; y >= 0; y -= 120) { shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(0, y), new cpVect(640, y), 0)); shape.SetElasticity(1); shape.SetFriction(1); shape.SetFilter(NOT_GRABBABLE_FILTER); } for (var x = 0; x <= 640; x += 160) { shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(x, 0), new cpVect(x, 480), 0)); shape.SetElasticity(1); shape.SetFriction(1); shape.SetFilter(NOT_GRABBABLE_FILTER); } cpBody body1, body2; var posA = new cpVect(50, 60); var posB = new cpVect(110, 60); var POS_A = new Func <cpVect>(() => { return(cpVect.cpvadd(boxOffset, posA)); }); var POS_B = new Func <cpVect>(() => { return(cpVect.cpvadd(boxOffset, posB)); }); // Keeps the anchor points the same distance apart from when the joint was created. boxOffset = new cpVect(0, 0); label("Pin Joint"); body1 = addBall(posA); body2 = addBall(posB); body2.SetAngle((float)Math.PI); space.AddConstraint(new cpPinJoint(body1, body2, new cpVect(15, 0), new cpVect(15, 0))); // Slide Joints - Like pin joints but with a min/max distance. // Can be used for a cheap approximation of a rope. boxOffset = new cpVect(160, 0); label("Slide Joint"); body1 = addBall(posA); body2 = addBall(posB); body2.SetAngle((float)Math.PI); space.AddConstraint(new cpSlideJoint(body1, body2, new cpVect(15, 0), new cpVect(15, 0), 20, 40)); // Pivot Joints - Holds the two anchor points together. Like a swivel. boxOffset = new cpVect(320, 0); label("Pivot Joint"); body1 = addBall(posA); body2 = addBall(posB); body2.SetAngle((float)Math.PI); // Alternately, specify two anchor points using cp.PivotJoint(a, b, anch1, anch2) space.AddConstraint(new cpPivotJoint(body1, body2, cpVect.cpvadd(boxOffset, new cpVect(80, 60)))); // Groove Joints - Like a pivot joint, but one of the anchors is a line segment that the pivot can slide in boxOffset = new cpVect(480, 0); label("Groove Joint"); body1 = addBall(posA); body2 = addBall(posB); space.AddConstraint(new cpGrooveJoint(body1, body2, new cpVect(30, 30), new cpVect(30, -30), new cpVect(-30, 0))); // Damped Springs boxOffset = new cpVect(0, 120); label("Damped Spring"); body1 = addBall(posA); body2 = addBall(posB); body2.SetAngle((float)Math.PI); space.AddConstraint(new cpDampedSpring(body1, body2, new cpVect(15, 0), new cpVect(15, 0), 20, 5, 0.3f)); // Damped Rotary Springs boxOffset = new cpVect(160, 120); label("Damped Rotary Spring"); body1 = addBar(posA); body2 = addBar(posB); // Add some pin joints to hold the circles in place. space.AddConstraint(new cpPivotJoint(body1, staticBody, POS_A())); space.AddConstraint(new cpPivotJoint(body2, staticBody, POS_B())); space.AddConstraint(new cpDampedRotarySpring(body1, body2, 0, 3000, 60)); // Rotary Limit Joint boxOffset = new cpVect(320, 120); label("Rotary Limit Joint"); body1 = addLever(posA); body2 = addLever(posB); // Add some pin joints to hold the circles in place. space.AddConstraint(new cpPivotJoint(body1, staticBody, POS_A())); space.AddConstraint(new cpPivotJoint(body2, staticBody, POS_B())); // Hold their rotation within 90 degrees of each other. space.AddConstraint(new cpRotaryLimitJoint(body1, body2, -(float)Math.PI / 2, (float)Math.PI / 2)); // Ratchet Joint - A rotary ratchet, like a socket wrench boxOffset = new cpVect(480, 120); label("Ratchet Joint"); body1 = addLever(posA); body2 = addLever(posB); // Add some pin joints to hold the circles in place. space.AddConstraint(new cpPivotJoint(body1, staticBody, POS_A())); space.AddConstraint(new cpPivotJoint(body2, staticBody, POS_B())); // Ratchet every 90 degrees space.AddConstraint(new cpRatchetJoint(body1, body2, 0, (float)Math.PI / 2f)); // Gear Joint - Maintain a specific angular velocity ratio boxOffset = new cpVect(0, 240); label("Gear Joint"); body1 = addBar(posA); body2 = addBar(posB); // Add some pin joints to hold the circles in place. space.AddConstraint(new cpPivotJoint(body1, staticBody, POS_A())); space.AddConstraint(new cpPivotJoint(body2, staticBody, POS_B())); // Force one to sping 2x as fast as the other space.AddConstraint(new cpGearJoint(body1, body2, 0, 2)); // Simple Motor - Maintain a specific angular relative velocity boxOffset = new cpVect(160, 240); label("Simple Motor"); body1 = addBar(posA); body2 = addBar(posB); // Add some pin joints to hold the circles in place. space.AddConstraint(new cpPivotJoint(body1, staticBody, POS_A())); space.AddConstraint(new cpPivotJoint(body2, staticBody, POS_B())); // Make them spin at 1/2 revolution per second in relation to each other. space.AddConstraint(new cpSimpleMotor(body1, body2, (float)Math.PI)); // Make a car with some nice soft suspension boxOffset = new cpVect(320, 240); var wheel1 = addWheel(posA); var wheel2 = addWheel(posB); var chassis = addChassis(new cpVect(80, 100)); space.AddConstraint(new cpGrooveJoint(chassis, wheel1, new cpVect(-30, -10), new cpVect(-30, -40), new cpVect(0, 0))); space.AddConstraint(new cpGrooveJoint(chassis, wheel2, new cpVect(30, -10), new cpVect(30, -40), new cpVect(0, 0))); space.AddConstraint(new cpDampedSpring(chassis, wheel1, new cpVect(-30, 0), new cpVect(0, 0), 50, 20, 10)); space.AddConstraint(new cpDampedSpring(chassis, wheel2, new cpVect(30, 0), new cpVect(0, 0), 50, 20, 10)); Schedule(); }
public override void OnEnter() { base.OnEnter(); platformInstance = new OneWayPlatform(); SetSubTitle("One way platforms are trivial in Chipmunk using a very simple collision callback."); space.SetIterations(10); space.SetGravity(new cpVect(0, -100)); cpBody body, staticBody = space.GetStaticBody(); cpShape shape; // Create segments around the edge of the screen. 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 our one way segment shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-160, -100), new cpVect(160, -100), 10.0f)); shape.SetElasticity(1.0f); shape.SetFriction(1.0f); shape.SetCollisionType(COLLISION_TYPE_ONE_WAY); shape.SetFilter(NOT_GRABBABLE_FILTER); // We'll use the data pointer for the OneWayPlatform struct platformInstance.n = new cpVect(0, 1); // let objects pass upwards shape.userData = platformInstance; // Add a ball to test it out float radius = 15.0f; body = space.AddBody(new cpBody(10.0f, cp.MomentForCircle(10.0f, 0.0f, radius, cpVect.Zero))); body.SetPosition(new cpVect(0, -200)); body.SetVelocity(new cpVect(0, 170)); shape = space.AddShape(new cpCircleShape(body, radius, cpVect.Zero)); shape.SetElasticity(0.0f); shape.SetFriction(0.9f); shape.SetCollisionType(2); cpCollisionHandler handler = space.AddWildcardHandler(COLLISION_TYPE_ONE_WAY); handler.preSolveFunc = preSolve; Schedule(); }
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(); }