Пример #1
0
        private void FillHash()
        {
            //Average used to optimize cell size if AutoAdjustCellSize = true.
            float average = 0;

            for (int i = 0; i < _physicsSimulator.GeomList.Count; i++)
            {
                Geom geom = _physicsSimulator.GeomList[i];

                //Note: Could do some checking here for geometries that should not be included in the hashmap

                AABB aabb = geom.AABB;

                if (AutoAdjustCellSize)
                {
                    average += Math.Max(aabb.Max.X - aabb.Min.X, aabb.Max.Y - aabb.Min.Y);
                }

                int minX = (int)(aabb.Min.X * _cellSizeInv);
                int maxX = (int)(aabb.Max.X * _cellSizeInv) + 1;
                int minY = (int)(aabb.Min.Y * _cellSizeInv);
                int maxY = (int)(aabb.Max.Y * _cellSizeInv) + 1;

                for (int x = minX; x < maxX; x++)
                {
                    for (int y = minY; y < maxY; y++)
                    {
                        long        key = PairID.GetHash(x, y);
                        List <Geom> list;
                        if (!_hash.TryGetValue(key, out list))
                        {
                            list = new List <Geom>();
                            _hash.Add(key, list);
                        }
                        list.Add(geom);
                    }
                }
            }

            if (AutoAdjustCellSize)
            {
                CellSize = 2 * average / (_physicsSimulator.GeomList.Count);
            }
        }
Пример #2
0
        private void RunHash()
        {
            _keysToRemove.Clear();
            foreach (KeyValuePair <long, List <Geom> > pair in _hash)
            {
                // If there are no geometries in the list. Remove it.
                // If there are any geometries in the list, process them.
                List <Geom> list = pair.Value;
                if (list.Count == 0)
                {
                    _keysToRemove.Add(pair.Key);
                }
                else
                {
                    for (int i = 0; i < list.Count - 1; i++)
                    {
                        Geom geometryA = list[i];
                        for (int j = i + 1; j < list.Count; j++)
                        {
                            Geom geometryB = list[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;
                            }

                            long key = PairID.GetId(geometryA.id, geometryB.id);
                            if (!_filter.ContainsKey(key))
                            {
                                _filter.Add(key, null);

                                //Check if there is intersection
                                bool intersection = AABB.Intersect(ref geometryA.AABB, ref geometryB.AABB);

                                //User can cancel collision
                                if (OnBroadPhaseCollision != null)
                                {
                                    intersection = OnBroadPhaseCollision(geometryA, geometryB);
                                }

                                if (!intersection)
                                {
                                    continue;
                                }

                                _physicsSimulator.ArbiterList.AddArbiterForGeomPair(_physicsSimulator, geometryA, geometryB);
                            }
                        }
                    }
                    list.Clear();
                }
            }
            _filter.Clear();

            //Remove all the empty lists from the hash
            for (int index = 0; index < _keysToRemove.Count; ++index)
            {
                _hash.Remove(_keysToRemove[index]);
            }
        }