public static NodeMap CreateNodeMap(List <BeefDefine.SchemaWrapper.RoadDataModel> roadDataModels, Vector2 worldCenter, Vector2 worldScale) { var _nodeMap = new NodeMap(); foreach (var roadData in roadDataModels) { if (!roadData.InfoList.FullInfoList.ContainsKey("highway")) { continue; } var positions = roadData.Positions; for (int i = 0; i < positions.Count; i++) { var position = positions[i]; var nodeName = position.Id; var linkedNode = new List <string>(); if (i != 0) { linkedNode.Add(positions[i - 1].Id); } if ((i + 1) != positions.Count) { linkedNode.Add(positions[i + 1].Id); } if (_nodeMap.nodeMap.ContainsKey(nodeName)) { var nodeData = _nodeMap.nodeMap[nodeName]; nodeData.Graph.AddRange(linkedNode); } else { var vector3position = new Vector3( (position.Position.EastLon - worldCenter.x) * worldScale.x, 1.5f, (position.Position.NorthLat - worldCenter.y) * worldScale.y ); var data = new NodeMap.NodeData { Graph = new List <string>(linkedNode), Position = vector3position }; _nodeMap.nodeMap.Add(nodeName, data); } } } return(_nodeMap); }
public static NodeMap FilterByGroup(this NodeMap @self, int group) { var groupDict = new NodeMap.GroupDict(); NodeMap.Group(@self, out groupDict); var objs = groupDict.Where((obj) => obj.Value == group); var res = new Dictionary <string, NodeMap.NodeData>(); foreach (var obj in objs) { res[obj.Key] = @self.nodeMap[obj.Key]; } @self.nodeMap = res; return(@self); }
/// <summary> /// 道がつながっているかどうかグループ分けする. /// </summary> /// <returns>The group.</returns> /// <param name="nodeMap">Node map.</param> /// <param name="group">Group.</param> public static int Group(NodeMap nodeMap, out GroupDict group) { var groupId = 0; var keys = nodeMap.nodeMap.Keys.ToArray(); group = new GroupDict(keys.Length); for (int i = 0; i < keys.Length; i++) { var key = keys[i]; if (!group.ContainsKey(key)) { Paint(nodeMap, group, key, groupId); groupId++; } } return(groupId); }
public static void CreateRoadByNodeMap(NodeMap nodeMap, Action <CreateRoadMeshScripts.MeshSet, string, string> createMeshGameObject) { var hash = new HashSet <string>(); var roadMeshSets = new List <CreateRoadMeshScripts.MeshSet>(); var areaMeshSets = new List <CreateRoadMeshScripts.MeshSet>(); var groupDict = new NodeMap.GroupDict(); NodeMap.Group(nodeMap, out groupDict); foreach (var entry in groupDict) { // FIXME: 1つ以上のグループが存在する場合の暫定対処, 警告だけ出して処理続行する. if (entry.Value != 0) { Debug.LogWarningFormat("More than one Node groups exist."); continue; } CreateRoadMeshFromNode(nodeMap.nodeMap, entry.Key, hash, CreateRoadMeshScripts.CreateAddToMeshSetListCallback(roadMeshSets) ); CreateCrossRoadMeshFromNode(nodeMap.nodeMap, entry.Key, CreateRoadMeshScripts.CreateAddToMeshSetListCallback(areaMeshSets) ); } roadMeshSets = CreateRoadMeshScripts.GetCombinedMesh(roadMeshSets); for (int i = 0; i < roadMeshSets.Count; i++) { createMeshGameObject(roadMeshSets[i], "Road" + i, "TileMaterial"); } areaMeshSets = CreateRoadMeshScripts.GetCombinedMesh(areaMeshSets.ConvertAll(ConvertUvSetting)); for (int i = 0; i < areaMeshSets.Count; i++) { createMeshGameObject(areaMeshSets[i], "CrossRoad" + i, "CrossTileMaterial"); } }
/// <summary> /// _transform にランダムな道を歩かせる. /// </summary> /// <param name="_transform">Transform.</param> public void Test(Transform _transform) { nextNode = null; _targetTransForm = _transform; var groupDict = new NodeMap.GroupDict(); var groupCount = NodeMap.Group(nodeMap, out groupDict); groupDict.Dump(); var sameGroup = groupDict.Where((obj) => { return(obj.Value == 0); }).ToList(); int start = Random.Range(0, sameGroup.Count); int goal = Random.Range(0, sameGroup.Count); var nodeNames = sameGroup.Select((arg) => arg.Key).ToArray(); Debug.Log(sameGroup.Count); NodeMap.CostDict keyValuePairs; LinkedList <string> route; var pathCount = NodeMap.GetShortestRoute(nodeMap, nodeNames[start], nodeNames[goal], 10000, out keyValuePairs, out route); Debug.Log(string.Format("道を探します : start : {0} {1}", nodeNames[start], nodeNames[goal])); if (route == null) { Debug.Log("道が遠すぎたため停止します"); currentRoute = null; return; } foreach (var nodeName in route) { Debug.Log("route : " + nodeName + " : " + nodeMap.nodeMap[nodeName].Position); } currentRoute = route; }
private static void Paint(NodeMap nodeMap, GroupDict costDict, string startKey, int paintId) { costDict[startKey] = paintId; var stack = new List <string>(); stack.Add(startKey); while (stack.Count != 0) { var key = stack[0]; var graph = nodeMap.nodeMap[key].Graph; foreach (var obj in graph) { if (!costDict.ContainsKey(obj)) { costDict[obj] = paintId; stack.Add(obj); } } stack.RemoveAt(0); } }
/// <summary> /// 道の情報を NodeMap に変換する. /// </summary> /// <param name="roadDataModels">Road data models.</param> /// <param name="worldCenter">World center.</param> /// <param name="worldScale">World scale.</param> public void Initialize(List <RoadDataModel> roadDataModels, Vector2 worldCenter, Vector2 worldScale) { nodeMap = NodeMap.CreateNodeMap(roadDataModels, worldCenter, worldScale); }
/// <summary> /// 最短経路を探す. /// </summary> /// <returns>The saitan.</returns> /// <param name="nodeMap">Node map.</param> /// <param name="startKey">Start key.</param> /// <param name="goalKey">Goal key.</param> /// <param name="loopout">計算を諦めるしきい値</param> /// <param name="costDict">Cost dict.</param> /// <param name="route">Route.</param> public static int GetShortestRoute(NodeMap nodeMap, string startKey, string goalKey, int loopout, out CostDict costDict, out LinkedList <string> route) { costDict = new CostDict(nodeMap.nodeMap.Count); var stack = new SortedSet <CostDataForStack>(new CostDataForStack.myReverserClass()); var startNode = nodeMap.nodeMap[startKey]; var goalNode = nodeMap.nodeMap[goalKey]; { var openNodeCostData = new CostData { cost = 0.0f, heuristicCost = Vector3.Distance(startNode.Position, goalNode.Position), parent = null }; costDict[startKey] = openNodeCostData; CostDataForStack costDataForStack = new CostDataForStack { cost = openNodeCostData.cost, score = openNodeCostData.cost + openNodeCostData.heuristicCost, nodeName = startKey }; stack.Add(costDataForStack); } while (stack.Count != 0 && 0 < loopout) { loopout--; var parent = stack.First(); stack.Remove(parent); var parentName = parent.nodeName; var parentNode = nodeMap.nodeMap[parentName]; var parentCost = costDict[parentName]; foreach (var openNodeName in parentNode.Graph) { if (costDict.ContainsKey(openNodeName)) { continue; } var openNode = nodeMap.nodeMap[openNodeName]; var openNodeCost = parentCost.cost + Vector3.Distance(openNode.Position, parentNode.Position); var hCost = Vector3.Distance(openNode.Position, goalNode.Position); var openNodeCostData = new CostData { cost = openNodeCost, heuristicCost = hCost, parent = parentName }; var costDataForStack = new CostDataForStack { cost = openNodeCostData.cost, score = openNodeCostData.cost + openNodeCostData.heuristicCost, nodeName = openNodeName }; costDict[openNodeName] = openNodeCostData; stack.Add(costDataForStack); CostDataForStack.Dump(costDataForStack); } if (costDict.ContainsKey(goalKey)) { break; } } if (costDict.ContainsKey(goalKey)) { route = new LinkedList <string>(); var node = costDict[goalKey]; while (node.parent != null) { route.AddFirst(node.parent); node = costDict[node.parent]; } return(route.Count); } else { route = null; return(0); } }
/// <summary> /// 最短経路を探す. /// </summary> /// <returns>The saitan.</returns> /// <param name="nodeMap">Node map.</param> /// <param name="startKey">Start key.</param> /// <param name="goalKey">Goal key.</param> /// <param name="costDict">Cost dict.</param> /// <param name="route">Route.</param> public static int GetShortestRoute(NodeMap nodeMap, string startKey, string goalKey, out CostDict costDict, out LinkedList <string> route) { return(GetShortestRoute(nodeMap, startKey, goalKey, 10000, out costDict, out route)); }
public static void CreateRoadByNodeMapNext(NodeMap nodeMap, Action <CreateRoadMeshScripts.MeshSet, string, string> createMeshGameObject) { var hash = new Dictionary <string, BeefMeshUtility.IPlaneMeshSet>(); var roadMeshSets = new List <BeefMeshUtility.IPlaneMeshSet>(); var curveMeshSets = new List <BeefMeshUtility.IPlaneMeshSet>(); var areaMeshSets = new List <BeefMeshUtility.IPlaneMeshSet>(); var groupDict = new NodeMap.GroupDict(nodeMap.nodeMap.Count); NodeMap.Group(nodeMap, out groupDict); foreach (var entry in groupDict) { // FIXME: 1つ以上のグループが存在する場合の暫定対処, 警告だけ出して処理続行する. if (entry.Value != 0) { Debug.LogWarningFormat("More than one Node groups exist."); continue; } CreateRoadMeshFromNodeLine(nodeMap.nodeMap, entry.Key, hash, roadMeshSets); var key1 = entry.Key; var centerNode = nodeMap.nodeMap[key1]; if (1 < centerNode.Graph.Count) { var connectedMeshSets = centerNode.Graph.ConvertAll((string key2) => key1 + ":" + key2).ConvertAll((string input) => hash[input]).ToList(); var meshSet = BeefMeshUtility.GetFrameMeshSet(connectedMeshSets); if (meshSet == null) { continue; } if (centerNode.Graph.Count == 2) { curveMeshSets.Add(meshSet); } else { areaMeshSets.Add(meshSet); } } } var roadMeshSetsNeo = CreateRoadMeshScripts.GetCombinedMesh(roadMeshSets.ConvertAll((input) => input.GetMeshSet())); for (int i = 0; i < roadMeshSetsNeo.Count; i++) { createMeshGameObject(roadMeshSetsNeo[i], "Road" + i, "TileMaterial"); } var curveMeshSetsNeo = CreateRoadMeshScripts.GetCombinedMesh(curveMeshSets.ConvertAll((input) => input.GetMeshSet())); for (int i = 0; i < curveMeshSetsNeo.Count; i++) { createMeshGameObject(curveMeshSetsNeo[i], "Curve" + i, "CurveTileMaterial"); } var areaMeshSetsNeo = CreateRoadMeshScripts.GetCombinedMesh(areaMeshSets.ConvertAll((input) => input.GetMeshSet())); for (int i = 0; i < areaMeshSetsNeo.Count; i++) { createMeshGameObject(areaMeshSetsNeo[i], "CrossRoad" + i, "CrossTileMaterial"); } }
public static void CreateRoadByNodeMap(NodeMap nodeMap) { CreateRoadByNodeMap(nodeMap, CreateMeshGameObject); }