Пример #1
0
 /// <summary>
 /// 指定の LOD についての分割ロード要求をキューへ追加します。
 /// </summary>
 /// <param name="interBlockMesh">BlockMesh のロード元となる InterBlockMesh。</param>
 /// <param name="blockMesh">分割ロード対応の BlockMesh。</param>
 /// <param name="levelOfDetail">対象とする LOD。</param>
 void Enqueue(InterBlockMesh interBlockMesh, BlockMesh blockMesh, int levelOfDetail)
 {
     for (int i = 0; i < blockMesh.MeshLods[levelOfDetail].MeshParts.Count; i++)
     {
         Enqueue(interBlockMesh, blockMesh, levelOfDetail, i);
     }
 }
Пример #2
0
        /// <summary>
        /// InterBlockMesh の頂点情報とエフェクト情報をもとに BlockMesh を生成します。
        /// </summary>
        /// <param name="interMesh">頂点情報とエフェクト情報を提供する InterBlockMesh。</param>
        /// <returns>生成された BlockMesh。</returns>
        public BlockMesh Create(InterBlockMesh interMesh)
        {
            var lodCount = interMesh.MeshLods.Length;

            var mesh = new BlockMesh();
            mesh.SetMeshMaterials(interMesh.MeshMaterials);

            mesh.AllocateMeshLods(lodCount);

            for (int lod = 0; lod < lodCount; lod++)
            {
                var interMeshLod = interMesh.MeshLods[lod];
                var meshLod = mesh.MeshLods[lod];

                var meshPartCount = interMeshLod.MeshParts.Length;
                meshLod.AllocateMeshParts(GraphicsDevice, meshPartCount);

                for (int i = 0; i < meshPartCount; i++)
                {
                    var interMeshPart = interMeshLod.MeshParts[i];
                    var meshPart = meshLod.MeshParts[i];

                    meshPart.MeshMaterial = mesh.MeshMaterials[interMeshPart.MeshMaterialIndex];
                    meshPart.PopulateVertices(interMeshPart.Vertices);
                    meshPart.PopulateIndices(interMeshPart.Indices);
                }
            }

            return mesh;
        }
Пример #3
0
        /// <summary>
        /// InterBlockMesh の頂点情報とエフェクト情報をもとに BlockMesh を生成します。
        /// </summary>
        /// <param name="interMesh">頂点情報とエフェクト情報を提供する InterBlockMesh。</param>
        /// <returns>生成された BlockMesh。</returns>
        public BlockMesh Create(InterBlockMesh interMesh)
        {
            var lodCount = interMesh.MeshLods.Length;

            var mesh = new BlockMesh();

            mesh.SetMeshMaterials(interMesh.MeshMaterials);

            mesh.AllocateMeshLods(lodCount);

            for (int lod = 0; lod < lodCount; lod++)
            {
                var interMeshLod = interMesh.MeshLods[lod];
                var meshLod      = mesh.MeshLods[lod];

                var meshPartCount = interMeshLod.MeshParts.Length;
                meshLod.AllocateMeshParts(GraphicsDevice, meshPartCount);

                for (int i = 0; i < meshPartCount; i++)
                {
                    var interMeshPart = interMeshLod.MeshParts[i];
                    var meshPart      = meshLod.MeshParts[i];

                    meshPart.MeshMaterial = mesh.MeshMaterials[interMeshPart.MeshMaterialIndex];
                    meshPart.PopulateVertices(interMeshPart.Vertices);
                    meshPart.PopulateIndices(interMeshPart.Indices);
                }
            }

            return(mesh);
        }
Пример #4
0
        /// <summary>
        /// 分割ロード対応の BlockMesh を生成します。
        /// </summary>
        /// <param name="graphicsDevice">GraphicsDevice。</param>
        /// <param name="interBlockMesh">BlockMesh のロード元となる InterBlockMesh。</param>
        /// <returns>分割ロード対応の BlockMesh。</returns>
        BlockMesh CreatePhasedBlockMesh(GraphicsDevice graphicsDevice, InterBlockMesh interBlockMesh)
        {
            var lodCount = interBlockMesh.MeshLods.Length;

            var blockMesh = new BlockMesh();

            blockMesh.SetMeshMaterials(interBlockMesh.MeshMaterials);
            blockMesh.AllocateMeshLods(lodCount);

            for (int lod = 0; lod < lodCount; lod++)
            {
                var interMeshLod  = interBlockMesh.MeshLods[lod];
                var meshPartCount = interMeshLod.MeshParts.Length;
                var meshLod       = blockMesh.MeshLods[lod];

                meshLod.AllocateMeshParts(graphicsDevice, meshPartCount);

                for (int i = 0; i < meshPartCount; i++)
                {
                    var interMeshPart = interMeshLod.MeshParts[i];
                    var meshPart      = meshLod.MeshParts[i];

                    meshPart.MeshMaterial = blockMesh.MeshMaterials[interMeshPart.MeshMaterialIndex];
                }
            }

            return(blockMesh);
        }
Пример #5
0
        /// <summary>
        /// ThreadPool から提供される Thread から呼び出されます。
        /// </summary>
        /// <param name="state">Task。</param>
        void WaitCallback(object state)
        {
            var taskInThread = state as TaskInThread;

            InterBlockMesh interBlockMesh = null;
            Exception      exception      = null;

            try
            {
                interBlockMesh = taskInThread.Task.Execute();
            }
            catch (Exception e)
            {
                exception = e;
            }

            var result = new ResultInQueue
            {
                ResultCallback = taskInThread.Task.Callback,
                Name           = taskInThread.Task.Name,
                InterBlockMesh = interBlockMesh,
                Exception      = exception
            };

            // 処理結果をキューへ入れます。
            lock (resultQueue) resultQueue.Enqueue(result);

            // 空き Thread としてマークします。
            lock (freeThread) freeThread.Enqueue(taskInThread);
        }
Пример #6
0
        /// <summary>
        /// BlockMesh の分割ロード要求を追加します。
        /// </summary>
        /// <param name="graphicsDevice">GraphicsDevice。</param>
        /// <param name="interBlockMesh">BlockMesh のロード元となる InterBlockMesh。</param>
        /// <returns>分割ロード対応の BlockMesh。</returns>
        public BlockMesh Load(GraphicsDevice graphicsDevice, InterBlockMesh interBlockMesh)
        {
            // 分割ロード対応の BlockMesh を生成します。
            var blockMesh = CreatePhasedBlockMesh(graphicsDevice, interBlockMesh);

            // ロード要求をキューに追加します。
            var coarsestLod = blockMesh.MeshLods.Count - 1;
            Enqueue(interBlockMesh, blockMesh, coarsestLod);

            // 分割ロード対応の BlockMesh を要求元へ返します。
            return blockMesh;
        }
Пример #7
0
        /// <summary>
        /// BlockMesh の分割ロード要求を追加します。
        /// </summary>
        /// <param name="graphicsDevice">GraphicsDevice。</param>
        /// <param name="interBlockMesh">BlockMesh のロード元となる InterBlockMesh。</param>
        /// <returns>分割ロード対応の BlockMesh。</returns>
        public BlockMesh Load(GraphicsDevice graphicsDevice, InterBlockMesh interBlockMesh)
        {
            // 分割ロード対応の BlockMesh を生成します。
            var blockMesh = CreatePhasedBlockMesh(graphicsDevice, interBlockMesh);

            // ロード要求をキューに追加します。
            var coarsestLod = blockMesh.MeshLods.Count - 1;

            Enqueue(interBlockMesh, blockMesh, coarsestLod);

            // 分割ロード対応の BlockMesh を要求元へ返します。
            return(blockMesh);
        }
Пример #8
0
        /// <summary>
        /// 指定の BlockMeshPart のロード要求をキューへ追加します。
        /// </summary>
        /// <param name="interBlockMesh">BlockMesh のロード元となる InterBlockMesh。</param>
        /// <param name="blockMesh">分割ロード対応の BlockMesh。</param>
        /// <param name="levelOfDetail">対象とする LOD。</param>
        /// <param name="meshPartIndex">対象とする BlockMeshPart のインデックス。</param>
        void Enqueue(InterBlockMesh interBlockMesh, BlockMesh blockMesh, int levelOfDetail, int meshPartIndex)
        {
            lock (this)
            {
                if (queue.Count == MaxCapacity)
                {
                    throw new InvalidOperationException("This queue is full.");
                }

                var item = new Item
                {
                    InterBlockMesh = interBlockMesh,
                    BlockMesh      = blockMesh,
                    LevelOfDetail  = levelOfDetail,
                    MeshPartIndex  = meshPartIndex
                };

                queue.Add(item);
            }
        }
Пример #9
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;
        }
Пример #10
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);
        }
Пример #11
0
        /// <summary>
        /// 指定の BlockMeshPart のロード要求をキューへ追加します。
        /// </summary>
        /// <param name="interBlockMesh">BlockMesh のロード元となる InterBlockMesh。</param>
        /// <param name="blockMesh">分割ロード対応の BlockMesh。</param>
        /// <param name="levelOfDetail">対象とする LOD。</param>
        /// <param name="meshPartIndex">対象とする BlockMeshPart のインデックス。</param>
        void Enqueue(InterBlockMesh interBlockMesh, BlockMesh blockMesh, int levelOfDetail, int meshPartIndex)
        {
            lock (this)
            {
                if (queue.Count == MaxCapacity)
                    throw new InvalidOperationException("This queue is full.");

                var item = new Item
                {
                    InterBlockMesh = interBlockMesh,
                    BlockMesh = blockMesh,
                    LevelOfDetail = levelOfDetail,
                    MeshPartIndex = meshPartIndex
                };

                queue.Add(item);
            }
        }
Пример #12
0
 /// <summary>
 /// 指定の LOD についての分割ロード要求をキューへ追加します。
 /// </summary>
 /// <param name="interBlockMesh">BlockMesh のロード元となる InterBlockMesh。</param>
 /// <param name="blockMesh">分割ロード対応の BlockMesh。</param>
 /// <param name="levelOfDetail">対象とする LOD。</param>
 void Enqueue(InterBlockMesh interBlockMesh, BlockMesh blockMesh, int levelOfDetail)
 {
     for (int i = 0; i < blockMesh.MeshLods[levelOfDetail].MeshParts.Count; i++)
     {
         Enqueue(interBlockMesh, blockMesh, levelOfDetail, i);
     }
 }
Пример #13
0
        /// <summary>
        /// 分割ロード対応の BlockMesh を生成します。
        /// </summary>
        /// <param name="graphicsDevice">GraphicsDevice。</param>
        /// <param name="interBlockMesh">BlockMesh のロード元となる InterBlockMesh。</param>
        /// <returns>分割ロード対応の BlockMesh。</returns>
        BlockMesh CreatePhasedBlockMesh(GraphicsDevice graphicsDevice, InterBlockMesh interBlockMesh)
        {
            var lodCount = interBlockMesh.MeshLods.Length;

            var blockMesh = new BlockMesh();
            blockMesh.SetMeshMaterials(interBlockMesh.MeshMaterials);
            blockMesh.AllocateMeshLods(lodCount);

            for (int lod = 0; lod < lodCount; lod++)
            {
                var interMeshLod = interBlockMesh.MeshLods[lod];
                var meshPartCount = interMeshLod.MeshParts.Length;
                var meshLod = blockMesh.MeshLods[lod];

                meshLod.AllocateMeshParts(graphicsDevice, meshPartCount);

                for (int i = 0; i < meshPartCount; i++)
                {
                    var interMeshPart = interMeshLod.MeshParts[i];
                    var meshPart = meshLod.MeshParts[i];

                    meshPart.MeshMaterial = blockMesh.MeshMaterials[interMeshPart.MeshMaterialIndex];
                }
            }

            return blockMesh;
        }
Пример #14
0
 void InterBlockMeshLoadTaskCallback(string name, InterBlockMesh result)
 {
     if (meshName == name) mesh = workspace.LoadBlockMesh(result);
 }
Пример #15
0
 public BlockMesh LoadBlockMesh(InterBlockMesh interBlockMesh)
 {
     return blockMeshLoadQueue.Load(GraphicsDevice, interBlockMesh);
 }