/** * 指定された線路と隣接するタスクの内、右向き正とした角度がもっとも大きいタスクを返します * これは線路を分岐させたとき、どの分岐先を選べばよいか判定するためのものです */ private LineTask FindFarLeft(RailEdge re) { if (Top == null) { return(null); } // セルフループの場合自身を返す if (Top.Next == Top) { if (!Top.IsNeighbor(re)) { throw new ArgumentException("top is not neighbored edge"); } return(Top); } // 隣接するタスクを絞り込む var neighbors = FilterNeighbors(re); if (neighbors.Count == 0) { throw new ArgumentException("edge is not any neighbored"); } // 候補が複数ある場合、距離0の移動タスクは角度の計算ができないのでスキップ var candidates = FilterOutUnangled(neighbors); // 次のタスクへの回転角が最も大きいものを返す return(FindLargestAngle(candidates, re)); }
private void Awake() { if (isTemplate) { template = this; } }
public (LineTask, LineTask) InsertEdge(RailEdge re) { var pivot = FindFarLeft(re); var prevNext = pivot.Next; pivot.InsertEdge(re); return(pivot, prevNext); }
public override void InsertEdge(RailEdge re) { var nx = Next; var inbound = CreateTask(re); inbound.Next = nx; nx.Prev = inbound; }
public override float SignedAngle(RailEdge re) { if (!IsNeighbor(re)) { throw new ArgumentException("could not calculate angle to un-neighbored edge"); } return(Vector3.SignedAngle(-Edge.Arrow, re.Arrow, Vector3.forward)); }
public float ExtendRail(Vector3 pos) { var action = new ExtendRailAction(TailNode, (prev) => { TailNode = prev; }); TailEdge = action.Act(pos); TailNode = TailEdge.To; Actions.AddLast(action); return(Vector3.Magnitude(TailEdge.Arrow)); }
private float Slide(RailEdge prev, RailEdge next, float slide) { var angle = Vector3.SignedAngle(prev.Arrow, next.Arrow, Vector3.forward); if (angle < 0) { angle = 360 + angle; } return(slide * Mathf.Sin(angle / 180 * Mathf.PI) * CurveRatio(angle)); }
public RailPart NewInstance(RailEdge parent, bool isForward) { var obj = Instantiate(template); obj.isTemplate = false; obj.GetComponent <MeshRenderer>().enabled = true; obj.Parent = parent; obj.IsForwardPart = isForward; obj.SetTransform(); return(obj); }
/** * 次のタスクへの回転角が最も大きいものを返す */ private LineTask FindLargestAngle(List <LineTask> list, RailEdge edge) { list.Sort((lt1, lt2) => { if (lt1.SignedAngle(edge) > lt2.SignedAngle(edge)) { return(1); } else if (lt1.SignedAngle(edge) < lt2.SignedAngle(edge)) { return(-1); } return(0); }); return(list[0]); }
/** * 現在のタスクに続く RailEdge に沿うタスクを作成します * 循環参照によるプロトタイプ生成失敗を防ぐため、別モジュールにしている */ protected LineTask CreateTask(RailEdge edge) { if (!IsNeighbor(edge)) { throw new ArgumentException("try to insert non-neighbored edge"); } var outBound = new EdgeTask(storage, listener, Parent, edge, this); EdgeTask inbound; if (!edge.To.StandsOver) { inbound = new EdgeTask(storage, listener, Parent, edge.Reverse, outBound); } else { inbound = new EdgeTask(storage, listener, Parent, edge.Reverse, new DeptTask(storage, listener, Parent, edge.To.StandsOver, outBound)); } return(inbound); }
public override float SignedAngle(RailEdge edge) { if (!IsNeighbor(edge)) { throw new ArgumentException("ould not calculate angle to un-neighbored edge"); } var obj = Prev; while (obj != this) { if (obj.Length > 0) { return(obj.SignedAngle(edge)); } obj = obj.Prev; } throw new ArgumentException("line has no edge task"); }
/** * 現在地点で路線を分断し、指定された往復路を路線タスクに挿入します * Before (a) = (a) -> (b) * After (a) = (a) -> (X) -> (a) -> (a) -> (b) * * edge : (a) -> (X) */ public override void InsertEdge(RailEdge edge) { var nx = Next; var inbound = CreateTask(edge); if (this != nx) { // 自身が発車タスクなので、復路の後の発車タスクを追加する var dept = new DeptTask(storage, listener, Parent, Stay, inbound); dept.Next = nx; nx.Prev = dept; } else { // 単体dept(セルフループ)の場合は例外で発車タスクをつけない inbound.Next = nx; nx.Prev = inbound; } }
/** * 指定された線路の始点を終点とする隣接タスクを返します */ private List <LineTask> FilterNeighbors(RailEdge re) { // 隣接していないタスクはスキップ // 駅に到着するタスクはスキップ。発車タスクの後に挿入する return(Filter((lt) => lt.IsNeighbor(re) && lt.Next is EdgeTask)); }
/** * 現在地点で路線を分断し、指定された往復路を路線タスクに挿入します * Before (a) ---------------> (b) -> (c) * After (a) -> (X) -> (a) -> (b) -> (c) * * edge : (a) -> (X) */ public abstract void InsertEdge(RailEdge edge);
/** * 指定された線路と隣接しているか判定します */ public abstract bool IsNeighbor(RailEdge edge);
/** * 自タスクの終点から何ラジアン回転すれば引数の線路に一致するか返す。(左回り正) */ public abstract float SignedAngle(RailEdge edge);
public RailEdge Act(Vector3 pos) { re = prevTail.Extend(pos); return(re); }
public void Act(RailEdge re) { (pivot, prevNext) = line.InsertEdge(re); }
public override bool IsNeighbor(RailEdge edge) { return(Stay.On == edge.From); }
public RailPart NewRailPart(RailEdge parent, bool isForward) { return(rp.NewInstance(parent, isForward)); }
public override bool IsNeighbor(RailEdge re) { return(Edge.To == re.From); }
public TestUtils() { storage = new GameObject().AddComponent <ModelStorage>(); listener = new GameObject().AddComponent <ModelListener>(); factory = new GameObject().AddComponent <ModelFactory>(); var co = new GameObject(); co.AddComponent <SpriteRenderer>(); factory.c = c = co.AddComponent <Company>(); var ro = new GameObject(); ro.AddComponent <SpriteRenderer>(); factory.r = r = ro.AddComponent <Residence>(); factory.rn = rn = new GameObject().AddComponent <RailNode>(); factory.re = re = new GameObject().AddComponent <RailEdge>(); var rpo = new GameObject(); rpo.AddComponent <MeshRenderer>(); factory.rp = rp = rpo.AddComponent <RailPart>(); var sto = new GameObject(); sto.AddComponent <SpriteRenderer>(); factory.st = st = sto.AddComponent <Station>(); factory.p = p = new GameObject().AddComponent <Platform>(); factory.g = g = new GameObject().AddComponent <Gate>(); var to = new GameObject(); to.AddComponent <SpriteRenderer>(); factory.t = t = to.AddComponent <Train>(); var ho = new GameObject(); ho.AddComponent <SpriteRenderer>(); factory.h = h = ho.AddComponent <Human>(); var ureso = new GameObject(); ures = ureso.AddComponent <UserResource>(); var transo = new GameObject(); trans = transo.AddComponent <Transport>(); var routeo = new GameObject(); route = routeo.AddComponent <Route>(); route.trans = trans; c.listener = r.listener = rn.listener = re.listener = rp.listener = st.listener = p.listener = g.listener = t.listener = h.listener = ures.listener = trans.listener = route.listener = listener; c.storage = r.storage = rn.storage = re.storage = rp.storage = st.storage = p.storage = g.storage = t.storage = h.storage = ures.storage = trans.storage = route.storage = storage; r.factory = rn.factory = re.factory = st.factory = ures.factory = factory; t.resource = trans.resource = route.resource = ures; }
public EdgeTask(ModelStorage db, ModelListener lis, RailLine l, RailEdge re, LineTask lt) : base(db, lis, l, lt) { Edge = re; db.Add(this); listener.Fire(EventType.CREATED, this); }