예제 #1
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;
                    }
                }
            }
예제 #2
0
        public VoxelPhysicsResponse Execute(VoxelPhysicsRequest request, VoxelModel model)
        {
            var volumeSize       = model.Size;
            var collapseVoxels   = new List <VoxelFallingEntity>(512 * 512);
            var voxelsDictionary = new Dictionary <int, byte>(1024 * 256);
            var position         = request.initialPosition;

            var bounds       = new VoxelPhysicsBounds(int.MaxValue, int.MinValue);
            var isDestructed = false;
            var voxelIndex   = VoxelUtility.GetVoxelIndex(position, volumeSize);
            var voxel        = model.GetVoxel(voxelIndex);
            var pivot        = new Vector3();

            if (voxel.IsEmpty)
            {
                var directionMask = new VoxelPhysicsDirectionMask(VoxelPhysicsDirectionMaskPriorityType.TopYPriority);

                for (var v = 0; v < 6; v++)
                {
                    var direction       = directionMask[v];
                    var currentPosition = new Vector3Int(
                        position.x + direction.x,
                        position.y + direction.y,
                        position.z + direction.z);

                    voxelIndex = VoxelUtility.GetVoxelIndex(currentPosition, volumeSize);
                    voxel      = model.GetVoxel(voxelIndex);

                    if (voxel.IsSolid)
                    {
                        var workerRequest = new VoxelPhysicsWorkerData
                        {
                            startVoxel       = voxel,
                            initialPosition  = currentPosition,
                            collapseVoxels   = collapseVoxels,
                            voxelsDictionary = voxelsDictionary
                        };
                        var result = _worker.Execute(workerRequest, model);

                        if (result.isDestroyed)
                        {
                            for (var i = 0; i < 3; i++)
                            {
                                if (bounds.min[i] > result.fallingVoxelBounds.min[i])
                                {
                                    bounds.min[i] = result.fallingVoxelBounds.min[i];
                                }

                                if (bounds.max[i] < result.fallingVoxelBounds.max[i])
                                {
                                    bounds.max[i] = result.fallingVoxelBounds.max[i];
                                }
                            }

                            isDestructed = true;
                        }
                    }
                }
            }

            var voxelsDictionaryCount = voxelsDictionary.Count;

            pivot.x = pivot.x / voxelsDictionaryCount + 0.5F;
            pivot.y = pivot.y / voxelsDictionaryCount + 0.5F;
            pivot.z = pivot.z / voxelsDictionaryCount + 0.5F;

            return(new VoxelPhysicsResponse
            {
                isDestroyed = isDestructed,
                fallingVoxelList = collapseVoxels,
                fallingVoxelDictionary = voxelsDictionary,
                fallingVoxelBounds = bounds,
            });
        }