private void ConstructPhysicsSimulator(Vector2 gravity)
        {
            geomList       = new GeomList();
            geomAddList    = new List <Geom>();
            geomRemoveList = new List <Geom>();

            bodyList       = new BodyList();
            bodyAddList    = new List <Body>();
            bodyRemoveList = new List <Body>();

            controllerList       = new ControllerList();
            controllerAddList    = new List <Controller>();
            controllerRemoveList = new List <Controller>();

            jointList       = new JointList();
            jointAddList    = new List <Joint>();
            jointRemoveList = new List <Joint>();

            _broadPhaseCollider = new SelectiveSweepCollider(this);

            arbiterList = new ArbiterList();
            _gravity    = gravity;

            arbiterPool = new Pool <Arbiter>(_arbiterPoolSize);

            #region Added by Daniel Pramel 08/17/08

            _inactivityController = new InactivityController(this);

            _scaling = new Scaling(0.001f, 0.01f);

            #endregion
        }
            public XnaBoneWeightChannel(MeshBuilder mb, VertexContainer vc, JointList joints)
                : base(mb)
            {
                try
                {
                    _indicesChannel = (from c in vc.VertexChannels
                                       where c.Contains(VertexElementUsage.BlendIndices)
                                       select c).First();

                    _weightChannel = (from c in vc.VertexChannels
                                      where c.Contains(VertexElementUsage.BlendWeight)
                                      select c).First();
                }
                catch (Exception)
                {
                    throw new Exception("Missing blend indices or weights");
                }

                _joints        = joints;
                _vertexSize    = vc.VertexSize;
                _indicesOffset = _indicesChannel.Source.Offset;
                _weightOffset  = _weightChannel.Source.Offset;

                this.Create();
            }
        /// <summary>
        /// Processes the disposed controllers, joints, springs, bodies and cleans up the arbiter list.
        /// </summary>
        private void ProcessDisposedItems()
        {
            //Allow each controller to validate itself. this is where a controller can Dispose of itself if need be.
            for (int i = 0; i < ControllerList.Count; i++)
            {
                ControllerList[i].Validate();
            }

            //Allow each joint to validate itself. this is where a joint can Dispose of itself if need be.
            for (int i = 0; i < JointList.Count; i++)
            {
                JointList[i].Validate();
            }

            //Allow each spring to validate itself. this is where a spring can Dispose of itself if need be.
            for (int i = 0; i < SpringList.Count; i++)
            {
                SpringList[i].Validate();
            }

            _tempCount = GeomList.RemoveDisposed();

            if (_tempCount > 0)
            {
                _broadPhaseCollider.ProcessDisposedGeoms();
            }

            BodyList.RemoveDisposed();
            ControllerList.RemoveDisposed();
            SpringList.RemoveDisposed();
            JointList.RemoveDisposed();

            //Clean up the arbiterlist
            ArbiterList.CleanArbiterList(arbiterPool);
        }
示例#4
0
 private void PhysicsConstructor(Vector2 gravity)
 {
     _rigidBodyList = new RigidBodyList();
     _arbiterList   = new ArbiterList();
     _springList    = new SpringList();
     _jointList     = new JointList();
     _gravity       = gravity;
 }
示例#5
0
 private void Awake()
 {
     FixedJoint[] componentsInChildren = GetComponentsInChildren <FixedJoint>();
     jointLists = new JointList[componentsInChildren.Length];
     for (int i = 0; i < componentsInChildren.Length; i++)
     {
         FixedJoint fixedJoint = componentsInChildren[i];
         jointLists[i] = new JointList(fixedJoint.gameObject, fixedJoint.connectedBody, fixedJoint.breakForce);
     }
 }
示例#6
0
        /// <summary>
        /// select/deselect all joints under `startJoint'
        /// </summary>
        public void RecurSelect(Transform startJoint, bool select)
        {
            JointList extendedJoints = SMREditor.GetExtendedJoints();

            if (!extendedJoints.Contains(startJoint))
            {
                return;
            }

            _Recur_SelectJointAndAllDescendants(startJoint, select);
        }
示例#7
0
        private float _width; // width and height of bodies to create

        /// <summary>
        /// Initializes a new instance of the <see cref="Path"/> class.
        /// </summary>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="mass">The mass.</param>
        /// <param name="endless">if set to <c>true</c> [endless].</param>
        public Path(float width, float height, float mass, bool endless)
        {
            _width = width;
            _height = height;
            _loop = endless;
            _mass = mass;
            _geoms = new GeomList();
            _bodies = new BodyList();
            _joints = new JointList();
            _springs = new SpringList();
            _controlPoints = new Vertices();
        }
示例#8
0
        private float _width;                            // width and height of bodies to create

        /// <summary>
        /// Initializes a new instance of the <see cref="Path"/> class.
        /// </summary>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="mass">The mass.</param>
        /// <param name="endless">if set to <c>true</c> [endless].</param>
        public Path(float width, float height, float mass, bool endless)
        {
            _width         = width;
            _height        = height;
            _loop          = endless;
            _mass          = mass;
            _geoms         = new GeomList();
            _bodies        = new BodyList();
            _joints        = new JointList();
            _springs       = new SpringList();
            _controlPoints = new Vertices();
        }
示例#9
0
        private void ProcessAddedJoints()
        {
            if (_jointAddList.Count > 0)
            {
                foreach (Joint joint in _jointAddList)
                {
                    // Connect to the world list.
                    JointList.Add(joint);

                    // Connect to the bodies' doubly linked lists.
                    joint.BodyA.JointList.Add(joint);

                    // WIP David
                    if (!joint.IsFixedType())
                    {
                        joint.BodyB.JointList.Add(joint);

                        Body bodyA = joint.BodyA;
                        Body bodyB = joint.BodyB;

                        // If the joint prevents collisions, then flag any contacts for filtering.
                        if (joint.CollideConnected == false)
                        {
                            ContactEdge edge = bodyB.ContactList;
                            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;
                            }
                        }
                    }

                    if (JointAdded != null)
                    {
                        JointAdded(joint);
                    }

                    // Note: creating a joint doesn't wake the bodies.
                }

                _jointAddList.Clear();
            }
        }
示例#10
0
        /// <summary>
        /// Samples this animation and applies the result to the target joint list
        /// </summary>
        /// <param name="time"></param>
        /// <param name="targetJoints"></param>
        public void Sample(float time, JointList targetJoints)
        {
            if (_channels.Length == 0)
            {
                throw new ApplicationException("Animation contains no channels!");
            }

            foreach (var channel in _channels)
            {
                Joint target   = targetJoints[channel.Target.Index];
                var   keyframe = channel.Sampler.GetInterpolatedKeyframe(time);

                // TODO: Might be necessary to multiply keyframe transform rather than assign
                target.Transform = keyframe.Transform;
            }
        }
示例#11
0
 public virtual void Clear()
 {
     Header.ElementFormat.Ver      = 2.1f;
     Header.ElementFormat.UVACount = 0;
     ModelInfo.Clear();
     VertexList.Clear();
     FaceList.Clear();
     MaterialList.Clear();
     BoneList.Clear();
     MorphList.Clear();
     BodyList.Clear();
     JointList.Clear();
     SoftBodyList.Clear();
     InitializeSystemNode();
     FilePath     = "";
     LoadErrCount = 0;
 }
示例#12
0
        private void _Recur_SelectJointAndAllDescendants(Transform joint, bool select)
        {
            JointList extendedJoints = SMREditor.GetExtendedJoints();

            if (!extendedJoints.Contains(joint))
            {
                return;
            }

            if (select)
            {
                IncSelect(joint);
            }
            else
            {
                DecSelect(joint);
            }

            for (int idx = 0; idx < joint.childCount; ++idx)
            {
                Transform j = joint.GetChild(idx);
                _Recur_SelectJointAndAllDescendants(j, select);
            }
        }
        /// <summary>
        /// Create a joint to constrain bodies together. This may cause the connected bodies to cease colliding.
        /// Warning: This function is locked during callbacks.
        /// </summary>
        /// <param name="joint">The joint.</param>
        public void AddJoint(Joint joint)
        {
            Debug.Assert(!IsLocked);
            if (IsLocked)
            {
                return;
            }

            // Connect to the world list.
            JointList.Add(joint);

            // Connect to the bodies' doubly linked lists.
            joint.EdgeA.Joint = joint;
            joint.EdgeA.Other = joint.BodyB;
            joint.EdgeA.Prev  = null;
            joint.EdgeA.Next  = joint.BodyA.JointList;

            if (joint.BodyA.JointList != null)
            {
                joint.BodyA.JointList.Prev = joint.EdgeA;
            }

            joint.BodyA.JointList = joint.EdgeA;

            // WIP David
            if (!joint.IsFixedType())
            {
                joint.EdgeB.Joint = joint;
                joint.EdgeB.Other = joint.BodyA;
                joint.EdgeB.Prev  = null;
                joint.EdgeB.Next  = joint.BodyB.JointList;

                if (joint.BodyB.JointList != null)
                {
                    joint.BodyB.JointList.Prev = joint.EdgeB;
                }

                joint.BodyB.JointList = joint.EdgeB;
            }

            // WIP David
            if (!joint.IsFixedType())
            {
                Body bodyA = joint.BodyA;
                Body bodyB = joint.BodyB;

                // If the joint prevents collisions, then flag any contacts for filtering.
                if (joint.CollideConnected == false)
                {
                    ContactEdge edge = bodyB.ContactList;
                    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;
                    }
                }
            }

            if (JointAdded != null)
            {
                JointAdded(joint);
            }

            // Note: creating a joint doesn't wake the bodies.
        }
示例#14
0
        private void ProcessRemovedJoints()
        {
            if (_jointRemoveList.Count > 0)
            {
                foreach (Joint joint in _jointRemoveList)
                {
                    bool collideConnected = joint.CollideConnected;

                    // Remove from the world list.
                    JointList.Remove(joint);

                    // Disconnect from island graph.
                    Body bodyA = joint.BodyA;
                    Body bodyB = joint.BodyB;

                    // Wake up connected bodies.
                    bodyA.Awake = true;

                    // WIP David
                    if (!joint.IsFixedType())
                    {
                        bodyB.Awake = true;
                    }

                    // Remove from body 1.
                    bodyA.JointList.Remove(joint);

                    // WIP David
                    if (!joint.IsFixedType())
                    {
                        // Remove from body 2
                        bodyB.JointList.Remove(joint);
                    }

                    // WIP David
                    if (!joint.IsFixedType())
                    {
                        // If the joint prevents collisions, then flag any contacts for filtering.
                        if (collideConnected == false)
                        {
                            ContactEdge edge = bodyB.ContactList;
                            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;
                            }
                        }
                    }

                    if (JointRemoved != null)
                    {
                        JointRemoved(joint);
                    }
                }

                _jointRemoveList.Clear();
            }
        }
示例#15
0
 private void PhysicsConstructor(Vector2 gravity)
 {
     _rigidBodyList = new RigidBodyList();
     _arbiterList = new ArbiterList();
     _springList = new SpringList();
     _jointList = new JointList();
     _gravity = gravity;
 }
示例#16
0
        public virtual void FromStream(Stream s, bool id)
        {
            Action <Action> action = delegate(Action a)
            {
                try
                {
                    a();
                }
                catch (Exception)
                {
                    LoadErrCount++;
                }
            };
            PmxHeader head = new PmxHeader();

            head.FromStreamEx(s);
            Header.FromHeader(head);
            head.ElementFormat.WithID = id;
            action(delegate
            {
                ModelInfo.FromStreamEx(s, head.ElementFormat);
            });
            int count = 0;

            action(delegate
            {
                count = PmxStreamHelper.ReadElement_Int32(s);
            });
            VertexList.Clear();
            VertexList.Capacity = count;
            for (int k = 0; k < count; k++)
            {
                PmxVertex v = new PmxVertex();
                action(delegate
                {
                    v.FromStreamEx(s, head.ElementFormat);
                });
                VertexList.Add(v);
            }
            action(delegate
            {
                count = PmxStreamHelper.ReadElement_Int32(s);
            });
            FaceList.Clear();
            FaceList.Capacity = count;
            for (int l = 0; l < count; l++)
            {
                int ix = 0;
                action(delegate
                {
                    ix = PmxStreamHelper.ReadElement_Int32(s, head.ElementFormat.VertexSize, signed: false);
                });
                FaceList.Add(ix);
            }
            PmxTextureTable tx = new PmxTextureTable();

            action(delegate
            {
                tx.FromStreamEx(s, head.ElementFormat);
            });
            action(delegate
            {
                count = PmxStreamHelper.ReadElement_Int32(s);
            });
            MaterialList.Clear();
            MaterialList.Capacity = count;
            for (int m = 0; m < count; m++)
            {
                PmxMaterial j = new PmxMaterial();
                action(delegate
                {
                    j.FromStreamEx_TexTable(s, tx, head.ElementFormat);
                });
                MaterialList.Add(j);
            }
            action(delegate
            {
                count = PmxStreamHelper.ReadElement_Int32(s);
            });
            BoneList.Clear();
            BoneList.Capacity = count;
            for (int n = 0; n < count; n++)
            {
                PmxBone b = new PmxBone();
                action(delegate
                {
                    b.FromStreamEx(s, head.ElementFormat);
                });
                BoneList.Add(b);
            }
            action(delegate
            {
                count = PmxStreamHelper.ReadElement_Int32(s);
            });
            MorphList.Clear();
            MorphList.Capacity = count;
            for (int num = 0; num < count; num++)
            {
                PmxMorph morph = new PmxMorph();
                action(delegate
                {
                    morph.FromStreamEx(s, head.ElementFormat);
                });
                MorphList.Add(morph);
            }
            action(delegate
            {
                count = PmxStreamHelper.ReadElement_Int32(s);
            });
            NodeList.Clear();
            NodeList.Capacity = count;
            for (int num2 = 0; num2 < count; num2++)
            {
                PmxNode node = new PmxNode();
                action(delegate
                {
                    node.FromStreamEx(s, head.ElementFormat);
                });
                NodeList.Add(node);
                if (NodeList[num2].SystemNode)
                {
                    if (NodeList[num2].Name == "Root")
                    {
                        RootNode = NodeList[num2];
                    }
                    else if (NodeList[num2].Name == "表情")
                    {
                        ExpNode = NodeList[num2];
                    }
                }
            }
            action(delegate
            {
                count = PmxStreamHelper.ReadElement_Int32(s);
            });
            BodyList.Clear();
            BodyList.Capacity = count;
            for (int num3 = 0; num3 < count; num3++)
            {
                PmxBody b2 = new PmxBody();
                action(delegate
                {
                    b2.FromStreamEx(s, head.ElementFormat);
                });
                BodyList.Add(b2);
            }
            action(delegate
            {
                count = PmxStreamHelper.ReadElement_Int32(s);
            });
            JointList.Clear();
            JointList.Capacity = count;
            for (int num4 = 0; num4 < count; num4++)
            {
                PmxJoint i = new PmxJoint();
                action(delegate
                {
                    i.FromStreamEx(s, head.ElementFormat);
                });
                JointList.Add(i);
            }
            if (head.Ver >= 2.1f)
            {
                action(delegate
                {
                    count = PmxStreamHelper.ReadElement_Int32(s);
                });
                SoftBodyList.Clear();
                SoftBodyList.Capacity = count;
                for (int num5 = 0; num5 < count; num5++)
                {
                    PmxSoftBody b3 = new PmxSoftBody();
                    action(delegate
                    {
                        b3.FromStreamEx(s, head.ElementFormat);
                    });
                    SoftBodyList.Add(b3);
                }
            }
            if (id)
            {
                action(delegate
                {
                    FilePath = PmxStreamHelper.ReadString(s, head.ElementFormat);
                });
            }
            head.ElementFormat.WithID = false;
        }
示例#17
0
        public void FromPmx(Pmx pmx)
        {
            Clear();
            FilePath     = pmx.FilePath;
            LoadErrCount = pmx.LoadErrCount;
            Header       = pmx.Header.Clone();
            ModelInfo    = pmx.ModelInfo.Clone();
            int count = pmx.VertexList.Count;

            VertexList.Capacity = count;
            for (int i = 0; i < count; i++)
            {
                VertexList.Add(pmx.VertexList[i].Clone());
            }
            count             = pmx.FaceList.Count;
            FaceList.Capacity = count;
            for (int j = 0; j < count; j++)
            {
                FaceList.Add(pmx.FaceList[j]);
            }
            count = pmx.MaterialList.Count;
            MaterialList.Capacity = count;
            for (int k = 0; k < count; k++)
            {
                MaterialList.Add(pmx.MaterialList[k].Clone());
            }
            count             = pmx.BoneList.Count;
            BoneList.Capacity = count;
            for (int l = 0; l < count; l++)
            {
                BoneList.Add(pmx.BoneList[l].Clone());
            }
            count = pmx.MorphList.Count;
            MorphList.Capacity = count;
            for (int m = 0; m < count; m++)
            {
                MorphList.Add(pmx.MorphList[m].Clone());
            }
            count = pmx.NodeList.Count;
            NodeList.Clear();
            NodeList.Capacity = count;
            for (int n = 0; n < count; n++)
            {
                NodeList.Add(pmx.NodeList[n].Clone());
                if (NodeList[n].SystemNode)
                {
                    if (NodeList[n].Name == "Root")
                    {
                        RootNode = NodeList[n];
                    }
                    else if (NodeList[n].Name == "表情")
                    {
                        ExpNode = NodeList[n];
                    }
                }
            }
            count             = pmx.BodyList.Count;
            BodyList.Capacity = count;
            for (int num = 0; num < count; num++)
            {
                BodyList.Add(pmx.BodyList[num].Clone());
            }
            count = pmx.JointList.Count;
            JointList.Capacity = count;
            for (int num2 = 0; num2 < count; num2++)
            {
                JointList.Add(pmx.JointList[num2].Clone());
            }
            count = pmx.SoftBodyList.Count;
            SoftBodyList.Capacity = count;
            for (int num3 = 0; num3 < count; num3++)
            {
                SoftBodyList.Add(pmx.SoftBodyList[num3].Clone());
            }
        }
示例#18
0
        private void ConstructPhysicsSimulator(Vector2 gravity)
        {
            geomList = new GeomList();
            geomAddList = new List<Geom>();
            geomRemoveList = new List<Geom>();

            bodyList = new BodyList();
            bodyAddList = new List<Body>();
            bodyRemoveList = new List<Body>();

            controllerList = new ControllerList();
            controllerAddList = new List<Controller>();
            controllerRemoveList = new List<Controller>();

            jointList = new JointList();
            jointAddList = new List<Joint>();
            jointRemoveList = new List<Joint>();

            springList = new SpringList();
            springAddList = new List<Spring>();
            springRemoveList = new List<Spring>();

            _broadPhaseCollider = new SelectiveSweepCollider(this);

            arbiterList = new ArbiterList();
            _gravity = gravity;

            arbiterPool = new Pool<Arbiter>(_arbiterPoolSize);

            #region Added by Daniel Pramel 08/17/08

            _inactivityController = new InactivityController(this);

            _scaling = new Scaling(0.001f, 0.01f);

            #endregion
        }
示例#19
0
        private void ProcessRemovedJoints()
        {
            if (_jointRemoveList.Count > 0)
            {
                foreach (var joint in _jointRemoveList)
                {
                    var collideConnected = joint.CollideConnected;

                    // Remove from the world list.
                    JointList.Remove(joint);

                    // Disconnect from island graph.
                    var bodyA = joint.BodyA;
                    var bodyB = joint.BodyB;

                    // Wake up connected bodies.
                    bodyA.Awake = true;

                    // WIP David
                    if (!joint.IsFixedType())
                    {
                        bodyB.Awake = true;
                    }

                    // Remove from body 1.
                    if (joint.EdgeA.Prev != null)
                    {
                        joint.EdgeA.Prev.Next = joint.EdgeA.Next;
                    }

                    if (joint.EdgeA.Next != null)
                    {
                        joint.EdgeA.Next.Prev = joint.EdgeA.Prev;
                    }

                    if (joint.EdgeA == bodyA.JointList)
                    {
                        bodyA.JointList = joint.EdgeA.Next;
                    }

                    joint.EdgeA.Prev = null;
                    joint.EdgeA.Next = null;

                    // WIP David
                    if (!joint.IsFixedType())
                    {
                        // Remove from body 2
                        if (joint.EdgeB.Prev != null)
                        {
                            joint.EdgeB.Prev.Next = joint.EdgeB.Next;
                        }

                        if (joint.EdgeB.Next != null)
                        {
                            joint.EdgeB.Next.Prev = joint.EdgeB.Prev;
                        }

                        if (joint.EdgeB == bodyB.JointList)
                        {
                            bodyB.JointList = joint.EdgeB.Next;
                        }

                        joint.EdgeB.Prev = null;
                        joint.EdgeB.Next = null;

                        // If the joint prevents collisions, then flag any contacts for filtering.
                        if (collideConnected == false)
                        {
                            var edge = bodyB.ContactList;
                            while (edge != null)
                            {
                                if (edge.Other == bodyA)
                                {
                                    // Flag the contact for filtering at the next time step (where either
                                    // body is awake).
                                    edge.Contact._flags |= ContactFlags.FilterFlag;
                                }

                                edge = edge.Next;
                            }
                        }
                    }

                    JointRemoved?.Invoke(joint);
                }

                _jointRemoveList.Clear();
            }
        }
        /// <summary>
        /// Processes the added geometries, springs, joints, bodies and controllers.
        /// </summary>
        private void ProcessAddedItems()
        {
            //Add any new geometries
            _tempCount = _geomAddList.Count;
            for (int i = 0; i < _tempCount; i++)
            {
                if (!GeomList.Contains(_geomAddList[i]))
                {
                    _geomAddList[i].InSimulation = true;
                    GeomList.Add(_geomAddList[i]);

                    //Add the new geometry to the broad phase collider.
                    _broadPhaseCollider.Add(_geomAddList[i]);
                }
            }
            _geomAddList.Clear();

            //Add any new bodies
            _tempCount = _bodyAddList.Count;
            for (int i = 0; i < _tempCount; i++)
            {
                if (!BodyList.Contains(_bodyAddList[i]))
                {
                    BodyList.Add(_bodyAddList[i]);
                }
            }
            _bodyAddList.Clear();

            //Add any new controllers
            _tempCount = _controllerAddList.Count;
            for (int i = 0; i < _tempCount; i++)
            {
                if (!ControllerList.Contains(_controllerAddList[i]))
                {
                    ControllerList.Add(_controllerAddList[i]);
                }
            }
            _controllerAddList.Clear();

            //Add any new joints
            _tempCount = _jointAddList.Count;
            for (int i = 0; i < _tempCount; i++)
            {
                if (!JointList.Contains(_jointAddList[i]))
                {
                    JointList.Add(_jointAddList[i]);
                }
            }
            _jointAddList.Clear();

            //Add any new springs
            _tempCount = _springAddList.Count;
            for (int i = 0; i < _tempCount; i++)
            {
                if (!SpringList.Contains(_springAddList[i]))
                {
                    SpringList.Add(_springAddList[i]);
                }
            }
            _springAddList.Clear();
        }
        /// <summary>
        /// Processes the removed geometries (and their arbiters), bodies, controllers, joints and springs.
        /// </summary>
        private void ProcessRemovedItems()
        {
            //Remove any new geometries
            _tempCount = _geomRemoveList.Count;
            for (int i = 0; i < _tempCount; i++)
            {
                _geomRemoveList[i].InSimulation = false;
                GeomList.Remove(_geomRemoveList[i]);

                //Remove any arbiters associated with the geometries being removed
                for (int j = ArbiterList.Count; j > 0; j--)
                {
                    if (ArbiterList[j - 1].GeometryA == _geomRemoveList[i] ||
                        ArbiterList[j - 1].GeometryB == _geomRemoveList[i])
                    {
                        //TODO: Should we create a RemoveComplete method and remove all Contacts associated
                        //with the arbiter?
                        arbiterPool.Insert(ArbiterList[j - 1]);
                        ArbiterList.Remove(ArbiterList[j - 1]);
                    }
                }
            }

            if (_geomRemoveList.Count > 0)
            {
                _broadPhaseCollider.ProcessRemovedGeoms();
            }

            _geomRemoveList.Clear();

            //Remove any new bodies
            _tempCount = _bodyRemoveList.Count;
            for (int i = 0; i < _tempCount; i++)
            {
                BodyList.Remove(_bodyRemoveList[i]);
            }
            _bodyRemoveList.Clear();

            //Remove any new controllers
            _tempCount = _controllerRemoveList.Count;
            for (int i = 0; i < _tempCount; i++)
            {
                ControllerList.Remove(_controllerRemoveList[i]);
            }
            _controllerRemoveList.Clear();

            //Remove any new joints
            int jointRemoveCount = _jointRemoveList.Count;

            for (int i = 0; i < jointRemoveCount; i++)
            {
                JointList.Remove(_jointRemoveList[i]);
            }
            _jointRemoveList.Clear();

            //Remove any new springs
            _tempCount = _springRemoveList.Count;
            for (int i = 0; i < _tempCount; i++)
            {
                SpringList.Remove(_springRemoveList[i]);
            }
            _springRemoveList.Clear();
        }
示例#22
0
        private void ProcessAddedJoints()
        {
            if (_jointAddList.Count > 0)
            {
                foreach (var joint in _jointAddList)
                {
                    // Connect to the world list.
                    JointList.Add(joint);

                    // Connect to the bodies' doubly linked lists.
                    joint.EdgeA.Joint = joint;
                    joint.EdgeA.Other = joint.BodyB;
                    joint.EdgeA.Prev  = null;
                    joint.EdgeA.Next  = joint.BodyA.JointList;

                    if (joint.BodyA.JointList != null)
                    {
                        joint.BodyA.JointList.Prev = joint.EdgeA;
                    }

                    joint.BodyA.JointList = joint.EdgeA;

                    // WIP David
                    if (!joint.IsFixedType())
                    {
                        joint.EdgeB.Joint = joint;
                        joint.EdgeB.Other = joint.BodyA;
                        joint.EdgeB.Prev  = null;
                        joint.EdgeB.Next  = joint.BodyB.JointList;

                        if (joint.BodyB.JointList != null)
                        {
                            joint.BodyB.JointList.Prev = joint.EdgeB;
                        }

                        joint.BodyB.JointList = joint.EdgeB;

                        var bodyA = joint.BodyA;
                        var bodyB = joint.BodyB;

                        // If the joint prevents collisions, then flag any contacts for filtering.
                        if (joint.CollideConnected == false)
                        {
                            var edge = bodyB.ContactList;
                            while (edge != null)
                            {
                                if (edge.Other == bodyA)
                                {
                                    // Flag the contact for filtering at the next time step (where either
                                    // body is awake).
                                    edge.Contact._flags |= ContactFlags.FilterFlag;
                                }

                                edge = edge.Next;
                            }
                        }
                    }

                    JointAdded?.Invoke(joint);

                    // Note: creating a joint doesn't wake the bodies.
                }

                _jointAddList.Clear();
            }
        }
        /// <summary>
        /// Destroy a joint. This may cause the connected bodies to begin colliding.
        /// Warning: This function is locked during callbacks.
        /// </summary>
        /// <param name="joint">The joint.</param>
        public void RemoveJoint(Joint joint)
        {
            Debug.Assert(!IsLocked);
            if (IsLocked)
            {
                return;
            }

            bool collideConnected = joint.CollideConnected;

            // Remove from the world list.
            JointList.Remove(joint);

            // Disconnect from island graph.
            Body bodyA = joint.BodyA;
            Body bodyB = joint.BodyB;

            // Wake up connected bodies.
            bodyA.Awake = true;

            // WIP David
            if (!joint.IsFixedType())
            {
                bodyB.Awake = true;
            }

            // Remove from body 1.
            if (joint.EdgeA.Prev != null)
            {
                joint.EdgeA.Prev.Next = joint.EdgeA.Next;
            }

            if (joint.EdgeA.Next != null)
            {
                joint.EdgeA.Next.Prev = joint.EdgeA.Prev;
            }

            if (joint.EdgeA == bodyA.JointList)
            {
                bodyA.JointList = joint.EdgeA.Next;
            }

            joint.EdgeA.Prev = null;
            joint.EdgeA.Next = null;

            // WIP David
            if (!joint.IsFixedType())
            {
                // Remove from body 2
                if (joint.EdgeB.Prev != null)
                {
                    joint.EdgeB.Prev.Next = joint.EdgeB.Next;
                }

                if (joint.EdgeB.Next != null)
                {
                    joint.EdgeB.Next.Prev = joint.EdgeB.Prev;
                }

                if (joint.EdgeB == bodyB.JointList)
                {
                    bodyB.JointList = joint.EdgeB.Next;
                }

                joint.EdgeB.Prev = null;
                joint.EdgeB.Next = null;
            }

            // WIP David
            if (!joint.IsFixedType())
            {
                // If the joint prevents collisions, then flag any contacts for filtering.
                if (collideConnected == false)
                {
                    ContactEdge edge = bodyB.ContactList;
                    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;
                    }
                }
            }

            if (JointRemoved != null)
            {
                JointRemoved(joint);
            }
        }