private RoadTypes CheckSurface(RoadTypes rt, string surface) { if (pavedMapping.ContainsKey(surface)) { if (pavedMapping[surface]) { if (rt == RoadTypes.GravelRoad) { return(RoadTypes.BasicRoad); } else if (rt == RoadTypes.PedestrianGravel) { return(RoadTypes.PedestrianPavement); } } else { if (rt == RoadTypes.PedestrianPavement || rt == RoadTypes.PedestrianGravel) { return(RoadTypes.PedestrianGravel); } else { return(RoadTypes.GravelRoad); } } } return(rt); }
private RoadTypes GetOneway(RoadTypes rt) { switch (rt) { case RoadTypes.BasicRoad: case RoadTypes.MediumRoad: return(RoadTypes.OnewayRoad); case RoadTypes.BasicRoadDecorationTrees: case RoadTypes.MediumRoadDecorationTrees: return(RoadTypes.OnewayRoadDecorationTrees); case RoadTypes.MediumRoadDecorationGrass: case RoadTypes.BasicRoadDecorationGrass: return(RoadTypes.OnewayRoadDecorationGrass); case RoadTypes.LargeRoad: case RoadTypes.LargeRoadDecorationGrass: case RoadTypes.LargeRoadDecorationTrees: case RoadTypes.Highway: return(RoadTypes.Highway); case RoadTypes.GravelRoad: return(RoadTypes.OnewayRoad); case RoadTypes.HighwayRamp: return(RoadTypes.HighwayRamp); case RoadTypes.LargeOneway: return(RoadTypes.LargeOneway); } return(RoadTypes.None); }
/// <summary> /// Returns a boolean that tells if the two endpoints in input are valid endpoints for a road. /// </summary> /// <param name="n1"></param> /// <param name="n2"></param> /// <returns></returns> private static bool areNodesOK(Node n1, Node n2, RoadTypes roadType) { float distance = (n1.pos - n2.pos).magnitude; float roadSlope = (float)Mathf.Abs(CoordinateHelper.worldToTerrainHeight(n2) - CoordinateHelper.worldToTerrainHeight(n1)) / (float)distance; float maxSlope = (roadType == RoadTypes.HIGHWAY) ? CityGenerator.highwayMaxSlope : CityGenerator.streetMaxSlope; return((roadSlope <= maxSlope) && !isNodeUnderWater(n2) && CoordinateHelper.validEndPoint(n2)); }
public Edge(Node n1, Node n2, RoadTypes type, int t) { this.n1 = n1; this.n2 = n2; this.type = type; this.priority = t; computeDirection(); }
public Way(List <long> points, RoadTypes rt, OSMRoadTypes osmrt, int layer, string name) { this.roadType = rt; this.nodes = points; this.layer = layer; this.name = name; this.osmRoadType = osmrt; }
/** * Make the given tile a drivethrough roadstop tile. * @param t the tile to make a roadstop * @param station the owner of the roadstop * @param road the owner of the road * @param tram the owner of the tram * @param sid the station to which this tile belongs * @param rst the type of roadstop to make this tile * @param rt the roadtypes on this tile * @param a the direction of the roadstop */ public static void MakeDriveThroughRoadStop(this TileIndex t, Owner station, Owner road, Owner tram, StationID sid, RoadStopType rst, RoadTypes rt, Axis a) { MakeStation(t, station, sid, (rst == RoadStopType.ROADSTOP_BUS ? StationType.STATION_BUS : StationType.STATION_TRUCK), GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET + a); t.SetRoadTypes(rt); t.SetRoadOwner(RoadType.ROADTYPE_ROAD, road); t.SetRoadOwner(RoadType.ROADTYPE_TRAM, tram); }
public Edge(Node n1, Node n2, RoadTypes type, int t, Edge pred, Edge succ) { this.n1 = n1; this.n2 = n2; this.type = type; this.priority = t; this.pred = pred; this.succ = succ; computeDirection(); }
/** * Make a level crossing. * @param t Tile to make a level crossing. * @param road New owner of road. * @param tram New owner of tram tracks. * @param rail New owner of the rail track. * @param roaddir Axis of the road. * @param rat New rail type. * @param rot New present road types. * @param town Town ID if the road is a town-owned road. */ public static void MakeRoadCrossing(this TileIndex t, Owner road, Owner tram, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town) { TileMap.SetTileType(t, TileType.MP_ROAD); TileMap.SetTileOwner(t, rail); Map._m[t].m2 = town; Map._m[t].m3 = rat; Map._m[t].m4 = 0; Map._m[t].m5 = RoadTileType.ROAD_TILE_CROSSING << 6 | roaddir; Map._me[t].m6 = BitMath.SB(Map._me[t].m6, 2, 4, 0); Map._me[t].m7 = rot << 6 | road; SetRoadOwner(t, RoadType.ROADTYPE_TRAM, tram); }
/** * Make a normal road tile. * @param t Tile to make a normal road. * @param bits Road bits to set for all present road types. * @param rot New present road types. * @param town Town ID if the road is a town-owned road. * @param road New owner of road. * @param tram New owner of tram tracks. */ public static void MakeRoadNormal(this TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram) { TileMap.SetTileType(t, TileType.MP_ROAD); TileMap.SetTileOwner(t, road); Map._m[t].m2 = town; Map._m[t].m3 = (BitMath.HasBit(rot, RoadType.ROADTYPE_TRAM) ? bits : 0); Map._m[t].m4 = 0; Map._m[t].m5 = (BitMath.HasBit(rot, RoadType.ROADTYPE_ROAD) ? bits : 0) | RoadTileType.ROAD_TILE_NORMAL << 6; BitMath.SB(Map._me[t].m6, 2, 4, 0); Map._me[t].m7 = rot << 6; SetRoadOwner(t, RoadType.ROADTYPE_TRAM, tram); }
public GlobalParametersDialog() { InitializeComponent(); Owner = App.Window; Icon = AppResources.GetAppIcon; _cityTags = App.DataBase.GetCollection <CityTags>().FindOne(ct => ct.IsPrimary); _roadTypes = App.DataBase.GetCollection <RoadTypes>().FindOne(rt => rt.IsPrimary); InitCityTagsProperty(); InitRoadTypesProperty(); Closed += (sender, args) => CancelClick(); }
public static void Invoke() { var selectDialog = new GenericSelectEntitiesDialog <TransportSystem>( "Выберите транспортную систему", TransportSystem.PropertyMatcher(), App.DataBase.GetCollection <TransportSystem>().FindAll()); if (selectDialog.Selected == null) { return; } _selectedSystem = selectDialog.Selected[0]; _availableRoadTypes = App.DataBase.GetCollection <RoadTypes>().FindOne(ct => ct.IsPrimary); _idToNameCitiesMap = App.DataBase.GetCitiesOfTransportSystem(_selectedSystem) .ToDictionary(c => c.Id, c => c.Name); _nameToIdCitiesMap = _idToNameCitiesMap .ToDictionary(kv => kv.Value, kv => kv.Key); _dialog = new GenericEntityDialog <Road>() { Title = "Маршруты", ListTitle = "Доступные маршруты", OpenAddNewItemWindowButtonTitle = "Открыть окно для добавления маршрута", AddNewItemWindowTitle = "Добавить маршрут", UpdateItemWindowTitle = "Обновить маршрут", AddItemFunction = AddRoad, UpdateItemFunction = UpdateRoad, RemoveItemFunction = RemoveRoad, UpdateCollectionFunction = UpdateCollection }; _dialog.AddColumns(Road.PropertyMatcher(_idToNameCitiesMap)); InitFromCityProperty(); InitToCityProperty(); InitLengthProperty(); InitCostProperty(); InitTimeProperty(); InitRoadTypeProperty(); InitTimeTableProperty(); UpdateCollection(); _dialog.ShowDialog(); }
/** * Get the road types the given company can build. * @param company the company to get the roadtypes for. * @return the road types. */ public static RoadTypes GetCompanyRoadtypes(CompanyID company) { RoadTypes rt = RoadTypes.ROADTYPES_NONE; Engine e; FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) { EngineInfo ei = e.info; if (BitMath.HasBit(ei.climates, _settings_game.game_creation.landscape) && (BitMath.HasBit(e.company_avail, company) || DateConstants._date >= e.intro_date + DateConstants.DAYS_IN_YEAR)) { BitMath.SetBit(rt, BitMath.HasBit(ei.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD); } } return(rt); }
public TaskSpecificationDialog() { InitializeComponent(); Owner = App.Window; Icon = AppResources.GetAppIcon; _availableTransportSystems = App.DataBase.GetCollection <TransportSystem>().FindAll().ToList(); _availableCityTags = App.DataBase.GetCollection <CityTags>().FindOne(ct => ct.IsPrimary); _availableRoadTypes = App.DataBase.GetCollection <RoadTypes>().FindOne(rt => rt.IsPrimary); _config = App.DataBase.GetCollection <AlgorithmConfig>().FindOne(a => a.IsPrimary); InitTransportSystemsProperty(); InitAlgorithmTypeProperty(); InitMethodTypeProperty(); InitCityTagsProperty(); InitUnusedRoadTypesProperty(); Closed += (sender, args) => CancelClick(); }
/** * Finds out, whether given company has all given RoadTypes available * @param company ID of company * @param rts RoadTypes to test * @return true if company has all requested RoadTypes available */ public static bool HasRoadTypesAvail(CompanyID company, RoadTypes rts) { RoadTypes avail_roadtypes; if (company == OWNER_DEITY || company == OWNER_TOWN || _game_mode == GM_EDITOR || _generating_world) { avail_roadtypes = ROADTYPES_ROAD; } else { Company c = Company.GetIfValid(company); if (c == null) { return(false); } avail_roadtypes = (RoadTypes)c.avail_roadtypes | RoadTypes.ROADTYPES_ROAD; // road is available for always for everybody } return((rts & ~avail_roadtypes) == 0); }
/// <summary> /// Generates the road mesh. Takes an array of points (road nodes) and makes a smooth road based on these points /// </summary> /// <param name="roadPoints">Road points.</param> /// <param name="width">Width of the road</param> private void generateRoadMesh(Node[] roadPoints, RoadTypes type) { if (roadMeshes == null) { roadMeshes = new GameObject(); roadMeshes.name = "RoadMeshes"; } road = new GameObject(); road.name = "Road"; road.transform.parent = roadMeshes.transform; mf = road.AddComponent <MeshFilter> (); mr = road.AddComponent <MeshRenderer> (); mr.material = (Material)Resources.Load("roadMaterial") as Material; mesh = new Mesh(); mesh.name = "Road"; //generate the road using the smoothpoints generateRoad(smoothPoints(roadPoints), type, roadPoints[0], roadPoints[roadPoints.Length - 1]); }
private static RoadTypes ConvertToOneWayRoadType(RoadTypes rt) { switch (rt) { case RoadTypes.BasicRoad: case RoadTypes.MediumRoad: return(RoadTypes.OnewayRoad); case RoadTypes.BasicRoadDecorationTrees: case RoadTypes.MediumRoadDecorationTrees: return(RoadTypes.OnewayRoadDecorationTrees); case RoadTypes.MediumRoadDecorationGrass: case RoadTypes.BasicRoadDecorationGrass: return(RoadTypes.OnewayRoadDecorationGrass); case RoadTypes.LargeRoad: case RoadTypes.LargeRoadDecorationGrass: case RoadTypes.LargeRoadDecorationTrees: case RoadTypes.Highway: return(RoadTypes.Highway); case RoadTypes.TwoLaneHighway: return(RoadTypes.TwoLaneHighway); case RoadTypes.GravelRoad: return(RoadTypes.OnewayRoad); case RoadTypes.HighwayRamp: return(RoadTypes.HighwayRamp); case RoadTypes.LargeOneway: return(RoadTypes.LargeOneway); } return(RoadTypes.None); }
protected StraightRoad(Scene scene, IMap map, RoadTypes roadtype, Texture2D texture) : base(scene.Game, texture) { this.scene = scene; this.map = map; this.roadtype = roadtype; this.SpriteBatch = scene.currentSpriteBatch; this.Scrollable = true; this.Location = Vector2.Zero; commonInit(); }
public static Texture2D RoadTexture(RoadTypes roadtype, Game game) { switch (roadtype) { case RoadTypes.Road4: return game.Content.Load<Texture2D>("Textures/road1024_4"); case RoadTypes.Road4to3: return game.Content.Load<Texture2D>("Textures/road1024_4-3"); case RoadTypes.Road3: return game.Content.Load<Texture2D>("Textures/road1024_3"); case RoadTypes.Road3to2: return game.Content.Load<Texture2D>("Textures/road1024_3-2"); case RoadTypes.Road2: return game.Content.Load<Texture2D>("Textures/road1024_2"); case RoadTypes.Road2to3: return game.Content.Load<Texture2D>("Textures/road1024_2-3"); case RoadTypes.Road3to4: return game.Content.Load<Texture2D>("Textures/road1024_3-4"); default: return game.Content.Load<Texture2D>("Textures/road1024_4"); } }
/// <summary> /// Checks if the road intersects with other roads within a certain distance from the road (in the direction the road is facing) /// </summary> /// <returns><c>true</c>, if intersection was found and also changes fixedRoad, <c>false</c> otherwise.</returns> /// <param name="road">Road.</param> /// <param name="dist">Distance over which the intersection should be checked</param> private bool checkIntersection(Edge road, float dist) { //set up variables needed for boxcastall int layerMask = 1 << LayerMask.NameToLayer("Edge"); Vector3 halfExtends = new Vector3(0.1f, 100, ((posN1 - posN2).magnitude) / 2); Vector3 roadCenter = Vector3.Lerp(posN1, posN2, 0.5f); Vector3 direction = posN2 - posN1; Vector2 roadOrientation = new Vector2(direction.x, direction.z); //get the intersections with roads RaycastHit[] intersections = Physics.BoxCastAll(roadCenter, halfExtends, direction, Quaternion.LookRotation(direction), dist, layerMask); //no intersections, good! if (intersections.Length == 0) { //Debug.Log ("Road did not intersect"); return(false); } else { float closestRoadDistance = float.MaxValue; //just set it to the first value GameObject closestRoad = null; Vector2 closestIntersection = Vector2.zero; //first we check which road is closest foreach (RaycastHit hit in intersections) { //Debug.Log (road.getRoadType().ToString() + " intersects with: " + hit.collider.gameObject.name + " which has N1 at: " + hit.transform.GetChild (0).localPosition + " and posN1 is: " + posN1); //Debug.Log (road.getRoadType().ToString() + " intersects with: " + hit.collider.gameObject.name + " which has N2 at: " + hit.transform.GetChild (1).localPosition + " and posN1 is: " + posN1); //Debug.Log (hit.collider.gameObject.name + " shares N1: " + CoordinateHelper.areEqual (hit.transform.GetChild (0).localPosition, posN1)); //Debug.Log (hit.collider.gameObject.name + " shares N2: " + CoordinateHelper.areEqual (hit.transform.GetChild (1).localPosition, posN1)); //consider the case where roads have the same endpoints, i.e., they overlap exactly if ((CoordinateHelper.areEqual(hit.transform.GetChild(1).localPosition, posN1) && CoordinateHelper.areEqual(hit.transform.GetChild(0).localPosition, posN2)) || (CoordinateHelper.areEqual(hit.transform.GetChild(1).localPosition, posN2) && CoordinateHelper.areEqual(hit.transform.GetChild(0).localPosition, posN1))) { //in this case the road cannot be placed if (CityGeneratorUI.DebugMode) { Debug.Log("Intersection checker: roads overlapped exactly"); } fixedRoad = null; return(true); } else { //only consider road segments that are not a predecessor if (!CoordinateHelper.areEqual(hit.transform.GetChild(1).localPosition, posN1)) { //also dont consider roads that branch out from the same point if (!CoordinateHelper.areEqual(hit.transform.GetChild(0).localPosition, posN1)) { //these are the roads that have no endpoints in common with the current road. //check if the angle is valid Vector2 otherRoadOrientation = new Vector2(hit.transform.forward.x, hit.transform.forward.z); //check if the two roads have enough "space" between them. if (isValidAngle(roadOrientation.normalized, otherRoadOrientation.normalized)) { //find the road that is intersected with first Vector2 intersectionPoint = lineIntersectionPoint( road.n1.pos, road.n2.pos, CoordinateHelper.threeDtoTwoD(hit.transform.GetChild(0).localPosition), CoordinateHelper.threeDtoTwoD(hit.transform.GetChild(1).localPosition)); float distance = (road.n1.pos - intersectionPoint).magnitude; if (distance < closestRoadDistance) { //Debug.Log ("Road: " + hit.collider.gameObject.name + " has distance: " + (posN1 - hit.collider.transform.position).magnitude + " to n1"); closestRoad = hit.collider.gameObject; closestIntersection = intersectionPoint; closestRoadDistance = distance; } } else { //return that the road is invalid fixedRoad = null; return(true); } } else { if (CityGeneratorUI.DebugMode) { Debug.Log("Roads have same start point"); } //there is another road branching out from the same point.. check their angle Vector2 sameBranchRoadOrientation = new Vector2(hit.transform.forward.x, hit.transform.forward.z); if (Vector2.Angle(roadOrientation.normalized, sameBranchRoadOrientation.normalized) > CityGenerator.minRoadAngle) { //this is fine } else { //when this happens we cannot place this road fixedRoad = null; return(true); } } } else { //just to be sure, we dont want to make sharp turns if (CityGeneratorUI.DebugMode) { Debug.Log("Roads have same start point"); } //there is another road branching out from the same point.. check their angle Vector2 sameBranchRoadOrientation = new Vector2(hit.transform.forward.x, hit.transform.forward.z); if (Vector2.Angle(roadOrientation.normalized, sameBranchRoadOrientation.normalized) < 180 - CityGenerator.minRoadAngle) { //this is fine } else { //when this happens we cannot place this road fixedRoad = null; return(true); } } } } //no legitimate intersection was found if (closestRoad == null) { //return that no intersection was found return(false); } else { //Now we want to see if the angle between the roads is large enough. Vector2 closestRoadOrientation = new Vector2(closestRoad.transform.forward.x, closestRoad.transform.forward.z); //we want to make sure the angle is large enough if (isValidAngle(roadOrientation.normalized, closestRoadOrientation.normalized)) { //now we also need to update the roads list in the roadmapgenerator //set up all involved nodes Node roadToReplaceN1 = new Node(closestRoad.transform.GetChild(0).localPosition.x, closestRoad.transform.GetChild(0).localPosition.z); Node intersectionNode = new Node(closestIntersection); Node roadToReplaceN2 = new Node(closestRoad.transform.GetChild(1).localPosition.x, closestRoad.transform.GetChild(1).localPosition.z); //check if after splitting the new road segments are long enough if ((intersectionNode.pos - roadToReplaceN1.pos).magnitude > CityGenerator.minRoadLengthAfterSplit) { if ((intersectionNode.pos - roadToReplaceN2.pos).magnitude > CityGenerator.minRoadLengthAfterSplit) { fixedRoad.n2 = intersectionNode; //also check if the fixed road is long enough, do this before generating intersections! if (CoordinateHelper.validRoadLength(fixedRoad)) { //if the width of the closest road equals the highwaywidth, we create new highways RoadTypes roadType = (closestRoad.transform.localScale.x == CityGenerator.highwayWidth) ? RoadTypes.HIGHWAY : RoadTypes.STREET; //create new road segments for the road that is going to be split Edge splitRoad1 = new Edge(roadToReplaceN1, intersectionNode, roadType); Edge splitRoad2 = new Edge(intersectionNode, roadToReplaceN2, roadType); //get a reference to the road that is going to be split Edge roadToReplace = RoadMapGenerator.getRoad(roadToReplaceN1, roadToReplaceN2); //the road segments which will replace closestRoad List <Edge> replacementRoads = new List <Edge> (); replacementRoads.Add(splitRoad1); replacementRoads.Add(splitRoad2); if (CityGeneratorUI.DebugMode) { Debug.Log(closestRoad.name + " was split by road starting at" + road.n1 + " and ending at " + road.n2); } //physically change the road RoadVisualizer.replaceRoad(closestRoad, replacementRoads); //now replace the roads in the road list (logically) RoadMapGenerator.replaceRoad(roadToReplace, replacementRoads); } } else { //we cannot fix this intersection fixedRoad = null; return(true); } } else { //we cannot fix this intersection fixedRoad = null; return(true); } return(true); } else { //the road intersects with a road while the angle between them is too small //so we cannot place this road fixedRoad = null; return(true); } } } }
/// <summary> /// Branches a new Vector2 starting at Vector2 point. The new branch is based on an old direction, which is then changed by a random value /// in between minAngle and maxAngle. The length is the length of the new edge that is created. /// </summary> /// <param name="point"></param> /// <param name="directionVector"></param> /// <param name="minAngle"></param> /// <param name="maxAngle"></param> /// <param name="length"></param> /// <returns></returns> protected virtual Vector2 branchVectorFromPoint(Vector2 point, Vector2 directionVector, float minAngle, float maxAngle, RoadTypes roadType) { float diff = maxAngle - minAngle; float randomAngle = Random.value * diff; Vector2 newDirectionVector = Vector2.zero + directionVector; newDirectionVector.Normalize(); newDirectionVector *= (roadType == RoadTypes.HIGHWAY) ? CityGenerator.highwayMinLength * CityGenerator.highwayLookAhead: CityGenerator.streetMinLength * CityGenerator.streetLookAhead; Vector2 vector = point + (Vector2)(Quaternion.Euler(0, 0, minAngle + randomAngle) * newDirectionVector); return(vector); }
/** * Make the given tile a roadstop tile. * @param t the tile to make a roadstop * @param o the owner of the roadstop * @param sid the station to which this tile belongs * @param rst the type of roadstop to make this tile * @param rt the roadtypes on this tile * @param d the direction of the roadstop */ public static void MakeRoadStop(this TileIndex t, Owner o, StationID sid, RoadStopType rst, RoadTypes rt, DiagDirection d) { MakeStation(t, o, sid, (rst == RoadStopType.ROADSTOP_BUS ? StationType.STATION_BUS : StationType.STATION_TRUCK), d); t.SetRoadTypes(rt); t.SetRoadOwner(RoadType.ROADTYPE_ROAD, o); t.SetRoadOwner(RoadType.ROADTYPE_TRAM, o); }
/// <summary> /// Generates the road mesh given an array of nodes along which the road should traverse /// </summary> /// <param name="nodes">Nodes along which the road traverses</param> /// <param name="width">Width of the road</param> /// <param name="startNode">Reference to the start node of this road</param> /// <param name="endNode">Reference to the end node of this road</param> private void generateRoad(Node[] nodes, RoadTypes type, Node startNode, Node endNode) { //set up arrays needed for mesh generation vertices = new List <Vector3> (); tri = new List <int> (); uv = new List <Vector2> (); //used to determine the correct UV height float uvHeight = 0.0f; bool up = true; //the point from which we "move" in the roads direction Vector2 origin = nodes[0].pos; //used to keep track of index of previous vertices in index array. int prevLeft = -1; int prevRight = -1; //highways are a bit higher s.t. they are always "above" float extraHeight = (type == RoadTypes.HIGHWAY) ? 0.02f : 0.01f; float width = (type == RoadTypes.HIGHWAY) ? (float)CityGenerator.highwayWidth : (float)CityGenerator.streetWidth; //we loop over the points (except the last one) for (int i = 0; i < nodes.Length - 1; i++) { //now for each point we determin how many road "segments" we need to make Vector2 localDirection = (nodes[i + 1].pos - origin); //we make roadsegments equal to the amount of units we have for (int j = 0; j < Mathf.RoundToInt(localDirection.magnitude); j++) { Vector2 leftPoint2D = origin + (new Vector2(-localDirection.y, localDirection.x).normalized *(width / 2)); Vector2 rightPoint2D = origin + (new Vector2(localDirection.y, -localDirection.x).normalized *(width / 2)); //find right and left point with respect to origin and update minHeight Vector3 leftPoint = new Vector3(leftPoint2D.x, CoordinateHelper.getAccurateTerrainHeight(leftPoint2D.x, leftPoint2D.y) + extraHeight, leftPoint2D.y); Vector3 rightPoint = new Vector3(rightPoint2D.x, CoordinateHelper.getAccurateTerrainHeight(rightPoint2D.x, rightPoint2D.y) + extraHeight, rightPoint2D.y); // Fixes for water if (CityGenerator.rWater) { leftPoint.y = Mathf.Max(leftPoint.y, 1f); rightPoint.y = Mathf.Max(rightPoint.y, 1f); } //if we have previous coordinates if (prevLeft >= 0 && prevRight >= 0) { int triSize = tri.Count; int vertSize = vertices.Count; //lower left triangle tri.Add(prevLeft); //the previous left point tri.Add(vertSize); //the current left point tri.Add(prevRight); //the current right point //upper right triangle tri.Add(vertSize); //the current left point tri.Add(vertSize + 1); //the current right point tri.Add(prevRight); //the previous right point //we also make a box collider for this "segment" GameObject coll = new GameObject(); coll.transform.parent = road.transform; coll.transform.localPosition = Vector3.Lerp(leftPoint, rightPoint, 0.5f); coll.layer = LayerMask.NameToLayer("Road"); BoxCollider bc = coll.AddComponent <BoxCollider> (); bc.size = new Vector3(2.0f, 0.01f, width); //allign it with the road coll.transform.LookAt(rightPoint); } else { //prevLeft and prevRight are not set so do nothing here } if (up) { uvHeight += 0.1f; if (Mathf.Approximately(1.0f, uvHeight) || (uvHeight > 1)) { uvHeight = 1.0f; up = false; } } else { uvHeight -= 0.1f; if (Mathf.Approximately(0.0f, uvHeight) || (uvHeight < 0)) { uvHeight = 0.0f; up = true; } } //add the points to the vertex list vertices.Add(leftPoint); //and set the uv coordinates for leftPoint uv.Add(new Vector2(0, uvHeight)); //do the same for rightPoint vertices.Add(rightPoint); uv.Add(new Vector2(1, uvHeight)); //set the previous indices prevLeft = vertices.Count - 2; prevRight = vertices.Count - 1; //move 1 unit towards our "local goal" origin += localDirection.normalized; } } //store these values int startLeftIndex = 0; int startRightIndex = 1; int endLeftIndex = vertices.Count - 2; int endRightIndex = vertices.Count - 1; //and these Vector3 startLeftVertex = vertices [startLeftIndex]; Vector3 startRightVertex = vertices [startRightIndex]; Vector3 endLeftVertex = vertices [endLeftIndex]; Vector3 endRightVertex = vertices [endRightIndex]; //now check the ends of the road mesh //the start of this road is an roadEnd if (startNode.nodeType == NodeTypes.ROADEND) { //make a road end makeRoadEnd(startRightVertex, startLeftVertex, startRightIndex, startLeftIndex, type); } if (endNode.nodeType == NodeTypes.ROADEND) { //make a road end makeRoadEnd(endLeftVertex, endRightVertex, endLeftIndex, endRightIndex, type); } //finalize the mesh by setting the values mesh.vertices = vertices.ToArray(); mesh.triangles = tri.ToArray(); mesh.RecalculateNormals(); mesh.uv = uv.ToArray(); mf.mesh = mesh; }
private RoadTypes GetOneway(RoadTypes rt) { switch (rt) { case RoadTypes.BasicRoad: case RoadTypes.MediumRoad: return RoadTypes.OnewayRoad; case RoadTypes.BasicRoadDecorationTrees: case RoadTypes.MediumRoadDecorationTrees: return RoadTypes.OnewayRoadDecorationTrees; case RoadTypes.MediumRoadDecorationGrass: case RoadTypes.BasicRoadDecorationGrass: return RoadTypes.OnewayRoadDecorationGrass; case RoadTypes.LargeRoad: case RoadTypes.LargeRoadDecorationGrass: case RoadTypes.LargeRoadDecorationTrees: case RoadTypes.Highway: return RoadTypes.Highway; case RoadTypes.GravelRoad: return RoadTypes.OnewayRoad; case RoadTypes.HighwayRamp: return RoadTypes.HighwayRamp; case RoadTypes.LargeOneway: return RoadTypes.LargeOneway; } return RoadTypes.None; }
/** * Makes a road tunnel entrance * @param t the entrance of the tunnel * @param o the owner of the entrance * @param d the direction facing out of the tunnel * @param r the road type used in the tunnel */ public static void MakeRoadTunnel(this TileIndex t, Owner o, DiagDirection d, RoadTypes r) { TileMap.SetTileType(t, TileType.MP_TUNNELBRIDGE); TileMap.SetTileOwner(t, o); Map._m[t].m2 = 0; Map._m[t].m3 = 0; Map._m[t].m4 = 0; Map._m[t].m5 = (byte)((int)TransportType.TRANSPORT_ROAD << 2 | (int)d); Map._me[t].m6 = BitMath.SB(Map._me[t].m6, 2, 4, 0); Map._me[t].m7 = 0; t.SetRoadOwner(RoadType.ROADTYPE_ROAD, o); if (o != Owner.OWNER_TOWN) { t.SetRoadOwner(RoadType.ROADTYPE_TRAM, o); } t.SetRoadTypes(r); }
public bool Mapped(osmWay way, ref List<uint> points, ref RoadTypes rt, ref int layer) { if (way.tag == null || way.nd == null || way.nd.Count() < 2) { return false; } rt = RoadTypes.None; bool oneWay = false; bool invert = false; var surface = ""; foreach (var tag in way.tag) { if (tag.k.Trim().ToLower() == "oneway") { oneWay = true; if (tag.v.Trim() == "-1") { invert = true; } } else if(tag.k.Trim().ToLower() =="bridge"){ layer = Math.Max(layer, 1); } else if (tag.k.Trim().ToLower() == "layer") { int.TryParse(tag.v.Trim(), out layer); } else if (tag.k.Trim().ToLower() == "surface") { surface = tag.v.Trim().ToLower(); } else { var kvp = new KeyValuePair<string, string>(tag.k.Trim(), tag.v.Trim()); if (roadTypeMapping.ContainsKey(kvp)) { rt = roadTypeMapping[kvp]; } } } if (oneWay) { rt = GetOneway(rt); } if (rt != RoadTypes.None) { if (surface != "") { rt = CheckSurface(rt, surface); } points = new List<uint>(); if (invert) { for (var i = way.nd.Count() - 1; i >= 0; i -=1 ) { points.Add(way.nd[i].@ref); } } else { foreach (var nd in way.nd) { points.Add(nd.@ref); } } return true; } return false; }
private RoadTypes CheckSurface(RoadTypes rt, string surface) { if (pavedMapping.ContainsKey(surface)) { if (pavedMapping[surface]){ if (rt == RoadTypes.GravelRoad){ return RoadTypes.BasicRoad; } else if (rt == RoadTypes.PedestrianGravel) { return RoadTypes.PedestrianPavement; } } else { if (rt == RoadTypes.PedestrianPavement || rt == RoadTypes.PedestrianGravel) { return RoadTypes.PedestrianGravel; } else { return RoadTypes.GravelRoad; } } } return rt; }
/** * Set the present road types of a tile. * @param t The tile to change. * @param rt The new road types. */ public static void SetRoadTypes(this TileIndex t, RoadTypes rt) { Debug.Assert(TileMap.IsTileType(t, TileType.MP_ROAD) || TileMap.IsTileType(t, TileType.MP_STATION) || TileMap.IsTileType(t, TileType.MP_TUNNELBRIDGE)); Map._me[t].m7 = BitMath.SB(Map._me[t].m7, 6, 2, rt); }
/** * Make a bridge ramp for roads. * @param t the tile to make a bridge ramp * @param o the new owner of the bridge ramp * @param owner_road the new owner of the road on the bridge * @param owner_tram the new owner of the tram on the bridge * @param bridgetype the type of bridge this bridge ramp belongs to * @param d the direction this ramp must be facing * @param r the road type of the bridge */ public static void MakeRoadBridgeRamp(TileIndex t, Owner o, Owner owner_road, Owner owner_tram, BridgeType bridgetype, DiagDirection d, RoadTypes r) { MakeBridgeRamp(t, o, bridgetype, d, TransportType.TRANSPORT_ROAD, 0); SetRoadOwner(t, RoadType.ROADTYPE_ROAD, owner_road); if (owner_tram != Owner.OWNER_TOWN) { SetRoadOwner(t, RoadType.ROADTYPE_TRAM, owner_tram); } SetRoadTypes(t, r); }
/// <summary> /// Casts a number of random rays within a given range, using the branchVectorFromPoint method. /// </summary> /// <param name="point"></param> /// <param name="oldDirection"></param> /// <param name="minAngle"></param> /// <param name="maxAngle"></param> /// <param name="length"></param> /// <param name="rayCount"></param> /// <returns></returns> public List <Vector2> castVectorsFromPoint(Vector2 point, Vector2 oldDirection, float minAngle, float maxAngle, RoadTypes roadType, int rayCount) { float totalRange = maxAngle - minAngle; // If the total angle range is X, the angle range for every ray is (X/rayCount) float rayRange = totalRange / (float)rayCount; // Create a number of rays List <Vector2> rays = new List <Vector2>(); for (int ray = 0; ray < rayCount; ray++) { float minAngleForRay = minAngle + rayRange * ray; float maxAngleForRay = minAngle + rayRange * (ray + 1); rays.Add(this.branchVectorFromPoint(point, oldDirection, minAngleForRay, maxAngleForRay, roadType)); } return(rays); }
public Way(List <uint> points, RoadTypes rt, int layer) { this.roadTypes = rt; this.nodes = points; this.layer = layer; }
/// <summary> /// gera aleatóriamente um novo trecho de estrada baseado na estrada corrente /// e atualiza a estrada corrente com a nova estrada /// </summary> /// <returns></returns> public StraightRoad NextRoad() { int index = random.Next ( NextList[ current ].NextRoads.Count); current = NextList[current].NextRoads[index]; return RoadList[current].Clone(); }
public Way(List<uint> points, RoadTypes rt,int layer) { this.roadTypes = rt; this.nodes = points; this.layer = layer; }
public StraightRoad NextRoadCheckPoint() { current = NextList[current].NextRoads[0]; if (current != checkPointTargetRoad) { foreach (RoadTypes road in NextList[current].NextRoads) { if (road == checkPointTargetRoad) { current = road; break; } } if (current != checkPointTargetRoad) { foreach (RoadTypes road in NextList[current].NextRoads) { if (RoadList[road].Lanes.Count > RoadList[current].Lanes.Count) { current = road; break; } } } } return RoadList[current].Clone(); }
public bool Mapped(osmWay way, ref List <long> points, ref RoadTypes rt, ref int layer) { if (way.tag == null || way.nd == null || way.nd.Count() < 2) { return(false); } rt = RoadTypes.None; bool oneWay = false; bool invert = false; var surface = ""; foreach (var tag in way.tag) { if (tag.k.Trim().ToLower() == "oneway") { oneWay = true; if (tag.v.Trim() == "-1") { invert = true; } } else if (tag.k.Trim().ToLower() == "bridge") { layer = Math.Max(layer, 1); } else if (tag.k.Trim().ToLower() == "layer") { int.TryParse(tag.v.Trim(), out layer); } else if (tag.k.Trim().ToLower() == "surface") { surface = tag.v.Trim().ToLower(); } else { var kvp = new KeyValuePair <string, string>(tag.k.Trim(), tag.v.Trim()); if (roadTypeMapping.ContainsKey(kvp)) { rt = roadTypeMapping[kvp]; } } } if (oneWay) { rt = GetOneway(rt); } if (rt != RoadTypes.None) { if (surface != "") { rt = CheckSurface(rt, surface); } points = new List <long>(); if (invert) { for (var i = way.nd.Count() - 1; i >= 0; i -= 1) { points.Add(way.nd[i].@ref); } } else { foreach (var nd in way.nd) { points.Add(nd.@ref); } } return(true); } return(false); }
/// <summary> /// metodo auxiliar para incluir as transições das estradas /// </summary> /// <param name="roadtype"></param> /// <param name="nextroads"></param> private void AddInNextList(RoadTypes roadtype, RoadTypes[] nextroads) { NextList.Add(roadtype, new NodeRoad(RoadList[roadtype], new List<RoadTypes>(nextroads), roadtype)); }
private void makeRoadEnd(Vector3 leftPoint, Vector3 rightPoint, int leftPointIndex, int rightPointIndex, RoadTypes roadType) { //find point between leftPoint and rightPoint and add it to the mesh Vector3 middle = Vector3.Lerp(leftPoint, rightPoint, 0.5f); vertices.Add(middle); uv.Add(new Vector2(0.5f, 0)); //store the index int middleIndex = vertices.Count - 1; //direction of the road end Vector2 endDirection = new Vector2(rightPoint.x, rightPoint.z) - new Vector2(leftPoint.x, leftPoint.z); //angle between roadend direction and xAxis float angleXAxis = Vector2.Angle(Vector2.right, endDirection); //if the vector points down we need to subtract the angle if (endDirection.y < 0) { angleXAxis = -angleXAxis; } int numPoints = 9; //number of points on circle List <Vector3> circlePoints = new List <Vector3>(); Vector3 previousPoint = Vector3.zero; Vector3 newPoint = Vector3.zero; float radius = (roadType == RoadTypes.HIGHWAY) ? ((float)CityGenerator.highwayWidth / 2f) : ((float)CityGenerator.streetWidth / 2f); //generate points on a (half) circle for (int i = 0; i <= numPoints; i++) { //store previous point previousPoint = newPoint; //set up angle and find coordinates on circle float angle = ((float)(numPoints - i) * (180f / (float)numPoints)) + angleXAxis; float x = (float)(radius * Mathf.Cos(angle * Mathf.PI / 180F)) + middle.x; float z = (float)(radius * Mathf.Sin(angle * Mathf.PI / 180F)) + middle.z; float y = CoordinateHelper.getAccurateTerrainHeight(x, z); if (CityGenerator.rWater) { y = Mathf.Max(1f, y); } //define new point newPoint = new Vector3(x, y, z); if (previousPoint != Vector3.zero) { circlePoints.Add(previousPoint); vertices.Add(previousPoint); uv.Add(new Vector2(0, 0)); } //add the point to the mesh circlePoints.Add(newPoint); vertices.Add(newPoint); uv.Add(new Vector2(0, 0.1f)); //now make triangles, we need at least two points if (i > 0) { tri.Add(vertices.Count - 2); tri.Add(vertices.Count - 1); tri.Add(middleIndex); } //make colliders such that the terrain can be fixed GameObject collider = new GameObject(); collider.transform.parent = road.transform; collider.transform.position = middle; collider.layer = LayerMask.NameToLayer("Road"); collider.transform.LookAt(newPoint); //set up collider and its size BoxCollider bc = collider.AddComponent <BoxCollider> (); bc.size = new Vector3(4f, 0.1f, radius * 2); } }
/// <summary> /// Inicialização. definição da transição das estradas /// </summary> private void Init() { //Carrega a lista de tipos de estrada foreach (RoadTypes roadtype in Enum.GetValues(typeof(RoadTypes))) { RoadList.Add(roadtype, new StraightRoad(scene, map, roadtype)); } //define o tipo de estrada inicial current = RoadTypes.Road4; //RoadList.FirstOrDefault().Key; //define a pista para checkpoint checkPointTargetRoad = RoadTypes.Road4; #region sequencia das estradas //define a sequencia das estradas //estrada 4 pistas AddInNextList(RoadTypes.Road4, new RoadTypes[] { RoadTypes.Road4, RoadTypes.Road4, RoadTypes.Road4, RoadTypes.Road4, RoadTypes.Road4, RoadTypes.Road4, RoadTypes.Road4, RoadTypes.Road4, RoadTypes.Road4, RoadTypes.Road4to3 }); //estrada 4 p/ 3 pistas AddInNextList(RoadTypes.Road4to3, new RoadTypes[] { RoadTypes.Road3}); //estrada 3 pistas AddInNextList(RoadTypes.Road3, new RoadTypes[] { RoadTypes.Road3, RoadTypes.Road3, RoadTypes.Road3, RoadTypes.Road3, RoadTypes.Road3, RoadTypes.Road3, RoadTypes.Road3to2, RoadTypes.Road3, RoadTypes.Road3to2, RoadTypes.Road3to4, RoadTypes.Road3to4, RoadTypes.Road3to4 }); //estrada 3 p/ 2 pistas AddInNextList(RoadTypes.Road3to2, new RoadTypes[] { RoadTypes.Road2 }); //estrada 2 pistas AddInNextList(RoadTypes.Road2, new RoadTypes[] { RoadTypes.Road2, RoadTypes.Road2, RoadTypes.Road2, RoadTypes.Road2, RoadTypes.Road2, RoadTypes.Road2to3 }); //estrada 2 p/ 3 pistas AddInNextList(RoadTypes.Road2to3, new RoadTypes[] { RoadTypes.Road3}); //estrada 3 p/ 4 pistas AddInNextList(RoadTypes.Road3to4, new RoadTypes[] { RoadTypes.Road4}); //AddInNextList(RoadTypes.Road3to4, new RoadTypes[] { RoadTypes.Road4, RoadTypes.Road4to3 }); #endregion }
public void generateRoadMeshNetwork(List <Edge> r, List <Node> n) { //make sure we dont change the original road and nodes lists List <Edge> roads = new List <Edge>(r); List <Node> nodes = new List <Node>(n); List <List <Node> > highwayRoadPoints = new List <List <Node> > (); List <List <Node> > streetRoadPoints = new List <List <Node> > (); while (roads.Count != 0) { //get the first road from the list and remove it from the list Edge roadStart = roads [0]; RoadTypes roadType = roadStart.getRoadType(); roads.RemoveAt(0); //set up roadPoints list List <Node> roadPoints = new List <Node> (); roadPoints.Add(roadStart.n1); roadPoints.Add(roadStart.n2); //now traverse the graph in both directions to find the successors/predecessors Edge nextSucc = findNext(roadStart, roadStart.n2, roads); while (nextSucc != null) { //find the node of nextSucc which is not in roadPoints yet Node nodeToInsert = findCorrectNode(roadPoints, nextSucc, nodes); /*if(nodeToInsert == null){ * Debug.Log ("nodeToInsert was null for " + nextSucc.ToString()); * Debug.Log ("roadPoints contains: ["); * foreach (Vector2 point in roadPoints) { * Debug.Log (point+", "); * } * Debug.Log ("]"); * }*/ //add the point to the end of roadPoints roadPoints.Add(nodeToInsert); //delete the edge from the roads list roads.Remove(nextSucc); nextSucc = findNext(nextSucc, nodeToInsert, roads); } //find the next predecessor by going back from N1 Edge nextPred = findNext(roadStart, roadStart.n1, roads); //as long as we find new predecessors while (nextPred != null) { //find the node of nextPred which is not in roadPoints yet Node nodeToInsert = findCorrectNode(roadPoints, nextPred, nodes); //add the point to the beginning roadPoints roadPoints.Insert(0, nodeToInsert); //delete the edge from the roads list roads.Remove(nextPred); nextPred = findNext(nextPred, nodeToInsert, roads); } if (roadType == RoadTypes.HIGHWAY) { highwayRoadPoints.Add(roadPoints); } else { streetRoadPoints.Add(roadPoints); } } //now generate the highway meshes foreach (List <Node> points in highwayRoadPoints) { generateRoadMesh(points.ToArray(), RoadTypes.HIGHWAY); } //fix the heightmap based on the highways fixHeightMap(); //now generate the street meshes foreach (List <Node> points in streetRoadPoints) { generateRoadMesh(points.ToArray(), RoadTypes.STREET); } //fix the heightmap based on the streets fixHeightMap(); }
public NodeRoad(StraightRoad road, List<RoadTypes> NextRoads, RoadTypes roadtype) { this.road = road; this.NextRoads = NextRoads; this.roadtype = roadtype; }
private void Init(osm osm, double scale) { mapping.InitBoundingBox(osm.bounds, scale); foreach (var node in osm.node) { if (!nodes.ContainsKey(node.id) && node.lat != 0 && node.lon != 0) { Vector2 pos = Vector2.zero; if (mapping.GetPos(node.lon, node.lat, ref pos)) { nodes.Add(node.id, pos); } } } foreach (var way in osm.way.OrderBy(c => c.changeset)) { RoadTypes rt = RoadTypes.None; List <long> points = null; int layer = 0; if (mapping.Mapped(way, ref points, ref rt, ref layer)) { var currentList = new List <long>(); for (var i = 0; i < points.Count; i += 1) { var pp = points[i]; if (nodes.ContainsKey(pp)) { currentList.Add(pp); } else { if (currentList.Count() > 1 || currentList.Contains(pp)) { ways.AddLast(new Way(currentList, rt, layer)); currentList = new List <long>(); } } } if (currentList.Count() > 1) { ways.AddLast(new Way(currentList, rt, layer)); } } } var intersection = new Dictionary <long, List <Way> >(); foreach (var ww in ways) { foreach (var pp in ww.nodes) { if (!intersection.ContainsKey(pp)) { intersection.Add(pp, new List <Way>()); } intersection[pp].Add(ww); } } var allSplits = new Dictionary <Way, List <int> >(); foreach (var inter in intersection) { if (inter.Value.Count > 1) { foreach (var way in inter.Value) { if (!allSplits.ContainsKey(way)) { allSplits.Add(way, new List <int>()); } allSplits[way].Add(way.nodes.IndexOf(inter.Key)); } } } foreach (var waySplits in allSplits) { SplitWay(waySplits.Key, waySplits.Value); } BreakWaysWhichAreTooLong(); SimplifyWays(); }
/// <summary> /// Gets the ray that results in the highest population and return it together with the population value. /// </summary> /// <param name="rayEndPoints">List of Vector2 points representing the ends of rays.</param> /// <returns></returns> public virtual KeyValuePair <Vector2, float> getBestRay(Vector2 point, List <Vector2> rayEndPoints, RoadTypes roadType) { float maxPopulation = float.NegativeInfinity; Vector2 bestDirection = Vector2.zero; // Loop through all rays and find the one that results in the highest population density. for (int i = 0; i < rayEndPoints.Count; i++) { float rayLength = (roadType == RoadTypes.HIGHWAY) ? CityGenerator.highwayMinLength * CityGenerator.highwayLookAhead : CityGenerator.streetMinLength * CityGenerator.streetLookAhead; int raySamples = (int)Mathf.Sqrt(rayLength); float rayStepSize = (float)rayLength / (float)raySamples; // take samples along the ray. Vector2 rayDirection = getRayDirection(point, rayEndPoints[i]); float rayPopulation = 0f; Vector2 directionPoint = Vector2.zero; bool isDirectionSet = false; for (int sample = 1; sample <= raySamples; sample++) { //save the first point over the ray that is at a suitable distance for a road/highway Vector2 sampleEndPoint = point + rayDirection * sample * rayStepSize; if ((roadType == RoadTypes.HIGHWAY && sample * rayStepSize >= CityGenerator.highwayMinLength || roadType != RoadTypes.HIGHWAY && sample * rayStepSize >= CityGenerator.streetMinLength) && !isDirectionSet) { directionPoint = sampleEndPoint; isDirectionSet = true; } if (!CoordinateHelper.validEndPoint(sampleEndPoint)) { raySamples = sample - 1; break; } float popValue = CoordinateHelper.worldToPop(sampleEndPoint.x, sampleEndPoint.y); /*popValue = (roadType == RoadTypes.HIGHWAY) ? * ((float)sample / (float)raySamples) * popValue : // more weight to further points * (1 - (float)(sample-1) / (float)raySamples) * popValue; // more weight to closer points*/ rayPopulation = (popValue > rayPopulation) ? popValue : rayPopulation; } if (rayPopulation > maxPopulation && isDirectionSet) { maxPopulation = rayPopulation; bestDirection = directionPoint; } } return(new KeyValuePair <Vector2, float>(bestDirection, maxPopulation)); }