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