Beispiel #1
0
        private void OnCollision(Geom geom1, Geom geom2)
        {
            if (!geom1.body.Enabled || !geom2.body.Enabled)
            {
                return;
            }

            if ((geom1.collisionGroup == geom2.collisionGroup) &&
                geom1.collisionGroup != 0 && geom2.collisionGroup != 0)
            {
                return;
            }

            if (!geom1.collisionEnabled || !geom2.collisionEnabled)
            {
                return;
            }

            if (geom1.body.isStatic && geom2.body.isStatic)
            {
                return;
            }

            if (geom1.body == geom2.body)
            {
                return;
            }

            if (((geom1.collisionCategories & geom2.collidesWith) ==
                 CollisionCategory.None) & ((geom2.collisionCategories &
                                             geom1.collidesWith) == CollisionCategory.None))
            {
                return;
            }

            Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch();

            arbiter.ConstructArbiter(geom1, geom2, _physicsSimulator);

            //TODO: Since we insert all arbiters that is already in the arbiterList into the pool
            //should we not restrict the size of the pool to a fixed number? A large simulation
            //that runs for some time might accumulate A LOT of arbiters in the pool.
            if (!_physicsSimulator.arbiterList.Contains(arbiter))
            {
                _physicsSimulator.arbiterList.Add(arbiter);
            }
            else
            {
                _physicsSimulator.arbiterPool.Insert(arbiter);
            }
        }
        private void OnCollision(Geom geom1, Geom geom2)
        {
            if (!geom1.body.enabled || !geom2.body.enabled)
            {
                return;
            }

            if ((geom1.collisionGroup == geom2.collisionGroup) &&
                geom1.collisionGroup != 0 &&
                geom2.collisionGroup != 0)
            {
                return;
            }

            if (!geom1.collisionEnabled || !geom2.collisionEnabled)
            {
                return;
            }

            if (geom1.body.isStatic && geom2.body.isStatic)
            {
                //don't collide two static bodies
                return;
            }

            if (((geom1.collisionCategories & geom2.collidesWith) == CollisionCategories.None) &
                ((geom2.collisionCategories & geom1.collidesWith) == CollisionCategories.None))
            {
                return;
            }

            Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch();

            arbiter.ConstructArbiter(geom1, geom2, _physicsSimulator);

            if (!_physicsSimulator.arbiterList.Contains(arbiter))
            {
                _physicsSimulator.arbiterList.Add(arbiter);
            }
            else
            {
                _physicsSimulator.arbiterPool.Release(arbiter);
            }
        }
        /// <summary>
        /// Iterates over the collision pairs and creates arbiters.
        /// </summary>
        private void HandleCollisions()
        {
            foreach (CollisionPair cp in collisionPairs.Keys)
            {
                // Note: Possible optimization. Maybe arbiter can be cached into value of
                // collisionPairs? Currently, the collisionPairs hash doesn't use its
                // value parameter - its just an unused bool value.
                Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch();
                arbiter.ConstructArbiter(cp.geom1, cp.geom2, _physicsSimulator);

                if (!_physicsSimulator.arbiterList.Contains(arbiter))
                {
                    _physicsSimulator.arbiterList.Add(arbiter);
                }
                else
                {
                    _physicsSimulator.arbiterPool.Release(arbiter);
                }
            }
        }
Beispiel #4
0
        private void DoCollision()
        {
            //Iterate all the geoms and check against the next
            for (int i = 0; i < _physicsSimulator.geomList.Count - 1; i++)
            {
                for (int j = i + 1; j < _physicsSimulator.geomList.Count; j++)
                {
                    _geometryA = _physicsSimulator.geomList[i];
                    _geometryB = _physicsSimulator.geomList[j];

                    if (!_geometryA.body.Enabled || !_geometryB.body.Enabled)
                    {
                        continue;
                    }

                    if ((_geometryA.collisionGroup == _geometryB.collisionGroup) &&
                        _geometryA.collisionGroup != 0 && _geometryB.collisionGroup != 0)
                    {
                        continue;
                    }

                    if (!_geometryA.collisionEnabled || !_geometryB.collisionEnabled)
                    {
                        continue;
                    }

                    if (_geometryA.body.isStatic && _geometryB.body.isStatic)
                    {
                        continue;
                    }

                    if (_geometryA.body == _geometryB.body)
                    {
                        continue;
                    }

                    if (((_geometryA.CollisionCategories & _geometryB.CollidesWith) == CollisionCategory.None) &
                        ((_geometryB.CollisionCategories & _geometryA.CollidesWith) == CollisionCategory.None))
                    {
                        continue;
                    }

                    //Assume intersection
                    bool intersection = true;

                    #region INLINE: if (AABB.Intersect(_geometryA.aabb, _geometryB.aabb)) ....

                    //Check if there is no intersection
                    if (_geometryA.AABB.min.X > _geometryB.AABB.max.X || _geometryB.AABB.min.X > _geometryA.AABB.max.X)
                    {
                        intersection = false;
                    }
                    else if (_geometryA.AABB.min.Y > _geometryB.AABB.Max.Y ||
                             _geometryB.AABB.min.Y > _geometryA.AABB.Max.Y)
                    {
                        intersection = false;
                    }

                    #endregion

                    //Call the OnBroadPhaseCollision event first. If the user aborts the collision
                    //it will not create an arbiter

                    if (OnBroadPhaseCollision != null)
                    {
                        intersection = OnBroadPhaseCollision(_geometryA, _geometryB);
                    }

                    //If the user aborted the intersection, continue to the next geometry.
                    if (!intersection)
                    {
                        continue;
                    }

                    //Note: Commented this out and copy-paste into from other colliders
                    //_arbiter = _physicsSimulator.arbiterPool.Fetch();
                    //_arbiter.ConstructArbiter(_geometryA, _geometryB, _physicsSimulator);

                    //if (_physicsSimulator.arbiterList.Contains(_arbiter))
                    //{
                    //    _physicsSimulator.arbiterPool.Insert(_arbiter);
                    //}
                    //else
                    //{
                    //    _physicsSimulator.arbiterList.Add(_arbiter);
                    //}

                    Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch();
                    arbiter.ConstructArbiter(_geometryA, _geometryB, _physicsSimulator);

                    if (!_physicsSimulator.arbiterList.Contains(arbiter))
                    {
                        _physicsSimulator.arbiterList.Add(arbiter);
                    }
                    else
                    {
                        _physicsSimulator.arbiterPool.Insert(arbiter);
                    }
                }
            }
        }
        /// <summary>
        /// Updates this instance.
        /// </summary>
        public void Update()
        {
            //Iterate all the geoms and check against the next
            for (int i = 0; i < _physicsSimulator.GeomList.Count - 1; i++)
            {
                for (int j = i + 1; j < _physicsSimulator.GeomList.Count; j++)
                {
                    _geometryA = _physicsSimulator.GeomList[i];
                    _geometryB = _physicsSimulator.GeomList[j];

                    if (!_geometryA.body.Enabled || !_geometryB.body.Enabled)
                    {
                        continue;
                    }

                    if ((_geometryA.CollisionGroup == _geometryB.CollisionGroup) &&
                        _geometryA.CollisionGroup != 0 && _geometryB.CollisionGroup != 0)
                    {
                        continue;
                    }

                    if (!_geometryA.CollisionEnabled || !_geometryB.CollisionEnabled)
                    {
                        continue;
                    }

                    if (_geometryA.body.isStatic && _geometryB.body.isStatic)
                    {
                        continue;
                    }

                    if (_geometryA.body == _geometryB.body)
                    {
                        continue;
                    }

                    if (((_geometryA.CollisionCategories & _geometryB.CollidesWith) == CollisionCategory.None) &
                        ((_geometryB.CollisionCategories & _geometryA.CollidesWith) == CollisionCategory.None))
                    {
                        continue;
                    }

                    if (_geometryA.IsGeometryIgnored(_geometryB) || _geometryB.IsGeometryIgnored(_geometryA))
                    {
                        continue;
                    }

                    //Assume intersection
                    bool intersection = true;

                    //Check if there is no intersection
                    if (_geometryA.AABB.min.X > _geometryB.AABB.max.X || _geometryB.AABB.min.X > _geometryA.AABB.max.X)
                    {
                        intersection = false;
                    }
                    else if (_geometryA.AABB.min.Y > _geometryB.AABB.Max.Y || _geometryB.AABB.min.Y > _geometryA.AABB.Max.Y)
                    {
                        intersection = false;
                    }

                    //Call the OnBroadPhaseCollision event first. If the user aborts the collision
                    //it will not create an arbiter
                    if (OnBroadPhaseCollision != null)
                    {
                        intersection = OnBroadPhaseCollision(_geometryA, _geometryB);
                    }

                    //If the user aborted the intersection, continue to the next geometry.
                    if (!intersection)
                    {
                        continue;
                    }

                    Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch();
                    arbiter.ConstructArbiter(_geometryA, _geometryB, _physicsSimulator);

                    if (!_physicsSimulator.ArbiterList.Contains(arbiter))
                    {
                        _physicsSimulator.ArbiterList.Add(arbiter);
                    }
                    else
                    {
                        _physicsSimulator.arbiterPool.Insert(arbiter);
                    }
                }
            }
        }
Beispiel #6
0
        private void DoCollision()
        {
            for (int i = 0; i < _physicsSimulator.geomList.Count - 1; i++)
            {
                for (int j = i + 1; j < _physicsSimulator.geomList.Count; j++)
                {
                    _geometryA = _physicsSimulator.geomList[i];
                    _geometryB = _physicsSimulator.geomList[j];
                    //possible early exits
                    if (!_geometryA.Body.enabled || !_geometryB.Body.enabled)
                    {
                        continue;
                    }

                    if ((_geometryA.CollisionGroup == _geometryB.CollisionGroup) && _geometryA.CollisionGroup != 0 &&
                        _geometryB.CollisionGroup != 0)
                    {
                        continue;
                    }

                    if (!_geometryA.CollisionEnabled || !_geometryB.CollisionEnabled)
                    {
                        continue;
                    }

                    if (_geometryA.Body.isStatic && _geometryB.Body.isStatic)
                    {
                        //don't collide two static bodies
                        continue;
                    }

                    if (_geometryA.Body == _geometryB.Body)
                    {
                        //don't collide two geometries connected to the same body
                        continue;
                    }

                    if (((_geometryA.CollisionCategories & _geometryB.CollidesWith) == CollisionCategories.None) &
                        ((_geometryB.CollisionCategories & _geometryA.CollidesWith) == CollisionCategories.None))
                    {
                        continue;
                    }

                    bool intersection = true;

                    #region INLINE: if (AABB.Intersect(_geometryA.aabb, _geometryB.aabb)) ....

                    if (_geometryA.AABB.min.X > _geometryB.AABB.max.X || _geometryB.AABB.min.X > _geometryA.AABB.max.X)
                    {
                        intersection = false;
                    }
                    else if (_geometryA.AABB.min.Y > _geometryB.AABB.Max.Y ||
                             _geometryB.AABB.min.Y > _geometryA.AABB.Max.Y)
                    {
                        intersection = false;
                    }

                    #endregion

                    if (intersection)
                    {
                        _arbiter = _physicsSimulator.arbiterPool.Fetch();
                        _arbiter.ConstructArbiter(_geometryA, _geometryB, _physicsSimulator);

                        if (!_physicsSimulator.arbiterList.Contains(_arbiter))
                        {
                            _physicsSimulator.arbiterList.Add(_arbiter);
                        }
                        else
                        {
                            _physicsSimulator.arbiterPool.Release(_arbiter);
                        }
                    }
                }
            }
        }