public void Reset(int bodyCapacity, int contactCapacity, int jointCapacity, IContactListener listener) { _bodyCapacity = bodyCapacity; _contactCapacity = contactCapacity; _jointCapacity = jointCapacity; _bodyCount = 0; _jointCount = 0; _listener = listener; if (_bodies == null || _bodies.Length < bodyCapacity) { _bodies = new Body[bodyCapacity]; } if (_contacts == null || _contacts.Length < contactCapacity) { _contacts = new Contact[contactCapacity * 2]; } if (_joints == null || _joints.Length < jointCapacity) { _joints = new Joint[jointCapacity * 2]; } }
public Bond(Atom atom, Atom other, Joint shortJoint, Joint midJoint, int numberOfBonds, GameContent gameContent) { this.numberOfBonds = numberOfBonds; this.atom = atom; this.other = other; this.shortJoint = shortJoint; this.midJoint = midJoint; this.gameContent = gameContent; Vector2 localAnchor; if (atom.body == shortJoint.GetBodyA()) { localAnchor = atom.body.GetLocalPoint(shortJoint.GetAnchorA()); midJoint.SetUserData(this); } else localAnchor = atom.body.GetLocalPoint(shortJoint.GetAnchorB()); float angle = (float)Math.Atan2(localAnchor.Y, localAnchor.X); if (angle < 0) angle = 2 * (float)Math.PI + angle; jointAngle = finalJointAngle = angle; }
/// <summary> /// Create a joint to rain bodies together. No reference to the definition /// is retained. This may cause the connected bodies to cease colliding. /// @warning This function is locked during callbacks. /// </summary> /// <param name="def"></param> /// <returns></returns> public Joint CreateJoint(JointDef def) { Debug.Assert(!IsLocked); if (IsLocked) { return null; } Joint j = Joint.Create(def); // Connect to the world list. j._prev = null; j._next = _jointList; if (_jointList != null) { _jointList._prev = j; } _jointList = j; ++_jointCount; // Connect to the bodies' doubly linked lists. j._edgeA.Joint = j; j._edgeA.Other = j._bodyB; j._edgeA.Prev = null; j._edgeA.Next = j._bodyA._jointList; if (j._bodyA._jointList != null) j._bodyA._jointList.Prev = j._edgeA; j._bodyA._jointList = j._edgeA; j._edgeB.Joint = j; j._edgeB.Other = j._bodyA; j._edgeB.Prev = null; j._edgeB.Next = j._bodyB._jointList; if (j._bodyB._jointList != null) j._bodyB._jointList.Prev = j._edgeB; j._bodyB._jointList = j._edgeB; Body bodyA = def.bodyA; Body bodyB = def.bodyB; bool staticA = bodyA.GetType() == BodyType.Static; bool staticB = bodyB.GetType() == BodyType.Static; // If the joint prevents collisions, then flag any contacts for filtering. if (def.collideConnected == false) { ContactEdge edge = bodyB.GetContactList(); while (edge != null) { if (edge.Other == bodyA) { // Flag the contact for filtering at the next time step (where either // body is awake). edge.Contact.FlagForFiltering(); } edge = edge.Next; } } // Note: creating a joint doesn't wake the bodies. return j; }
void DestroyJoint() { if (joint != null) { body.GetWorld().DestroyJoint(joint); joint = null; } }
void CreateJoint(Body other, Vector2 contact) { // cannot move from stable situation to unstable if (isStable && other.GetUserData() is Soldier && !((Soldier)other.GetUserData()).isStable) return; DestroyJoint(); if (!(other.GetUserData() is Soldier) || ((Soldier)other.GetUserData()).joint == null || ((Soldier)other.GetUserData()).joint.GetBodyB() != body) { DistanceJointDef jd = new DistanceJointDef(); //jd.frequencyHz = 10; jd.dampingRatio = 0f; jd.Initialize(body, other, body.Position, contact); jd.length = Size / 2 / gameContent.b2Scale; jd.collideConnected = true; joint = body.GetWorld().CreateJoint(jd); if (joint.GetBodyB().GetUserData() is Soldier) isStable = ((Soldier)joint.GetBodyB().GetUserData()).isStable; else isStable = true; } }
/// <summary> Destroy a joint. This may cause the connected bodies to begin colliding. /// </summary> <warning> This function is locked during callbacks. /// </warning> public void DestroyJoint(Joint j) { Debug.Assert(!IsLocked); if (IsLocked) { return; } bool collideConnected = j._collideConnected; // Remove from the doubly linked list. if (j._prev != null) { j._prev._next = j._next; } if (j._next != null) { j._next._prev = j._prev; } if (j == _jointList) { _jointList = j._next; } // Disconnect from island graph. Body bodyA = j._bodyA; Body bodyB = j._bodyB; // Wake up connected bodies. bodyA.SetAwake(true); bodyB.SetAwake(true); // Remove from body 1. if (j._edgeA.Prev != null) { j._edgeA.Prev.Next = j._edgeA.Next; } if (j._edgeA.Next != null) { j._edgeA.Next.Prev = j._edgeA.Prev; } if (j._edgeA == bodyA._jointList) { bodyA._jointList = j._edgeA.Next; } j._edgeA.Prev = null; j._edgeA.Next = null; // Remove from body 2 if (j._edgeB.Prev != null) { j._edgeB.Prev.Next = j._edgeB.Next; } if (j._edgeB.Next != null) { j._edgeB.Next.Prev = j._edgeB.Prev; } if (j._edgeB == bodyB._jointList) { bodyB._jointList = j._edgeB.Next; } j._edgeB.Prev = null; j._edgeB.Next = null; Debug.Assert(_jointCount > 0); --_jointCount; // If the joint prevents collisions, then flag any contacts for filtering. if (collideConnected == false) { ContactEdge edge = bodyB.GetContactList(); while (edge != null) { if (edge.Other == bodyA) { // Flag the contact for filtering at the next time step (where either // body is awake). edge.Contact.FlagForFiltering(); } edge = edge.Next; } } }
/// <summary> /// Creates a new motorcycle and a driver into the given Box2D world. /// Creates all the parts of the motorcycle and driver and joints them together. /// </summary> /// <param name="pBikeSpeed">A pointer to the variable that describes the speed of the /// motorcycle</param> /// <param name="pRotationData">RotationData to provide the information of the rotation /// of the device</param> /// <param name="pWorld">The Box2D world where the bike is created into</param> /// <param name="pCamPos">A pointer to the variable that describes the position of the /// camera</param> /// <param name="pContent">The used ContentManager instance</param> /// <param name="pSpriteBatch">The used SpriteBatch instance</param> public Bike(float []pBikeSpeed, RotationData pRotationData, World pWorld, float[] pCamPos, ContentManager pContent) { OffTheBike = false; camPos = pCamPos; world = pWorld; content = pContent; RotationData = pRotationData; bikeSpeed = pBikeSpeed; frontWheel = CreateCirclePart("wheel", frontWheelInitPos, 35.0f, 0, 0.1f, 0.9f, 0.2f); frontFork = CreateBoxPart("susp_lower_long", frontForkInitPos, 20.53f, 21.33f, 0, 0.8f, 1.0f, 0.2f); rearWheel = CreateCirclePart("rearWheel", rearWheelInitPos, 32.0f, 0, 0.4f, 1.0f, 0.2f); rearFork = CreateBoxPart("rearFork", rearForkInitPos, 64.0f, 17.0f, rearForkInitRot, 0.5f, 1.0f, 0.2f); bikeBody = CreateBikeBody(bikeBodyInitPos, bikeBodyInitRot, 0.5f, 1.0f, 0.2f); RevoluteJointDef motorDef = new RevoluteJointDef(); motorDef.Initialize(rearWheel, rearFork, rearWheel.GetWorldCenter()); motorDef.maxMotorTorque = 2.0f; motorDef.enableMotor = true; motor = (RevoluteJoint)world.CreateJoint(motorDef); RevoluteJointDef rearForkBodyDef = new RevoluteJointDef(); Vector2 anchor = rearFork.GetWorldCenter(); anchor.X += (32.0f / Level.FACTOR); anchor.Y += (13.5f / Level.FACTOR); rearForkBodyDef.Initialize(rearFork, bikeBody, anchor); rearForkBodyDef.bodyA = rearFork; rearForkBodyDef.bodyB = bikeBody; rearForkBodyDef.maxMotorTorque = 300.0f; world.CreateJoint(rearForkBodyDef); RevoluteJointDef frontWheelJointDef = new RevoluteJointDef(); frontWheelJointDef.Initialize(frontWheel, frontFork, frontWheel.GetWorldCenter()); frontWheelJointDef.maxMotorTorque = 300.0f; world.CreateJoint(frontWheelJointDef); DistanceJointDef frontSuspToBikeDef = new DistanceJointDef(); frontSuspToBikeDef.Initialize(bikeBody, frontFork, frontFork.GetWorldCenter() + new Vector2(0, 0.4f), frontFork.GetWorldCenter()); frontSuspToBikeDef.frequencyHz = 4.0f; frontSuspToBikeDef.dampingRatio = 0.1f; frontSuspToBikeDef.collideConnected = true; world.CreateJoint(frontSuspToBikeDef); DistanceJointDef rearForkDistanceDef = new DistanceJointDef(); rearForkDistanceDef.Initialize(bikeBody, rearFork, rearFork.GetWorldCenter() + new Vector2(0, 0.4f), rearFork.GetWorldCenter()); rearForkDistanceDef.frequencyHz = 7.0f; rearForkDistanceDef.dampingRatio = 0.1f; rearForkDistanceDef.collideConnected = true; world.CreateJoint(rearForkDistanceDef); PrismaticJointDef fSuspBikePrismaticDef = new PrismaticJointDef(); fSuspBikePrismaticDef.Initialize(bikeBody, frontFork, bikeBody.GetWorldCenter(), new Vector2(0, 1)); fSuspBikePrismaticDef.enableLimit = true; fSuspBikePrismaticDef.lowerTranslation = -0.2f; fSuspBikePrismaticDef.upperTranslation = 0.2f; fSuspBikePrismaticDef.collideConnected = true; world.CreateJoint(fSuspBikePrismaticDef); humanBody = CreateBoxPart("human", humanBodyInitPos, 17.0f, 64.0f, 0, 0.1f, 1.0f, 0.2f); head = CreateBoxPart("head", headInitPos, 38.4f, 29.9f, headInitRot, 0.1f, 1.0f, 0.2f); hand = CreateBoxPart("hand", handInitPos, 34.13f, 8.53f, handInitRot, 0.1f, 1.0f, 0.2f); arm = CreateBoxPart("arm", armInitPos, 42.67f, 8.53f, armInitRot, 0.1f, 1.0f, 0.2f); WeldJointDef headToHumanDef = new WeldJointDef(); headToHumanDef.Initialize(head, humanBody, head.GetWorldCenter()); world.CreateJoint(headToHumanDef); RevoluteJointDef humanToBikeDef = new RevoluteJointDef(); anchor = humanBody.GetWorldCenter(); anchor.Y += (30.0f / Level.FACTOR); humanToBikeDef.Initialize(humanBody, bikeBody, anchor); humanToBikeDef.maxMotorTorque = 300.0f; humanToBike = world.CreateJoint(humanToBikeDef); RevoluteJointDef humanToArmDef = new RevoluteJointDef(); anchor = arm.GetWorldPoint(new Vector2(-21.33f / Level.FACTOR, 4.26f / Level.FACTOR)); humanToArmDef.Initialize(humanBody, arm, anchor); humanToArmDef.maxMotorTorque = 300.0f; world.CreateJoint(humanToArmDef); RevoluteJointDef armToHandDef = new RevoluteJointDef(); anchor = arm.GetWorldPoint(new Vector2(21.33f / Level.FACTOR, 4.26f / Level.FACTOR)); armToHandDef.Initialize(arm, hand, anchor); armToHandDef.maxMotorTorque = 300.0f; world.CreateJoint(armToHandDef); RevoluteJointDef handToBikeDef = new RevoluteJointDef(); anchor = hand.GetWorldPoint(new Vector2(17.06f / Level.FACTOR, 4.26f / Level.FACTOR)); handToBikeDef.Initialize(hand, bikeBody, anchor); handToBikeDef.maxMotorTorque = 300.0f; handToBike = world.CreateJoint(handToBikeDef); DistanceJointDef armToBikeDef = new DistanceJointDef(); armToBikeDef.Initialize(hand, bikeBody, hand.GetWorldPoint(new Vector2(-17.00f / Level.FACTOR, 4.26f / Level.FACTOR)), bikeBody.GetWorldCenter()); armToBikeDef.length = 40.0f / Level.FACTOR; armToBikeDef.frequencyHz = 10.0f; armToBikeDef.dampingRatio = 1.0f; armToBikeDef.collideConnected = true; armToBike = world.CreateJoint(armToBikeDef); }
/// <summary> /// Destroys the joints between the driver and the motorcycle /// </summary> public void Release() { OffTheBike = true; world.DestroyJoint(handToBike); handToBike = null; world.DestroyJoint(humanToBike); humanToBike = null; world.DestroyJoint(armToBike); armToBike = null; }
public void AddJointReference(Joint j) { jointRefs.Add(j); }
public void Add(Joint joint) { Debug.Assert(_jointCount < _jointCapacity); _joints[_jointCount++] = joint; }
internal static Joint Create(JointDef def) { Joint joint = null; switch (def.type) { case JointType.Distance: { joint = new DistanceJoint((DistanceJointDef)def); } break; case JointType.Mouse: { joint = new MouseJoint((MouseJointDef)def); } break; case JointType.Prismatic: { joint = new PrismaticJoint((PrismaticJointDef)def); } break; case JointType.Revolute: { joint = new RevoluteJoint((RevoluteJointDef)def); } break; case JointType.Pulley: { joint = new PulleyJoint((PulleyJointDef)def); } break; case JointType.Gear: { joint = new GearJoint((GearJointDef)def); } break; case JointType.Line: { joint = new LineJoint((LineJointDef)def); } break; case JointType.Weld: { joint = new WeldJoint((WeldJointDef)def); } break; case JointType.Friction: { joint = new FrictionJoint((FrictionJointDef)def); } break; case JointType.MaxDistance: { joint = new MaxDistanceJoint((MaxDistanceJointDef)def); } break; default: Debug.Assert(false); break; } return(joint); }
void Solve(ref TimeStep step) { // Size the island for the worst case. _island.Reset(_bodyCount, _contactManager._contactCount, _jointCount, _contactManager.ContactListener); // Clear all the island flags. for (Body b = _bodyList; b != null; b = b._next) { b._flags &= ~BodyFlags.Island; } for (Contact c = _contactManager._contactList; c != null; c = c._next) { c._flags &= ~ContactFlags.Island; } for (Joint j = _jointList; j != null; j = j._next) { j._islandFlag = false; } // Build and simulate all awake islands. int stackSize = _bodyCount; if (stackSize > stack.Length) { stack = new Body[Math.Max(stack.Length * 2, stackSize)]; } for (Body seed = _bodyList; seed != null; seed = seed._next) { if ((seed._flags & (BodyFlags.Island)) != BodyFlags.None) { continue; } if (seed.IsAwake() == false || seed.IsActive() == false) { continue; } // The seed can be dynamic or kinematic. if (seed.GetType() == BodyType.Static) { continue; } // Reset island and stack. _island.Clear(); int stackCount = 0; stack[stackCount++] = seed; seed._flags |= BodyFlags.Island; // Perform a depth first search (DFS) on the raint graph. while (stackCount > 0) { // Grab the next body off the stack and add it to the island. Body b = stack[--stackCount]; Debug.Assert(b.IsActive() == true); _island.Add(b); // Make sure the body is awake. b.SetAwake(true); // To keep islands as small as possible, we don't // propagate islands across static bodies. if (b.GetType() == BodyType.Static) { continue; } // Search all contacts connected to this body. for (ContactEdge ce = b._contactList; ce != null; ce = ce.Next) { Contact contact = ce.Contact; // Has this contact already been added to an island? if ((contact._flags & ContactFlags.Island) != ContactFlags.None) { continue; } // Is this contact solid and touching? if (!ce.Contact.IsEnabled() || !ce.Contact.IsTouching()) { continue; } // Skip sensors. bool sensorA = contact._fixtureA._isSensor; bool sensorB = contact._fixtureB._isSensor; if (sensorA || sensorB) { continue; } _island.Add(contact); contact._flags |= ContactFlags.Island; Body other = ce.Other; // Was the other body already added to this island? if ((other._flags & BodyFlags.Island) != BodyFlags.None) { continue; } Debug.Assert(stackCount < stackSize); stack[stackCount++] = other; other._flags |= BodyFlags.Island; } // Search all joints connect to this body. for (JointEdge je = b._jointList; je != null; je = je.Next) { if (je.Joint._islandFlag == true) { continue; } Body other = je.Other; // Don't simulate joints connected to inactive bodies. if (other.IsActive() == false) { continue; } _island.Add(je.Joint); je.Joint._islandFlag = true; if ((other._flags & BodyFlags.Island) != BodyFlags.None) { continue; } Debug.Assert(stackCount < stackSize); stack[stackCount++] = other; other._flags |= BodyFlags.Island; } } _island.Solve(ref step, Gravity, _allowSleep); // Post solve cleanup. for (int i = 0; i < _island._bodyCount; ++i) { // Allow static bodies to participate in other islands. Body b = _island._bodies[i]; if (b.GetType() == BodyType.Static) { b._flags &= ~BodyFlags.Island; } } } // Synchronize fixtures, check for out of range bodies. for (Body b = _bodyList; b != null; b = b.GetNext()) { // If a body was not in an island then it did not move. if ((b._flags & BodyFlags.Island) != BodyFlags.Island) { continue; } if (b.GetType() == BodyType.Static) { continue; } // Update fixtures (for broad-phase). b.SynchronizeFixtures(); } // Look for new contacts. _contactManager.FindNewContacts(); }
/// <summary> Call this to draw shapes and other debug draw data. /// </summary> public void DrawDebugData() { if (DebugDraw == null) { return; } DebugDrawFlags flags = DebugDraw.Flags; if ((flags & DebugDrawFlags.Shape) == DebugDrawFlags.Shape) { for (Body b = _bodyList; b != null; b = b.GetNext()) { Transform xf; b.GetTransform(out xf); for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext()) { if (b.IsActive() == false) { DrawShape(f, xf, new Color(0.5f, 0.5f, 0.3f)); } else if (b.GetType() == BodyType.Static) { DrawShape(f, xf, new Color(0.5f, 0.9f, 0.5f)); } else if (b.GetType() == BodyType.Kinematic) { DrawShape(f, xf, new Color(0.5f, 0.5f, 0.9f)); } else if (b.IsAwake() == false) { DrawShape(f, xf, new Color(0.6f, 0.6f, 0.6f)); } else { DrawShape(f, xf, new Color(0.9f, 0.7f, 0.7f)); } } } } if ((flags & DebugDrawFlags.Joint) == DebugDrawFlags.Joint) { for (Joint j = _jointList; j != null; j = j.GetNext()) { DrawJoint(j); } } if ((flags & DebugDrawFlags.Pair) == DebugDrawFlags.Pair) { Color color = new Color(0.3f, 0.9f, 0.9f); for (Contact c = _contactManager._contactList; c != null; c = c.GetNext()) { /* * Fixture fixtureA = c.GetFixtureA(); * Fixture fixtureB = c.GetFixtureB(); * * AABB aabbA; * AABB aabbB; * fixtureA.GetAABB(out aabbA); * fixtureB.GetAABB(out aabbB); * * Vector2 cA = aabbA.GetCenter(); * Vector2 cB = aabbB.GetCenter(); * * DebugDraw.DrawSegment(cA, cB, color); */ } } if ((flags & DebugDrawFlags.AABB) == DebugDrawFlags.AABB) { Color color = new Color(0.9f, 0.3f, 0.9f); BroadPhase bp = _contactManager._broadPhase; for (Body b = _bodyList; b != null; b = b.GetNext()) { if (b.IsActive() == false) { continue; } for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext()) { for (int i = 0; i < f._proxyCount; ++i) { FixtureProxy proxy = f._proxies[i]; AABB aabb; bp.GetFatAABB(proxy.proxyId, out aabb); FixedArray8 <Vector2> vs = new FixedArray8 <Vector2>(); vs[0] = new Vector2(aabb.lowerBound.X, aabb.lowerBound.Y); vs[1] = new Vector2(aabb.upperBound.X, aabb.lowerBound.Y); vs[2] = new Vector2(aabb.upperBound.X, aabb.upperBound.Y); vs[3] = new Vector2(aabb.lowerBound.X, aabb.upperBound.Y); DebugDraw.DrawPolygon(ref vs, 4, color); } } } } if ((flags & DebugDrawFlags.CenterOfMass) == DebugDrawFlags.CenterOfMass) { for (Body b = _bodyList; b != null; b = b.GetNext()) { Transform xf; b.GetTransform(out xf); xf.Position = b.GetWorldCenter(); DebugDraw.DrawTransform(ref xf); } } }
/// <summary> /// Destroy a joint. This may cause the connected bodies to begin colliding. /// @warning This function is locked during callbacks. /// </summary> /// <param name="j"></param> public void DestroyJoint(Joint j) { Debug.Assert(!IsLocked); if (IsLocked) { return; } bool collideConnected = j._collideConnected; // Remove from the doubly linked list. if (j._prev != null) { j._prev._next = j._next; } if (j._next != null) { j._next._prev = j._prev; } if (j == _jointList) { _jointList = j._next; } // Disconnect from island graph. Body bodyA = j._bodyA; Body bodyB = j._bodyB; // Wake up connected bodies. bodyA.SetAwake(true); bodyB.SetAwake(true); // Remove from body 1. if (j._edgeA.Prev != null) { j._edgeA.Prev.Next = j._edgeA.Next; } if (j._edgeA.Next != null) { j._edgeA.Next.Prev = j._edgeA.Prev; } if (j._edgeA == bodyA._jointList) { bodyA._jointList = j._edgeA.Next; } j._edgeA.Prev = null; j._edgeA.Next = null; // Remove from body 2 if (j._edgeB.Prev != null) { j._edgeB.Prev.Next = j._edgeB.Next; } if (j._edgeB.Next != null) { j._edgeB.Next.Prev = j._edgeB.Prev; } if (j._edgeB == bodyB._jointList) { bodyB._jointList = j._edgeB.Next; } j._edgeB.Prev = null; j._edgeB.Next = null; Debug.Assert(_jointCount > 0); --_jointCount; // If the joint prevents collisions, then flag any contacts for filtering. if (collideConnected == false) { ContactEdge edge = bodyB.GetContactList(); while (edge != null) { if (edge.Other == bodyA) { // Flag the contact for filtering at the next time step (where either // body is awake). edge.Contact.FlagForFiltering(); } edge = edge.Next; } } }
public GearJointDef() { type = JointType.Gear; joint1 = null; joint2 = null; ratio = 1.0f; }
void DrawJoint(Joint joint) { Body b1 = joint.GetBodyA(); Body b2 = joint.GetBodyB(); Transform xf1, xf2; b1.GetTransform(out xf1); b2.GetTransform(out xf2); Vector2 x1 = xf1.Position; Vector2 x2 = xf2.Position; Vector2 p1 = joint.GetAnchorA(); Vector2 p2 = joint.GetAnchorB(); Color color = new Color(0.5f, 0.8f, 0.8f); switch (joint.JointType) { case JointType.Distance: DebugDraw.DrawSegment(p1, p2, color); break; case JointType.Pulley: { PulleyJoint pulley = (PulleyJoint)joint; Vector2 s1 = pulley.GetGroundAnchorA(); Vector2 s2 = pulley.GetGroundAnchorB(); DebugDraw.DrawSegment(s1, p1, color); DebugDraw.DrawSegment(s2, p2, color); DebugDraw.DrawSegment(s1, s2, color); } break; case JointType.Mouse: // don't draw this break; default: DebugDraw.DrawSegment(x1, p1, color); DebugDraw.DrawSegment(p1, p2, color); DebugDraw.DrawSegment(x2, p2, color); break; } }
public void RemoveJointReference(Joint j) { if (jointRefs.Contains(j)) { jointRefs.Remove(j); } }
public void RemoveJoint(Joint joint) { Joint j = world.GetJointList(); while (j != null) { if (j == joint) { world.DestroyJoint(joint); break; } j = j.GetNext(); } }
/// <summary> /// Resets the bike and the driver to their initial positions /// Resets all angular and linear speeds /// Recreates the joints if they were destroyed /// </summary> public void Reset() { foreach (var part in parts) { part.SetAngularVelocity(0); part.SetLinearVelocity(Vector2.Zero); } frontWheel.SetTransform(frontWheelInitPos / Level.FACTOR, 0); frontFork.SetTransform(frontForkInitPos / Level.FACTOR, 0); rearWheel.SetTransform(rearWheelInitPos / Level.FACTOR, 0); rearFork.SetTransform(rearForkInitPos / Level.FACTOR, rearForkInitRot * Level.DEG_TO_RAD); bikeBody.SetTransform(bikeBodyInitPos / Level.FACTOR, bikeBodyInitRot * Level.DEG_TO_RAD); head.SetTransform(headInitPos / Level.FACTOR, headInitRot * Level.DEG_TO_RAD); humanBody.SetTransform(humanBodyInitPos / Level.FACTOR, 0); hand.SetTransform(handInitPos / Level.FACTOR, handInitRot * Level.DEG_TO_RAD); arm.SetTransform(armInitPos / Level.FACTOR, armInitRot * Level.DEG_TO_RAD); if (OffTheBike) { RevoluteJointDef handToBikeDef = new RevoluteJointDef(); Vector2 anchor = hand.GetWorldPoint(new Vector2(17.06f / Level.FACTOR, 4.26f / Level.FACTOR)); handToBikeDef.Initialize(hand, bikeBody, anchor); handToBikeDef.maxMotorTorque = 300.0f; handToBike = world.CreateJoint(handToBikeDef); RevoluteJointDef humanToBikeDef = new RevoluteJointDef(); anchor = humanBody.GetWorldCenter(); anchor.Y += (30.0f / Level.FACTOR); humanToBikeDef.Initialize(humanBody, bikeBody, anchor); humanToBikeDef.maxMotorTorque = 300.0f; humanToBike = world.CreateJoint(humanToBikeDef); DistanceJointDef armToBikeDef = new DistanceJointDef(); armToBikeDef.Initialize(hand, bikeBody, hand.GetWorldPoint(new Vector2(-17.00f / Level.FACTOR, 4.26f / Level.FACTOR)), bikeBody.GetWorldCenter()); armToBikeDef.length = 40.0f / Level.FACTOR; armToBikeDef.frequencyHz = 10.0f; armToBikeDef.dampingRatio = 1.0f; armToBikeDef.collideConnected = true; armToBike = world.CreateJoint(armToBikeDef); OffTheBike = false; } if (!bikeBody.IsAwake()) bikeBody.SetAwake(true); if (RotationData.device) motor._enableMotor = true; }
void HandleEquipment(InputState input) { Vector2 m = mousePos * gameContent.scale; Point mp = new Point((int)m.X, (int)m.Y); Equipment mouseOverEq = null; if (mouseEq == null) foreach (Equipment e in equipments) { e.isMouseOver = false; if (mouseOverEq == null && !isMenuEntrySelected && (e.MoveButtonBound.Contains(mp) || e.RotationButtonBound.Contains(mp))) { mouseOverEq = e; e.isMouseOver = true; } } if (input.IsLeftClicked() && mouseOverEq != null) { if (mouseOverEq.MoveButtonBound.Contains(mp) || mouseOverEq.RotationButtonBound.Contains(mp)) { MouseJointDef mjd = new MouseJointDef(); mjd.maxForce = 500; //mjd.frequencyHz = 10f; mjd.dampingRatio = .1f; mjd.target = mousePos; mjd.bodyA = mouseGroundBody; mjd.bodyB = mouseOverEq.body; mouseJoint = (MouseJoint)world.CreateJoint(mjd); mouseEq = mouseOverEq; mouseEq.body.SetAngularDamping(20000); if (mouseOverEq.RotationButtonBound.Contains(mp)) { RevoluteJointDef rjd = new RevoluteJointDef(); rjd.bodyA = mouseGroundBody; rjd.bodyB = mouseOverEq.body; rjd.localAnchorA = mouseOverEq.body.Position; rjd.localAnchorB = Vector2.Zero; pin = world.CreateJoint(rjd); mouseEq.body.SetAngularDamping(20); } if (selectedEq != mouseOverEq) { if (selectedEq != null) { selectedEq.isSelected = false; selectedEq.SetMode(editMode, false); selectedEq = null; } selectedEq = mouseOverEq; selectedEq.isClamped = false; selectedEq.isSelected = true; } mouseEq.SetMode(editMode, true); } } else if (mouseOverEq != null && input.IsRightClicked() || input.CurrentMouseState[0].LeftButton == ButtonState.Released) { if (mouseJoint != null && mouseEq != null) { world.DestroyJoint(mouseJoint); mouseJoint = null; if (pin != null) { world.DestroyJoint(pin); pin = null; } mouseEq.SetMode(editMode, false); mouseEq = null; } if (mouseOverEq != null && input.IsRightClicked()) { selectedEq = null; mouseOverEq.Remove(); equipments.Remove(mouseOverEq); } } // Remove if (!equipmentAdded && (input.IsLeftClicked() || input.IsRightClicked()) && mouseOverEq == null && mouseEq == null && selectedEq != null) { selectedEq.isSelected = false; selectedEq.SetMode(editMode, false); selectedEq = null; } equipmentAdded = false; }
public void SetMode(bool editMode, bool isMouse) { if (!clampEnabled) isClamped = false; this.editMode = editMode; float reqMass = 10; if (isSelected) reqMass = .2f; else { body.SetActive(true); body.SetLinearDamping(0); body.SetAngularDamping(0); } for (Fixture f = body.GetFixtureList(); f != null; f = f.GetNext()) { object area = f.GetUserData(); if (area is float) f.SetDensity(reqMass / (float)area / fixtureCount); if (isSelected) f.SetFilterData(ref mouseFilter); else if (editMode) f.SetFilterData(ref equipFilter); else f.SetFilterData(ref groundFilter); } body.ResetMassData(); if (!editMode || (isSelected && !isMouse) || isClamped) { if (pin == null) // Pin { BodyDef bd = new BodyDef(); Body b = world.CreateBody(bd); RevoluteJointDef jd = new RevoluteJointDef(); jd.bodyA = b; jd.bodyB = body; jd.localAnchorA = body.Position; jd.localAnchorB = Vector2.Zero; pin = world.CreateJoint(jd); body.SetAngularVelocity(0); body.SetFixedRotation(true); } } else if (pin != null) { body.SetFixedRotation(false); world.DestroyJoint(pin); pin = null; } }
/// <summary> Create a joint to rain bodies together. No reference to the definition /// is retained. This may cause the connected bodies to cease colliding. /// </summary> <warning> This function is locked during callbacks. /// </warning> public Joint CreateJoint(JointDef def) { Debug.Assert(!IsLocked); if (IsLocked) { return(null); } Joint j = Joint.Create(def); // Connect to the world list. j._prev = null; j._next = _jointList; if (_jointList != null) { _jointList._prev = j; } _jointList = j; ++_jointCount; // Connect to the bodies' doubly linked lists. j._edgeA.Joint = j; j._edgeA.Other = j._bodyB; j._edgeA.Prev = null; j._edgeA.Next = j._bodyA._jointList; if (j._bodyA._jointList != null) { j._bodyA._jointList.Prev = j._edgeA; } j._bodyA._jointList = j._edgeA; j._edgeB.Joint = j; j._edgeB.Other = j._bodyA; j._edgeB.Prev = null; j._edgeB.Next = j._bodyB._jointList; if (j._bodyB._jointList != null) { j._bodyB._jointList.Prev = j._edgeB; } j._bodyB._jointList = j._edgeB; Body bodyA = def.bodyA; Body bodyB = def.bodyB; bool staticA = bodyA.GetType() == BodyType.Static; bool staticB = bodyB.GetType() == BodyType.Static; // If the joint prevents collisions, then flag any contacts for filtering. if (def.collideConnected == false) { ContactEdge edge = bodyB.GetContactList(); while (edge != null) { if (edge.Other == bodyA) { // Flag the contact for filtering at the next time step (where either // body is awake). edge.Contact.FlagForFiltering(); } edge = edge.Next; } } // Note: creating a joint doesn't wake the bodies. return(j); }