예제 #1
0
        public override RefStructure Build(Matrix4x4 toWorld)
        {
            var s = RefStructure.CreateNew();

            var stepSize = Mathf.PI * 2f / _resolution;

            //パーティクルを配置
            var p = new RefParticle[_resolution];

            for (var i = 0; i < _resolution; ++i)
            {
                var t = stepSize * i;
                var x = Mathf.Cos(t) * _radius;
                var y = Mathf.Sin(t) * _radius;

                p[i] = _particleBuilder.Add(s, new Vector2(x, y));
            }

            // エッジを配置
            for (var i = 0; i < _resolution; ++i)
            {
                _edgeBuilder.Add(s, p[i], p[(i + 1) % _resolution]);

                for (var j = 0; j < _supportIntervals.Length; ++j)
                {
                    _supportEdgeBuilder.Add(s, p[i], p[(i + _supportIntervals[j]) % _resolution]);
                }
            }

            s.TranslateParticles(toWorld);

            return(s);
        }
        RefParticle MakeBranch(RefStructure s, int depth, RefParticle parent, float angle, float length)
        {
            var dir     = Utilities.Angle2Vector(angle * Mathf.Deg2Rad);
            var pos     = parent.position + dir * length;
            var current = _branchParticleBuilder.Add(s, pos);

            depth--;
            if (depth > 0)
            {
                /*var edge = */
                _branchEdgeBuilder.Add(s, parent, current);

                // 分岐していく
                RefParticle b1, b2;
                if (length * Random.Range(1f, 2f) / _tempBaseBranchLength > 1f)
                {
                    b1 = MakeBranch(s, depth, current, angle + _angleoffsetA.random, length * _branchLengthDampingA.random);
                }
                else
                {
                    b1 = MakeBranch(s, depth, current, angle + _angleoffsetB.random, length * _branchLengthDampingB.random);
                }

                if (length * Random.Range(1f, 2f) / _tempBaseBranchLength > 1f)
                {
                    b2 = MakeBranch(s, depth, current, angle - _angleoffsetA.random, length * _branchLengthDampingA.random);
                }
                else
                {
                    b2 = MakeBranch(s, depth, current, angle - _angleoffsetB.random, length * _branchLengthDampingB.random);
                }

                // サポート
                _branchSupportEdgeBuilder.Add(s, b1, b2);
                _branchSupportEdgeBuilder.Add(s, parent, b1);
                _branchSupportEdgeBuilder.Add(s, parent, b2);
            }
            else
            {
                current.position = parent.position + dir * _leafLength.random;

                /*var leaf = */
                _leafEdgeBuilder.Add(s, parent, current);
            }

            return(current);
        }
예제 #3
0
        /// <summary>
        /// エッジの追加処理
        /// </summary>
        void HandleAddEdge()
        {
            if (_structure)
            {
                var wpos   = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                var hitten = RefStructure.HitParticle(_structure, wpos);
                if (hitten != null)
                {
                    if (_prevHitten == null)
                    {
                        _prevHitten = hitten;
                    }
                    else if (_prevHitten != hitten)
                    {
                        _edgeBuilder.Add(_structure, _prevHitten, hitten);
                        AddEditHistory();

                        _prevHitten = null;
                        SetDirty();
                    }
                }
            }
        }
예제 #4
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);
        }