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); } }
/// <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); } }
public override RefEdge Add(RefStructure s, int aIdx, int bIdx) { return(s.AddEdge(aIdx, bIdx, _width.random, _color.E_Random(), _materialID)); }
public override RefEdge Add(RefStructure s, RefParticle a, RefParticle b) { return(s.AddEdge(a, b, _width.random, _color.E_Random(), _materialID)); }
public override RefEdge Add(RefStructure s, RefParticle a, RefParticle b, float t) { return(s.AddEdge(a, b, _width.Lerp(t), _color.Evaluate(t), _materialID)); }
public override RefEdge Add(RefStructure s, int aIdx, int bIdx, float t) { return(s.AddEdge(aIdx, bIdx, _width.Lerp(t), _color.Evaluate(t), _materialID)); }
/// <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); }
/// <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); }
/// <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); }
public override RefParticle Add(RefStructure s, Vector2 p, float t) { return(s.AddParticle(p, _size.Lerp(t), _color.Evaluate(t), _materialID)); }