int ProcessMaterial(ref Block block, ref Color color)
        {
            Material material = null;
            int materialIndex = -1;
            for (int i = 0; i < block.Materials.Count; i++)
            {
                var m = block.Materials[i];
                var mColor = m.DiffuseColor;

                // RGB で比較し、A が異なっても同じ Material とします。
                if (mColor.R == color.R && mColor.G == color.G && mColor.B == color.B)
                {
                    material = m;
                    materialIndex = i;
                    break;
                }
            }

            if (material == null)
            {
                material = new Material
                {
                    DiffuseColor = new MaterialColor
                    {
                        R = color.R,
                        G = color.G,
                        B = color.B
                    }
                };
                block.Materials.Add(material);
                materialIndex = block.Materials.Count - 1;
            }

            return materialIndex;
        }
        /// <summary>
        /// InterBlockMesh を生成します。
        /// </summary>
        /// <param name="block">Block。</param>
        /// <param name="lodSize">LOD のサイズ。</param>
        /// <returns>生成された InterBlockMesh。</returns>
        public static InterBlockMesh InterBlockMesh(Block block, int lodCount)
        {
            if (block == null) throw new ArgumentNullException("block");
            if (lodCount < 1 || InterBlock.MaxLodCount < lodCount)
                throw new ArgumentOutOfRangeException("lodCount");

            // 中間データを作成します。
            var interBlocks = InterBlock.CreateInterBlock(block, lodCount);

            // 中間データから InterBlockMesh を作成します。
            return Create(interBlocks);
        }
        public Block Process(BlockSprite blockSprite)
        {
            var block = new Block();

            var w = blockSprite.Width;
            var h = blockSprite.Height;

            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    var color = blockSprite.GetPixel(x, y);

                    // 透明はその位置に要素がないことを表します。
                    if (color.A == 0) continue;

                    var materialIndex = ProcessMaterial(ref block, ref color);

                    // Block は [-8, 7] で 16x16 になっています。

                    var element = new Element
                    {
                        MaterialIndex = materialIndex,
                        Position = new Position
                        {
                            X = x - 8,
                            Y = 7 - y
                        }
                    };

                    block.Elements.Add(element);
                }
            }

            return block;
        }
Exemple #4
0
        /// <summary>
        /// 指定された数の LOD でそれぞれの LOD を持つ InterBlock の配列を生成します。
        /// </summary>
        /// <param name="block">Block。</param>
        /// <param name="lodCount">LOD の数。</param>
        /// <returns>生成された InterBlock の配列。</returns>
        public static InterBlock[] CreateInterBlock(Block block, int lodCount)
        {
            if (lodCount < 1 || MaxLodCount < lodCount)
                throw new ArgumentOutOfRangeException("lodCount");

            var interBlocks = new InterBlock[lodCount];

            // インデックス 0 は常に最大 LOD です。
            interBlocks[0] = CreateMaxDetailLevelInterBlock(block);

            // 要求された分の下位 LOD を生成します。
            for (int i = 1; i < lodCount; i++) interBlocks[i] = CreateLowDetailLevelInterBlock(interBlocks[i - 1]);

            return interBlocks;
        }
Exemple #5
0
        /// <summary>
        /// Block から最大 LOD の InterBlock を作成します。
        /// </summary>
        /// <param name="block">Block。</param>
        /// <returns>生成された InterBlock。</returns>
        static InterBlock CreateMaxDetailLevelInterBlock(Block block)
        {
            var interBlock = new InterBlock();

            // 最大 LOD として作成します。
            interBlock.GridSize = MaxLodGridSize;

            // Block の Material をそのままコピーします。
            interBlock.Materials = new List<Material>(block.Materials.Count);
            foreach (var material in block.Materials) interBlock.Materials.Add(material);

            // Block の Element をそのままコピーします。
            interBlock.Elements = new InterElementCollection();
            foreach (var element in block.Elements) interBlock.Elements.Add(element);

            // 最大 LOD の Element サイズを設定します。
            interBlock.ElementSize = MaxLodElementSize;

            return interBlock;
        }
        // I/F
        public void Save(string name, Block block, Description description)
        {
            EnsureDirectory();

            var blockFileName = Block.ResolveFileName(name);
            var descriptionFileName = Description.ResolveFileName(name);

            using (var stream = directory.CreateFile(blockFileName))
            {
                blockSerializer.Serialize(stream, block);
            }

            using (var stream = directory.CreateFile(descriptionFileName))
            {
                descriptionSerializer.Serialize(stream, description);
            }
        }
        /// <summary>
        /// 正八面体風のデータを定義する Block を作成します。
        /// </summary>
        /// <returns>作成された Block。</returns>
        Block CreateOctahedronLikeBlock()
        {
            var block = new Block();
            block.Materials = new List<Material>();
            block.Elements = new List<Element>();

            MaterialColor[] diffuses =
            {
                new MaterialColor(255, 255, 255),
                new MaterialColor(255,   0,   0),
                new MaterialColor(  0, 255,   0),
                new MaterialColor(  0,   0, 255),
                new MaterialColor(127, 127,   0),
                new MaterialColor(127,   0, 127),
                new MaterialColor(  0, 127, 127),
                new MaterialColor(  0,   0,   0),
            };
            Material[] materials = new Material[8];
            for (int i = 0; i < 8; i++)
            {
                materials[i] = new Material();
                materials[i].DiffuseColor = diffuses[i];
                block.Materials.Add(materials[i]);
            }

            int materialIndex;
            for (int x = -8; x < 8; x++)
            {
                for (int y = -8; y < 8; y++)
                {
                    for (int z = -8; z < 8; z++)
                    {
                        int testX = (x < 0) ? -x : x + 1;
                        int testY = (y < 0) ? -y : y + 1;
                        int testZ = (z < 0) ? -z : z + 1;

                        if (testX + testY + testZ <= 10)
                        {
                            materialIndex = 0;
                            if (x < 0) materialIndex |= 1;
                            if (y < 0) materialIndex |= 2;
                            if (z < 0) materialIndex |= 4;

                            var element = new Element();
                            element.Position = new Position(x, y, z);
                            element.MaterialIndex = materialIndex;
                            block.Elements.Add(element);
                        }
                    }
                }
            }

            return block;
        }
        /// <summary>
        /// 16 * 16 * 16 の全てを使用した Block を生成します。
        /// </summary>
        Block CreateFullFilledBlock()
        {
            var block = new Block();
            block.Materials = new List<Material>();
            block.Elements = new List<Element>();

            MaterialColor[] diffuses =
            {
                new MaterialColor(255, 255, 255),
                new MaterialColor(255,   0,   0),
                new MaterialColor(  0, 255,   0),
                new MaterialColor(  0,   0, 255),
                new MaterialColor(127, 127,   0),
                new MaterialColor(127,   0, 127),
                new MaterialColor(  0, 127, 127),
                new MaterialColor(  0,   0,   0),
            };
            Material[] materials = new Material[8];
            for (int i = 0; i < 8; i++)
            {
                materials[i] = new Material();
                materials[i].DiffuseColor = diffuses[i];
                block.Materials.Add(materials[i]);
            }

            int materialIndex;
            for (int x = -8; x < 8; x++)
            {
                for (int y = -8; y < 8; y++)
                {
                    for (int z = -8; z < 8; z++)
                    {
                        materialIndex = 0;
                        if (x < 0) materialIndex |= 1;
                        if (y < 0) materialIndex |= 2;
                        if (z < 0) materialIndex |= 4;

                        var element = new Element();
                        element.Position = new Position(x, y, z);
                        element.MaterialIndex = materialIndex;
                        block.Elements.Add(element);
                    }
                }
            }

            return block;
        }
        UploadFile CreateUploadBlock(string name, Block block)
        {
            using (var stream = new MemoryStream())
            {
                blockSerializer.Serialize(stream, block);

                return new UploadFile
                {
                    ContentType = "text/xml",
                    Name = Block.ResolveFileName(name),
                    Content = Encoding.UTF8.GetString(stream.ToArray())
                };
            }
        }