//Default Face Generation Checks !
        public bool FaceGenerationCheck(ref TerraCube cube, ref Vector3I cubePosiInWorld, CubeFaces cubeFace, ref TerraCube NeightBorFaceCube)
        {
            //if (cubeFace != CubeFaces.Top)
            //{
            //    blockProfile NeightBorProfile = _wp.WorldParameters.Configuration.CubeProfiles[NeightBorFaceCube.Id];

            //    if ((!NeightBorProfile.IsBlockingLight && NeightBorProfile.CubeFamilly != enuCubeFamilly.Liquid))
            //    {
            //        return true;
            //    }
            //}else{
            //    if (cubePosiInWorld.Y == seaLevel || NeightBorFaceCube.Id == WorldConfiguration.CubeId.Air)
            //    {
            //        return true;
            //    }
            //}

            BlockProfile NeightBorProfile = _wp.WorldParameters.Configuration.BlockProfiles[NeightBorFaceCube.Id];

            if ((!NeightBorProfile.IsBlockingLight && NeightBorProfile.CubeFamilly != enuCubeFamilly.Liquid))
            {
                return(true);
            }

            return(false);
        }
        private void CheckHeadUnderWater()
        {
            if (_cubesHolder.IndexYSafe(MathHelper.Floor(CameraWorldPosition.X), MathHelper.Floor(CameraWorldPosition.Y), MathHelper.Floor(CameraWorldPosition.Z), out _headCubeIndex))
            {
                //Get the cube at the camera position !
                _headCube = _cubesHolder.Cubes[_headCubeIndex];

                //Get Feet block
                int       feetBlockIdx = _cubesHolder.FastIndex(_headCubeIndex, MathHelper.Floor(CameraWorldPosition.Y), SingleArrayChunkContainer.IdxRelativeMove.Y_Minus1);
                TerraCube feetBlock    = _cubesHolder.Cubes[feetBlockIdx];

                var belowIndex = _cubesHolder.FastIndex(feetBlockIdx, MathHelper.Floor(CameraWorldPosition.Y) - 1, SingleArrayChunkContainer.IdxRelativeMove.Y_Minus1);

                if (belowIndex < 0 || belowIndex > _cubesHolder.Cubes.Length)
                {
                    return;
                }

                TerraCube BelowfeetBlock = _cubesHolder.Cubes[belowIndex];

                if (_visualWorldParameters.WorldParameters.Configuration.BlockProfiles[feetBlock.Id].CubeFamilly == Shared.Enums.enuCubeFamilly.Liquid &&
                    (_visualWorldParameters.WorldParameters.Configuration.BlockProfiles[BelowfeetBlock.Id].CubeFamilly == Shared.Enums.enuCubeFamilly.Liquid || _visualWorldParameters.WorldParameters.Configuration.BlockProfiles[_headCube.Id].CubeFamilly == Shared.Enums.enuCubeFamilly.Liquid))
                {
                    if (_playerCharacter.DisplacementMode == EntityDisplacementModes.Walking)
                    {
                        _playerCharacter.DisplacementMode = EntityDisplacementModes.Swiming;
                    }
                }
                else
                {
                    if (_playerCharacter.DisplacementMode == EntityDisplacementModes.Swiming)
                    {
                        _playerCharacter.DisplacementMode = EntityDisplacementModes.Walking;
                    }
                }

                //Eyes under water (Used to change view Color)
                BlockProfile headCubeProfile = _visualWorldParameters.WorldParameters.Configuration.BlockProfiles[_headCube.Id];
                if (headCubeProfile.CubeFamilly == Shared.Enums.enuCubeFamilly.Liquid)
                {
                    int AboveHead = _cubesHolder.FastIndex(_headCubeIndex, MathHelper.Floor(CameraWorldPosition.Y), SingleArrayChunkContainer.IdxRelativeMove.Y_Plus1);
                    if (_cubesHolder.Cubes[AboveHead].Id == WorldConfiguration.CubeId.Air)
                    {
                        //Check the offset of the water
                        var Offset = CameraWorldPosition.Y - MathHelper.Floor(CameraWorldPosition.Y);
                        if (Offset >= 1 - _visualWorldParameters.WorldParameters.Configuration.BlockProfiles[_headCube.Id].YBlockOffset)
                        {
                            IsHeadInsideWater = false;
                            return;
                        }
                    }

                    IsHeadInsideWater = true;
                }
                else
                {
                    IsHeadInsideWater = false;
                }
            }
        }
Exemple #3
0
        public bool IsSolidToPlayer(ref Vector3D worldPosition)
        {
            int index;

            if (IndexYSafe(MathHelper.Floor(worldPosition.X), MathHelper.Floor(worldPosition.Y), MathHelper.Floor(worldPosition.Z), out index))
            {
                TerraCube cube = Cubes[index];
                return(_config.BlockProfiles[cube.Id].IsSolidToEntity);
            }

            return(true);
        }
Exemple #4
0
        public bool isPickable(ref Vector3 position, out TerraCube cube)
        {
            int cubeIndex;

            if (Index(MathHelper.Floor(position.X), MathHelper.Floor(position.Y), MathHelper.Floor(position.Z), true, out cubeIndex))
            {
                cube = Cubes[cubeIndex];
                // Simon disabled this, i dont want it and method was not in use :  if (Cubes[cubeIndex].Id == RealmConfiguration.CubeId.Air) cube = new TerraCube(CubeId.Error);
                return(_config.BlockProfiles[cube.Id].IsPickable);
            }

            cube = new TerraCube();
            return(false);
        }
Exemple #5
0
        //Default Face Generation Checks !
        public bool FaceGenerationCheck(ref TerraCube cube, ref Vector3I cubePosiInWorld, CubeFaces cubeFace, ref TerraCube NeightBorFaceCube)
        {
            //By default I don't need to trace the cubeFace of my cube if the face NeightBor cube is blocking light ! (Not see-through)
            BlockProfile blockProfile        = _wp.WorldParameters.Configuration.BlockProfiles[cube.Id];
            BlockProfile NeighborCubeProfile = _wp.WorldParameters.Configuration.BlockProfiles[NeightBorFaceCube.Id];

            if ((NeighborCubeProfile.IsSeeThrough) ||
                ((blockProfile.SideOffsetMultiplier > 0 ^ NeighborCubeProfile.SideOffsetMultiplier > 0) && cube.Id != NeightBorFaceCube.Id))
            {
                return(true);
            }
            //Else draw the face
            return(false);
        }
Exemple #6
0
        public bool isPickable(ref Vector3 position, ITool withTool, out TerraCube cube)
        {
            int cubeIndex;

            var cubePosition = new Vector3I(MathHelper.Floor(position.X), MathHelper.Floor(position.Y), MathHelper.Floor(position.Z));

            if (cubePosition.Y < _visualWorldParam.WorldRange.Max.Y - 1 && Index(ref cubePosition, true, out cubeIndex))
            {
                cube = Cubes[cubeIndex];
                return(_config.BlockProfiles[cube.Id].IsPickable);
            }

            cube = new TerraCube();
            return(false);
        }
        //Can only be done if surrounding chunks have their landscape initialized !
        //Will force lighting from cubes passed, even if not Alpha is not 255 = borderAsLightSource = true
        private void PropagateLightSourcesForced(Vector3I cubePosition, VisualChunk chunk)
        {
            int       index = _cubesHolder.Index(ref cubePosition);
            TerraCube cube  = _cubesHolder.Cubes[index];

            PropagateLight(cubePosition.X, cubePosition.Y, cubePosition.Z, cube.EmissiveColor.A, LightComponent.SunLight, true, index);

            if (cube.EmissiveColor.R > 0)
            {
                PropagateLight(cubePosition.X, cubePosition.Y, cubePosition.Z, cube.EmissiveColor.R, LightComponent.Red, true, index);
            }
            if (cube.EmissiveColor.G > 0)
            {
                PropagateLight(cubePosition.X, cubePosition.Y, cubePosition.Z, cube.EmissiveColor.G, LightComponent.Green, true, index);
            }
            if (cube.EmissiveColor.B > 0)
            {
                PropagateLight(cubePosition.X, cubePosition.Y, cubePosition.Z, cube.EmissiveColor.B, LightComponent.Blue, true, index);
            }
        }
 public TerraCubeWithPosition(Vector3I pos, byte cubeId, BlockProfile profile)
 {
     BlockProfile = profile;
     Position     = pos;
     Cube         = new TerraCube(cubeId);
 }
 public TerraCubeWithPosition(Vector3I pos, TerraCube cube, BlockProfile profile)
 {
     BlockProfile = profile;
     Position     = pos;
     Cube         = cube;
 }
        public void GenCubeFace(ref TerraCube cube, CubeFaces cubeFace, ref Vector4B cubePosition, ref Vector3I cubePosiInWorld, VisualChunk chunk, ref TerraCube topCube, Dictionary <long, int> verticeDico)
        {
            int       yBlockOffsetAsInt = 0;
            float     yBlockOffset      = 0;
            int       verticeCubeOffset = chunk.Graphics.LiquidCubeVertices.Count;
            int       indiceCubeOffset  = chunk.Graphics.LiquidCubeIndices.Count;
            ByteColor newColor          = cube.EmissiveColor;
            BlockTag  tag = null;

            BlockProfile blockProfile = _wp.WorldParameters.Configuration.BlockProfiles[cube.Id];

            //Get the Cube Tag Informations
            if (blockProfile.IsTaggable)
            {
                tag = chunk.BlockData.GetTag(new Vector3I(cubePosition.X, cubePosition.Y, cubePosition.Z));
            }

            bool IsEmissiveColor = blockProfile.IsEmissiveColorLightSource;
            bool vertexInDico;

            //Les 4 vertex de ma face.... en fct de leur position dans le cube leur valeur en Z va changer ! (Face Top, Bottom, ...
            Vector4B topLeft;
            Vector4B topRight;
            Vector4B bottomLeft;
            Vector4B bottomRight;

            //GetBlock Offset
            if (blockProfile.IsTaggable && tag is ICubeYOffsetModifier)
            {
                yBlockOffset = ((ICubeYOffsetModifier)tag).YOffset;
            }
            else
            {
                //Add a naturel Offset to StillWater when touching water at the surface !
                if (topCube.Id != cube.Id)
                {
                    yBlockOffset = (float)blockProfile.YBlockOffset;
                }
            }

            yBlockOffsetAsInt = (int)(yBlockOffset * 255);

            ChunkColumnInfo chunkInfo = chunk.BlockData.GetColumnInfo(new Vector2I(cubePosition.X, cubePosition.Z));

            Vector4B vertexInfo2 = new Vector4B(chunkInfo.Moisture, chunkInfo.Temperature, (byte)0, (byte)0);
            Vector4B vertexInfo1 = new Vector4B((byte)cubeFace,
                                                (byte)0,                //Is "UP" vertex
                                                blockProfile.BiomeColorArrayTexture,
                                                (byte)0);

            long hashVertex;
            int  generatedVertex = 0;
            int  vertexOffset0, vertexOffset1, vertexOffset2, vertexOffset3;

            int[] ind = new int[9];

            //Get the index of the current cube.
            int baseIndex = _cubesHolder.Index(ref cubePosiInWorld);

            switch (cubeFace)
            {
            case CubeFaces.Front:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.Z, SingleArrayChunkContainer.IdxRelativeMove.Z_Plus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.Z, ind, true);

                ByteColor Back_Cube            = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor;
                ByteColor BackLeft_Cube        = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor;
                ByteColor BackRight_Cube       = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor;
                ByteColor BackTop_Cube         = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor;
                ByteColor BackBottom_Cube      = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor;
                ByteColor BackLeftTop_Cube     = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor;
                ByteColor BackRightTop_Cube    = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor;
                ByteColor BackLeftBottom_Cube  = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor;
                ByteColor BackRightBottom_Cube = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor;

                topLeft     = cubePosition + new Vector4B(0, 1, 1, yBlockOffsetAsInt);
                topRight    = cubePosition + new Vector4B(1, 1, 1, yBlockOffsetAsInt);
                bottomLeft  = cubePosition + new Vector4B(0, 0, 1, yBlockOffsetAsInt);
                bottomRight = cubePosition + new Vector4B(1, 0, 1, yBlockOffsetAsInt);

                vertexInfo2.Z = blockProfile.Tex_Front.AnimationSpeed;
                vertexInfo2.W = blockProfile.Tex_Front.Texture.AnimationFrames;

                hashVertex   = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset0);
                if (vertexInDico == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Back_Cube, BackLeft_Cube, BackTop_Cube, BackLeftTop_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topLeft, blockProfile.Tex_Front.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset1);
                if (vertexInDico == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Back_Cube, BackRight_Cube, BackTop_Cube, BackRightTop_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topRight, blockProfile.Tex_Front.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset2);
                if (vertexInDico == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Back_Cube, BackLeft_Cube, BackBottom_Cube, BackLeftBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomLeft, blockProfile.Tex_Front.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset3);
                if (vertexInDico == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Back_Cube, BackRight_Cube, BackBottom_Cube, BackRightBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomRight, blockProfile.Tex_Front.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));

                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset3));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));

                break;

            case CubeFaces.Back:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.Z, SingleArrayChunkContainer.IdxRelativeMove.Z_Minus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.Z, ind, true);
                ByteColor Front_Cube            = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor;
                ByteColor FrontLeft_Cube        = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor;
                ByteColor FrontRight_Cube       = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor;
                ByteColor FrontTop_Cube         = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor;
                ByteColor FrontBottom_Cube      = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor;
                ByteColor FrontLeftTop_Cube     = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor;
                ByteColor FrontRightTop_Cube    = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor;
                ByteColor FrontLeftBottom_Cube  = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor;
                ByteColor FrontRightBottom_Cube = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor;

                topLeft     = cubePosition + new Vector4B(1, 1, 0, yBlockOffsetAsInt);
                topRight    = cubePosition + new Vector4B(0, 1, 0, yBlockOffsetAsInt);
                bottomLeft  = cubePosition + new Vector4B(1, 0, 0, yBlockOffsetAsInt);
                bottomRight = cubePosition + new Vector4B(0, 0, 0, yBlockOffsetAsInt);

                vertexInfo2.Z = blockProfile.Tex_Back.AnimationSpeed;
                vertexInfo2.W = blockProfile.Tex_Back.Texture.AnimationFrames;

                hashVertex   = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset0);
                if (vertexInDico == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Front_Cube, FrontTop_Cube, FrontLeftTop_Cube, FrontLeft_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topRight, blockProfile.Tex_Back.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset1);
                if (vertexInDico == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Front_Cube, FrontTop_Cube, FrontRight_Cube, FrontRightTop_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topLeft, blockProfile.Tex_Back.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset2);
                if (vertexInDico == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Front_Cube, FrontBottom_Cube, FrontLeft_Cube, FrontLeftBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomRight, blockProfile.Tex_Back.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset3);
                if (vertexInDico == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Front_Cube, FrontBottom_Cube, FrontRight_Cube, FrontRightBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomLeft, blockProfile.Tex_Back.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));

                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset3));

                break;

            case CubeFaces.Top:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.Y, SingleArrayChunkContainer.IdxRelativeMove.Y_Plus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.Y, ind, true);

                ByteColor Bottom_Cube            = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor;
                ByteColor BottomLeft_Cube        = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor;
                ByteColor BottomRight_Cube       = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor;
                ByteColor BottomTop_Cube         = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor;
                ByteColor BottomBottom_Cube      = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor;
                ByteColor BottomLeftTop_Cube     = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor;
                ByteColor BottomRightTop_Cube    = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor;
                ByteColor BottomLeftBottom_Cube  = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor;
                ByteColor BottomRightBottom_Cube = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor;

                topLeft     = cubePosition + new Vector4B(0, 1, 0, yBlockOffsetAsInt);
                topRight    = cubePosition + new Vector4B(1, 1, 0, yBlockOffsetAsInt);
                bottomLeft  = cubePosition + new Vector4B(0, 1, 1, yBlockOffsetAsInt);
                bottomRight = cubePosition + new Vector4B(1, 1, 1, yBlockOffsetAsInt);

                vertexInfo2.Z = blockProfile.Tex_Top.AnimationSpeed;
                vertexInfo2.W = blockProfile.Tex_Top.Texture.AnimationFrames;

                hashVertex   = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset0);
                if (vertexInDico == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Bottom_Cube, BottomLeft_Cube, BottomLeftTop_Cube, BottomTop_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topLeft, blockProfile.Tex_Top.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset1);
                if (vertexInDico == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Bottom_Cube, BottomRight_Cube, BottomBottom_Cube, BottomRightBottom_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomRight, blockProfile.Tex_Top.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset2);
                if (vertexInDico == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Bottom_Cube, BottomBottom_Cube, BottomLeft_Cube, BottomLeftBottom_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomLeft, blockProfile.Tex_Top.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset3);
                if (vertexInDico == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Bottom_Cube, BottomTop_Cube, BottomRight_Cube, BottomRightTop_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topRight, blockProfile.Tex_Top.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));

                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset3));
                break;

            case CubeFaces.Bottom:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.Y, SingleArrayChunkContainer.IdxRelativeMove.Y_Minus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.Y, ind, true);

                ByteColor Top_Cube            = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor;
                ByteColor TopLeft_Cube        = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor;
                ByteColor TopRight_Cube       = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor;
                ByteColor TopTop_Cube         = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor;
                ByteColor TopBottom_Cube      = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor;
                ByteColor TopLeftTop_Cube     = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor;
                ByteColor TopRightTop_Cube    = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor;
                ByteColor TopLeftBottom_Cube  = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor;
                ByteColor TopRightBottom_Cube = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor;

                topLeft     = cubePosition + new Vector4B(0, 0, 1, yBlockOffsetAsInt);
                topRight    = cubePosition + new Vector4B(1, 0, 1, yBlockOffsetAsInt);
                bottomLeft  = cubePosition + new Vector4B(0, 0, 0, yBlockOffsetAsInt);
                bottomRight = cubePosition + new Vector4B(1, 0, 0, yBlockOffsetAsInt);

                vertexInfo2.Z = blockProfile.Tex_Bottom.AnimationSpeed;
                vertexInfo2.W = blockProfile.Tex_Bottom.Texture.AnimationFrames;

                hashVertex   = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset0);
                if (vertexInDico == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Top_Cube, TopBottom_Cube, TopLeft_Cube, TopLeftBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topLeft, blockProfile.Tex_Bottom.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset1);
                if (vertexInDico == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Top_Cube, TopTop_Cube, TopLeft_Cube, TopLeftTop_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomLeft, blockProfile.Tex_Bottom.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset2);
                if (vertexInDico == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Top_Cube, TopBottom_Cube, TopRight_Cube, TopRightBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topRight, blockProfile.Tex_Bottom.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset3);
                if (vertexInDico == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Top_Cube, TopTop_Cube, TopRight_Cube, TopRightTop_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomRight, blockProfile.Tex_Bottom.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));

                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset3));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));
                break;

            case CubeFaces.Left:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.X, SingleArrayChunkContainer.IdxRelativeMove.X_Minus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.X, ind, true);

                ByteColor Right_Cube            = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor;
                ByteColor RightLeft_Cube        = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor;
                ByteColor RightRight_Cube       = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor;
                ByteColor RightTop_Cube         = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor;
                ByteColor RightBottom_Cube      = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor;
                ByteColor RightLeftTop_Cube     = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor;
                ByteColor RightRightTop_Cube    = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor;
                ByteColor RightLeftBottom_Cube  = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor;
                ByteColor RightRightBottom_Cube = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor;

                topLeft     = cubePosition + new Vector4B(0, 1, 0, yBlockOffsetAsInt);
                bottomRight = cubePosition + new Vector4B(0, 0, 1, yBlockOffsetAsInt);
                bottomLeft  = cubePosition + new Vector4B(0, 0, 0, yBlockOffsetAsInt);
                topRight    = cubePosition + new Vector4B(0, 1, 1, yBlockOffsetAsInt);

                vertexInfo2.Z = blockProfile.Tex_Left.AnimationSpeed;
                vertexInfo2.W = blockProfile.Tex_Left.Texture.AnimationFrames;

                hashVertex   = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset0);
                if (vertexInDico == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Right_Cube, RightTop_Cube, RightRight_Cube, RightRightTop_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topLeft, blockProfile.Tex_Left.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset1);
                if (vertexInDico == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Right_Cube, RightTop_Cube, RightLeft_Cube, RightLeftTop_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topRight, blockProfile.Tex_Left.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset2);
                if (vertexInDico == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Right_Cube, RightBottom_Cube, RightRight_Cube, RightRightBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomLeft, blockProfile.Tex_Left.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset3);
                if (vertexInDico == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Right_Cube, RightBottom_Cube, RightLeft_Cube, RightLeftBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomRight, blockProfile.Tex_Left.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset3));

                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset3));
                break;

            case CubeFaces.Right:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.X, SingleArrayChunkContainer.IdxRelativeMove.X_Plus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.X, ind, true);

                ByteColor Left_Cube            = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor;
                ByteColor LeftLeft_Cube        = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor;
                ByteColor LefttRight_Cube      = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor;
                ByteColor LeftTop_Cube         = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor;
                ByteColor LeftBottom_Cube      = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor;
                ByteColor LeftLeftTop_Cube     = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor;
                ByteColor LeftRightTop_Cube    = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor;
                ByteColor LeftLeftBottom_Cube  = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor;
                ByteColor LeftRightBottom_Cube = _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor;

                topLeft     = cubePosition + new Vector4B(1, 1, 1, yBlockOffsetAsInt);
                topRight    = cubePosition + new Vector4B(1, 1, 0, yBlockOffsetAsInt);
                bottomLeft  = cubePosition + new Vector4B(1, 0, 1, yBlockOffsetAsInt);
                bottomRight = cubePosition + new Vector4B(1, 0, 0, yBlockOffsetAsInt);

                vertexInfo2.Z = blockProfile.Tex_Right.AnimationSpeed;
                vertexInfo2.W = blockProfile.Tex_Right.Texture.AnimationFrames;

                hashVertex   = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset0);
                if (vertexInDico == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Left_Cube, LeftTop_Cube, LefttRight_Cube, LeftRightTop_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topRight, blockProfile.Tex_Right.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffsetAsInt << 48);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset1);
                if (vertexInDico == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Left_Cube, LeftTop_Cube, LeftLeft_Cube, LeftLeftTop_Cube);
                    }
                    vertexInfo1.Y = 1;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref topLeft, blockProfile.Tex_Right.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset2);
                if (vertexInDico == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Left_Cube, LeftBottom_Cube, LeftLeft_Cube, LeftLeftBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomLeft, blockProfile.Tex_Right.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                hashVertex   = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                vertexInDico = verticeDico.TryGetValue(hashVertex, out vertexOffset3);
                if (vertexInDico == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Left_Cube, LeftBottom_Cube, LefttRight_Cube, LeftRightBottom_Cube);
                    }
                    vertexInfo1.Y = 0;
                    chunk.Graphics.LiquidCubeVertices.Add(new VertexCubeLiquid(ref bottomRight, blockProfile.Tex_Right.TextureArrayId, ref newColor, ref vertexInfo2, ref vertexInfo1));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset3));

                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.LiquidCubeIndices.Add((ushort)(vertexOffset0));
                break;
            }
        }
Exemple #11
0
        public void EmitParticuleForCubeDestruction(int nbr, TerraCube cube, Vector3I CubeLocation, ref Vector3D cameraLocation)
        {
            //Check distance to emit
            if (MaxRenderingDistance > 0 && Vector3D.DistanceSquared(cameraLocation, new Vector3D(CubeLocation)) > _maxRenderingDistanceSquared)
            {
                return;
            }

            //GetCube Profile
            VisualChunk chunk   = null;
            var         profile = _visualWorldParameters.WorldParameters.Configuration.BlockProfiles[cube.Id];

            //Get Chunk in case if the block is subject to BiomeColoring
            chunk = _worldChunk.GetChunk(CubeLocation.X, CubeLocation.Z);

            //Foreach Surrending Cube
            ByteColor blockAvgColorReceived = new ByteColor();

            foreach (var surrendingCube in chunk.BlockData.ChunkCubes.GetSurroundingBlocksIndex(ref CubeLocation))
            {
                var cubeColor = chunk.BlockData.ChunkCubes.Cubes[surrendingCube.Index].EmissiveColor;
                blockAvgColorReceived.A = Math.Max(blockAvgColorReceived.A, cubeColor.A);
                blockAvgColorReceived.R = Math.Max(blockAvgColorReceived.R, cubeColor.R);
                blockAvgColorReceived.G = Math.Max(blockAvgColorReceived.G, cubeColor.G);
                blockAvgColorReceived.B = Math.Max(blockAvgColorReceived.B, cubeColor.B);
            }

            //Get Cube color palette
            Color[] palette = _cubeColorSampled[cube.Id];

            while (nbr > 0)
            {
                //Randomize the Velocity
                Vector3 finalVelocity = new Vector3(0, 1, 0);
                finalVelocity.X += (float)_rnd.NextDouble(-1.0, 1.0) * 1.5f;
                finalVelocity.Y += (float)_rnd.NextDouble() * 3f;
                finalVelocity.Z += (float)_rnd.NextDouble(-1.0, 1.0) * 1.5f;

                Vector3D CubeCenteredPosition = new Vector3D(CubeLocation.X + _rnd.NextDouble(0.2, 0.8), CubeLocation.Y + _rnd.NextDouble(0.2, 0.8), CubeLocation.Z + _rnd.NextDouble(0.2, 0.8));

                //Get Color
                var color = palette[_rnd.Next(24)];
                if (color.A < 255)
                {
                    ApplyBiomeColor(ref color, profile.BiomeColorArrayTexture, chunk.BlockData.GetColumnInfo(CubeLocation.X - chunk.ChunkPositionBlockUnit.X, CubeLocation.Z - chunk.ChunkPositionBlockUnit.Y));
                }

                _particules.Add(new ColoredParticule()
                {
                    Age              = 0 + (float)_rnd.NextDouble(0, 2.0),
                    computationAge   = 0,
                    InitialPosition  = CubeCenteredPosition,
                    ParticuleColor   = color,
                    Position         = new FTSValue <Vector3D>(CubeCenteredPosition),
                    Size             = new Vector2(0.1f, 0.1f),
                    Velocity         = finalVelocity,
                    ColorReceived    = blockAvgColorReceived,
                    SpinningRotation = Quaternion.RotationAxis(Vector3.UnitY, _rnd.NextFloat(-MathHelper.Pi / 8, MathHelper.Pi / 8)) *
                                       Quaternion.RotationAxis(Vector3.UnitX, _rnd.NextFloat(-MathHelper.Pi / 16, MathHelper.Pi / 16)) *
                                       Quaternion.RotationAxis(Vector3.UnitZ, _rnd.NextFloat(-MathHelper.Pi / 16, MathHelper.Pi / 16)),
                    RotationAngles = new FTSValue <Quaternion>(Quaternion.Identity)
                });

                nbr--;
            }
        }
Exemple #12
0
        public void GenCubeFace(ref TerraCube cube, CubeFaces cubeFace, ref Vector4B cubePosition, ref Vector3I cubePosiInWorld, VisualChunk chunk, ref TerraCube topCube, Dictionary <long, int> verticeDico)
        {
            byte      yBlockOffset      = 0;
            int       verticeCubeOffset = chunk.Graphics.SolidCubeVertices.Count;
            int       indiceCubeOffset  = chunk.Graphics.SolidCubeIndices.Count;
            ByteColor newColor          = cube.EmissiveColor;

            BlockProfile blockProfile    = _wp.WorldParameters.Configuration.BlockProfiles[cube.Id];
            bool         IsEmissiveColor = blockProfile.IsEmissiveColorLightSource;
            //Les 4 vertex de ma face.... en fct de leur position dans le cube leur valeur en Z va changer ! (Face Top, Bottom, ...)
            Vector4B topLeft;
            Vector4B topRight;
            Vector4B bottomLeft;
            Vector4B bottomRight;

            //x = Is Upper VErtex or not
            //y = Cube Face
            //z = Not used
            //w = Cube "Offset"

            //GetBlock Offset
            //This "natural" offset should only be made when the upper block is not the same as the block itself
            if (topCube.Id != cube.Id)
            {
                yBlockOffset = (byte)(blockProfile.YBlockOffset * 255);
            }

            Vector4B vertexInfo = new Vector4B((byte)0, (byte)cubeFace, (byte)(0), yBlockOffset);

            long hashVertex;
            int  generatedVertex = 0;
            int  vertexOffset0, vertexOffset1, vertexOffset2, vertexOffset3;

            //Get the index of the current cube.
            int baseIndex = _cubesHolder.Index(ref cubePosiInWorld);

            int[] ind = new int[9];

            ChunkColumnInfo chunkInfo = chunk.BlockData.GetColumnInfo(cubePosition.X, cubePosition.Z);

            Vector4B biomeInfo = new Vector4B(chunkInfo.Moisture, chunkInfo.Temperature, blockProfile.BiomeColorArrayTexture, blockProfile.SideOffsetMultiplier);

            switch (cubeFace)
            {
            case CubeFaces.Front:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.Z, SingleArrayChunkContainer.IdxRelativeMove.Z_Plus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.Z, ind, false);

                ByteColor Back_Cube            = (ind[SingleArrayChunkContainer.BaseIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor : new ByteColor();
                ByteColor BackLeft_Cube        = (ind[SingleArrayChunkContainer.LeftIndex] != int.MaxValue) ?_cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor : new ByteColor();
                ByteColor BackRight_Cube       = (ind[SingleArrayChunkContainer.RightIndex] != int.MaxValue) ?_cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor : new ByteColor();
                ByteColor BackTop_Cube         = (ind[SingleArrayChunkContainer.UpIndex] != int.MaxValue) ?_cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor : new ByteColor();
                ByteColor BackBottom_Cube      = (ind[SingleArrayChunkContainer.DownIndex] != int.MaxValue) ?_cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor : new ByteColor();
                ByteColor BackLeftTop_Cube     = (ind[SingleArrayChunkContainer.UpLeftIndex] != int.MaxValue) ?_cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor BackRightTop_Cube    = (ind[SingleArrayChunkContainer.UpRightIndex] != int.MaxValue) ?_cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor : new ByteColor();
                ByteColor BackLeftBottom_Cube  = (ind[SingleArrayChunkContainer.DownLeftIndex] != int.MaxValue) ?_cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor BackRightBottom_Cube = (ind[SingleArrayChunkContainer.DownRightIndex] != int.MaxValue) ?_cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor : new ByteColor();

                topLeft     = cubePosition + new Vector4B(0, 1, 1, 0);
                topRight    = cubePosition + new Vector4B(1, 1, 1, 0);
                bottomLeft  = cubePosition + new Vector4B(0, 0, 1, 0);
                bottomRight = cubePosition + new Vector4B(1, 0, 1, 0);

                hashVertex = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset0) == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Back_Cube, BackLeft_Cube, BackTop_Cube, BackLeftTop_Cube);
                    }
                    vertexInfo.X = 1;

                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topLeft, blockProfile.Tex_Front.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Front.AnimationSpeed, blockProfile.Tex_Front.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset1) == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Back_Cube, BackRight_Cube, BackTop_Cube, BackRightTop_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topRight, blockProfile.Tex_Front.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Front.AnimationSpeed, blockProfile.Tex_Front.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset2) == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Back_Cube, BackLeft_Cube, BackBottom_Cube, BackLeftBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomLeft, blockProfile.Tex_Front.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Front.AnimationSpeed, blockProfile.Tex_Front.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset3) == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Back_Cube, BackRight_Cube, BackBottom_Cube, BackRightBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomRight, blockProfile.Tex_Front.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Front.AnimationSpeed, blockProfile.Tex_Front.Texture.AnimationFrames));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));

                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset3));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));

                break;

            case CubeFaces.Back:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.Z, SingleArrayChunkContainer.IdxRelativeMove.Z_Minus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.Z, ind, false);

                ByteColor Front_Cube            = (ind[SingleArrayChunkContainer.BaseIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor : new ByteColor();
                ByteColor FrontLeft_Cube        = (ind[SingleArrayChunkContainer.LeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor : new ByteColor();
                ByteColor FrontRight_Cube       = (ind[SingleArrayChunkContainer.RightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor : new ByteColor();
                ByteColor FrontTop_Cube         = (ind[SingleArrayChunkContainer.UpIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor : new ByteColor();
                ByteColor FrontBottom_Cube      = (ind[SingleArrayChunkContainer.DownIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor : new ByteColor();
                ByteColor FrontLeftTop_Cube     = (ind[SingleArrayChunkContainer.UpLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor FrontRightTop_Cube    = (ind[SingleArrayChunkContainer.UpRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor : new ByteColor();
                ByteColor FrontLeftBottom_Cube  = (ind[SingleArrayChunkContainer.DownLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor FrontRightBottom_Cube = (ind[SingleArrayChunkContainer.DownRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor : new ByteColor();

                topLeft     = cubePosition + new Vector4B(1, 1, 0, 0);
                topRight    = cubePosition + new Vector4B(0, 1, 0, 0);
                bottomLeft  = cubePosition + new Vector4B(1, 0, 0, 0);
                bottomRight = cubePosition + new Vector4B(0, 0, 0, 0);

                hashVertex = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset0) == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Front_Cube, FrontTop_Cube, FrontLeftTop_Cube, FrontLeft_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topRight, blockProfile.Tex_Back.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Back.AnimationSpeed, blockProfile.Tex_Back.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset1) == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Front_Cube, FrontTop_Cube, FrontRight_Cube, FrontRightTop_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topLeft, blockProfile.Tex_Back.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Back.AnimationSpeed, blockProfile.Tex_Back.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset2) == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Front_Cube, FrontBottom_Cube, FrontLeft_Cube, FrontLeftBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomRight, blockProfile.Tex_Back.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Back.AnimationSpeed, blockProfile.Tex_Back.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset3) == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Front_Cube, FrontBottom_Cube, FrontRight_Cube, FrontRightBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomLeft, blockProfile.Tex_Back.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Back.AnimationSpeed, blockProfile.Tex_Back.Texture.AnimationFrames));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));

                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset3));

                break;

            case CubeFaces.Top:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.Y, SingleArrayChunkContainer.IdxRelativeMove.Y_Plus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.Y, ind, false);

                ByteColor Bottom_Cube            = (ind[SingleArrayChunkContainer.BaseIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor : new ByteColor();
                ByteColor BottomLeft_Cube        = (ind[SingleArrayChunkContainer.LeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor : new ByteColor();
                ByteColor BottomRight_Cube       = (ind[SingleArrayChunkContainer.RightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor : new ByteColor();
                ByteColor BottomTop_Cube         = (ind[SingleArrayChunkContainer.UpIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor : new ByteColor();
                ByteColor BottomBottom_Cube      = (ind[SingleArrayChunkContainer.DownIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor : new ByteColor();
                ByteColor BottomLeftTop_Cube     = (ind[SingleArrayChunkContainer.UpLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor BottomRightTop_Cube    = (ind[SingleArrayChunkContainer.UpRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor : new ByteColor();
                ByteColor BottomLeftBottom_Cube  = (ind[SingleArrayChunkContainer.DownLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor BottomRightBottom_Cube = (ind[SingleArrayChunkContainer.DownRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor : new ByteColor();

                topLeft     = cubePosition + new Vector4B(0, 1, 0, 0);
                topRight    = cubePosition + new Vector4B(1, 1, 0, 0);
                bottomLeft  = cubePosition + new Vector4B(0, 1, 1, 0);
                bottomRight = cubePosition + new Vector4B(1, 1, 1, 0);

                hashVertex = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset0) == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Bottom_Cube, BottomLeft_Cube, BottomLeftTop_Cube, BottomTop_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topLeft, blockProfile.Tex_Top.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Top.AnimationSpeed, blockProfile.Tex_Top.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset1) == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Bottom_Cube, BottomRight_Cube, BottomBottom_Cube, BottomRightBottom_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomRight, blockProfile.Tex_Top.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Top.AnimationSpeed, blockProfile.Tex_Top.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset2) == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Bottom_Cube, BottomBottom_Cube, BottomLeft_Cube, BottomLeftBottom_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomLeft, blockProfile.Tex_Top.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Top.AnimationSpeed, blockProfile.Tex_Top.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset3) == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Bottom_Cube, BottomTop_Cube, BottomRight_Cube, BottomRightTop_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topRight, blockProfile.Tex_Top.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Top.AnimationSpeed, blockProfile.Tex_Top.Texture.AnimationFrames));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));

                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset3));

                break;

            case CubeFaces.Bottom:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.Y, SingleArrayChunkContainer.IdxRelativeMove.Y_Minus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.Y, ind, false);

                ByteColor Top_Cube            = (ind[SingleArrayChunkContainer.BaseIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor : new ByteColor();
                ByteColor TopLeft_Cube        = (ind[SingleArrayChunkContainer.LeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor : new ByteColor();
                ByteColor TopRight_Cube       = (ind[SingleArrayChunkContainer.RightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor : new ByteColor();
                ByteColor TopTop_Cube         = (ind[SingleArrayChunkContainer.UpIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor : new ByteColor();
                ByteColor TopBottom_Cube      = (ind[SingleArrayChunkContainer.DownIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor : new ByteColor();
                ByteColor TopLeftTop_Cube     = (ind[SingleArrayChunkContainer.UpLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor TopRightTop_Cube    = (ind[SingleArrayChunkContainer.UpRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor : new ByteColor();
                ByteColor TopLeftBottom_Cube  = (ind[SingleArrayChunkContainer.DownLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor TopRightBottom_Cube = (ind[SingleArrayChunkContainer.DownRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor : new ByteColor();

                topLeft     = cubePosition + new Vector4B(0, 0, 1, 0);
                topRight    = cubePosition + new Vector4B(1, 0, 1, 0);
                bottomLeft  = cubePosition + new Vector4B(0, 0, 0, 0);
                bottomRight = cubePosition + new Vector4B(1, 0, 0, 0);

                hashVertex = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset0) == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Top_Cube, TopBottom_Cube, TopLeft_Cube, TopLeftBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topLeft, blockProfile.Tex_Bottom.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Bottom.AnimationSpeed, blockProfile.Tex_Bottom.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset1) == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Top_Cube, TopTop_Cube, TopLeft_Cube, TopLeftTop_Cube);
                    }
                    vertexInfo.X = 0;
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomLeft, blockProfile.Tex_Bottom.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Bottom.AnimationSpeed, blockProfile.Tex_Bottom.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset2) == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Top_Cube, TopBottom_Cube, TopRight_Cube, TopRightBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topRight, blockProfile.Tex_Bottom.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Bottom.AnimationSpeed, blockProfile.Tex_Bottom.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset3) == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Top_Cube, TopTop_Cube, TopRight_Cube, TopRightTop_Cube);
                    }
                    vertexInfo.X = 0;
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomRight, blockProfile.Tex_Bottom.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Bottom.AnimationSpeed, blockProfile.Tex_Bottom.Texture.AnimationFrames));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));

                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset3));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));

                break;

            case CubeFaces.Left:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.X, SingleArrayChunkContainer.IdxRelativeMove.X_Minus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.X, ind, false);

                ByteColor Right_Cube            = (ind[SingleArrayChunkContainer.BaseIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor : new ByteColor();
                ByteColor RightLeft_Cube        = (ind[SingleArrayChunkContainer.LeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor : new ByteColor();
                ByteColor RightRight_Cube       = (ind[SingleArrayChunkContainer.RightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor : new ByteColor();
                ByteColor RightTop_Cube         = (ind[SingleArrayChunkContainer.UpIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor : new ByteColor();
                ByteColor RightBottom_Cube      = (ind[SingleArrayChunkContainer.DownIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor : new ByteColor();
                ByteColor RightLeftTop_Cube     = (ind[SingleArrayChunkContainer.UpLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor RightRightTop_Cube    = (ind[SingleArrayChunkContainer.UpRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor : new ByteColor();
                ByteColor RightLeftBottom_Cube  = (ind[SingleArrayChunkContainer.DownLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor RightRightBottom_Cube = (ind[SingleArrayChunkContainer.DownRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor : new ByteColor();

                topLeft     = cubePosition + new Vector4B(0, 1, 0, 0);
                bottomRight = cubePosition + new Vector4B(0, 0, 1, 0);
                bottomLeft  = cubePosition + new Vector4B(0, 0, 0, 0);
                topRight    = cubePosition + new Vector4B(0, 1, 1, 0);

                hashVertex = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset0) == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Right_Cube, RightTop_Cube, RightRight_Cube, RightRightTop_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topLeft, blockProfile.Tex_Left.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Left.AnimationSpeed, blockProfile.Tex_Left.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset1) == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Right_Cube, RightTop_Cube, RightLeft_Cube, RightLeftTop_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topRight, blockProfile.Tex_Left.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Left.AnimationSpeed, blockProfile.Tex_Left.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset2) == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Right_Cube, RightBottom_Cube, RightRight_Cube, RightRightBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomLeft, blockProfile.Tex_Left.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Left.AnimationSpeed, blockProfile.Tex_Left.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset3) == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Right_Cube, RightBottom_Cube, RightLeft_Cube, RightLeftBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomRight, blockProfile.Tex_Left.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Left.AnimationSpeed, blockProfile.Tex_Left.Texture.AnimationFrames));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset3));

                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset3));
                break;

            case CubeFaces.Right:

                //Get the 9 Facing cubes to the face
                _cubesHolder.SurroundingAxisIndex(_cubesHolder.FastIndex(baseIndex, cubePosiInWorld.X, SingleArrayChunkContainer.IdxRelativeMove.X_Plus1), cubePosiInWorld.X, cubePosiInWorld.Y, cubePosiInWorld.Z, SingleArrayChunkContainer.Axis.X, ind, false);

                ByteColor Left_Cube            = (ind[SingleArrayChunkContainer.BaseIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.BaseIndex]].EmissiveColor : new ByteColor();
                ByteColor LeftLeft_Cube        = (ind[SingleArrayChunkContainer.LeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.LeftIndex]].EmissiveColor : new ByteColor();
                ByteColor LefttRight_Cube      = (ind[SingleArrayChunkContainer.RightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.RightIndex]].EmissiveColor : new ByteColor();
                ByteColor LeftTop_Cube         = (ind[SingleArrayChunkContainer.UpIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpIndex]].EmissiveColor : new ByteColor();
                ByteColor LeftBottom_Cube      = (ind[SingleArrayChunkContainer.DownIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownIndex]].EmissiveColor : new ByteColor();
                ByteColor LeftLeftTop_Cube     = (ind[SingleArrayChunkContainer.UpLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor LeftRightTop_Cube    = (ind[SingleArrayChunkContainer.UpRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.UpRightIndex]].EmissiveColor : new ByteColor();
                ByteColor LeftLeftBottom_Cube  = (ind[SingleArrayChunkContainer.DownLeftIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownLeftIndex]].EmissiveColor : new ByteColor();
                ByteColor LeftRightBottom_Cube = (ind[SingleArrayChunkContainer.DownRightIndex] != int.MaxValue) ? _cubesHolder.Cubes[ind[SingleArrayChunkContainer.DownRightIndex]].EmissiveColor : new ByteColor();

                topLeft     = cubePosition + new Vector4B(1, 1, 1, 0);
                topRight    = cubePosition + new Vector4B(1, 1, 0, 0);
                bottomLeft  = cubePosition + new Vector4B(1, 0, 1, 0);
                bottomRight = cubePosition + new Vector4B(1, 0, 0, 0);

                hashVertex = (long)cubeFace + ((long)topRight.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset0) == false)
                {
                    vertexOffset0 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset0);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Left_Cube, LeftTop_Cube, LefttRight_Cube, LeftRightTop_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topRight, blockProfile.Tex_Right.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Right.AnimationSpeed, blockProfile.Tex_Left.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)topLeft.GetHashCode() << 8) + ((long)cube.Id << 40) + ((long)yBlockOffset << 48);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset1) == false)
                {
                    vertexOffset1 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset1);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Left_Cube, LeftTop_Cube, LeftLeft_Cube, LeftLeftTop_Cube);
                    }
                    vertexInfo.X = 1;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref topLeft, blockProfile.Tex_Right.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Right.AnimationSpeed, blockProfile.Tex_Left.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomLeft.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset2) == false)
                {
                    vertexOffset2 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset2);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Left_Cube, LeftBottom_Cube, LeftLeft_Cube, LeftLeftBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomLeft, blockProfile.Tex_Right.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Right.AnimationSpeed, blockProfile.Tex_Left.Texture.AnimationFrames));
                    generatedVertex++;
                }

                hashVertex = (long)cubeFace + ((long)bottomRight.GetHashCode() << 8) + ((long)cube.Id << 40);
                if (verticeDico.TryGetValue(hashVertex, out vertexOffset3) == false)
                {
                    vertexOffset3 = generatedVertex + verticeCubeOffset;
                    verticeDico.Add(hashVertex, vertexOffset3);
                    if (!IsEmissiveColor)
                    {
                        newColor = ByteColor.Average(Left_Cube, LeftBottom_Cube, LefttRight_Cube, LeftRightBottom_Cube);
                    }
                    vertexInfo.X = 0;
                    //if (chunk.SliceValue > 0 && newColor == ByteColor.Zero) newColor = new ByteColor(0, 0, 0, 40);
                    chunk.Graphics.SolidCubeVertices.Add(new VertexCubeSolid(ref bottomRight, blockProfile.Tex_Right.TextureArrayId, ref newColor, ref vertexInfo, ref biomeInfo, blockProfile.Tex_Right.AnimationSpeed, blockProfile.Tex_Left.Texture.AnimationFrames));
                    generatedVertex++;
                }

                //Create Vertices
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset0));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset3));

                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset1));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset2));
                chunk.Graphics.SolidCubeIndices.Add((ushort)(vertexOffset0));

                break;
            }
        }
        private void GenerateCubesFace(CubeFaces cubeFace, VisualChunk chunk)
        {
            TerraCube    currentCube, neightborCube, topCube;
            BlockProfile blockProfile, neightborCubeProfile;

            Vector4B cubePosiInChunk = new Vector4B(0, 0, 0, 1);
            Vector3I cubePosiInWorld;
            int      XWorld, YWorld, ZWorld;
            int      neightborCubeIndex;

            int baseCubeIndex = _cubesHolder.Index(chunk.CubeRange.Position.X, chunk.CubeRange.Position.Y, chunk.CubeRange.Position.Z);
            int cubeIndexX    = baseCubeIndex;
            int cubeIndexZ    = baseCubeIndex;
            int cubeIndex     = baseCubeIndex;

            var worldRangeMaxX = _visualWorldParameters.WorldRange.Max.X;
            var worldRangeMaxY = _visualWorldParameters.WorldRange.Max.Y;
            var worldRangeMaxZ = _visualWorldParameters.WorldRange.Max.Z;
            int xNeight, yNeight, zNeight;

            byte yMin = (byte)(chunk.Graphics.SliceValue == -1 ? 0 : Math.Max(0, chunk.Graphics.SliceValue - 5));
            byte yMax = (byte)(chunk.Graphics.SliceValue == -1 ? chunk.CubeRange.Size.Y : chunk.Graphics.SliceValue);

            Dictionary <long, int> verticeDico = new Dictionary <long, int>();

            for (byte x = 0; x < AbstractChunk.ChunkSize.X; x++)
            {
                XWorld = (x + chunk.CubeRange.Position.X);
                if (x != 0)
                {
                    cubeIndexX += _cubesHolder.MoveX;
                    cubeIndexZ  = cubeIndexX;
                    cubeIndex   = cubeIndexX;
                }

                for (byte z = 0; z < AbstractChunk.ChunkSize.Z; z++)
                {
                    ZWorld = (z + chunk.CubeRange.Position.Z);

                    if (z != 0)
                    {
                        cubeIndexZ += _cubesHolder.MoveZ;
                        cubeIndex   = cubeIndexZ;
                    }

                    for (byte y = yMin; y < yMax; y++)
                    {
                        //_cubeRange in fact identify the chunk, the chunk position in the world being _cubeRange.Min
                        YWorld = (y + chunk.CubeRange.Position.Y);

                        if (y != yMin)
                        {
                            cubeIndex += _cubesHolder.MoveY;
                        }
                        else
                        {
                            cubeIndex += _cubesHolder.MoveY * yMin;
                        }

                        //_cubesHolder.Cubes[] is the BIG table containing all terraCube in the visible world.
                        //For speed access, I use an array with only one dimension, thus the table index must be computed from the X, Y, Z position of the terracube.
                        //Computing myself this index, is faster than using an array defined as [x,y,z]

                        //Terra Cube contain only the data that are variables, and could be different between 2 cube.
                        currentCube = _cubesHolder.Cubes[cubeIndex];

                        // ? Am I an Air Cube ? ==> Default Value, not needed to render !
                        if (currentCube.Id == WorldConfiguration.CubeId.Air)
                        {
                            continue;
                        }

                        //The Cube profile contain the value that are fixed for a block type.
                        blockProfile = _visualWorldParameters.WorldParameters.Configuration.BlockProfiles[currentCube.Id];

                        cubePosiInWorld   = new Vector3I(XWorld, YWorld, ZWorld);
                        cubePosiInChunk.X = x; //cubePosiInChunk = new Vector4B(x, y, z);
                        cubePosiInChunk.Y = y;
                        cubePosiInChunk.Z = z;
                        //Check to see if the face needs to be generated or not !
                        //Border Chunk test ! ==> Don't generate faces that are "border" chunks
                        //BorderChunk value is true if the chunk is at the border of the visible world.
                        int topCubeIndex = cubeIndex + _cubesHolder.MoveY;

                        xNeight = x;
                        yNeight = y;
                        zNeight = z;

                        switch (cubeFace)
                        {
                        case CubeFaces.Back:
                            if (ZWorld - 1 < _visualWorldParameters.WorldRange.Position.Z)
                            {
                                continue;
                            }
                            neightborCubeIndex = _cubesHolder.FastIndex(cubeIndex, ZWorld, SingleArrayChunkContainer.IdxRelativeMove.Z_Minus1);
                            zNeight--;
                            break;

                        case CubeFaces.Front:
                            if (ZWorld + 1 >= worldRangeMaxZ)
                            {
                                continue;
                            }
                            neightborCubeIndex = _cubesHolder.FastIndex(cubeIndex, ZWorld, SingleArrayChunkContainer.IdxRelativeMove.Z_Plus1);
                            zNeight++;
                            break;

                        case CubeFaces.Bottom:
                            if (YWorld - 1 < yMin)
                            {
                                continue;
                            }
                            neightborCubeIndex = cubeIndex - _cubesHolder.MoveY;
                            yNeight--;
                            break;

                        case CubeFaces.Top:
                            if (YWorld + 1 > worldRangeMaxY)
                            {
                                continue;
                            }
                            neightborCubeIndex = topCubeIndex;
                            yNeight++;
                            break;

                        case CubeFaces.Left:
                            if (XWorld - 1 < _visualWorldParameters.WorldRange.Position.X)
                            {
                                continue;
                            }
                            neightborCubeIndex = _cubesHolder.FastIndex(cubeIndex, XWorld, SingleArrayChunkContainer.IdxRelativeMove.X_Minus1);
                            xNeight--;
                            break;

                        case CubeFaces.Right:
                            if (XWorld + 1 >= worldRangeMaxX)
                            {
                                continue;
                            }
                            neightborCubeIndex = _cubesHolder.FastIndex(cubeIndex, XWorld, SingleArrayChunkContainer.IdxRelativeMove.X_Plus1);
                            xNeight++;
                            break;

                        default:
                            throw new NullReferenceException();
                        }

                        if (YWorld + 1 < yMax)
                        {
                            neightborCube = _cubesHolder.Cubes[neightborCubeIndex];
                        }
                        else
                        {
                            neightborCube = new TerraCube(WorldConfiguration.CubeId.Air);
                        }

                        neightborCubeProfile = _visualWorldParameters.WorldParameters.Configuration.BlockProfiles[neightborCube.Id];

                        //Check if a tag is present and ICubeYOffsetModifier is implementad by the tag;
                        float cubeYOffset = (float)blockProfile.YBlockOffset;    //Natural YOffset of the Cube
                        if (blockProfile.IsTaggable)
                        {
                            BlockTag             tag       = chunk.BlockData.GetTag(new Vector3I(x, y, z));
                            ICubeYOffsetModifier tagOffset = tag as ICubeYOffsetModifier;   //If block is taggle then it will overide the natural UOffset
                            if (tagOffset != null)
                            {
                                cubeYOffset = tagOffset.YOffset;
                            }
                        }

                        float neightborcubeYOffset = (float)neightborCubeProfile.YBlockOffset;
                        if (neightborCubeProfile.IsTaggable)
                        {
                            //Find the chunk where this neightboor is located !! (Could be a chunk next to this one !)
                            Vector3I    NeightCubeWorldPosition = new Vector3I(xNeight + chunk.CubeRange.Position.X, yNeight, zNeight + chunk.CubeRange.Position.Z);
                            VisualChunk neighbChunk             = WorldChunks.GetChunk(NeightCubeWorldPosition);

                            BlockTag             tag       = neighbChunk.BlockData.GetTag(new Vector3I(NeightCubeWorldPosition.X - neighbChunk.CubeRange.Position.X, yNeight, NeightCubeWorldPosition.Z - neighbChunk.CubeRange.Position.Z));
                            ICubeYOffsetModifier tagOffset = tag as ICubeYOffsetModifier;
                            if (tagOffset != null)
                            {
                                neightborcubeYOffset = tagOffset.YOffset;
                            }
                        }

                        bool yOffsetDiff = (cubeYOffset < neightborcubeYOffset && cubeFace != CubeFaces.Top) || (cubeYOffset > 0 && cubeFace == CubeFaces.Top); // && neightborCube.Id != currentCube.Id);

                        switch (blockProfile.CubeFamilly)
                        {
                        case enuCubeFamilly.Solid:
                            //Default linked to : CubeMeshFactory.GenSolidCubeFace;
                            if (!yOffsetDiff && !_solidCubeMeshFactory.FaceGenerationCheck(ref currentCube, ref cubePosiInWorld, cubeFace, ref neightborCube))
                            {
                                continue;
                            }
                            topCube = _cubesHolder.Cubes[topCubeIndex];
                            _solidCubeMeshFactory.GenCubeFace(ref currentCube, cubeFace, ref cubePosiInChunk, ref cubePosiInWorld, chunk, ref topCube, verticeDico);
                            break;

                        case enuCubeFamilly.Liquid:
                            //Default linked to : CubeMeshFactory.GenLiquidCubeFace;

                            //In case of Water block, never display the bottom or up face if both cube are of the same type !
                            if (cubeFace == CubeFaces.Top || cubeFace == CubeFaces.Bottom)
                            {
                                if (neightborCube.Id == currentCube.Id)
                                {
                                    continue;
                                }
                            }

                            if (!yOffsetDiff && !_liquidCubeMeshFactory.FaceGenerationCheck(ref currentCube, ref cubePosiInWorld, cubeFace, ref neightborCube))
                            {
                                continue;
                            }
                            topCube = _cubesHolder.Cubes[topCubeIndex];
                            _liquidCubeMeshFactory.GenCubeFace(ref currentCube, cubeFace, ref cubePosiInChunk, ref cubePosiInWorld, chunk, ref topCube, verticeDico);
                            break;

                        case enuCubeFamilly.Other:
                            break;
                        }
                    }
                }
            }
            verticeDico.Clear();
        }