/// <summary>
        /// 参照からなる構造体を実際に使用する構造体に変換する
        /// </summary>
        /// <param name="structure"></param>
        /// <param name="materialDict"></param>
        public static CompiledStructure Compile(RefStructure structure, MaterialDictionary materialDict)
        {
            // パーティクルのuidとindexの辞書を作成
            var refParticles = structure.GetParticles();
            var refEdges     = structure.GetEdges();

            // 描画用マテリアルの順番を考慮する
            var matDict = materialDict.ExportDictionry();
            var particleMaterialList = CreateParticleMaterialList(refParticles, matDict);
            var edgeMaterialList     = CreateEdgeMaterialList(refEdges, matDict);

            // パーティクルとエッジを使用マテリアルの順番に整列する
            var materialOrderRefParticles = AlignParticlesWithMaterialOrder(refParticles, particleMaterialList);
            var materialOrderRefEdges     = AlignEdgesWithMaterialOrder(refEdges, edgeMaterialList);

            // 各種データを変換
            var indexDict = CreateUID2IndexDictionary(materialOrderRefParticles);
            var particles = CompileParticles(materialOrderRefParticles);
            var edges     = CompileEdges(materialOrderRefEdges, materialOrderRefParticles, indexDict);

            // マテリアルとそれぞれのオフセットを配列に
            var particleMaterials = particleMaterialList.Select(x => x.Key).ToArray();
            var edgeMaterials     = edgeMaterialList.Select(x => x.Key).ToArray();

            var particleOffsets = CreateMaterialOffsets(particleMaterialList);
            var edgeOffsets     = CreateMaterialOffsets(edgeMaterialList);

            // それぞれのマテリアル毎のパーティクルとエッジの数を配列に
            var particleCounts = CalcCountEachMaterials(particleMaterialList);
            var edgeCounts     = CalcCountEachMaterials(edgeMaterialList);

            // インスタンスを生成してデータを設定
            var compiled = UnityEngine.ScriptableObject.CreateInstance <CompiledStructure>();

            compiled.SetDatas(particles, edges, particleMaterials, edgeMaterials, particleOffsets, edgeOffsets, particleCounts, edgeCounts);

            return(compiled);
        }
예제 #2
0
        /// <summary>
        /// 特定のパーティクルの距離によるミックスを行う。多分これが一番シンプルな方法何じゃないかな?
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="dist"></param>
        /// <param name="edgeBuilder"></param>
        /// <returns></returns>
        public static RefStructure Mix(RefStructure a, RefStructure b, float dist, BaseEdgeBuilder edgeBuilder)
        {
            Assert.IsNotNull(a);
            Assert.IsNotNull(b);
            Assert.IsNotNull(edgeBuilder);

            var dst = RefStructure.CreateNew();

            // それぞれの構造体の中から一定の距離感にある。パーティクル同士をエッジでつなげる。

            var aParticles = a.GetParticles();
            var bParticles = b.GetParticles();

            var pairDict = new Dictionary <RefParticle, int[]>();

            for (var i = 0; i < aParticles.Length; ++i)
            {
                var t          = aParticles[i];
                var neighbours = FindParticles(t, dist, bParticles);
                pairDict.Add(t, neighbours);
            }

            // とりあえずペアを見つけ出したので、つないでみる。
            // ここで注意なのがパーティクルがaとbのどちらに属しているのかということ。
            // それらを意識しながら、接続関係をまとめていく。

            var aCount = aParticles.Length;

            // 一旦すべてのパーティクルとエッジを追加する
            AddParticles(dst, aParticles);
            AddParticles(dst, bParticles);

            // エッジの追加にはパーティクルのUIDからIdxへのマッピング辞書が必要。
            var aEdges = a.GetEdges();
            var bEdges = b.GetEdges();

            var uid2IdxDictA = CreateUID2IdxDictionary(aParticles);
            var uid2IdxDictB = CreateUID2IdxDictionary(bParticles);

            // Debug.Log(uid2IdxDictA.Count);
            AddEdges(dst, aEdges, uid2IdxDictA, 0);
            AddEdges(dst, bEdges, uid2IdxDictB, aCount);

            // ここから新しい接続用のエッジを追加していく。

            foreach (var pair in pairDict)
            {
                if (pair.Value.Length == 0)
                {
                    continue;
                }
                var idx = uid2IdxDictA[pair.Key.uid];

                for (var i = 0; i < pair.Value.Length; ++i)
                {
                    var tIdx = pair.Value[i] + aCount;
                    // 2つのインデックスが揃ったのでエッジを作る
                    edgeBuilder.Add(dst, idx, tIdx);
                }
            }

            return(dst);
        }