void motor_preSolve(cpConstraint motor, cpSpace space) { float dt = space.GetCurrentTimeStep(); float target_x = CCMouse.Instance.Position.x; paint = new shape { point1 = new cpVect(target_x, -1000.0f), point2 = new cpVect(target_x, 1000.0f), }; float max_v = 500.0f; float target_v = cp.cpfclamp(cp.bias_coef(0.5f, dt / 1.2f) * (target_x - balance_body.GetPosition().x) / dt, -max_v, max_v); float error_v = (target_v - balance_body.GetVelocity().x); float target_sin = 3.0e-3f * cp.bias_coef(0.1f, dt) * error_v / dt; float max_sin = cp.cpfsin(0.6f); balance_sin = cp.cpfclamp(balance_sin - 6.0e-5f * cp.bias_coef(0.2f, dt) * error_v / dt, -max_sin, max_sin); float target_a = (float)Math.Asin(cp.cpfclamp(-target_sin + balance_sin, -max_sin, max_sin)); float angular_diff = (float)Math.Asin(cpVect.cpvcross(balance_body.GetRotation(), cpVect.cpvforangle(target_a))); float target_w = cp.bias_coef(0.1f, dt / 0.4f) * (angular_diff) / dt; float max_rate = 50.0f; float rate = cp.cpfclamp(wheel_body.GetAngularVelocity() + balance_body.GetAngularVelocity() - target_w, -max_rate, max_rate); motor.SetRate(cp.cpfclamp(rate, -max_rate, max_rate)); motor.SetMaxForce(8.0e4f); }
public override void Update(float dt) { base.Update(dt); float coef = (2.0f + ChipmunkDemoKeyboard.y) / 3.0f; float rate = ChipmunkDemoKeyboard.x * 10.0f * coef; motor.SetRate(rate); motor.SetMaxForce(rate != 0 ? 100000.0f : 0.0f); space.Step(dt); }
public void StickySeparate(cpArbiter arb, object data) { cpConstraint joint = (cpConstraint)arb.GetUserData(); if (joint != null) { // The joint won't be removed until the step is done. // Need to disable it so that it won't apply itself. // Setting the force to 0 will do just that joint.SetMaxForce(0.0f); space.AddPostStepCallback((s1, o1, o2) => PostStepRemoveJoint(o1, o2), joint, null ); // Perform the removal in a post-step() callback. // NULL out the reference to the joint. // Not required, but it's a good practice. arb.SetUserData(null); } }
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(); 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(); }
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(); 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(); }