示例#1
0
        public VoxelPhysicsHeapElement Put(VoxelPhysicsHeapElement element)
        {
            var indexCopy = _index;

            if (indexCopy >= _capacity)
            {
                var capacityCopy   = _capacity;
                var doubleCapacity = capacityCopy * 2;
                var extendedNodes  = new VoxelPhysicsHeapElement[doubleCapacity];
                Array.Copy(_nodes, extendedNodes, capacityCopy);

                _capacity = doubleCapacity;
                _nodes    = extendedNodes;
            }

            var k = indexCopy;

            element.index     = indexCopy;
            _nodes[indexCopy] = element;

            _index++;

            while (k > 0)
            {
                var halfK = (k - 1) / 2;

                if (_nodes[k].Y < _nodes[halfK].Y)
                {
                    Swap(k, halfK);
                    k = halfK;
                }
                else
                {
                    break;
                }
            }

            return(_nodes[k]);
        }
示例#2
0
        public VoxelPhysicsResponse Execute()
        {
            if (startPosition.y <= 1)
            {
                return(new VoxelPhysicsResponse());
            }

            if (startVoxel.IsEmpty)
            {
                return(new VoxelPhysicsResponse());
            }

            var volumeSize    = voxelsSize;
            var directionMask = new VoxelPhysicsDirectionMask();
            var closedList    = new Hashtable <int>(1024 * 128);
            var openList      = new VoxelPhysicsHeap(1024 * 128);

            var startElement = new VoxelPhysicsHeapElement(startPosition);

            openList.Put(startElement);
            closedList.Add(startElement.Key);

            while (!openList.IsEmpty)
            {
                var currentElement = openList.Extract();

                if (currentElement.Y <= 1)
                {
                    return(new VoxelPhysicsResponse());
                }

                for (var k = 0; k < 6; k++)
                {
                    var direction = directionMask[k];
                    var currentElementPosition = currentElement.Position;
                    var currentDirection       = new Vector3Int(
                        currentElementPosition.x + direction.x,
                        currentElementPosition.y + direction.y,
                        currentElementPosition.z + direction.z);

                    var element    = new VoxelPhysicsHeapElement(currentDirection.x, currentDirection.y, currentDirection.z);
                    var key        = element.Key;
                    var voxelIndex = VoxelUtility.GetVoxelIndex(currentDirection.x, currentDirection.y, currentDirection.z, volumeSize);
                    var voxel      = volumeVoxels[voxelIndex];

                    if (currentDirection.y >= 0 && currentDirection.y < volumeSize.y &&
                        currentDirection.x >= 0 && currentDirection.x < volumeSize.x &&
                        currentDirection.z >= 0 && currentDirection.z < volumeSize.z &&
                        voxel.IsSolid && !closedList.ContainsKey(key))
                    {
                        openList.Put(element);
                        closedList.Add(element.Key);
                    }
                }
            }

            var bounds          = new VoxelPhysicsBounds(int.MaxValue, int.MinValue);
            var voxels          = voxelsList;
            var voxelsPositions = voxelsDictionary;
            var volVoxels       = volumeVoxels;

            var entries      = closedList.Entries;
            var entriesCount = entries.Length;

            for (var i = 0; i < entriesCount; i++)
            {
                var entry = entries[i];

                if (!entry.IsEmpty)
                {
                    var     key      = entries[i].key;
                    var     position = VoxelUtility.GetPositionByHash(key);
                    var     index    = VoxelUtility.GetVoxelIndex(position, volumeSize);
                    ref var voxel    = ref volVoxels[index];

                    voxels.Add(new VoxelFallingEntity
                    {
                        colorIndex = voxel.colorIndex,
                        position   = new VoxelPosition(key)
                    });
                    voxelsPositions.Add(key, 0);

                    voxel.data       = 0;
                    voxel.colorIndex = 0;

                    if (bounds.min.x > position.x)
                    {
                        bounds.min.x = position.x;
                    }
                    if (bounds.max.x < position.x)
                    {
                        bounds.max.x = position.x;
                    }

                    if (bounds.min.y > position.y)
                    {
                        bounds.min.y = position.y;
                    }
                    if (bounds.max.y < position.y)
                    {
                        bounds.max.y = position.y;
                    }

                    if (bounds.min.z > position.z)
                    {
                        bounds.min.z = position.z;
                    }
                    if (bounds.max.z < position.z)
                    {
                        bounds.max.z = position.z;
                    }
                }
            }