//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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        /// <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);
            }
        }
Exemple #5
0
        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();
            }
        }
Exemple #6
0
 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);
 }
Exemple #7
0
        // 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);
        }
Exemple #8
0
        /// <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);
        }
Exemple #9
0
        /// <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);
        }
Exemple #12
0
        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;
            }
        }
Exemple #13
0
        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();
                }
            }
        }
Exemple #14
0
        /// <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);
        }
Exemple #15
0
        /**
         * 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);
        }
Exemple #16
0
        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);
        }
Exemple #18
0
        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();
        }
Exemple #19
0
        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);
        }
Exemple #20
0
        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;
        }