Ejemplo n.º 1
0
        public static FarPosition GetSubCellCoordinatesFromId(ulong id)
        {
            int x, y;

            BitwiseMagic.Unpack(id, out x, out y);
            return(new FarPosition(x << SubCellSizeShiftAmount, y << SubCellSizeShiftAmount));
        }
Ejemplo n.º 2
0
        public void OnUpdate(Update message)
        {
            foreach (var info in _newCollisions)
            {
                // Check if we already have contact between the two entities.
                ActiveCollisionInfo active;
                if (_activeCollisions.TryGetValue(info.Key, out active))
                {
                    // Yes, just update the number of fixture contacts.
                    active.Count += info.Value.Count;
                }
                else
                {
                    // Nothing yet, save the contact and apply effects.
                    if (info.Value.Count > 0)
                    {
                        active = new ActiveCollisionInfo {
                            Count = info.Value.Count
                        };
                        _activeCollisions.Add(info.Key, active);
                    }

                    int entityA, entityB;
                    BitwiseMagic.Unpack(info.Key, out entityA, out entityB);

                    OnEntityContact(entityA, entityB, info.Value.IsShieldA, info.Value.Normal);
                    OnEntityContact(entityB, entityA, info.Value.IsShieldB, -info.Value.Normal);
                }
            }
            _newCollisions.Clear();
        }
Ejemplo n.º 3
0
        public void OnDraw(Draw message)
        {
            if (!Enabled)
            {
                return;
            }

            var camera = (CameraSystem)Manager.GetSystem(CameraSystem.TypeId);

            // Get camera transform.
            var cameraTransform   = camera.Transform;
            var cameraTranslation = camera.Translation;
            var interpolation     = (InterpolationSystem)Manager.GetSystem(InterpolationSystem.TypeId);

            // Iterate over all visible entities.
            _spriteBatch.Begin(
                SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, cameraTransform);
            foreach (var entity in camera.VisibleEntities)
            {
                var transform = (ITransform)Manager.GetComponent(entity, TransformTypeId);
                if (transform != null)
                {
                    int x, y, subX, subY;
                    BitwiseMagic.Unpack(CellSystem.GetCellIdFromCoordinates(transform.Position), out x, out y);
                    BitwiseMagic.Unpack(CellSystem.GetSubCellIdFromCoordinates(transform.Position), out subX, out subY);
                    var text = string.Format(
                        "ID: {0} @ {1} / {2}\nCell: {3}:{4}, SubCell: {5}:{6}",
                        transform.Entity,
                        transform.Position,
                        transform.Angle,
                        x,
                        y,
                        subX,
                        subY);

                    FarPosition position;
                    float       angle;
                    interpolation.GetInterpolatedTransform(transform.Entity, out position, out angle);
                    position = FarUnitConversion.ToScreenUnits(position + cameraTranslation);
                    _spriteBatch.DrawString(
                        _font,
                        text,
                        (Vector2)position,
                        Color.White,
                        0,
                        Vector2.Zero,
                        1f / camera.CameraZoom,
                        SpriteEffects.None,
                        1);
                }
            }
            _spriteBatch.End();
        }
Ejemplo n.º 4
0
        /// <summary>
        ///     A utility enumerator allowing the iteration over all trees in the index. This also yields the position for
        ///     each tree.
        /// </summary>
        /// <returns>An enumerator over all trees in the index.</returns>
        /// <remarks>This is mainly intended for debugging purposes, to allow rendering the tree bounds.</remarks>
        public IEnumerable <Tuple <TPoint, Collections.DynamicQuadTree <T> > > GetTreeEnumerable()
        {
            foreach (var entry in _cells)
            {
                int segmentX, segmentY;
                BitwiseMagic.Unpack(entry.Key, out segmentX, out segmentY);

                TPoint center;
                center.X = segmentX * CellSize;
                center.Y = segmentY * CellSize;
                yield return(Tuple.Create(center, entry.Value));
            }
        }
Ejemplo n.º 5
0
        private void UpdateCellState(long frame, bool isSubCell, int size, ISet <ulong> living, IDictionary <ulong, long> pending)
        {
            // Check the positions of all avatars to check which cells
            // should live, and which should die / stay dead.
            var avatarSystem = (AvatarSystem)Manager.GetSystem(AvatarSystem.TypeId);

            foreach (var avatar in avatarSystem.Avatars)
            {
                var transform = (ITransform)Manager.GetComponent(avatar, TransformTypeId);
                int x, y;
                if (isSubCell)
                {
                    BitwiseMagic.Unpack(GetSubCellIdFromCoordinates(transform.Position), out x, out y);
                }
                else
                {
                    BitwiseMagic.Unpack(GetCellIdFromCoordinates(transform.Position), out x, out y);
                }
                AddCellAndNeighbors(x, y, _reusableNewCellIds);
            }

            // Get the cells that became alive, notify systems and components.
            _reusableBornCellsIds.UnionWith(_reusableNewCellIds);
            _reusableBornCellsIds.ExceptWith(living);
            CellStateChanged changedMessage;

            changedMessage.IsSubCell = isSubCell;
            foreach (var cellId in _reusableBornCellsIds)
            {
                // If its in there, remove it from the pending list.
                if (!pending.Remove(cellId))
                {
                    // Notify if cell wasn't alive already.
                    changedMessage.Id = cellId;
                    BitwiseMagic.Unpack(cellId, out changedMessage.X, out changedMessage.Y);
                    changedMessage.IsActive = true;
                    Manager.SendMessage(changedMessage);
                }
            }
            _reusableBornCellsIds.Clear();

            // Check pending list, kill off old cells, notify systems etc.
            var cellDeathIndex = ((IndexSystem)Manager.GetSystem(IndexSystem.TypeId))[CellDeathAutoRemoveIndexId];

            _reusablePendingList.AddRange(pending.Keys);
            foreach (var cellId in _reusablePendingList)
            {
                // Are we still delaying?
                if (frame - pending[cellId] <= CellDeathDelay)
                {
                    continue;
                }

                // Timed out, kill it for good.
                pending.Remove(cellId);

                int x, y;
                BitwiseMagic.Unpack(cellId, out x, out y);

                // Notify.
                changedMessage.Id       = cellId;
                changedMessage.X        = x;
                changedMessage.Y        = y;
                changedMessage.IsActive = false;
                Manager.SendMessage(changedMessage);

                // Kill any remaining entities in the area covered by the
                // cell that just died.
                FarRectangle cellBounds;
                cellBounds.X      = x * size;
                cellBounds.Y      = y * size;
                cellBounds.Width  = size;
                cellBounds.Height = size;
                cellDeathIndex.Find(cellBounds, _reusableComponentList);
                foreach (IIndexable neighbor in _reusableComponentList.Select(Manager.GetComponentById))
                {
                    var cellDeath = (CellDeath)Manager.GetComponent(neighbor.Entity, CellDeath.TypeId);
                    if (cellDeath.IsForSubCell == isSubCell)
                    {
                        Manager.RemoveEntity(neighbor.Entity);
                    }
                }
                _reusableComponentList.Clear();
            }
            _reusablePendingList.Clear();

            // Get the cells that died, put to pending list.
            _reusableDeceasedCellsIds.UnionWith(living);
            _reusableDeceasedCellsIds.ExceptWith(_reusableNewCellIds);
            foreach (var cellId in _reusableDeceasedCellsIds)
            {
                // Add it to the pending list.
                pending.Add(cellId, frame);
            }
            _reusableDeceasedCellsIds.Clear();

            living.Clear();
            living.UnionWith(_reusableNewCellIds);

            _reusableNewCellIds.Clear();
        }