示例#1
0
        public static int GetChunkIndex(Vector3Int chunkPosition, Vector3Int chunkSize, Vector3Int volumeSize)
        {
            var chunkDimensions = new Vector3Int(
                volumeSize.x / chunkSize.x,
                volumeSize.y / chunkSize.y,
                volumeSize.z / chunkSize.z);

            return(VoxelUtility.GetVoxelIndex(chunkPosition, chunkDimensions));
        }
示例#2
0
        private VoxelEntity GetVoxelAtPosition(int x, int y, int z, Dictionary <int, byte> voxelsDictionary)
        {
            var hash = VoxelUtility.GetHashByPosition(x, y, z);

            if (voxelsDictionary.ContainsKey(hash))
            {
                return(new VoxelEntity
                {
                    colorIndex = 2,
                    data = 100
                });
            }

            return(new VoxelEntity());
        }
        public void Execute()
        {
            var volumeSize = new Vector3Int(
                geometryVolumeRequest.model.Size.x,
                geometryVolumeRequest.model.Size.y,
                geometryVolumeRequest.model.Size.z);
            var volumeVoxels  = geometryVolumeRequest.model.Voxels;
            var volumePalette = geometryVolumeRequest.model.Palette;
            var chunkSize     = geometryVolumeRequest.chunkSize;

            var chunkIndex = geometryVolumeRequest.chunkPosition * chunkSize;
            var scale      = geometryVolumeRequest.scale;
            var pivot      = geometryVolumeRequest.pivot;

            var faceColorMultipliers = geometryVolumeRequest.faceColorMultipliers;
            var neighbourDirections  = new VoxelGeometryNeighbourDirection();

            var edgeColorMultiplier   = geometryVolumeRequest.edgeColorMultiplier;
            var cornerColorMultiplier = geometryVolumeRequest.cornerColorMultiplier;

            var facesCount  = 0;
            var voxelsCount = chunkSize.x * chunkSize.y * chunkSize.z;

            for (var voxelIndex = 0; voxelIndex < voxelsCount; voxelIndex++)
            {
                var pos   = VoxelUtility.GetVoxelPosition(voxelIndex, chunkSize);
                var x     = pos.x;
                var y     = pos.y;
                var z     = pos.z;
                var voxel = GetVoxelAtPosition(pos.x, pos.y, pos.z, chunkIndex, volumeVoxels, volumeSize);

                if (voxel.IsSolid)
                {
                    var voxelColor = volumePalette[voxel.colorIndex];

                    var i = 1 * scale;

                    var xScale = x * scale - 0.5f;
                    var yScale = y * scale - 0.5f + i;
                    var zScale = z * scale - 0.5f;

                    xScale -= chunkSize.x * scale * pivot.x - 0.5f;
                    yScale -= chunkSize.y * scale * pivot.y - 0.5f;
                    zScale -= chunkSize.z * scale * pivot.z - 0.5f;

                    var xScalePlusI  = xScale + i;
                    var yScaleMinusI = yScale - i;
                    var zScalePlusI  = zScale + i;

                    for (var neighbourIndex = 0; neighbourIndex < 6; neighbourIndex++)
                    {
                        var neighbourDirection     = neighbourDirections[neighbourIndex];
                        var neighbourVoxelPosition = pos + neighbourDirection;
                        var neighbourVoxel         = GetVoxelAtPosition(neighbourVoxelPosition, chunkIndex,
                                                                        volumeVoxels, volumeSize);

                        if (neighbourVoxel.IsEmpty)
                        {
                            var flip           = false;
                            var faceIndex      = facesCount;
                            var face           = faceIndex;
                            var trianglesIndex = faceIndex * 6;

                            var baseVertexIndex = faceIndex * 4;

                            var faceColorMultiplier = faceColorMultipliers[neighbourIndex];
                            var baseColor           = ColorUtility.GetClampedColor32(
                                voxelColor.r + voxelColor.r * faceColorMultiplier,
                                voxelColor.g + voxelColor.g * faceColorMultiplier,
                                voxelColor.b + voxelColor.b * faceColorMultiplier);

                            for (var vertexIndex = 0; vertexIndex < 4; vertexIndex++)
                            {
                                var vertexPosition = new Vector3();
                                var vertexColor    = baseColor;                             //ColorUtility.GetFaceColor32(baseColor, ec2, ec1, ec4, cc2, cc1, cc4,
                                //vertexIndex, edgeColorMultiplier, cornerColorMultiplier, ref flip);
                                vertices[baseVertexIndex + vertexIndex] = vertexPosition;
                                colors[baseVertexIndex + vertexIndex]   = vertexColor;
                            }

                            var quadFace = face * 4;

                            if (!flip)
                            {
                                var quadFace2 = quadFace + 2;

                                indices[trianglesIndex]     = quadFace;
                                indices[trianglesIndex + 1] = quadFace + 1;
                                indices[trianglesIndex + 2] = quadFace2;
                                indices[trianglesIndex + 3] = quadFace;
                                indices[trianglesIndex + 4] = quadFace2;
                                indices[trianglesIndex + 5] = quadFace + 3;
                            }
                            else
                            {
                                var quadFace1 = quadFace + 1;
                                var quadFace3 = quadFace + 3;

                                indices[trianglesIndex]     = quadFace3;
                                indices[trianglesIndex + 1] = quadFace;
                                indices[trianglesIndex + 2] = quadFace1;
                                indices[trianglesIndex + 3] = quadFace3;
                                indices[trianglesIndex + 4] = quadFace1;
                                indices[trianglesIndex + 5] = quadFace + 2;
                            }
                        }
                    }
                }
            }

            elementLengths[0] = facesCount * 4;
            elementLengths[1] = facesCount * 6;
        }
示例#4
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;
                    }
                }
            }
示例#5
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,
            });
        }
示例#6
0
        public void Execute()
        {
            var volumeSize = new Vector3Int(
                geometryVolumeRequest.model.Size.x,
                geometryVolumeRequest.model.Size.y,
                geometryVolumeRequest.model.Size.z);
            var volumeVoxels  = geometryVolumeRequest.model.Voxels;
            var volumePalette = geometryVolumeRequest.model.Palette;
            var chunkSize     = geometryVolumeRequest.chunkSize;

            var chunkIndex = geometryVolumeRequest.chunkPosition * chunkSize;
            var scale      = geometryVolumeRequest.scale;
            var pivot      = geometryVolumeRequest.pivot;

            var rightFaceColorMultiplier  = geometryVolumeRequest.faceColorMultipliers[0];
            var leftFaceColorMultiplier   = geometryVolumeRequest.faceColorMultipliers[1];
            var upperFaceColorMultiplier  = geometryVolumeRequest.faceColorMultipliers[2];
            var bottomFaceColorMultiplier = geometryVolumeRequest.faceColorMultipliers[3];
            var frontFaceColorMultiplier  = geometryVolumeRequest.faceColorMultipliers[4];
            var backFaceColorMultiplier   = geometryVolumeRequest.faceColorMultipliers[5];

            var edgeColorMultiplier   = geometryVolumeRequest.edgeColorMultiplier;
            var cornerColorMultiplier = geometryVolumeRequest.cornerColorMultiplier;

            var facesCount  = 0;
            var voxelsCount = chunkSize.x * chunkSize.y * chunkSize.z;

            for (var voxelIndex = 0; voxelIndex < voxelsCount; voxelIndex++)
            {
                var pos   = VoxelUtility.GetVoxelPosition(voxelIndex, chunkSize);
                var x     = pos.x;
                var y     = pos.y;
                var z     = pos.z;
                var voxel = GetVoxelAtPosition(pos.x, pos.y, pos.z, chunkIndex, volumeVoxels, volumeSize);

                if (voxel.IsSolid)
                {
                    var voxelColor = volumePalette[voxel.colorIndex];
                    var xm1        = x - 1;
                    var xp1        = x + 1;
                    var ym1        = y - 1;
                    var yp1        = y + 1;
                    var zm1        = z - 1;
                    var zp1        = z + 1;

                    var rightVoxel  = GetVoxelAtPosition(xp1, y, z, chunkIndex, volumeVoxels, volumeSize);
                    var leftVoxel   = GetVoxelAtPosition(xm1, y, z, chunkIndex, volumeVoxels, volumeSize);
                    var upperVoxel  = GetVoxelAtPosition(x, yp1, z, chunkIndex, volumeVoxels, volumeSize);
                    var bottomVoxel = GetVoxelAtPosition(x, ym1, z, chunkIndex, volumeVoxels, volumeSize);
                    var frontVoxel  = GetVoxelAtPosition(x, y, zp1, chunkIndex, volumeVoxels, volumeSize);
                    var backVoxel   = GetVoxelAtPosition(x, y, zm1, chunkIndex, volumeVoxels, volumeSize);

                    if (upperVoxel.IsEmpty || rightVoxel.IsEmpty || leftVoxel.IsEmpty ||
                        frontVoxel.IsEmpty || backVoxel.IsEmpty || bottomVoxel.IsEmpty)
                    {
                        var block01 = GetVoxelAtPosition(xm1, ym1, zp1, chunkIndex, volumeVoxels, volumeSize);
                        var block02 = GetVoxelAtPosition(x, ym1, zp1, chunkIndex, volumeVoxels, volumeSize);
                        var block03 = GetVoxelAtPosition(xp1, ym1, zp1, chunkIndex, volumeVoxels, volumeSize);
                        var block04 = GetVoxelAtPosition(xm1, ym1, z, chunkIndex, volumeVoxels, volumeSize);
                        var block06 = GetVoxelAtPosition(xp1, ym1, z, chunkIndex, volumeVoxels, volumeSize);
                        var block07 = GetVoxelAtPosition(xm1, ym1, zm1, chunkIndex, volumeVoxels, volumeSize);
                        var block08 = GetVoxelAtPosition(x, ym1, zm1, chunkIndex, volumeVoxels, volumeSize);
                        var block09 = GetVoxelAtPosition(xp1, ym1, zm1, chunkIndex, volumeVoxels, volumeSize);

                        var block11 = GetVoxelAtPosition(xm1, y, zp1, chunkIndex, volumeVoxels, volumeSize);
                        var block13 = GetVoxelAtPosition(xp1, y, zp1, chunkIndex, volumeVoxels, volumeSize);
                        var block17 = GetVoxelAtPosition(xm1, y, zm1, chunkIndex, volumeVoxels, volumeSize);
                        var block19 = GetVoxelAtPosition(xp1, y, zm1, chunkIndex, volumeVoxels, volumeSize);

                        var block21 = GetVoxelAtPosition(xm1, yp1, zp1, chunkIndex, volumeVoxels, volumeSize);
                        var block22 = GetVoxelAtPosition(x, yp1, zp1, chunkIndex, volumeVoxels, volumeSize);
                        var block23 = GetVoxelAtPosition(xp1, yp1, zp1, chunkIndex, volumeVoxels, volumeSize);
                        var block24 = GetVoxelAtPosition(xm1, yp1, z, chunkIndex, volumeVoxels, volumeSize);
                        var block26 = GetVoxelAtPosition(xp1, yp1, z, chunkIndex, volumeVoxels, volumeSize);
                        var block27 = GetVoxelAtPosition(xm1, yp1, zm1, chunkIndex, volumeVoxels, volumeSize);
                        var block28 = GetVoxelAtPosition(x, yp1, zm1, chunkIndex, volumeVoxels, volumeSize);
                        var block29 = GetVoxelAtPosition(xp1, yp1, zm1, chunkIndex, volumeVoxels, volumeSize);

                        var i = 1 * scale;

                        var xScale = x * scale - 0.5f;
                        var yScale = y * scale - 0.5f + i;
                        var zScale = z * scale - 0.5f;

                        xScale -= chunkSize.x * scale * pivot.x - 0.5f;
                        yScale -= chunkSize.y * scale * pivot.y - 0.5f;
                        zScale -= chunkSize.z * scale * pivot.z - 0.5f;

                        var xScalePlusI  = xScale + i;
                        var yScaleMinusI = yScale - i;
                        var zScalePlusI  = zScale + i;

                        var noneScaleAdj = new Vector3(xScale, yScale, zScale);
                        var xScaleAdj    = new Vector3(xScalePlusI, yScale, zScale);
                        var xzScaleAdj   = new Vector3(xScalePlusI, yScale, zScalePlusI);
                        var xyzScaleAdj  = new Vector3(xScalePlusI, yScaleMinusI, zScalePlusI);
                        var xyScaleAdj   = new Vector3(xScalePlusI, yScaleMinusI, zScale);
                        var yScaleAdj    = new Vector3(xScale, yScaleMinusI, zScale);
                        var yzScaleAdj   = new Vector3(xScale, yScaleMinusI, zScalePlusI);
                        var zScaleAdj    = new Vector3(xScale, yScale, zScalePlusI);

                        if (rightVoxel.IsEmpty)
                        {
                            SetFace(
                                xyScaleAdj, xScaleAdj, xzScaleAdj, xyzScaleAdj,
                                facesCount, voxelColor, rightFaceColorMultiplier,
                                edgeColorMultiplier, cornerColorMultiplier,
                                block09.data, block06.data, block03.data,
                                block19.data, block13.data,
                                block29.data, block26.data, block23.data,
                                block08.data, bottomVoxel.data, block02.data,
                                backVoxel.data, frontVoxel.data,
                                block28.data, upperVoxel.data, block22.data);

                            facesCount++;
                        }

                        if (leftVoxel.IsEmpty)
                        {
                            SetFace(
                                yzScaleAdj, zScaleAdj, noneScaleAdj, yScaleAdj,
                                facesCount, voxelColor, leftFaceColorMultiplier,
                                edgeColorMultiplier, cornerColorMultiplier,
                                block01.data, block04.data, block07.data,
                                block11.data, block17.data,
                                block21.data, block24.data, block27.data,
                                block02.data, bottomVoxel.data, block08.data,
                                frontVoxel.data, backVoxel.data,
                                block22.data, upperVoxel.data, block28.data);

                            facesCount++;
                        }

                        if (upperVoxel.IsEmpty)
                        {
                            SetFace(
                                zScaleAdj, xzScaleAdj, xScaleAdj, noneScaleAdj,
                                facesCount, voxelColor, upperFaceColorMultiplier,
                                edgeColorMultiplier, cornerColorMultiplier,
                                block21.data, block24.data, block27.data,
                                block22.data, block28.data,
                                block23.data, block26.data, block29.data,
                                block11.data, leftVoxel.data, block17.data,
                                frontVoxel.data, backVoxel.data,
                                block13.data, rightVoxel.data, block19.data);

                            facesCount++;
                        }

                        if (bottomVoxel.IsEmpty)
                        {
                            SetFace(
                                yScaleAdj, xyScaleAdj, xyzScaleAdj, yzScaleAdj,
                                facesCount, voxelColor, bottomFaceColorMultiplier,
                                edgeColorMultiplier, cornerColorMultiplier,
                                block07.data, block04.data, block01.data,
                                block08.data, block02.data,
                                block09.data, block06.data, block03.data,
                                block17.data, leftVoxel.data, block11.data,
                                backVoxel.data, frontVoxel.data,
                                block19.data, rightVoxel.data, block13.data);

                            facesCount++;
                        }

                        if (frontVoxel.IsEmpty)
                        {
                            SetFace(
                                xyzScaleAdj, xzScaleAdj, zScaleAdj, yzScaleAdj,
                                facesCount, voxelColor, frontFaceColorMultiplier,
                                edgeColorMultiplier, cornerColorMultiplier,
                                block03.data, block02.data, block01.data,
                                block13.data, block11.data,
                                block23.data, block22.data, block21.data,
                                block06.data, bottomVoxel.data, block04.data,
                                rightVoxel.data, leftVoxel.data,
                                block26.data, upperVoxel.data, block24.data);

                            facesCount++;
                        }

                        if (backVoxel.IsEmpty)
                        {
                            SetFace(
                                yScaleAdj, noneScaleAdj, xScaleAdj, xyScaleAdj,
                                facesCount, voxelColor, backFaceColorMultiplier,
                                edgeColorMultiplier, cornerColorMultiplier,
                                block07.data, block08.data, block09.data,
                                block17.data, block19.data,
                                block27.data, block28.data, block29.data,
                                block04.data, bottomVoxel.data, block06.data,
                                leftVoxel.data, rightVoxel.data,
                                block24.data, upperVoxel.data, block26.data);

                            facesCount++;
                        }
                    }
                }
            }

            elementLengths[0] = facesCount * 4;
            elementLengths[1] = facesCount * 6;
        }
示例#7
0
        public VoxelEntity GetVoxel(Vector3Int position)
        {
            var index = VoxelUtility.GetVoxelIndex(position.x, position.y, position.z, Size);

            return(Voxels[index]);
        }
示例#8
0
        public VoxelEntity GetVoxel(int x, int y, int z)
        {
            var index = VoxelUtility.GetVoxelIndex(x, y, z, Size);

            return(Voxels[index]);
        }
示例#9
0
        public void SetVoxel(Vector3Int position, VoxelEntity voxelEntity)
        {
            var index = VoxelUtility.GetVoxelIndex(position, Size);

            Voxels[index] = voxelEntity;
        }
示例#10
0
        public void SetVoxel(int x, int y, int z, VoxelEntity voxelEntity)
        {
            var index = VoxelUtility.GetVoxelIndex(x, y, z, Size);

            Voxels[index] = voxelEntity;
        }