示例#1
0
        public override RefStructure Build(Matrix4x4 toWorld)
        {
            _s = RefStructure.CreateNew();
            var origin = _branchParticleBuilder.Add(_s, Vector2.zero, 0f);

            var maxDepth = _branchMaxDepth.randomInt;

            // 枝の作成
            MakeBranch(0, maxDepth, origin, 90f * Mathf.Deg2Rad);

            // 支持枝の作成
            var count = _s.GetParticleCount();

            for (int i = 0, n = _supportEdgeInterval.Length; i < n; ++i)
            {
                var interval = _supportEdgeInterval[i];
                for (int j = interval, n2 = count; j < n2; ++j)
                {
                    _branchEdgeBuilder.Add(_s, j - interval, j, 0f);
                }
            }

            _s.TranslateParticles(toWorld);

            return(_s);
        }
        /// <summary>
        /// 指定した構造体にパーティクルを追加する
        /// </summary>
        /// <param name="s"></param>
        /// <param name="targets"></param>
        static void AddParticles(RefStructure s, RefParticle[] targets)
        {
            Assert.IsNotNull(s);
            Assert.IsNotNull(targets);

            for (var i = 0; i < targets.Length; ++i)
            {
                var t = targets[i];
                s.AddParticle(t.position, t.size, t.color, t.materialID);
            }
        }
        /// <summary>
        /// 指定した構造体にエッジを追加する。エッジの追加には対応するUIDからIdxへのマッピング辞書が必要。
        /// </summary>
        /// <param name="s"></param>
        /// <param name="targets"></param>
        /// <param name="uid2IdxDict"></param>
        /// <param name="idxOffset"></param>
        static void AddEdges(RefStructure s, RefEdge[] targets, Dictionary <uint, int> uid2IdxDict, int idxOffset = 0)
        {
            Assert.IsNotNull(s);
            Assert.IsNotNull(targets);
            Assert.IsNotNull(uid2IdxDict);

            for (var i = 0; i < targets.Length; ++i)
            {
                var t    = targets[i];
                var aIdx = uid2IdxDict[t.aUID] + idxOffset;
                var bIdx = uid2IdxDict[t.bUID] + idxOffset;
                s.AddEdge(aIdx, bIdx, t.width, t.color, t.materialID);
            }
        }
示例#4
0
        /// <summary>
        /// 枝を再起的に生成する
        /// </summary>
        /// <param name="s"></param>
        /// <param name="depth"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        RefParticle MakeBranch(int depth, int maxDepth, RefParticle parent, float angle)
        {
            var t = depth / (float)maxDepth;

            angle += (_branchAngleCurve.Evaluate(t) * _branchAngleFactor) * Mathf.Deg2Rad;
            var dir    = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
            var length = _branchLengthCurve.Evaluate(t) * _branchLengthFactor;

            var pos     = parent.position + dir * length;
            var current = _branchParticleBuilder.Add(_s, pos, t);

            _branchEdgeBuilder.Add(_s, parent, current, t);

            if (depth > maxDepth)
            {
                return(current);
            }
            else
            {
                var child = MakeBranch(++depth, maxDepth, current, angle);

                // 枝を伸ばせる場合は枝を伸ばす
                if (_subBranchArchitect && _connectionEdgeBuilder)
                {
                    // Debug.Log("before: " + _s.GetParticleCount());
                    var subBranchMatrix = Matrix4x4.TRS(pos, Quaternion.AngleAxis(angle * Mathf.Rad2Deg, Vector3.forward), Vector3.one);
                    var branch          = _subBranchArchitect.Build(subBranchMatrix);
                    // var branch = _subBranchArchitect.Build(Matrix4x4.identity);
                    // Debug.Log(branch.GetParticleCount());
                    _s = DistanceMixer.Mix(_s, branch, 3f, _connectionEdgeBuilder);
                    // Debug.Log("after: " + _s.GetParticleCount());
                }

                return(child);
            }
        }
示例#5
0
 public override RefEdge Add(RefStructure s, int aIdx, int bIdx)
 {
     return(s.AddEdge(aIdx, bIdx, _width.random, _color.E_Random(), _materialID));
 }
示例#6
0
 public override RefEdge Add(RefStructure s, RefParticle a, RefParticle b)
 {
     return(s.AddEdge(a, b, _width.random, _color.E_Random(), _materialID));
 }
示例#7
0
 public override RefEdge Add(RefStructure s, RefParticle a, RefParticle b, float t)
 {
     return(s.AddEdge(a, b, _width.Lerp(t), _color.Evaluate(t), _materialID));
 }
示例#8
0
 public override RefEdge Add(RefStructure s, int aIdx, int bIdx, float t)
 {
     return(s.AddEdge(aIdx, bIdx, _width.Lerp(t), _color.Evaluate(t), _materialID));
 }
示例#9
0
 /// <summary>
 /// エッジを追加する
 /// </summary>
 /// <param name="s"></param>
 /// <param name="aIdx"></param>
 /// <param name="bIdx"></param>
 /// <param name="t"></param>
 /// <returns></returns>
 public virtual RefEdge Add(RefStructure s, int aIdx, int bIdx, float t)
 {
     return(null);
 }
示例#10
0
 /// <summary>
 /// エッジを追加する
 /// </summary>
 /// <param name="s"></param>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <param name="t"></param>
 /// <returns></returns>
 public virtual RefEdge Add(RefStructure s, RefParticle a, RefParticle b, float t)
 {
     return(null);
 }
示例#11
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);
        }
示例#12
0
 public override RefParticle Add(RefStructure s, Vector2 p, float t)
 {
     return(s.AddParticle(p, _size.Lerp(t), _color.Evaluate(t), _materialID));
 }