Exemplo n.º 1
0
            /// <summary>
            /// Element を分類します。
            /// </summary>
            /// <param name="elements">Element のリスト。</param>
            /// <returns>分類結果を管理する ElementClassifier。</returns>
            public static ElementClassifier Classify(InterElementCollection elements)
            {
                var instance = new ElementClassifier();

                foreach (var element in elements)
                {
                    // 面の結合状態を解析します。
                    var resolvedElement = ResolvedElement.Resolve(elements, element);

                    // 立方体が完全に囲まれているのではないならば分類を開始します。
                    if (!resolvedElement.Enclosed)
                    {
                        instance.Classify(resolvedElement);
                    }
                }

                // Parts プロパティへ全ての Part を追加します。
                foreach (var partList in instance.partListMap.Values)
                {
                    foreach (var part in partList)
                    {
                        instance.Parts.Add(part);
                    }
                }

                return(instance);
            }
Exemplo n.º 2
0
            /// <summary>
            /// Element を分類します。
            /// </summary>
            /// <param name="elements">Element のリスト。</param>
            /// <returns>分類結果を管理する ElementClassifier。</returns>
            public static ElementClassifier Classify(InterElementCollection elements)
            {
                var instance = new ElementClassifier();

                foreach (var element in elements)
                {
                    // 面の結合状態を解析します。
                    var resolvedElement = ResolvedElement.Resolve(elements, element);

                    // 立方体が完全に囲まれているのではないならば分類を開始します。
                    if (!resolvedElement.Enclosed) instance.Classify(resolvedElement);
                }

                // Parts プロパティへ全ての Part を追加します。
                foreach (var partList in instance.partListMap.Values)
                {
                    foreach (var part in partList) instance.Parts.Add(part);
                }

                return instance;
            }
Exemplo n.º 3
0
        /// <summary>
        /// InterBlockMesh を生成します。
        /// </summary>
        /// <param name="lodBlocks">各 LOD の InterBlock を要素とした配列。</param>
        /// <returns>生成された BlockMesh。</returns>
        static InterBlockMesh Create(InterBlock[] lodBlocks)
        {
            // InterBlockMesh を生成します。
            var mesh = new InterBlockMesh();

            // InterBlockEffect を生成します。
            // LOD 間で Material は共有しているので、最大 LOD の Material から生成します。
            mesh.MeshMaterials = new BlockMeshMaterial[lodBlocks[0].Materials.Count];
            for (int i = 0; i < mesh.MeshMaterials.Length; i++)
            {
                var block = lodBlocks[0];

                mesh.MeshMaterials[i] = new BlockMeshMaterial
                {
                    DiffuseColor  = block.Materials[i].DiffuseColor.ToVector3(),
                    EmissiveColor = block.Materials[i].EmissiveColor.ToVector3(),
                    SpecularColor = block.Materials[i].SpecularColor.ToVector3(),
                    SpecularPower = block.Materials[i].SpecularPower
                };
            }

            // 実際に必要となる LOD 数をもとめます。
            int actualLodCount = 0;

            for (int lod = 0; lod < lodBlocks.Length; lod++)
            {
                // 要素数 0 の InterBlock は、それ以上粒度を荒くできなかったことを表します。
                if (lodBlocks[lod].Elements.Count == 0)
                {
                    break;
                }

                actualLodCount++;
            }

            // 実際の LOD 数の分だけ InterBlockMeshLod 領域を確保します。
            mesh.MeshLods = new InterBlockMeshLod[actualLodCount];

            var meshPartVS = new VertexSource <VertexPositionNormal, ushort>();

            // LOD ごとに InterBlockMeshPart を生成します。
            for (int lod = 0; lod < actualLodCount; lod++)
            {
                var block = lodBlocks[lod];

                // Element を分類します。
                var elementClassifier = ElementClassifier.Classify(block.Elements);

                var cubeSurfaceVS = cubeSurfaceVertexSourceMap[block.ElementSize];

                int meshPartCount = elementClassifier.Parts.Count;
                var meshLod       = new InterBlockMeshLod
                {
                    MeshParts = new InterBlockMeshPart[meshPartCount]
                };
                mesh.MeshLods[lod] = meshLod;

                // InterBlockMeshPart を生成して登録します。
                for (int i = 0; i < meshPartCount; i++)
                {
                    var part = elementClassifier.Parts[i];

                    // 頂点データを作成します。
                    meshPartVS.Clear();
                    MakeMeshPartVertexSource(meshPartVS, part, cubeSurfaceVS, block.ElementSize);

                    // InterBlockMeshPart を生成します。
                    meshLod.MeshParts[i] = new InterBlockMeshPart
                    {
                        MeshMaterialIndex = part.MaterialIndex,
                        Vertices          = meshPartVS.Vertices.ToArray(),
                        Indices           = meshPartVS.Indices.ToArray()
                    };
                }
            }

            return(mesh);
        }