//internal void SetObject(object o) //{ // grid.SelectedObject = o; // history.Clear(); // List<Object> list = new List<Object>(); // list.Add(o); // history.Push(list); //} private void grid_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e) { if (e.NewSelection.Value is IEnumerable <Object> ) { IEnumerable <Object> list = (IEnumerable <Object>)e.NewSelection.Value; PopulateSelectList(list); } if (e.NewSelection.Value is JointEdge) { HashSet <Joint> joints = new HashSet <Joint>(); JointEdge j = (JointEdge)e.NewSelection.Value; while (j != null) { joints.Add(j.Joint); j = j.Next; } PopulateSelectList(joints); } Object oldObj = null; Object newObj = null; if (e.OldSelection != null) { oldObj = e.OldSelection.Value; } if (e.NewSelection != null) { newObj = e.NewSelection.Value; } doHighlighting(oldObj, newObj); }
public void RemoveObject(GameObject gameObject) { foreach (GameObjectPart part in gameObject) { JointEdge iterator = part.Body.JointList; while (iterator != null) { List <Joint> jointsToRemove = new List <Joint>(); foreach (Joint joint in _joints) { if (joint == iterator.Joint) { jointsToRemove.Add(joint); } } foreach (Joint joint in jointsToRemove) { _joints.Remove(joint); } iterator = iterator.Next; } part.RemoveBody(World); } _objects.Remove(gameObject); }
/// <summary> /// Kills all joints the player is involved with /// </summary> public void killJoints() { JointEdge je = my_Body.GetJointList(); while (je != null) { gameWorld.physicsWorld.DestroyJoint(je.Joint); je = je.Next; } }
/// <summary> /// Destroy a rigid body. /// Warning: This function is locked during callbacks. /// Warning: This automatically deletes all associated shapes and joints. /// </summary> /// <param name="body">The body.</param> public void RemoveBody(Body body) { Debug.Assert(BodyList.Count > 0); Debug.Assert(!IsLocked); if (IsLocked) { return; } // You tried to remove a body that is not contained in the BodyList. // Are you removing the body more than once? Debug.Assert(BodyList.Contains(body)); // Delete the attached joints. JointEdge je = body.JointList; while (je != null) { JointEdge je0 = je; je = je.Next; RemoveJoint(je0.Joint); } body.JointList = null; // Delete the attached contacts. ContactEdge ce = body.ContactList; while (ce != null) { ContactEdge ce0 = ce; ce = ce.Next; ContactManager.Destroy(ce0.Contact); } body.ContactList = null; // Delete the attached fixtures. This destroys broad-phase proxies. foreach (Fixture fixture in body.FixtureList) { fixture.DestroyProxies(ContactManager.BroadPhase); fixture.Destroy(); } body.FixtureList = null; // Remove world body list. BodyList.Remove(body); if (BodyRemoved != null) { BodyRemoved(body); } }
private void ProcessRemovedBodies() { if (this._bodyRemoveList.Count > 0) { foreach (Body body in this._bodyRemoveList) { Debug.Assert(this.BodyList.Count > 0); // You tried to remove a body that is not contained in the BodyList. // Are you removing the body more than once? Debug.Assert(this.BodyList.Contains(body)); // Delete the attached joints. JointEdge je = body.JointList; while (je != null) { JointEdge je0 = je; je = je.Next; RemoveJoint(je0.Joint, false); } body.JointList = null; // Delete the attached contacts. ContactEdge ce = body.ContactList; while (ce != null) { ContactEdge ce0 = ce; ce = ce.Next; this.ContactManager.Destroy(ce0.Contact); } body.ContactList = null; // Delete the attached fixtures. This destroys broad-phase proxies. for (int i = 0; i < body.FixtureList.Count; i++) { body.FixtureList[i].DestroyProxies(this.ContactManager.BroadPhase); body.FixtureList[i].Destroy(); } body.FixtureList = null; // Remove world body list. this.BodyList.Remove(body); if (this.BodyRemoved != null) { this.BodyRemoved(body); } } this._bodyRemoveList.Clear(); } }
private static Joint GetFirstGearableJoint(JointEdge je) { while (je != null && !(je.Joint is PrismaticJoint || je.Joint is RevoluteJoint)) { je = je.Next; } if (je == null) { throw (new Exception("missing gear joint target")); } return(je.Joint); }
// This is used to prevent connected bodies from colliding. // It may lie, depending on the collideConnected flag. /// <summary> /// Describes whether this instance is connected /// </summary> /// <param name="other">The other</param> /// <returns>The bool</returns> internal bool IsConnected(Body other) { for (JointEdge jn = JointList; jn != null; jn = jn.Next) { if (jn.Other == other) { return(jn.Joint.CollideConnected == false); } } return(false); }
/// <summary> /// Is this connected to the given body. /// </summary> /// <param name="other">Other body.</param> /// <returns>True if connected by a joint, false if otherwise.</returns> public bool areJoined(Body other) { JointEdge jointEdge = my_Body.GetJointList(); while (jointEdge != null) { if (jointEdge.Joint.GetBodyB().Equals(other) || jointEdge.Joint.GetBodyA().Equals(other)) { return(true); } jointEdge = jointEdge.Next; } return(false); }
/// <summary> /// Removes all jointed items and adds them to the inventory /// </summary> public void collectItems() { JointEdge je = my_Body.GetJointList(); while (je != null) { Body b = je.Other; Joint j = je.Joint; Item itemEnt = b.GetUserData() as Item; if (itemEnt.type.type == TypeOfThing.ITEM) { inventory.AddItems((itemEnt).itemType, 1); } je = je.Next; gameWorld.physicsWorld.DestroyJoint(j); gameWorld.removeEntity(itemEnt); } }
private void DrawObjectPart(GameObjectPart objectPart, Color color) { List <Fixture> fixtureList = objectPart.Body.FixtureList; Transform xf; objectPart.Body.GetTransform(out xf); if (DrawAssociatedJoints) { JointEdge iterator = objectPart.Body.JointList; while (iterator != null) { DrawJoint(iterator.Joint, Color.Multiply(Color.Blue, 0.5f)); iterator = iterator.Next; } } foreach (Fixture fix in fixtureList) { DrawShape(fix, xf, Color.Multiply(color, 0.5f)); } }
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null); List <Joint> jointList = new List <Joint>(); JointEdge iterator = (JointEdge)value; while (iterator != null) { jointList.Add(iterator.Joint); iterator = iterator.Next; } foreach (Joint element in jointList) { ListDescriptor <Joint> desc = new ListDescriptor <Joint>(jointList.IndexOf(element), jointList); pds.Add(desc); } return(pds); }
public virtual void Update(FixedMouseJoint fixedMouseJoint) { if (_breakableBody.State == SegmentableBody.BreakableBodyState.ShouldBreak) { // save MouseJoint position Vector2?worldAnchor = null; for (JointEdge je = _breakableBody.MainBody.JointList; je != null; je = je.Next) { if (je.Joint == fixedMouseJoint) { worldAnchor = fixedMouseJoint.WorldAnchorA; break; } } // break body _breakableBody.Update(); // restore MouseJoint if (worldAnchor != null && fixedMouseJoint == null) { var ficture = _world.TestPoint(worldAnchor.Value); if (ficture != null) { fixedMouseJoint = new FixedMouseJoint(ficture.Body, worldAnchor.Value); fixedMouseJoint.MaxForce = 1000.0f * ficture.Body.Mass; _world.Add(fixedMouseJoint); } } //CreateGFX(_breakableBody); } else { _breakableBody.Update(); } if (this._blockState == BlockState.Griped) { body.Rotation = fixedRotation; } }
public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) { base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen); foreach (var breakableBody in _breakableBodies) { if (breakableBody.State == BreakableBody.BreakableBodyState.ShouldBreak) { // save MouseJoint position Vector2?worldAnchor = null; for (JointEdge je = breakableBody.MainBody.JointList; je != null; je = je.Next) { if (je.Joint == _fixedMouseJoint) { worldAnchor = _fixedMouseJoint.WorldAnchorA; break; } } // break body breakableBody.Update(); // restore MouseJoint if (worldAnchor != null && _fixedMouseJoint == null) { var ficture = World.TestPoint(worldAnchor.Value); if (ficture != null) { _fixedMouseJoint = new FixedMouseJoint(ficture.Body, worldAnchor.Value); _fixedMouseJoint.MaxForce = 1000.0f * ficture.Body.Mass; World.Add(_fixedMouseJoint); } } } else { breakableBody.Update(); } } }
/// <summary> /// This is used to prevent connected bodies from colliding. /// It may lie, depending on the collideConnected flag. /// </summary> /// <param name="other">The other body.</param> /// <returns></returns> internal bool ShouldCollide(Body other) { // At least one body should be dynamic. if (_bodyType != BodyType.Dynamic && other._bodyType != BodyType.Dynamic) { return(false); } // Does a joint prevent collision? for (JointEdge jn = JointList; jn != null; jn = jn.Next) { if (jn.Other == other) { if (jn.Joint.CollideConnected == false) { return(false); } } } return(true); }
/** * This is used to prevent connected bodies from colliding. It may lie, depending on the * collideConnected flag. * * @param other * @return */ public bool shouldCollide(Body other) { // At least one body should be dynamic. if (m_type != BodyType.DYNAMIC && other.m_type != BodyType.DYNAMIC) { return(false); } // Does a joint prevent collision? for (JointEdge jn = m_jointList; jn != null; jn = jn.next) { if (jn.other == other) { if (jn.joint.getCollideConnected() == false) { return(false); } } } return(true); }
private void NextStepGearJoint(Vector2 position) { switch (_step) { case 0: _currentStateMessage = "Creating Gear joint. Choose BodyA with one revolute or prismatic joint..."; _step++; break; case 1: Body bodyA = CommonHelpers.FindBody(position, _world); if (bodyA == null) { _currentStateMessage = "Cant find body in this position. Choose BodyA..."; break; } { if (bodyA.JointList == null) { _currentStateMessage = "This body doesnt contain joints. Choose BodyA with one revolute or prismatic joint..."; break; } JointEdge iterator = bodyA.JointList; int validJoints = 0; do { JointType type = iterator.Joint.JointType; if (type == JointType.Revolute || type == JointType.Prismatic || type == JointType.FixedRevolute || type == JointType.FixedPrismatic) { _jointParameters.jointA = iterator.Joint; validJoints++; } } while ((iterator = iterator.Next) != null); if (validJoints > 1) { _currentStateMessage = "This body contains more than one valid joints. Choose BodyA with one revolute or prismatic joint..."; break; } } _currentStateMessage = "BodyA with valid joint has been selected. Choose BodyB with revolute or prismatic joint..."; _step++; break; case 2: Body bodyB = CommonHelpers.FindBody(position, _world); if (bodyB == null) { _currentStateMessage = "Cant find body in this position. Choose BodyB..."; break; } { JointEdge iterator = bodyB.JointList; int validJoints = 0; do { JointType type = iterator.Joint.JointType; if (type == JointType.Revolute || type == JointType.Prismatic || type == JointType.FixedRevolute || type == JointType.FixedPrismatic) { _jointParameters.jointB = iterator.Joint; validJoints++; } } while ((iterator = iterator.Next) != null); if (validJoints > 1) { _currentStateMessage = "This body contains more than one valid joints. Choose BodyB with one revolute or prismatic joint..."; break; } } _currentStateMessage = "BodyB wiht valid has been selected. GEAR JOINT CREATED"; _joint = new GearJoint(_jointParameters.jointA, _jointParameters.jointB, 1f); _step = 0; break; default: throw new ArgumentOutOfRangeException("Unknown join creation step"); } }
public void Update(float deltaTime) { while (impactQueue.Count > 0) { var impact = impactQueue.Dequeue(); if (impact.Target.UserData is VoronoiCell cell) { HandleLevelCollision(impact); } else if (impact.Target.Body.UserData is Structure) { HandleLevelCollision(impact); } else if (impact.Target.Body.UserData is Submarine otherSub) { HandleSubCollision(impact, otherSub); } else if (impact.Target.Body.UserData is Limb limb) { HandleLimbCollision(impact, limb); } } //------------------------- if (Body.FarseerBody.BodyType == BodyType.Static) { return; } ClientUpdatePosition(deltaTime); if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; } Vector2 totalForce = CalculateBuoyancy(); //------------------------- //if outside left or right edge of the level if (Level.Loaded != null && (Position.X < 0 || Position.X > Level.Loaded.Size.X)) { Rectangle worldBorders = Borders; worldBorders.Location += MathUtils.ToPoint(Position); //push the sub back below the upper "barrier" of the level if (worldBorders.Y > Level.Loaded.Size.Y) { Body.LinearVelocity = new Vector2( Body.LinearVelocity.X, Math.Min(Body.LinearVelocity.Y, ConvertUnits.ToSimUnits(Level.Loaded.Size.Y - worldBorders.Y))); } else if (worldBorders.Y - worldBorders.Height < Level.Loaded.BottomPos) { Body.LinearVelocity = new Vector2( Body.LinearVelocity.X, Math.Max(Body.LinearVelocity.Y, ConvertUnits.ToSimUnits(Level.Loaded.BottomPos - (worldBorders.Y - worldBorders.Height)))); } if (Position.X < 0) { float force = Math.Abs(Position.X * 0.5f); totalForce += Vector2.UnitX * force; if (Character.Controlled != null && Character.Controlled.Submarine == submarine) { GameMain.GameScreen.Cam.Shake = Math.Max(GameMain.GameScreen.Cam.Shake, Math.Min(force * 0.0001f, 5.0f)); } } else { float force = (Position.X - Level.Loaded.Size.X) * 0.5f; totalForce -= Vector2.UnitX * force; if (Character.Controlled != null && Character.Controlled.Submarine == submarine) { GameMain.GameScreen.Cam.Shake = Math.Max(GameMain.GameScreen.Cam.Shake, Math.Min(force * 0.0001f, 5.0f)); } } } //------------------------- if (Body.LinearVelocity.LengthSquared() > 0.0001f) { //TODO: sync current drag with clients? float attachedMass = 0.0f; JointEdge jointEdge = Body.FarseerBody.JointList; while (jointEdge != null) { Body otherBody = jointEdge.Joint.BodyA == Body.FarseerBody ? jointEdge.Joint.BodyB : jointEdge.Joint.BodyA; Character character = (otherBody.UserData as Limb)?.character; if (character != null) { attachedMass += character.Mass; } jointEdge = jointEdge.Next; } float horizontalDragCoefficient = MathHelper.Clamp(HorizontalDrag + attachedMass / 5000.0f, 0.0f, MaxDrag); totalForce.X -= Math.Sign(Body.LinearVelocity.X) * Body.LinearVelocity.X * Body.LinearVelocity.X * horizontalDragCoefficient * Body.Mass; float verticalDragCoefficient = MathHelper.Clamp(VerticalDrag + attachedMass / 5000.0f, 0.0f, MaxDrag); totalForce.Y -= Math.Sign(Body.LinearVelocity.Y) * Body.LinearVelocity.Y * Body.LinearVelocity.Y * verticalDragCoefficient * Body.Mass; } ApplyForce(totalForce); UpdateDepthDamage(deltaTime); }
private void Solve(ref TimeStep step) { // Size the island for the worst case. Island.Reset(BodyList.Count, ContactManager.ContactList.Count, JointList.Count, ContactManager); // Clear all the island flags. foreach (Body b in BodyList) { b._flags &= ~BodyFlags.IslandFlag; } foreach (Contact c in ContactManager.ContactList) { c._flags &= ~ContactFlags.IslandFlag; } foreach (Joint j in JointList) { j.IslandFlag = false; } // Build and simulate all awake islands. int stackSize = BodyList.Count; if (stackSize > _stack.Length) { _stack = new Body[Math.Max(_stack.Length * 2, stackSize)]; } for (int index = BodyList.Count - 1; index >= 0; index--) { Body seed = BodyList[index]; if ((seed._flags & BodyFlags.IslandFlag) == BodyFlags.IslandFlag) { continue; } if (seed.Awake == false || seed.Enabled == false) { continue; } // The seed can be dynamic or kinematic. if (seed.BodyType == BodyType.Static) { continue; } // Reset island and stack. Island.Clear(); int stackCount = 0; _stack[stackCount++] = seed; seed._flags |= BodyFlags.IslandFlag; // Perform a depth first search (DFS) on the constraint graph. while (stackCount > 0) { // Grab the next body off the stack and add it to the island. Body b = _stack[--stackCount]; Debug.Assert(b.Enabled); Island.Add(b); // Make sure the body is awake (without resetting sleep timer). b._flags |= BodyFlags.AwakeFlag; // To keep islands as small as possible, we don't // propagate islands across static bodies. if (b.BodyType == 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.IslandFlag) { continue; } // Is this contact solid and touching? if (ce.Contact.Enabled == false || ce.Contact.IsTouching == false) { continue; } // Skip sensors. bool sensorA = contact.FixtureA.IsSensor; bool sensorB = contact.FixtureB.IsSensor; if (sensorA || sensorB) { continue; } Island.Add(contact); contact._flags |= ContactFlags.IslandFlag; Body other = ce.Other; // Was the other body already added to this island? if (other.IsIsland) { continue; } Debug.Assert(stackCount < stackSize); _stack[stackCount++] = other; other._flags |= BodyFlags.IslandFlag; } // Search all joints connect to this body. for (JointEdge je = b.JointList; je != null; je = je.Next) { if (je.Joint.IslandFlag) { continue; } Body other = je.Other; // WIP David //Enter here when it's a non-fixed joint. Non-fixed joints have a other body. if (other != null) { // Don't simulate joints connected to inactive bodies. if (other.Enabled == false) { continue; } Island.Add(je.Joint); je.Joint.IslandFlag = true; if (other.IsIsland) { continue; } Debug.Assert(stackCount < stackSize); _stack[stackCount++] = other; other._flags |= BodyFlags.IslandFlag; } else { Island.Add(je.Joint); je.Joint.IslandFlag = true; } } } Island.Solve(ref step, ref Gravity); // 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.BodyType == BodyType.Static) { b._flags &= ~BodyFlags.IslandFlag; } } } // Synchronize fixtures, check for out of range bodies. foreach (Body b in BodyList) { // If a body was not in an island then it did not move. if (!b.IsIsland) { continue; } if (b.BodyType == BodyType.Static) { continue; } // Update fixtures (for broad-phase). b.SynchronizeFixtures(); } // Look for new contacts. ContactManager.FindNewContacts(); }
public void Update(float deltaTime) { if (Body.FarseerBody.IsStatic) { return; } ClientUpdatePosition(deltaTime); if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; } //if outside left or right edge of the level if (Position.X < 0 || Position.X > Level.Loaded.Size.X) { Rectangle worldBorders = Borders; worldBorders.Location += MathUtils.ToPoint(Position); //push the sub back below the upper "barrier" of the level if (worldBorders.Y > Level.Loaded.Size.Y) { Body.LinearVelocity = new Vector2( Body.LinearVelocity.X, Math.Min(Body.LinearVelocity.Y, ConvertUnits.ToSimUnits(Level.Loaded.Size.Y - worldBorders.Y))); } else if (worldBorders.Y - worldBorders.Height < Level.Loaded.BottomPos) { Body.LinearVelocity = new Vector2( Body.LinearVelocity.X, Math.Max(Body.LinearVelocity.Y, ConvertUnits.ToSimUnits(Level.Loaded.BottomPos - (worldBorders.Y - worldBorders.Height)))); } } //------------------------- Vector2 totalForce = CalculateBuoyancy(); if (Body.LinearVelocity.LengthSquared() > 0.0001f) { //TODO: sync current drag with clients? float attachedMass = 0.0f; JointEdge jointEdge = Body.FarseerBody.JointList; while (jointEdge != null) { Body otherBody = jointEdge.Joint.BodyA == Body.FarseerBody ? jointEdge.Joint.BodyB : jointEdge.Joint.BodyA; Character character = (otherBody.UserData as Limb)?.character; if (character != null) { attachedMass += character.Mass; } jointEdge = jointEdge.Next; } float horizontalDragCoefficient = MathHelper.Clamp(HorizontalDrag + attachedMass / 5000.0f, 0.0f, MaxDrag); totalForce.X -= Math.Sign(Body.LinearVelocity.X) * Body.LinearVelocity.X * Body.LinearVelocity.X * horizontalDragCoefficient * Body.Mass; float verticalDragCoefficient = MathHelper.Clamp(VerticalDrag + attachedMass / 5000.0f, 0.0f, MaxDrag); totalForce.Y -= Math.Sign(Body.LinearVelocity.Y) * Body.LinearVelocity.Y * Body.LinearVelocity.Y * verticalDragCoefficient * Body.Mass; } ApplyForce(totalForce); UpdateDepthDamage(deltaTime); }
public Body(BodyDef bd, World world) { m_flags = 0; if (bd.bullet) { m_flags |= e_bulletFlag; } if (bd.fixedRotation) { m_flags |= e_fixedRotationFlag; } if (bd.allowSleep) { m_flags |= e_autoSleepFlag; } if (bd.awake) { m_flags |= e_awakeFlag; } if (bd.active) { m_flags |= e_activeFlag; } m_world = world; m_xf.p.set(bd.position); m_xf.q.set(bd.angle); m_sweep.localCenter.setZero(); m_sweep.c0.set(m_xf.p); m_sweep.c.set(m_xf.p); m_sweep.a0 = bd.angle; m_sweep.a = bd.angle; m_sweep.alpha0 = 0.0d; m_jointList = null; m_contactList = null; m_prev = null; m_next = null; m_linearVelocity.set(bd.linearVelocity); m_angularVelocity = bd.angularVelocity; m_linearDamping = bd.linearDamping; m_angularDamping = bd.angularDamping; m_gravityScale = bd.gravityScale; m_force.setZero(); m_torque = 0.0d; m_sleepTime = 0.0d; m_type = bd.type; if (m_type == BodyType.DYNAMIC) { m_mass = 1d; m_invMass = 1d; } else { m_mass = 0d; m_invMass = 0d; } m_I = 0.0d; m_invI = 0.0d; m_userData = bd.userData; m_fixtureList = null; m_fixtureCount = 0; }