Exemple #1
0
 /// <summary>
 /// Iterate all the the chunks within a radius of a given point.
 /// </summary>
 public static IEnumerable IterateChunksWithinRadius(BlockSpacePosition position, int distance)
 {
     foreach (Chunk chunk in Instance().IterateChunksWithinRadius(position, distance))
     {
         yield return(chunk);
     }
 }
Exemple #2
0
        public List <BlockLight> GetAllLightsWithinMaxRange(ChunkSpacePosition chunkPosition)
        {
            int distance = Configuration.MAX_LIGHT_RADIUS + Chunk.SIZE / 2;
            BlockSpacePosition checkPosition;

            checkPosition.x = chunkPosition.x * Chunk.SIZE + Chunk.SIZE / 2;
            checkPosition.y = chunkPosition.y * Chunk.SIZE + Chunk.SIZE / 2;
            checkPosition.z = chunkPosition.z * Chunk.SIZE + Chunk.SIZE / 2;

            List <BlockLight> lights = new List <BlockLight>();

            foreach (Chunk chunk in ChunkRepository.IterateChunksWithinRadius(checkPosition, distance))
            {
                // TODO -- This isn't super efficient on memory, but required for thread safety. Try to figure out a
                // better way of doing this.
                BlockLight[] chunkLights;
                lock (chunk) {
                    chunkLights = chunk.LightsArray();
                }

                int chunkLightsLength = chunkLights.Length;
                for (int chunkLightsIndex = 0; chunkLightsIndex < chunkLightsLength; chunkLightsIndex++)
                {
                    BlockLight         light         = chunkLights[chunkLightsIndex];
                    BlockSpacePosition lightPosition = light.chunkPosition.GetBlockSpacePosition(chunk);
                    if (BlockIsNotHidden(lightPosition))
                    {
                        lights.Add(light);
                    }
                }
            }
            return(lights);
        }
Exemple #3
0
        public void RemoveBlockAtPosition(BlockSpacePosition position, RemoveBlockCallback callback)
        {
            ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(this);

            if (subspacePosition.x < 0 || subspacePosition.y < 0 || subspacePosition.z < 0 ||
                subspacePosition.x >= SIZE || subspacePosition.y >= SIZE || subspacePosition.z >= SIZE)
            {
                return;
            }

            Block block = GetBlock(subspacePosition);

            if (block.IsBedrock())
            {
                // Bedrock is a special case - it can't be removed
                return;
            }

            if (callback != null)
            {
                callback(position, block);
            }

            SetBlock(subspacePosition, BlockType.Air, true);
        }
Exemple #4
0
 private bool LightCanAffectFace(BlockSpacePosition samplePosition, BlockSpacePosition lightPosition,
                                 CubeSide sampleSide)
 {
     if (sampleSide == CubeSide.Bottom)
     {
         return(lightPosition.y < samplePosition.y);
     }
     else if (sampleSide == CubeSide.Top)
     {
         return(lightPosition.y > samplePosition.y);
     }
     else if (sampleSide == CubeSide.West)
     {
         return(lightPosition.x < samplePosition.x);
     }
     else if (sampleSide == CubeSide.East)
     {
         return(lightPosition.x > samplePosition.x);
     }
     else if (sampleSide == CubeSide.North)
     {
         return(lightPosition.z < samplePosition.z);
     }
     else if (sampleSide == CubeSide.South)
     {
         return(lightPosition.z > samplePosition.z);
     }
     return(false);
 }
Exemple #5
0
        public IEnumerable IterateChunksWithinRadius(BlockSpacePosition position, int distance)
        {
            ChunkSpacePosition checkPosition;
            int xIttr, yIttr, zIttr;

            for (xIttr = (int)((position.x - distance) / Chunk.SIZE);
                 xIttr < (int)Math.Ceiling((position.x + distance) / (double)Chunk.SIZE);
                 xIttr += 1)
            {
                checkPosition.x = xIttr;
                for (yIttr = (int)((position.y - distance) / Chunk.SIZE);
                     yIttr < (int)Math.Ceiling((position.y + distance) / (double)Chunk.SIZE);
                     yIttr += 1)
                {
                    checkPosition.y = yIttr;
                    for (zIttr = (int)((position.z - distance) / Chunk.SIZE);
                         zIttr < (int)Math.Ceiling((position.z + distance) / (double)Chunk.SIZE);
                         zIttr += 1)
                    {
                        checkPosition.z = zIttr;

                        Chunk additionalChunk = GetChunkAtPosition(checkPosition);
                        if (additionalChunk != null)
                        {
                            yield return(additionalChunk);
                        }
                    }
                }
            }
        }
Exemple #6
0
        public List <BlockLight> GetAllLightsFromChunks(List <Chunk> chunkList)
        {
            if (chunkList == null)
            {
                Debug.LogWarning("GetAllLightsFromChunks provided with null chunkList.");
                return(null);
            }

            List <BlockLight> lights = new List <BlockLight>();
            int chunkListCount       = chunkList.Count;

            for (int chunkListIndex = 0; chunkListIndex < chunkListCount; chunkListIndex++)
            {
                Chunk chunk = chunkList[chunkListIndex];
                // TODO -- This isn't super effecient on memory, but required for thread safety. Try to figure out a
                // better way of doing this.
                BlockLight[] chunkLights       = chunk.LightsArray();
                int          chunkLightsLength = chunkLights.Length;
                for (int chunkLightsIndex = 0; chunkLightsIndex < chunkLightsLength; chunkLightsIndex++)
                {
                    BlockLight         light         = chunkLights[chunkLightsIndex];
                    BlockSpacePosition lightPosition = light.chunkPosition.GetBlockSpacePosition(chunk);
                    if (BlockIsNotHidden(lightPosition))
                    {
                        lights.Add(light);
                    }
                }
            }
            return(lights);
        }
Exemple #7
0
 private void MarkForMeshUpdateWithinRadius(BlockSpacePosition position, int distance)
 {
     foreach (Chunk updateChunk in IterateChunksWithinRadius(position, distance))
     {
         updateChunk.MarkForMeshUpdate();
     }
 }
Exemple #8
0
        private void PullTransparencyCacheFromAdjacentBlock(ChunkSubspacePosition position,
                                                            int xOffset, int yOffset, int zOffset)
        {
            ChunkSubspacePosition checkPosition;

            checkPosition    = position;
            checkPosition.x += xOffset;
            checkPosition.y += yOffset;
            checkPosition.z += zOffset;

            if (checkPosition.x >= 0 && checkPosition.x < SIZE &&
                checkPosition.y >= 0 && checkPosition.y < SIZE &&
                checkPosition.z >= 0 && checkPosition.z < SIZE)
            {
                SetAdjacentBlockTransparentFlag(position, xOffset, yOffset, zOffset,
                                                GetBlock(checkPosition).IsTransparent());
            }
            else
            {
                BlockSpacePosition blockPosition = checkPosition.GetBlockSpacePosition(this);
                Chunk otherChunk = ChunkRepository.GetChunkAtPosition(blockPosition);

                if (otherChunk != null)
                {
                    ChunkSubspacePosition otherChunkPosition = blockPosition.GetChunkSubspacePosition(otherChunk);

                    SetAdjacentBlockTransparentFlag(position, xOffset, yOffset, zOffset,
                                                    otherChunk.GetBlock(otherChunkPosition).IsTransparent());
                }
            }
        }
Exemple #9
0
        // TODO -- This needs to be updated to not directly reference the player
        public bool PotentialEntityCollision(BlockSpacePosition position)
        {
            Block block = ChunkRepository.GetBlockAtPosition(position);

            if (block.IsSolidToTouch())
            {
                // No use checking for entities if we already know that this spot is taken
                return(true);
            }
            VoxelCharacterController[] characters =
                UnityEngine.Component.FindObjectsOfType(typeof(VoxelCharacterController)) as VoxelCharacterController[];

            int charactersLength = characters.Length;

            for (int i = 0; i < charactersLength; i++)
            {
                VoxelCharacterController character = characters[i];
                if (character.transform.position.x - character.radius + 0.5f < position.x + 0.5f &&
                    character.transform.position.x + character.radius + 0.5f > position.x - 0.5f &&
                    character.transform.position.z - character.radius + 0.5f < position.z + 0.5f &&
                    character.transform.position.z + character.radius + 0.5f > position.z - 0.5f &&
                    character.transform.position.y - character.height / 2.0f + 0.5f < position.y + 0.5f &&
                    character.transform.position.y + character.height / 2.0f + 0.5f > position.y - 0.5f)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #10
0
        public ChunkBlockPair GetBlockAtPosition(BlockSpacePosition position, Chunk hintChunk)
        {
            if (hintChunk == null)
            {
                return(GetBlockAtPosition(position));
            }

            ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(hintChunk);

            if (subspacePosition.x < 0 ||
                subspacePosition.y < 0 ||
                subspacePosition.z < 0 ||
                subspacePosition.x >= Chunk.SIZE ||
                subspacePosition.y >= Chunk.SIZE ||
                subspacePosition.z >= Chunk.SIZE)
            {
                return(GetBlockAtPosition(position));
            }

            ChunkBlockPair returnPair;

            returnPair.block = hintChunk.GetBlock(subspacePosition);
            returnPair.chunk = hintChunk;
            return(returnPair);
        }
Exemple #11
0
 /// <summary>
 /// Runs a raytrace for a collision.
 /// </summary>
 /// <returns><c>true</c> if there was a collision</returns>
 /// <param name="origin">Point for the raytrace to start at.</param>
 /// <param name="endpoint">Point for the raytrace to end at.</param>
 /// <param name="endpointSide">Which side of the endpoint to target.</param>
 /// <param name="ignoreStartAndEnd">
 /// Whether to ignore blocks that are actually within the start and end point. You can enable this if you
 /// actually only care about what is between two blocks, but not the blocks themselves.
 /// </param>
 /// <param name="reverseScan">If set to <c>true</c>, it will scan from the endpoint towards the origin.</param>
 public static bool RaytraceCollision(BlockSpacePosition origin, BlockSpacePosition endpoint,
                                      CubeSide endpointSide,
                                      bool ignoreStartAndEnd,
                                      bool reverseScan)
 {
     return(Instance().RaytraceCollision(origin, endpoint, endpointSide, ignoreStartAndEnd, reverseScan));
 }
Exemple #12
0
        private void PushTransparencyCacheToAdjacentBlock(ChunkSubspacePosition position, int xOffset, int yOffset, int zOffset,
                                                          bool transparent)
        {
            position.x += xOffset;
            position.y += yOffset;
            position.z += zOffset;

            if (position.x >= 0 && position.x < SIZE &&
                position.y >= 0 && position.y < SIZE &&
                position.z >= 0 && position.z < SIZE)
            {
                SetAdjacentBlockTransparentFlag(position, -xOffset, -yOffset, -zOffset, transparent);
            }
            else
            {
                BlockSpacePosition blockPosition = position.GetBlockSpacePosition(this);
                Chunk otherChunk = ChunkRepository.GetChunkAtPosition(blockPosition);

                if (otherChunk != null)
                {
                    ChunkSubspacePosition otherChunkPosition = blockPosition.GetChunkSubspacePosition(otherChunk);

                    otherChunk.SetAdjacentBlockTransparentFlag(otherChunkPosition,
                                                               -xOffset, -yOffset, -zOffset, transparent);
                }
            }
        }
Exemple #13
0
        public void ApplyToChunk(BlockSpacePosition origin, ironVoxel.Domain.Chunk chunk)
        {
            if (chunk == null)
            {
                return;
            }

            BlockSpacePosition setPosition;
            BlockType          setType;
            int xIttr, yIttr, zIttr;

            for (xIttr = 0; xIttr < SizeX(); xIttr++)
            {
                for (yIttr = 0; yIttr < SizeY(); yIttr++)
                {
                    for (zIttr = 0; zIttr < SizeZ(); zIttr++)
                    {
                        setType = Blocks()[xIttr, yIttr, zIttr];
                        if (setType != BlockType.Air || SetAir())
                        {
                            setPosition.x = (int)(origin.x + xIttr - OriginX());
                            setPosition.y = (int)(origin.y + yIttr - OriginY() + 1);
                            setPosition.z = (int)(origin.z + zIttr - OriginZ());
                            chunk.SetBlockAtPosition(setPosition, setType, true);
                        }
                    }
                }
            }
        }
Exemple #14
0
 private static bool BlockIsHidden(BlockSpacePosition blockPosition)
 {
     return(BlockIsActive(blockPosition.x - 1, blockPosition.y, blockPosition.z) &&
            BlockIsActive(blockPosition.x + 1, blockPosition.y, blockPosition.z) &&
            BlockIsActive(blockPosition.x, blockPosition.y - 1, blockPosition.z) &&
            BlockIsActive(blockPosition.x, blockPosition.y + 1, blockPosition.z) &&
            BlockIsActive(blockPosition.x, blockPosition.y, blockPosition.z - 1) &&
            BlockIsActive(blockPosition.x, blockPosition.y, blockPosition.z + 1));
 }
Exemple #15
0
        public void MarkChunksWithinMaxLightRadiusForMeshUpdate(BlockSpacePosition position)
        {
            int distance = Configuration.MAX_LIGHT_RADIUS + Chunk.SIZE / 2;

            foreach (Chunk chunk in ChunkRepository.IterateChunksWithinRadius(position, distance))
            {
                chunk.MarkForMeshUpdate();
                ChunkRepository.AddToProcessingChunkList(chunk);
            }
        }
Exemple #16
0
        public Chunk GetChunkAtPosition(BlockSpacePosition position)
        {
            ChunkSpacePosition chunkspacePosition;

            chunkspacePosition.y = position.y / Chunk.SIZE;
            chunkspacePosition.x = (int)Math.Floor((double)position.x / (double)Chunk.SIZE);
            chunkspacePosition.z = (int)Math.Floor((double)position.z / (double)Chunk.SIZE);

            return(GetChunkAtPosition(chunkspacePosition));
        }
Exemple #17
0
        private bool GenerateIronSample(BlockSpacePosition blockPosition)
        {
            double calcX = blockPosition.x * 0.1 + 20.0;
            double calcY = blockPosition.y * 0.05 - 20.0;
            double calcZ = blockPosition.z * 0.1;

            double noiseSample = PerlinNoise.Generate(calcX, calcY + 0.01, calcZ);

            return(noiseSample < -7.5);
        }
Exemple #18
0
        private bool GenerateCoalSample(BlockSpacePosition blockPosition)
        {
            double calcX = blockPosition.x * 0.20;
            double calcY = blockPosition.y * 0.20 + 5.0;
            double calcZ = blockPosition.z * 0.20;

            double noiseSample = PerlinNoise.Generate(calcX, calcY + 0.01, calcZ);

            return(noiseSample < -0.465);
        }
Exemple #19
0
        private double GenerateCaveSample(BlockSpacePosition blockPosition)
        {
            double calcX = blockPosition.x * 0.03;
            double calcY = blockPosition.y * 0.03;
            double calcZ = blockPosition.z * 0.03;

            double noiseSample1 = MultifractalNoise.GenerateRidged((float)calcX, (float)calcY, (float)calcZ, 2.0f, 0.0f, 1.0f, 1.0f, 2.0f);
            double noiseSample2 = MultifractalNoise.GenerateRidged((float)calcX + 100.0f, (float)calcZ, (float)calcY, 2.0f, 0.0f, 1.0f, 1.0f, 2.0f);

            return(noiseSample1 * noiseSample2 - blockPosition.y * 0.002);
        }
Exemple #20
0
        private bool GenerateRockSample(BlockSpacePosition blockPosition)
        {
            double calcX = blockPosition.x * 0.018;
            double calcY = blockPosition.y * 0.020;
            double calcZ = blockPosition.z * 0.018;

            double noiseSample = PerlinNoise.Generate(calcX, calcY + 0.01, calcZ);

            return((1.0 + noiseSample - ((double)blockPosition.y / 32.0)) > -1.45 ||
                   noiseSample < -0.3);
        }
Exemple #21
0
        public void SetBlockAtPosition(BlockSpacePosition position, BlockType type, bool triggerLightingUpdate)
        {
            Chunk chunk = GetChunkAtPosition(position);

            if (chunk == null)
            {
                return;
            }
            chunk.SetBlockAtPosition(position, type, triggerLightingUpdate);
            MarkForMeshUpdateWithinRadius(position, Configuration.MAX_LIGHT_RADIUS);
        }
Exemple #22
0
        private double GenerateOverworldSample(BlockSpacePosition blockPosition)
        {
            Vector3Double calc;

            calc.x = blockPosition.x * 0.005;
            calc.y = blockPosition.y * 0.008;
            calc.z = blockPosition.z * 0.005;
            double sample = PerlinNoise.RidgedTurbulence(calc, 10);

            return(1.0 + sample - ((double)blockPosition.y / 64.0));
        }
Exemple #23
0
        public void RemoveBlockAtPosition(BlockSpacePosition position, Chunk.RemoveBlockCallback callback)
        {
            Chunk chunk = GetChunkAtPosition(position);

            if (chunk == null)
            {
                return;
            }
            chunk.RemoveBlockAtPosition(position, callback);
            MarkForMeshUpdateWithinRadius(position, Configuration.MAX_LIGHT_RADIUS);
        }
Exemple #24
0
        public void SetBlockAtPosition(BlockSpacePosition position, BlockType type, bool triggerLightingUpdate)
        {
            if (type == BlockType.Air)
            {
                throw new Exception("Can not use SetBlockAtPosition to set a block to air. Rather, use " +
                                    "RemoveBlockAtPosition for this purpose.");
            }

            ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(this);

            SetBlock(subspacePosition, type, triggerLightingUpdate);
        }
Exemple #25
0
 private void HandlePlacingBlock(bool hit, Vector3 hitPosition, Vector3 hitNormal)
 {
     if (Input.GetKeyDown(KeyCode.Mouse0))
     {
         BlockSpacePosition newBlockPosition = BlockSpacePosition.CreateFromVector3(hitPosition + hitNormal);
         if (hit && ironVoxel.Service.CollisionService.PotentialEntityCollision(newBlockPosition) == false)
         {
             Vector3 setPosition = hitPosition + hitNormal;
             ironVoxel.Service.ChunkRepository.SetBlockAtPosition(setPosition, buildType);
         }
     }
 }
Exemple #26
0
        private Sample GenerateDensitySample(BlockSpacePosition blockPosition)
        {
            Sample sample;

            sample.overworld = 0.0;
            sample.cave      = 0.0;

            sample.overworld = GenerateOverworldSample(blockPosition);
            if (OverworldSampleIsSolid(sample.overworld))
            {
                sample.cave = GenerateCaveSample(blockPosition);
            }
            return(sample);
        }
Exemple #27
0
        public bool RaytraceCollision(BlockSpacePosition origin, BlockSpacePosition endpoint, CubeSide endpointSide,
                                      bool ignoreStartAndEnd, bool reverseScan)
        {
            Vector3 originVector;
            Vector3 endpointVector;

            originVector      = origin.GetVector3();
            originVector.x   += 0.5f;
            originVector.y   += 0.5f;
            originVector.z   += 0.5f;
            endpointVector    = endpoint.GetVector3();
            endpointVector.x += 0.5f;
            endpointVector.y += 0.5f;
            endpointVector.z += 0.5f;

            if (endpointSide == CubeSide.West)
            {
                endpointVector.x -= 0.5f;
            }
            if (endpointSide == CubeSide.East)
            {
                endpointVector.x += 0.5f;
            }
            if (endpointSide == CubeSide.North)
            {
                endpointVector.z -= 0.5f;
            }
            if (endpointSide == CubeSide.South)
            {
                endpointVector.z += 0.5f;
            }
            if (endpointSide == CubeSide.Bottom)
            {
                endpointVector.y -= 0.5f;
            }
            if (endpointSide == CubeSide.Top)
            {
                endpointVector.y += 0.5f;
            }

            if (reverseScan)
            {
                Vector3 originalOriginVector = originVector;
                originVector   = endpointVector;
                endpointVector = originalOriginVector;
            }

            return(RaytraceCollision(originVector, Vector3.Normalize(endpointVector - originVector),
                                     Vector3.Distance(originVector, endpointVector) - 1.0f, ignoreStartAndEnd));
        }
Exemple #28
0
        public ChunkBlockPair GetBlockAtPosition(BlockSpacePosition position)
        {
            ChunkBlockPair returnPair;
            Chunk          chunk = GetChunkAtPosition(position);

            if (chunk == null)
            {
                returnPair.block = Block.EmptyBlock();
                returnPair.chunk = null;
                return(returnPair);
            }

            returnPair.block = chunk.GetBlockAtPosition(position);
            returnPair.chunk = chunk;
            return(returnPair);
        }
Exemple #29
0
    public static void CreateBlockParticle(BlockSpacePosition blockPosition, Block block)
    {
        if (block.IsNotActive())
        {
            return;
        }

        Vector3 position;

        position.x = blockPosition.x - 0.5f;
        position.y = blockPosition.y;
        position.z = blockPosition.z - 0.5f;
        BlockParticle createdBlockParticle = CreateBlockParticle(position);

        createdBlockParticle.UpdateTexture(blockPosition, block);
    }
Exemple #30
0
    public void UpdateTexture(BlockSpacePosition blockPosition, Block block)
    {
        Vector2 textureCoordinates    = block.GetTextureCoordinates(CubeSide.Top, true, true, (byte)254);
        Vector2 overallTextureSize    = block.GetOverallTextureSize();
        Vector2 individualTextureSize = block.GetIndividualTextureSize();

        Vector2 lowerUVs, upperUVs;

        lowerUVs.x = textureCoordinates.x / overallTextureSize.x;
        lowerUVs.y = 1.0f - textureCoordinates.y / overallTextureSize.y;
        upperUVs.x = (textureCoordinates.x + individualTextureSize.x) / overallTextureSize.x;
        upperUVs.y = 1.0f - (textureCoordinates.y + individualTextureSize.y) / overallTextureSize.y;

        Vector2[] uvs = CubeMesh.uv;
        for (int j = 0; j < 6; j++)
        {
            Vector2 uv;
            uv.x           = lowerUVs.x;
            uv.y           = upperUVs.y;
            uvs[j * 4 + 0] = uv;

            uv.x           = lowerUVs.x;
            uv.y           = lowerUVs.y;
            uvs[j * 4 + 1] = uv;

            uv.x           = upperUVs.x;
            uv.y           = upperUVs.y;
            uvs[j * 4 + 2] = uv;

            uv.x           = upperUVs.x;
            uv.y           = lowerUVs.y;
            uvs[j * 4 + 3] = uv;
        }
        CubeMesh.uv = uvs;


        Color lightColor = RenderService.SampleLight(blockPosition, CubeSide.Top);

        Color[] colors = CubeMesh.colors;
        for (int j = 0; j < 4 * 6; j++)
        {
            colors[j] = lightColor;
        }
        CubeMesh.colors = colors;
    }