/// <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); }
/// <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; }
/// <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); }