Exemplo n.º 1
0
        public bool EqualsID(BlockData bd)
        {
            if (bd == null)
                return false;

            return (ID == bd.ID);
        }
Exemplo n.º 2
0
        public bool EqualsFull(BlockData bd)
        {
            if (bd == null)
                return false;

            return (ID == bd.ID && Metadata == bd.Metadata);
        }
Exemplo n.º 3
0
        public static bool CanBuild(BlockData data, BlockData me)
        {
            if (_blocks[data.GetGlobalID()] == null)
                return true;

            if (_blocks[data.GetGlobalID()].IsTransparent())
            {
                return (data.ID != me.ID);
            }

            return true;
        }
Exemplo n.º 4
0
 public virtual List<CustomBlockData> GenerateModel(byte metadata, BlockData me, BlockData Xpos, BlockData Xneg, BlockData Ypos, BlockData Yneg, BlockData Zpos, BlockData Zneg, BlockSource source, Point3 blockPosition)
 {
     return new List<CustomBlockData>();
 }
Exemplo n.º 5
0
 public virtual List<CustomBlockData> GenerateSide(BlockSide side, byte metadata, BlockData me, BlockData Xpos, BlockData Xneg, BlockData Ypos, BlockData Yneg, BlockData Zpos, BlockData Zneg)
 {
     return new List<CustomBlockData>();
 }
        public bool Export(object arg, TaskProgressReport p)
        {
            int maxTotalTask = 8; //6 normals + geom build + file write
            int currentTotalTask = 0;

            PartTaskProgressReport rep = (PartTaskProgressReport)p;

            rep.SetTitle("Preparing input data");
            rep.Report();

            Dictionary<Vector4, BlockRange[]> ranges = new Dictionary<Vector4, BlockRange[]>();
            List<CustomBlockData> customData = new List<CustomBlockData>();

            Vector3[] normalsToFollow = new Vector3[] { new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, -1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1) };

            bool[, ,] customBuilt = new bool[_in.BlockIDs.GetLength(0), _in.BlockIDs.GetLength(1), _in.BlockIDs.GetLength(2)];
            for (int n = 0; n < normalsToFollow.Length; n++)
            {
                Vector3 normal = normalsToFollow[n];
                BlockSide normalSide = Block.GetSideFromNormal(normal);

                Vector2 xy = GetXYByNormal(normal);
                Point3 xyLength = GetLengthAxisByNormal(normal); //X:x, Y:y, Z:level

                int xs = _in.BlockIDs.GetLength(xyLength.X);
                int ys = _in.BlockIDs.GetLength(xyLength.Y);
                int zs = _in.BlockIDs.GetLength(xyLength.Z);

                rep.SetTitle("Processing side: " + TranslateNormal(normal));
                rep.Report();

                for (int lvl = 0; lvl < _in.BlockIDs.GetLength(xyLength.Z); lvl++)
                {
                    BlockData[,] lvlData = new BlockData[xs, ys];

                    int partMax = xs * ys;
                    int partProg = 0;

                    for (int a = 0; a < _in.BlockIDs.GetLength(xyLength.X); a++)
                    {
                        for (int b = 0; b < _in.BlockIDs.GetLength(xyLength.Y); b++)
                        {
                            Point3 pos = ConvertLevelAndXYToPos(a, b, lvl, xyLength);

                            if (_in.BlockIDs[pos.X, pos.Y, pos.Z] != 0)
                            {
                                BlockData bd = GetBlockDataAt(pos);
                                uint block = bd.GetGlobalID();
                                Block bl = Block.Blocks[block];
                                if (bl != null && !customBuilt[pos.X, pos.Y, pos.Z])
                                {
                                    bool canExportFace = (!_cfg.DontExportOuterFaces && !_cfg.InteriorOnly);

                                    if (_cfg.DontExportOuterFaces && CheckFace(pos, normal))
                                        canExportFace = true;
                                    else if (_cfg.InteriorOnly && CheckFaceInterior(pos, normal))
                                        canExportFace = true;

                                    if (canExportFace)
                                    {
                                        if (bl.IsFullyCustomModel())
                                        {
                                            List<CustomBlockData> dat = bl.GenerateModel(_in.BlockMetadatas[pos.X, pos.Y, pos.Z], bd, GetBlockDataAt(new Point3(pos.X + 1, pos.Y, pos.Z)), GetBlockDataAt(new Point3(pos.X - 1, pos.Y, pos.Z)), GetBlockDataAt(new Point3(pos.X, pos.Y + 1, pos.Z)), GetBlockDataAt(new Point3(pos.X, pos.Y - 1, pos.Z)), GetBlockDataAt(new Point3(pos.X, pos.Y, pos.Z + 1)), GetBlockDataAt(new Point3(pos.X, pos.Y, pos.Z - 1)), this, pos);
                                            for (int x = 0; x < dat.Count; x++)
                                            {
                                                dat[x].Vertex1 += pos.ToVector3();
                                                dat[x].Vertex2 += pos.ToVector3();
                                                dat[x].Vertex3 += pos.ToVector3();
                                                if (!dat[x].IsOneTriangle)
                                                    dat[x].Vertex4 += pos.ToVector3();
                                                dat[x].Source = bd;
                                            }
                                            customData.AddRange(dat);
                                            customBuilt[pos.X, pos.Y, pos.Z] = true;
                                        }
                                        else
                                        {
                                            if (bl.IsFullSide(normalSide))
                                            {
                                                if (CanGenerateSide(pos, normal))
                                                {
                                                    lvlData[a, b] = bd;
                                                }
                                            }
                                            else
                                            {
                                                List<CustomBlockData> dat = bl.GenerateSide(normalSide, _in.BlockMetadatas[pos.X, pos.Y, pos.Z], bd, GetBlockDataAt(new Point3(pos.X + 1, pos.Y, pos.Z)), GetBlockDataAt(new Point3(pos.X - 1, pos.Y, pos.Z)), GetBlockDataAt(new Point3(pos.X, pos.Y + 1, pos.Z)), GetBlockDataAt(new Point3(pos.X, pos.Y - 1, pos.Z)), GetBlockDataAt(new Point3(pos.X, pos.Y, pos.Z + 1)), GetBlockDataAt(new Point3(pos.X, pos.Y, pos.Z - 1)));
                                                for (int x = 0; x < dat.Count; x++)
                                                {
                                                    dat[x].Vertex1 += pos.ToVector3();
                                                    dat[x].Vertex2 += pos.ToVector3();
                                                    dat[x].Vertex3 += pos.ToVector3();
                                                    if (!dat[x].IsOneTriangle)
                                                        dat[x].Vertex4 += pos.ToVector3();
                                                    dat[x].Source = bd;
                                                }
                                                customData.AddRange(dat);
                                            }
                                        }
                                    }
                                }
                            }

                            partProg++;
                            rep.SetPartPercent((int)(((float)partProg / (float)partMax) * 100f));
                            rep.Report();
                        }
                    }

                    rep.SetTitle("Square-angulating level: " + lvl.ToString());
                    rep.Report();

                    if (_cfg.OptimizeModel)
                    {
                        List<BlockRange> sq = Squareangulate(lvlData);
                        if (sq.Count > 0)
                        {
                            ranges.Add(new Vector4(normal.X, normal.Y, normal.Z, lvl), sq.ToArray());
                        }
                    }
                    else
                    {
                        List<BlockRange> converted = new List<BlockRange>();
                        for (int x = 0; x < lvlData.GetLength(0); x++)
                        {
                            for (int y = 0; y < lvlData.GetLength(1); y++)
                            {
                                BlockData bd = lvlData[x, y];

                                if (bd == null)
                                    continue;

                                BlockRange range = new BlockRange();
                                range.Block = bd;
                                range.From = new PointF(x, y);
                                range.To = new PointF(x, y);

                                converted.Add(range);
                            }
                        }

                        ranges.Add(new Vector4(normal.X, normal.Y, normal.Z, lvl), converted.ToArray());
                    }
                }

                currentTotalTask++;
                rep.SetTotalPercent((int)(((float)currentTotalTask / (float)maxTotalTask) * 100f));
                rep.Report();
            }

            rep.SetTitle("Building geometry");
            rep.Report();

            Dictionary<string, DataSet> datas = new Dictionary<string, DataSet>();

            int pairIndex = 0;
            foreach (KeyValuePair<Vector4, BlockRange[]> pair in ranges)
            {
                Vector3 normal = new Vector3(pair.Key.X, pair.Key.Y, pair.Key.Z);
                int level = (int)pair.Key.Level;

                Vector3 addNormal = new Vector3(normal.X, normal.Y, normal.Z);
                if (addNormal.X < 0)
                    addNormal.X = 0;
                if (addNormal.Y < 0)
                    addNormal.Y = 0;
                if (addNormal.Z < 0)
                    addNormal.Z = 0;

                for (int x = 0; x < pair.Value.Length; x++)
                {
                    WriteRange(pair.Value[x], normal, level, addNormal, ref datas);
                }

                pairIndex++;
                rep.SetTotalPercent((int)(((float)pairIndex / (float)ranges.Count) * 100f));
                rep.Report();
            }

            for (int x = 0; x < customData.Count; x++)
            {
                WriteCustomData(customData[x], ref datas);
            }

            rep.SetTotalPercent(100);
            rep.Report();

            if (_cfg.CenterObject)
            {
                rep.SetTitle("Centering geometry");
                rep.Report();

                Vector3 min = new Vector3(0, 0, 0);
                Vector3 max = new Vector3(0, 0, 0);
                foreach (KeyValuePair<string, DataSet> pair2 in datas)
                {
                    foreach (Vector3 v in pair2.Value.verts)
                    {
                        min.X = Math.Min(min.X, v.X);
                        min.Y = Math.Min(min.Y, v.Y);
                        min.Z = Math.Min(min.Z, v.Z);

                        max.X = Math.Max(max.X, v.X);
                        max.Y = Math.Max(max.Y, v.Y);
                        max.Z = Math.Max(max.Z, v.Z);
                    }
                }

                Vector3 move = (max - min) / 2;
                foreach (KeyValuePair<string, DataSet> pair2 in datas)
                {
                    for (int x = 0; x < pair2.Value.verts.Count; x++)
                    {
                        pair2.Value.verts[x] -= move;
                    }
                }
            }

            currentTotalTask++;
            rep.SetTotalPercent((int)(((float)currentTotalTask / (float)maxTotalTask) * 100f));

            rep.SetTitle("Creating vertex data");
            rep.Report();

            ProcessedGeometryData geom = new ProcessedGeometryData();
            geom.ExportConfig = _cfg;
            geom.Data = datas.Values.ToList();

            //Export model file
            _outputWriter.Write(_outputFile, geom);

            //Export textures
            if (_cfg.ExportTextures)
            {
                rep.SetTitle("Exporting textures");
                rep.Report();

                List<string> failedTextures = new List<string>();

                string textureOutput = Path.Combine(Path.GetDirectoryName(_outputFile), _cfg.TextureOutputFolder);

                ResourcePack rs = new ResourcePack(_cfg.ResourcePack);
                rs.Open();

                foreach (KeyValuePair<string, DataSet> pair2 in datas)
                {
                    string tex = pair2.Value.Texture;

                    if (!rs.SaveBlockTexture(tex, textureOutput))
                        failedTextures.Add(tex);
                }

                rs.Close();
            }

            currentTotalTask++;
            rep.SetTotalPercent((int)(((float)currentTotalTask / (float)maxTotalTask) * 100f));

            return true;
        }
Exemplo n.º 7
0
        public static bool IsTransparent(BlockData data)
        {
            if (_blocks[data.GetGlobalID()] == null)
                return true;

            return _blocks[data.GetGlobalID()].IsTransparent();
        }
        private List<BlockRange> Squareangulate(BlockData[,] data)
        {
            List<BlockRange> ql = new List<BlockRange>();

            Dictionary<Tuple<uint, Byte>, BlockData[,]> types = CollectTypes(data);

            foreach (KeyValuePair<Tuple<uint, Byte>, BlockData[,]> pair in types)
            {
                BlockData[,] levelData = pair.Value;

                int rem = CountRem(levelData);
                if (rem > 0)
                {
                    bool[,] proc = new bool[levelData.GetLength(0), levelData.GetLength(1)];

                    while (rem > 0)
                    {
                        Point s = FindStart(levelData, proc);

                        if (s.X == -1 && s.Y == -1)
                            break;

                        Find(ref ql, ref levelData, ref proc, s, ref rem, levelData[s.X, s.Y]);
                    }
                }
            }

            return ql;
        }
        private Point FindStart(BlockData[,] grid, bool[,] exclude)
        {
            Point s = new Point(-1, -1);

            for (int y = 0; y < grid.GetLength(1); y++)
                for (int x = 0; x < grid.GetLength(0); x++)
                {
                    if (grid[x, y] != null && !exclude[x, y])
                        return new Point(x, y);
                }

            return s;
        }
Exemplo n.º 10
0
        private void Find(ref List<BlockRange> ql, ref BlockData[,] oData, ref bool[,] proc, Point s, ref int remains, BlockData data)
        {
            //Find square
            int fsx = 0;
            int fsy = 0;
            bool find = true;
            bool b1 = false;
            bool b2 = false;
            while (find)
            {
                if (!b1 && s.X + fsx + 1 < oData.GetLength(0) && s.Y + fsy < oData.GetLength(1) &&
                    oData[s.X + fsx + 1, s.Y + fsy] != null && !proc[s.X + fsx + 1, s.Y + fsy])
                {
                    bool canAdd = true;

                    for (int cx = s.X; cx <= s.X + fsx + 1; cx++)
                    {
                        for (int cy = s.Y; cy <= s.Y + fsy; cy++)
                        {
                            if (oData[cx, cy] == null || proc[cx, cy])
                            {
                                canAdd = false;
                                break;
                            }
                        }
                    }

                    if (canAdd)
                        fsx++;
                    else
                        b1 = true;
                }
                else
                    b1 = true;

                if (!b2 && s.X + fsx < oData.GetLength(0) && s.Y + fsy + 1 < oData.GetLength(1) &&
                   oData[s.X + fsx, s.Y + fsy + 1] != null && !proc[s.X + fsx, s.Y + fsy + 1])
                {
                    bool canAdd = true;

                    for (int cy = s.Y; cy <= s.Y + fsy + 1; cy++)
                    {
                        for (int cx = s.X; cx <= s.X + fsx; cx++)
                        {
                            if (oData[cx, cy] == null || proc[cx, cy])
                            {
                                canAdd = false;
                                break;
                            }
                        }
                    }

                    if (canAdd)
                        fsy++;
                    else
                        b2 = true;
                }
                else
                    b2 = true;

                if (b1 && b2)
                {
                    find = false;

                    BlockRange br = new BlockRange();
                    br.From = s;
                    br.To = new Point(s.X + fsx, s.Y + fsy);
                    br.Block = data;
                    ql.Add(br);

                    for (int rx = s.X; rx <= br.To.X; rx++)
                        for (int ry = s.Y; ry <= br.To.Y; ry++)
                        {
                            remains--;
                            proc[rx, ry] = true;
                        }
                }
            }
        }
Exemplo n.º 11
0
        private int CountRem(BlockData[,] datas)
        {
            int r = 0;

            for (int x = 0; x < datas.GetLength(0); x++)
                for (int y = 0; y < datas.GetLength(1); y++)
                    if (datas[x, y] != null)
                        r++;

            return r;
        }
Exemplo n.º 12
0
        private Dictionary<Tuple<uint, byte>, BlockData[, ]> CollectTypes(BlockData[,] source)
        {
            //ID, META : Level data
            Dictionary<Tuple<uint, byte>, BlockData[,]> dat = new Dictionary<Tuple<uint, byte>, BlockData[,]>();

            for (int x = 0; x < source.GetLength(0); x++)
            {
                for (int y = 0; y < source.GetLength(1); y++)
                {
                    BlockData d = source[x, y];

                    if (d != null)
                    {
                        Tuple<uint, byte> nd = new Tuple<uint, byte>(d.ID, d.Metadata);
                        if (!dat.ContainsKey(nd))
                        {
                            dat.Add(nd, new BlockData[source.GetLength(0), source.GetLength(1)]);
                        }

                        dat[nd][x, y] = d;
                    }
                }
            }

            return dat;
        }