Beispiel #1
0
        protected bool TrySnowGrowZ(CuboidWithMaterial cub, bool[,,] voxels, bool[,] voxelVisited)
        {
            if (cub.Z2 > 15)
            {
                return(false);
            }

            for (int x = cub.X1; x < cub.X2; x++)
            {
                // Stop if
                // "Floor" is gone, already visited, or there's a voxel above
                if (!voxels[x, cub.Y1, cub.Z2] || voxelVisited[x, cub.Z2] || (cub.Y2 < 15 && voxels[x, cub.Y2, cub.Z2]))
                {
                    return(false);
                }
            }

            for (int x = cub.X1; x < cub.X2; x++)
            {
                voxelVisited[x, cub.Z2] = true;
            }

            cub.Z2++;
            return(true);
        }
Beispiel #2
0
        public static MeshData CreateDecalMesh(ICoreClientAPI coreClientAPI, List <uint> voxelCuboids, ITexPositionSource decalTexSource)
        {
            MeshData mesh = new MeshData(24, 36, false).WithColorMaps().WithRenderpasses().WithXyzFaces();

            CuboidWithMaterial cwm = tmpCuboid;

            for (int i = 0; i < voxelCuboids.Count; i++)
            {
                FromUint(voxelCuboids[i], cwm);

                MeshData cuboidmesh = genCube(
                    cwm.X1, cwm.Y1, cwm.Z1,
                    cwm.X2 - cwm.X1, cwm.Y2 - cwm.Y1, cwm.Z2 - cwm.Z1,
                    coreClientAPI,
                    decalTexSource,
                    0,
                    0,
                    coreClientAPI.World.GetBlock(0)
                    );

                mesh.AddMeshData(cuboidmesh);
            }

            return(mesh);
        }
Beispiel #3
0
        private bool TryGrowX(CuboidWithMaterial cub, bool[,,] voxels, bool[,,] voxelVisited, byte[,,] voxelMaterial)
        {
            if (cub.X2 > 15)
            {
                return(false);
            }

            for (int y = cub.Y1; y < cub.Y2; y++)
            {
                for (int z = cub.Z1; z < cub.Z2; z++)
                {
                    if (!voxels[cub.X2, y, z] || voxelVisited[cub.X2, y, z] || voxelMaterial[cub.X2, y, z] != cub.Material)
                    {
                        return(false);
                    }
                }
            }

            for (int y = cub.Y1; y < cub.Y2; y++)
            {
                for (int z = cub.Z1; z < cub.Z2; z++)
                {
                    voxelVisited[cub.X2, y, z] = true;
                }
            }

            cub.X2++;
            return(true);
        }
Beispiel #4
0
        public override void RegenSelectionBoxes(IPlayer byPlayer)
        {
            // Create a temporary array first, because the offthread particle system might otherwise access a null collisionbox
            Cuboidf[]          selectionBoxesTmp = new Cuboidf[VoxelCuboids.Count];
            CuboidWithMaterial cwm = tmpCuboids[0];

            totalVoxels = 0;

            for (int i = 0; i < VoxelCuboids.Count; i++)
            {
                FromUint(VoxelCuboids[i], cwm);
                selectionBoxesTmp[i] = cwm.ToCuboidf();

                totalVoxels += cwm.Volume;
            }
            selectionBoxes = selectionBoxesTmp;


            if (byPlayer != null)
            {
                RegenSelectionVoxelBoxes(false, byPlayer);
            }
            else
            {
                selectionBoxesVoxels = null;
            }
        }
Beispiel #5
0
        private bool TryGrowY(CuboidWithMaterial cub, bool[,,] voxels, bool[,,] voxelVisited, byte[,,] voxelMaterial)
        {
            if (cub.Y2 > 15)
            {
                return(false);
            }

            for (int x = cub.X1; x < cub.X2; x++)
            {
                for (int z = cub.Z1; z < cub.Z2; z++)
                {
                    if (!voxels[x, cub.Y2, z] || voxelVisited[x, cub.Y2, z] || voxelMaterial[x, cub.Y2, z] != cub.Material)
                    {
                        return(false);
                    }
                }
            }

            for (int x = cub.X1; x < cub.X2; x++)
            {
                for (int z = cub.Z1; z < cub.Z2; z++)
                {
                    voxelVisited[x, cub.Y2, z] = true;
                }
            }

            cub.Y2++;
            return(true);
        }
Beispiel #6
0
        protected void RotateModel(IPlayer byPlayer, bool clockwise)
        {
            List <uint>        rotatedCuboids = new List <uint>();
            CuboidWithMaterial cwm            = tmpCuboid;

            foreach (var val in VoxelCuboids)
            {
                FromUint(val, cwm);
                Cuboidi rotated = cwm.RotatedCopy(0, clockwise ? 90 : -90, 0, new Vec3d(8, 8, 8));
                cwm.Set(rotated.X1, rotated.Y1, rotated.Z1, rotated.X2, rotated.Y2, rotated.Z2);
                rotatedCuboids.Add(ToCuboid(cwm));
            }
            VoxelCuboids = rotatedCuboids;

            rotatedCuboids = new List <uint>();
            foreach (var val in SnowCuboids)
            {
                FromUint(val, cwm);
                Cuboidi rotated = cwm.RotatedCopy(0, clockwise ? 90 : -90, 0, new Vec3d(8, 8, 8));
                cwm.Set(rotated.X1, rotated.Y1, rotated.Z1, rotated.X2, rotated.Y2, rotated.Z2);
                rotatedCuboids.Add(ToCuboid(cwm));
            }

            SnowCuboids = rotatedCuboids;
        }
Beispiel #7
0
        protected void convertToVoxels(out bool[,,] voxels, out byte[,,] materials)
        {
            voxels    = new bool[16, 16, 16];
            materials = new byte[16, 16, 16];
            CuboidWithMaterial cwm = tmpCuboid;



            for (int i = 0; i < VoxelCuboids.Count; i++)
            {
                FromUint(VoxelCuboids[i], cwm);

                for (int dx = cwm.X1; dx < cwm.X2; dx++)
                {
                    for (int dy = cwm.Y1; dy < cwm.Y2; dy++)
                    {
                        for (int dz = cwm.Z1; dz < cwm.Z2; dz++)
                        {
                            voxels[dx, dy, dz]    = true;
                            materials[dx, dy, dz] = cwm.Material;
                        }
                    }
                }
            }
        }
Beispiel #8
0
        private bool TryGrowZ(CuboidWithMaterial cub, bool[,,] voxels, bool[,,] voxelVisited, byte[,,] voxelMaterial)
        {
            if (cub.Z2 > 15)
            {
                return(false);
            }

            for (int x = cub.X1; x < cub.X2; x++)
            {
                for (int y = cub.Y1; y < cub.Y2; y++)
                {
                    if (!voxels[x, y, cub.Z2] || voxelVisited[x, y, cub.Z2] || voxelMaterial[x, y, cub.Z2] != cub.Material)
                    {
                        return(false);
                    }
                }
            }

            for (int x = cub.X1; x < cub.X2; x++)
            {
                for (int y = cub.Y1; y < cub.Y2; y++)
                {
                    voxelVisited[x, y, cub.Z2] = true;
                }
            }

            cub.Z2++;
            return(true);
        }
Beispiel #9
0
 public static void FromUint(uint val, ref CuboidWithMaterial tocuboid)
 {
     tocuboid.X1       = (int)((val) & 15);
     tocuboid.Y1       = (int)((val >> 4) & 15);
     tocuboid.Z1       = (int)((val >> 8) & 15);
     tocuboid.X2       = (int)(((val) >> 12) & 15) + 1;
     tocuboid.Y2       = (int)(((val) >> 16) & 15) + 1;
     tocuboid.Z2       = (int)(((val) >> 20) & 15) + 1;
     tocuboid.Material = (byte)((val >> 24) & 15);
 }
Beispiel #10
0
        public static MeshData CreateMesh(ICoreClientAPI coreClientAPI, List <uint> voxelCuboids, int[] materials, BlockPos posForRnd = null)
        {
            MeshData mesh = new MeshData(24, 36, false).WithColorMaps().WithRenderpasses().WithXyzFaces();

            if (voxelCuboids == null || materials == null)
            {
                return(mesh);
            }
            CuboidWithMaterial cwm = tmpCuboid;

            for (int i = 0; i < voxelCuboids.Count; i++)
            {
                FromUint(voxelCuboids[i], cwm);

                Block block = coreClientAPI.World.GetBlock(materials[cwm.Material]);

                float subPixelPaddingx = coreClientAPI.BlockTextureAtlas.SubPixelPaddingX;
                float subPixelPaddingy = coreClientAPI.BlockTextureAtlas.SubPixelPaddingY;

                int altNum = 0;

                if (block.HasAlternates && posForRnd != null)
                {
                    int altcount = 0;
                    foreach (var val in block.Textures)
                    {
                        BakedCompositeTexture bct = val.Value.Baked;
                        if (bct.BakedVariants == null)
                        {
                            continue;
                        }
                        altcount = Math.Max(altcount, bct.BakedVariants.Length);
                    }

                    altNum = block.RandomizeAxes == EnumRandomizeAxes.XYZ ? GameMath.MurmurHash3Mod(posForRnd.X, posForRnd.Y, posForRnd.Z, altcount) : GameMath.MurmurHash3Mod(posForRnd.X, 0, posForRnd.Z, altcount);
                }

                MeshData cuboidmesh = genCube(
                    cwm.X1, cwm.Y1, cwm.Z1,
                    cwm.X2 - cwm.X1, cwm.Y2 - cwm.Y1, cwm.Z2 - cwm.Z1,
                    coreClientAPI,
                    coreClientAPI.Tesselator.GetTexSource(block, altNum, true),
                    subPixelPaddingx,
                    subPixelPaddingy,
                    block
                    );

                mesh.AddMeshData(cuboidmesh);
            }

            return(mesh);
        }
Beispiel #11
0
        public virtual void RegenSelectionBoxes(IPlayer byPlayer)
        {
            // Create a temporary array first, because the offthread particle system might otherwise access a null collisionbox
            Cuboidf[]          selectionBoxesTmp = new Cuboidf[VoxelCuboids.Count];
            CuboidWithMaterial cwm = tmpCuboid;

            for (int i = 0; i < VoxelCuboids.Count; i++)
            {
                FromUint(VoxelCuboids[i], cwm);
                selectionBoxesTmp[i] = cwm.ToCuboidf();
            }
            this.selectionBoxes = selectionBoxesTmp;
        }
Beispiel #12
0
        public void RegenSelectionVoxelBoxes(bool mustLoad, IPlayer byPlayer)
        {
            if (selectionBoxesVoxels == null && !mustLoad)
            {
                return;
            }

            HashSet <Cuboidf> boxes = new HashSet <Cuboidf>();

            int size = GetChiselSize(byPlayer);

            if (size <= 0)
            {
                size = 16;
            }

            float sx = size / 16f;
            float sy = size / 16f;
            float sz = size / 16f;

            CuboidWithMaterial cwm = tmpCuboids[0];

            for (int i = 0; i < VoxelCuboids.Count; i++)
            {
                FromUint(VoxelCuboids[i], cwm);

                for (int x1 = cwm.X1; x1 < cwm.X2; x1 += size)
                {
                    for (int y1 = cwm.Y1; y1 < cwm.Y2; y1 += size)
                    {
                        for (int z1 = cwm.Z1; z1 < cwm.Z2; z1 += size)
                        {
                            float px = (float)Math.Floor((float)x1 / size) * sx;
                            float py = (float)Math.Floor((float)y1 / size) * sy;
                            float pz = (float)Math.Floor((float)z1 / size) * sz;

                            if (px + sx > 1 || py + sy > 1 || pz + sz > 1)
                            {
                                continue;
                            }

                            boxes.Add(new Cuboidf(px, py, pz, px + sx, py + sy, pz + sz));
                        }
                    }
                }
            }

            selectionBoxesVoxels = boxes.ToArray();
        }
Beispiel #13
0
        private void RebuildCuboidList(bool[,,] Voxels, byte[,,] VoxelMaterial)
        {
            bool[,,] VoxelVisited = new bool[16, 16, 16];

            // And now let's rebuild the cuboids with some greedy search algo thing
            VoxelCuboids.Clear();

            for (int dx = 0; dx < 16; dx++)
            {
                for (int dy = 0; dy < 16; dy++)
                {
                    for (int dz = 0; dz < 16; dz++)
                    {
                        if (VoxelVisited[dx, dy, dz] || !Voxels[dx, dy, dz])
                        {
                            continue;
                        }

                        CuboidWithMaterial cub = new CuboidWithMaterial()
                        {
                            Material = VoxelMaterial[dx, dy, dz],
                            X1       = dx, Y1 = dy, Z1 = dz,
                            X2       = dx + 1, Y2 = dy + 1, Z2 = dz + 1
                        };

                        // Try grow this cuboid for as long as we can
                        bool didGrowAny = true;
                        while (didGrowAny)
                        {
                            didGrowAny =
                                TryGrowX(cub, Voxels, VoxelVisited, VoxelMaterial) ||
                                TryGrowY(cub, Voxels, VoxelVisited, VoxelMaterial) ||
                                TryGrowZ(cub, Voxels, VoxelVisited, VoxelMaterial)
                            ;
                        }

                        VoxelCuboids.Add(ToCuboid(cub));
                    }
                }
            }
        }
Beispiel #14
0
        protected bool TrySnowGrowX(CuboidWithMaterial cub, bool[,,] voxels, bool[,] voxelVisited)
        {
            if (cub.X2 > 15)
            {
                return(false);
            }

            for (int z = cub.Z1; z < cub.Z2; z++)
            {
                if (!voxels[cub.X2, cub.Y1, z] || voxelVisited[cub.X2, z] || (cub.Y2 < 15 && voxels[cub.X2, cub.Y2, z]))
                {
                    return(false);
                }
            }

            for (int z = cub.Z1; z < cub.Z2; z++)
            {
                voxelVisited[cub.X2, z] = true;
            }

            cub.X2++;
            return(true);
        }
Beispiel #15
0
        public void OnTransformed(ITreeAttribute tree, int byDegrees, EnumAxis?aroundAxis)
        {
            List <uint> rotatedCuboids = new List <uint>();

            VoxelCuboids = new List <uint>((tree["cuboids"] as IntArrayAttribute).AsUint);
            CuboidWithMaterial cwm = tmpCuboid;

            foreach (var val in VoxelCuboids)
            {
                FromUint(val, cwm);
                Cuboidi rotated = cwm.Clone();

                if (aroundAxis == EnumAxis.X)
                {
                    rotated.X1 = 16 - rotated.X1;
                    rotated.X2 = 16 - rotated.X2;
                }
                if (aroundAxis == EnumAxis.Y)
                {
                    rotated.Y1 = 16 - rotated.Y1;
                    rotated.Y2 = 16 - rotated.Y2;
                }
                if (aroundAxis == EnumAxis.Z)
                {
                    rotated.Z1 = 16 - rotated.Z1;
                    rotated.Z2 = 16 - rotated.Z2;
                }

                rotated = rotated.RotatedCopy(0, byDegrees, 0, new Vec3d(8, 8, 8));


                cwm.Set(rotated.X1, rotated.Y1, rotated.Z1, rotated.X2, rotated.Y2, rotated.Z2);
                rotatedCuboids.Add(ToCuboid(cwm));
            }

            tree["cuboids"] = new IntArrayAttribute(rotatedCuboids.ToArray());
        }
Beispiel #16
0
        public bool CanAttachBlockAt(BlockFacing blockFace, Cuboidi attachmentArea = null)
        {
            if (attachmentArea == null)
            {
                return(sideSolid[blockFace.Index]);
            }
            else
            {
                HashSet <XYZ> req = new HashSet <XYZ>();
                for (int x = attachmentArea.X1; x <= attachmentArea.X2; x++)
                {
                    for (int y = attachmentArea.Y1; y <= attachmentArea.Y2; y++)
                    {
                        for (int z = attachmentArea.Z1; z <= attachmentArea.Z2; z++)
                        {
                            XYZ vec;

                            switch (blockFace.Index)
                            {
                            case 0: vec = new XYZ(x, y, 0); break;     // N

                            case 1: vec = new XYZ(15, y, z); break;    // E

                            case 2: vec = new XYZ(x, y, 15); break;    // S

                            case 3: vec = new XYZ(0, y, z); break;     // W

                            case 4: vec = new XYZ(x, 15, z); break;    // U

                            case 5: vec = new XYZ(x, 0, z); break;     // D

                            default: vec = new XYZ(0, 0, 0); break;
                            }

                            req.Add(vec);
                        }
                    }
                }

                CuboidWithMaterial cwm = tmpCuboid;

                for (int i = 0; i < VoxelCuboids.Count; i++)
                {
                    FromUint(VoxelCuboids[i], cwm);

                    for (int x = cwm.X1; x < cwm.X2; x++)
                    {
                        for (int y = cwm.Y1; y < cwm.Y2; y++)
                        {
                            for (int z = cwm.Z1; z < cwm.Z2; z++)
                            {
                                // Early exit
                                if (x != 0 && x != 15 && y != 0 && y != 15 && z != 0 && z != 15)
                                {
                                    continue;
                                }

                                req.Remove(new XYZ(x, y, z));
                            }
                        }
                    }
                }

                return(req.Count == 0);
            }
        }
Beispiel #17
0
        protected void RebuildCuboidList(bool[,,] Voxels, byte[,,] VoxelMaterial)
        {
            bool[,,] VoxelVisited = new bool[16, 16, 16];
            emitSideAo            = new bool[] { true, true, true, true, true, true };
            sideSolid             = new bool[] { true, true, true, true, true, true };
            float voxelCount = 0;

            // And now let's rebuild the cuboids with some greedy search algo thing
            VoxelCuboids.Clear();

            int[] edgeVoxelsMissing       = new int[6];
            int[] edgeCenterVoxelsMissing = new int[6];

            for (int dx = 0; dx < 16; dx++)
            {
                for (int dy = 0; dy < 16; dy++)
                {
                    for (int dz = 0; dz < 16; dz++)
                    {
                        bool isVoxel = Voxels[dx, dy, dz];

                        // North: Negative Z
                        // East: Positive X
                        // South: Positive Z
                        // West: Negative X
                        // Up: Positive Y
                        // Down: Negative Y
                        if (!isVoxel)
                        {
                            if (dz == 0)
                            {
                                edgeVoxelsMissing[BlockFacing.NORTH.Index]++;
                                if (Math.Abs(dy - 8) < 5 && Math.Abs(dx - 8) < 5)
                                {
                                    edgeCenterVoxelsMissing[BlockFacing.NORTH.Index]++;
                                }
                            }
                            if (dx == 15)
                            {
                                edgeVoxelsMissing[BlockFacing.EAST.Index]++;
                                if (Math.Abs(dy - 8) < 5 && Math.Abs(dz - 8) < 5)
                                {
                                    edgeCenterVoxelsMissing[BlockFacing.EAST.Index]++;
                                }
                            }
                            if (dz == 15)
                            {
                                edgeVoxelsMissing[BlockFacing.SOUTH.Index]++;
                                if (Math.Abs(dy - 8) < 5 && Math.Abs(dx - 8) < 5)
                                {
                                    edgeCenterVoxelsMissing[BlockFacing.SOUTH.Index]++;
                                }
                            }
                            if (dx == 0)
                            {
                                edgeVoxelsMissing[BlockFacing.WEST.Index]++;
                                if (Math.Abs(dy - 8) < 5 && Math.Abs(dz - 8) < 5)
                                {
                                    edgeCenterVoxelsMissing[BlockFacing.WEST.Index]++;
                                }
                            }
                            if (dy == 15)
                            {
                                edgeVoxelsMissing[BlockFacing.UP.Index]++;
                                if (Math.Abs(dz - 8) < 5 && Math.Abs(dx - 8) < 5)
                                {
                                    edgeCenterVoxelsMissing[BlockFacing.UP.Index]++;
                                }
                            }
                            if (dy == 0)
                            {
                                edgeVoxelsMissing[BlockFacing.DOWN.Index]++;
                                if (Math.Abs(dz - 8) < 5 && Math.Abs(dx - 8) < 5)
                                {
                                    edgeCenterVoxelsMissing[BlockFacing.DOWN.Index]++;
                                }
                            }
                            continue;
                        }
                        else
                        {
                            voxelCount++;
                        }

                        if (VoxelVisited[dx, dy, dz])
                        {
                            continue;
                        }

                        CuboidWithMaterial cub = new CuboidWithMaterial()
                        {
                            Material = VoxelMaterial[dx, dy, dz],
                            X1       = dx, Y1 = dy, Z1 = dz,
                            X2       = dx + 1, Y2 = dy + 1, Z2 = dz + 1
                        };

                        // Try grow this cuboid for as long as we can
                        bool didGrowAny = true;
                        while (didGrowAny)
                        {
                            didGrowAny  = false;
                            didGrowAny |= TryGrowX(cub, Voxels, VoxelVisited, VoxelMaterial);
                            didGrowAny |= TryGrowY(cub, Voxels, VoxelVisited, VoxelMaterial);
                            didGrowAny |= TryGrowZ(cub, Voxels, VoxelVisited, VoxelMaterial);
                        }

                        VoxelCuboids.Add(ToCuboid(cub));
                    }
                }
            }

            bool doEmitSideAo = edgeVoxelsMissing[0] < 64 || edgeVoxelsMissing[1] < 64 || edgeVoxelsMissing[2] < 64 || edgeVoxelsMissing[3] < 64;

            if (absorbAnyLight != doEmitSideAo)
            {
                int preva = GetLightAbsorption();
                absorbAnyLight = doEmitSideAo;
                int nowa = GetLightAbsorption();
                if (preva != nowa)
                {
                    Api.World.BlockAccessor.MarkAbsorptionChanged(preva, nowa, Pos);
                }
            }

            for (int i = 0; i < 6; i++)
            {
                emitSideAo[i] = doEmitSideAo;
                sideSolid[i]  = edgeCenterVoxelsMissing[i] < 5;
            }

            this.emitSideAoByFlags = Block.ResolveAoFlags(this.Block, emitSideAo);
            this.sizeRel           = voxelCount / (16f * 16f * 16f);

            buildSnowCuboids(Voxels);
        }
Beispiel #18
0
        void buildSnowCuboids(bool[,,] Voxels)
        {
            SnowCuboids.Clear();
            GroundSnowCuboids.Clear();

            //if (SnowLevel > 0) - always generate this
            {
                bool[,] snowVoxelVisited = new bool[16, 16];

                for (int dx = 0; dx < 16; dx++)
                {
                    for (int dz = 0; dz < 16; dz++)
                    {
                        if (snowVoxelVisited[dx, dz])
                        {
                            continue;
                        }

                        for (int dy = 15; dy >= 0; dy--)
                        {
                            bool ground = dy == 0;
                            bool solid  = ground || Voxels[dx, dy, dz];

                            if (solid)
                            {
                                CuboidWithMaterial cub = new CuboidWithMaterial()
                                {
                                    Material = 0,
                                    X1       = dx,
                                    Y1       = dy,
                                    Z1       = dz,
                                    X2       = dx + 1,
                                    Y2       = dy + 1,
                                    Z2       = dz + 1
                                };

                                // Try grow this cuboid for as long as we can
                                bool didGrowAny = true;
                                while (didGrowAny)
                                {
                                    didGrowAny  = false;
                                    didGrowAny |= TrySnowGrowX(cub, Voxels, snowVoxelVisited);
                                    didGrowAny |= TrySnowGrowZ(cub, Voxels, snowVoxelVisited);
                                }

                                if (ground)
                                {
                                    GroundSnowCuboids.Add(ToCuboid(cub));
                                }
                                else
                                {
                                    SnowCuboids.Add(ToCuboid(cub));
                                }

                                break;
                            }
                        }
                    }
                }
            }
        }
Beispiel #19
0
 private uint ToCuboid(CuboidWithMaterial cub)
 {
     return((uint)(cub.X1 | (cub.Y1 << 4) | (cub.Z1 << 8) | ((cub.X2 - 1) << 12) | ((cub.Y2 - 1) << 16) | ((cub.Z2 - 1) << 20) | (cub.Material << 24)));
 }