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]); }
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; } } }