protected override void EndOverlayImpl(RenderManager.CameraInfo cameraInfo) { base.EndOverlayImpl(cameraInfo); if (!MainLoad.active) { return; } float x = MainLoad.ps.x, y = MainLoad.ps.z; float sclx = MainLoad.sc.x, scly = MainLoad.sc.z; Quaternion rot = Quaternion.Euler(MainLoad.rt.x, MainLoad.rt.y, MainLoad.rt.z); Vector3 center = new Vector3(x, 0, y); Quad3 position = new Quad3( new Vector3(-sclx + x, 0, -scly + y), //lefttop 1 new Vector3(sclx + x, 0, -scly + y), //righttop 2 new Vector3(sclx + x, 0, scly + y), //rightbottom 3 new Vector3(-sclx + x, 0, scly + y) //leftbottom 4 ); position.a = rot * (position.a - center) + center; position.b = rot * (position.b - center) + center; position.c = rot * (position.c - center) + center; position.d = rot * (position.d - center) + center; RenderManager.instance.OverlayEffect.DrawQuad(cameraInfo, LoadingExtension.tex, Color.white, position, -1f, 1800f, false, true); }
/// <summary> /// Renders a grid /// </summary> /// <param name="cameraInfo">A <see cref="RenderManager.CameraInfo"/> object</param> /// <param name="region">The region to draw the roads</param> /// <param name="rows">The number of rows</param> /// <param name="columns">The number of columns</param> /// <param name="selectionColor">The color of the roads</param> public static void RenderRoadGrid(RenderManager.CameraInfo cameraInfo, Quad3 region, int rows, int columns, Color selectionColor) { // Gets road info var netPrefab = PrefabCollection <NetInfo> .FindLoaded("Basic Road"); // Render rows RenderStraightRoad(cameraInfo, region.a, region.b, netPrefab, selectionColor); for (int row = 0; row <= rows; row++) { // Interpolate positions var startPos = Vector3.Lerp(region.a, region.d, Convert.ToSingle(row) / Convert.ToSingle(rows)); var endPos = Vector3.Lerp(region.b, region.c, Convert.ToSingle(row) / Convert.ToSingle(rows)); // Render road RenderStraightRoad(cameraInfo, startPos, endPos, netPrefab, selectionColor); } RenderStraightRoad(cameraInfo, region.d, region.c, netPrefab, selectionColor); // Render columns RenderStraightRoad(cameraInfo, region.a, region.d, netPrefab, selectionColor); for (int col = 0; col <= columns; col++) { // Interpolate positions var startPos = Vector3.Lerp(region.a, region.b, Convert.ToSingle(col) / Convert.ToSingle(columns)); var endPos = Vector3.Lerp(region.d, region.c, Convert.ToSingle(col) / Convert.ToSingle(columns)); // Render road RenderStraightRoad(cameraInfo, startPos, endPos, netPrefab, selectionColor); } RenderStraightRoad(cameraInfo, region.b, region.c, netPrefab, selectionColor); }
/// <summary> /// Gets the proyection of a quad with the terrain /// </summary> /// <param name="quad"></param> /// <returns></returns> public static Quad3 Quad3ToTerrain(Quad3 quad) { var raycast = new Ray(quad.a, Vector3.up); if (!IndustryTool.instance.GetColisingWithTerrain(raycast, out Vector3 a1)) { raycast = new Ray(quad.a, Vector3.down); IndustryTool.instance.GetColisingWithTerrain(raycast, out a1); } raycast = new Ray(quad.b, Vector3.up); if (!IndustryTool.instance.GetColisingWithTerrain(raycast, out Vector3 b1)) { raycast = new Ray(quad.b, Vector3.down); IndustryTool.instance.GetColisingWithTerrain(raycast, out b1); } raycast = new Ray(quad.c, Vector3.up); if (!IndustryTool.instance.GetColisingWithTerrain(raycast, out Vector3 c1)) { raycast = new Ray(quad.c, Vector3.down); IndustryTool.instance.GetColisingWithTerrain(raycast, out c1); } raycast = new Ray(quad.d, Vector3.up); if (!IndustryTool.instance.GetColisingWithTerrain(raycast, out Vector3 d1)) { raycast = new Ray(quad.d, Vector3.down); IndustryTool.instance.GetColisingWithTerrain(raycast, out d1); } return(new Quad3(a1, b1, c1, d1)); }
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { base.RenderOverlay(cameraInfo); if (!instance.enabled) { return; } for (int i = 0; i < m_bounds.Count; i++) { Vector3 position = m_bounds[i]; Vector3 previousPosition = i == 0 ? m_bounds[m_bounds.Count - 1] : m_bounds[i - 1]; RenderManager.instance.OverlayEffect.DrawCircle( cameraInfo, (Vector3.Magnitude(m_mouseIngamePosition - position) < ObjectArray.selectionRadius) ? kSelectedColor : kHoveredColor, position, ObjectArray.selectionRadius, position.y - 1f, position.y + 1f, true, true ); Quad3 quad = new Quad3(position, position, previousPosition, previousPosition); RenderManager.instance.OverlayEffect.DrawQuad(cameraInfo, kHoveredColor, quad, Math.Min(position.y - 1f, previousPosition.y - 1f), Math.Max(position.y - 1f, previousPosition.y - 1f), true, true); } if (m_centroid != null) { Vector3 centroid = (Vector3)m_centroid; RenderManager.instance.OverlayEffect.DrawCircle( cameraInfo, (Vector3.Magnitude(m_mouseIngamePosition - centroid) < ObjectArray.selectionRadius * 0.7f) ? kSelectedColor : kHoveredColor, centroid, ObjectArray.selectionRadius * 0.7f, centroid.y - 1f, centroid.y + 1f, true, true ); } }
private static void DrawSearchConeQuad2(RenderManager.CameraInfo cameraInfo, float minOverlayY, float maxOverlayY, Quad2 searchConeQuad) { Quad3 searchConeQuad3 = new Quad3 { a = VectorUtils.X_Y(searchConeQuad.a), b = VectorUtils.X_Y(searchConeQuad.b), c = VectorUtils.X_Y(searchConeQuad.c), d = VectorUtils.X_Y(searchConeQuad.d) }; Singleton <RenderManager> .instance.OverlayEffect.DrawQuad(cameraInfo, Color.yellow, searchConeQuad3, minOverlayY, maxOverlayY, renderLimits : false, alphaBlend : true); }
private static void DrawBuildingGridRange(RenderManager.CameraInfo cameraInfo, float minOverlayY, float maxOverlayY, int minX, int minZ, int maxX, int maxZ) { Quad3 gridQuad = new Quad3 { a = new Vector3((float)(minX - 135) * 64f, 0f, (float)(minZ - 135) * 64f), b = new Vector3((float)(minX - 135) * 64f, 0f, (float)(maxZ - 135 + 1) * 64f), c = new Vector3((float)(maxX - 135 + 1) * 64f, 0f, (float)(maxZ - 135 + 1) * 64f), d = new Vector3((float)(maxX - 135 + 1) * 64f, 0f, (float)(minZ - 135) * 64f) }; Singleton <RenderManager> .instance.OverlayEffect.DrawQuad(cameraInfo, Color.yellow, gridQuad, minOverlayY, maxOverlayY, renderLimits : false, alphaBlend : true); }
/// <inheritdoc/> public void DoZoning(Quad3 selection, float angle) { Selection = selection; SelectionAngle = angle; m_optionPanel.EnableTab(1); m_optionPanel.DisableTab(2); if (m_distribution?.Type == DistributionType.GRID) { var distributionThread = new GridDistribution(); m_distribution = distributionThread.Generate(Selection.Value); } }
public static bool CheckZoning(Building b, ItemClass.Zone zone) { int width = b.Width; int length = b.Length; Vector3 vector3_1 = new Vector3(Mathf.Cos(b.m_angle), 0.0f, Mathf.Sin(b.m_angle)); Vector3 vector3_2 = new Vector3(vector3_1.z, 0.0f, -vector3_1.x); Vector3 vector3_3 = vector3_1 * ((float)width * 4f); Vector3 vector3_4 = vector3_2 * ((float)length * 4f); Quad3 quad3 = new Quad3(); quad3.a = b.m_position - vector3_3 - vector3_4; quad3.b = b.m_position + vector3_3 - vector3_4; quad3.c = b.m_position + vector3_3 + vector3_4; quad3.d = b.m_position - vector3_3 + vector3_4; Vector3 vector3_5 = quad3.Min(); Vector3 vector3_6 = quad3.Max(); int num1= Mathf.Max((int)((vector3_5.x - 46f) / 64f + FakeZoneManager.HALFGRID), 0); int num2 = Mathf.Max((int)((vector3_5.z - 46f) / 64f + FakeZoneManager.HALFGRID), 0); int num3 = Mathf.Min((int)((vector3_6.x + 46f) / 64f + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1); int num4 = Mathf.Min((int)((vector3_6.z + 46f) / 64f + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1); uint validCells = 0U; ZoneManager instance = Singleton<ZoneManager>.instance; for (int index1 = num2; index1 <= num4; ++index1) { for (int index2 = num1; index2 <= num3; ++index2) { ushort num5 = FakeZoneManager.zoneGrid[index1 * FakeZoneManager.GRIDSIZE + index2]; int num6 = 0; while ((int)num5 != 0) { Vector3 vector3_7 = instance.m_blocks.m_buffer[(int)num5].m_position; if ((double)Mathf.Max(Mathf.Max(vector3_5.x - 46f - vector3_7.x, vector3_5.z - 46f - vector3_7.z), Mathf.Max((float)((double)vector3_7.x - (double)vector3_6.x - 46.0), (float)((double)vector3_7.z - (double)vector3_6.z - 46.0))) < 0.0) CheckZoning(b,zone, ref validCells, ref instance.m_blocks.m_buffer[num5]); num5 = instance.m_blocks.m_buffer[(int)num5].m_nextGridBlock; if (++num6 >= 32768) { CODebugBase<LogChannel>.Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace); break; } } } } for (int index1 = 0; index1 < length; ++index1) { for (int index2 = 0; index2 < width; ++index2) { if (((int)validCells & 1 << (index1 << 3) + index2) == 0) return false; } } return true; }
public void RenderOverlay(RenderManager.CameraInfo cameraInfo, Color toolColor, ushort buildingId) { if (buildingId == 0) { return; } BuildingBuffer[buildingId].GetTotalPosition(out Vector3 pos, out Quaternion rot, out Vector3 size); var quad = new Quad3( (rot * new Vector3(-size.x, 0, size.z) / 2) + pos, (rot * new Vector3(-size.x, 0, -size.z) / 2) + pos, (rot * new Vector3(size.x, 0, -size.z) / 2) + pos, (rot * new Vector3(size.x, 0, size.z) / 2) + pos ); Singleton <RenderManager> .instance.OverlayEffect.DrawQuad(cameraInfo, toolColor, quad, -1f, 1280f, false, true); }
internal static void AddDebugBox(Bounds b, Color32?c = null) { if (c == null) { c = new Color32(255, 255, 255, 63); } Quad3 q = default; q.a = new Vector3(b.min.x, b.min.y, b.min.z); q.b = new Vector3(b.min.x, b.min.y, b.max.z); q.c = new Vector3(b.max.x, b.min.y, b.max.z); q.d = new Vector3(b.max.x, b.min.y, b.min.z); DebugOverlay d = new DebugOverlay(q, (Color32)c); DebugBoxes.Add(d); //Log.Debug($"\nBounds:{b}"); }
protected override void EndOverlayImpl(RenderManager.CameraInfo cameraInfo) { base.EndOverlayImpl(cameraInfo); if (!m_active) { return; } float l_dimension = m_defaultDimension + m_dimensionDelta; RenderManager renderManager = RenderManager.instance; Quad3 position = new Quad3( new Vector3(-l_dimension + m_translation.x, 0, -l_dimension + m_translation.y), new Vector3(l_dimension + m_translation.x, 0, -l_dimension + m_translation.y), new Vector3(l_dimension + m_translation.x, 0, l_dimension + m_translation.y), new Vector3(-l_dimension + m_translation.x, 0, l_dimension + m_translation.y) ); renderManager.OverlayEffect.DrawQuad(cameraInfo, m_lastTexture, Color.white, position, -1f, 1800f, false, true); }
private void RenderGrid(RenderManager.CameraInfo cameraInfo, Vector3 center, float size, float height) { Vector3 sizeVec = new Vector3(size, height, size); Bounds gridBounds = new Bounds(center, sizeVec); if (cameraInfo.Intersect(gridBounds)) { Vector3 xVec = new Vector3(1f, 0f, 0f); Vector3 zVec = new Vector3(0f, 0f, 1f); // Currently only draws a square - but could easily change shape by changing size in each direction. int xLineCount = (int)Math.Floor(size / GRID_CELL_SIZE); int zLineCount = (int)Math.Floor(size / GRID_CELL_SIZE); for (int i = 0; i < xLineCount; i++) { Quad3 quad = default(Quad3); quad.a = center - xVec * (size / 2) + zVec * (i * GRID_CELL_SIZE - (size / 2)); quad.b = center - xVec * (size / 2) + zVec * (i * GRID_CELL_SIZE - (size / 2)); quad.c = center + xVec * (size / 2) + zVec * (i * GRID_CELL_SIZE - (size / 2)); quad.d = center + xVec * (size / 2) + zVec * (i * GRID_CELL_SIZE - (size / 2)); Color color = (i % 5 == 0 ? Color.red : Color.white); color.a = GRID_COLOR_ALPHA; RenderManager.instance.OverlayEffect.DrawQuad(cameraInfo, color, quad, -1f, 1025f, false, true); } for (int i = 0; i < zLineCount; i++) { Quad3 quad = default(Quad3); quad.a = center - zVec * (size / 2) + xVec * (i * GRID_CELL_SIZE - (size / 2)); quad.b = center - zVec * (size / 2) + xVec * (i * GRID_CELL_SIZE - (size / 2)); quad.c = center + zVec * (size / 2) + xVec * (i * GRID_CELL_SIZE - (size / 2)); quad.d = center + zVec * (size / 2) + xVec * (i * GRID_CELL_SIZE - (size / 2)); Color color = (i % 5 == 0 ? Color.red : Color.white); color.a = GRID_COLOR_ALPHA; RenderManager.instance.OverlayEffect.DrawQuad(cameraInfo, color, quad, -1f, 1025f, false, true); } } }
private static void HoverBuilding(RenderManager.CameraInfo cameraInfo, Color toolColor, ushort buildingId) { BuildingBuffer[buildingId].GetTotalPosition(out Vector3 pos, out Quaternion rot, out Vector3 size); var quad = new Quad3( (rot * new Vector3(-size.x, 0, size.z) / 2) + pos, (rot * new Vector3(-size.x, 0, -size.z) / 2) + pos, (rot * new Vector3(size.x, 0, -size.z) / 2) + pos, (rot * new Vector3(size.x, 0, size.z) / 2) + pos ); Singleton <RenderManager> .instance.OverlayEffect.DrawQuad(cameraInfo, toolColor, quad, -1f, 1280f, false, true); var nets = BuildingBuffer[buildingId].m_netNode; var drawnSegments = new HashSet <ushort>(); var netManagerInstance = NetManager.instance; while (nets > 0) { ref NetNode currNode = ref netManagerInstance.m_nodes.m_buffer[nets]; for (int i = 0; i < 8; i++) { var segmentId = currNode.GetSegment(i); if (segmentId == 0) { break; } if (drawnSegments.Contains(segmentId)) { continue; } ref NetSegment nextSegment = ref netManagerInstance.m_segments.m_buffer[segmentId]; if (netManagerInstance.m_nodes.m_buffer[nextSegment.GetOtherNode(nets)].m_building != buildingId) { continue; } drawnSegments.Add(segmentId); RenderOverlayUtils.RenderNetSegmentOverlay(cameraInfo, toolColor, segmentId); }
/// <summary> /// Generates a building distribution inside a selection /// </summary> /// <param name="selection">A <see cref="Quad3"/> object</param> /// <returns>A <see cref="DistributionInfo"/> object</returns> public abstract DistributionInfo Generate(Quad3 selection);
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { while (!Monitor.TryEnter(this.m_dataLock, SimulationManager.SYNCHRONIZE_TIMEOUT)) { } Vector3 startPosition; Vector3 mousePosition; Vector3 startDirection; Vector3 mouseDirection; bool active; try { active = this.m_active; startPosition = this.m_startPosition; mousePosition = this.m_mousePosition; startDirection = this.m_startDirection; mouseDirection = this.m_mouseDirection; } finally { Monitor.Exit(this.m_dataLock); } var color = Color.red; if (!active) { base.RenderOverlay(cameraInfo); return; } Vector3 a = (!active) ? mousePosition : startPosition; Vector3 vector = mousePosition; Vector3 a2 = (!active) ? mouseDirection : startDirection; Vector3 a3 = new Vector3(a2.z, 0f, -a2.x); float num = Mathf.Round(((vector.x - a.x) * a2.x + (vector.z - a.z) * a2.z) * 0.125f) * 8f; float num2 = Mathf.Round(((vector.x - a.x) * a3.x + (vector.z - a.z) * a3.z) * 0.125f) * 8f; float num3 = (num < 0f) ? -4f : 4f; float num4 = (num2 < 0f) ? -4f : 4f; Quad3 quad = default(Quad3); quad.a = a - a2 * num3 - a3 * num4; quad.b = a - a2 * num3 + a3 * (num2 + num4); quad.c = a + a2 * (num + num3) + a3 * (num2 + num4); quad.d = a + a2 * (num + num3) - a3 * num4; if (num3 != num4) { Vector3 b = quad.b; quad.b = quad.d; quad.d = b; } ToolManager toolManager = ToolManager.instance; toolManager.m_drawCallData.m_overlayCalls++; RenderManager.instance.OverlayEffect.DrawQuad(cameraInfo, color, quad, -1f, 1025f, false, true); base.RenderOverlay(cameraInfo); return; }
private bool PointInRectangle(Quad3 rectangle, Vector3 p) { return(isLeft(rectangle.a, rectangle.b, p) && isLeft(rectangle.b, rectangle.c, p) && isLeft(rectangle.c, rectangle.d, p) && isLeft(rectangle.d, rectangle.a, p)); }
public static bool CheckZoning(ref Building b, ItemClass.Zone zone1, ItemClass.Zone zone2, bool allowCollapsed) { int width = b.Width; int length = b.Length; Vector3 vector3_1 = new Vector3(Mathf.Cos(b.m_angle), 0.0f, Mathf.Sin(b.m_angle)); Vector3 vector3_2 = new Vector3(vector3_1.z, 0.0f, -vector3_1.x); Vector3 vector3_3 = vector3_1 * ((float)width * 4f); Vector3 vector3_4 = vector3_2 * ((float)length * 4f); Quad3 quad3 = new Quad3(); quad3.a = b.m_position - vector3_3 - vector3_4; quad3.b = b.m_position + vector3_3 - vector3_4; quad3.c = b.m_position + vector3_3 + vector3_4; quad3.d = b.m_position - vector3_3 + vector3_4; Vector3 vector3_5 = quad3.Min(); Vector3 vector3_6 = quad3.Max(); //begin mod int num1 = Mathf.Max((int)(((double)vector3_5.x - 46.0) / 64.0 + FakeZoneManager.HALFGRID), 0); int num2 = Mathf.Max((int)(((double)vector3_5.z - 46.0) / 64.0 + FakeZoneManager.HALFGRID), 0); int num3 = Mathf.Min((int)(((double)vector3_6.x + 46.0) / 64.0 + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1); int num4 = Mathf.Min((int)(((double)vector3_6.z + 46.0) / 64.0 + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1); //end mod bool secondary = false; uint validCells = 0; ZoneManager instance = Singleton <ZoneManager> .instance; for (int index1 = num2; index1 <= num4; ++index1) { for (int index2 = num1; index2 <= num3; ++index2) { //begin mod ushort num5 = instance.m_zoneGrid[index1 * FakeZoneManager.GRIDSIZE + index2]; //end mod int num6 = 0; while ((int)num5 != 0) { if (allowCollapsed || ((int)instance.m_blocks.m_buffer[(int)num5].m_flags & 4) == 0) { Vector3 vector3_7 = instance.m_blocks.m_buffer[(int)num5].m_position; if ((double)Mathf.Max(Mathf.Max(vector3_5.x - 46f - vector3_7.x, vector3_5.z - 46f - vector3_7.z), Mathf.Max((float)((double)vector3_7.x - (double)vector3_6.x - 46.0), (float)((double)vector3_7.z - (double)vector3_6.z - 46.0))) < 0.0) { CheckZoning(ref b, zone1, zone2, ref validCells, ref secondary, ref instance.m_blocks.m_buffer[(int)num5]); } } num5 = instance.m_blocks.m_buffer[(int)num5].m_nextGridBlock; if (++num6 >= 49152) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace); break; } } } } for (int index1 = 0; index1 < length; ++index1) { for (int index2 = 0; index2 < width; ++index2) { if (((int)validCells & 1 << (index1 << 3) + index2) == 0) { return(false); } } } if (!secondary ? zone1 == ItemClass.Zone.CommercialHigh || zone1 == ItemClass.Zone.ResidentialHigh : zone2 == ItemClass.Zone.CommercialHigh || zone2 == ItemClass.Zone.ResidentialHigh) { b.m_flags |= Building.Flags.HighDensity; } else { b.m_flags &= ~Building.Flags.HighDensity; } return(true); }
public static void RenderQuad(this Quad3 quad, OverlayData data) => RenderManager.OverlayEffect.DrawQuad(data.CameraInfo, data.Color ?? Colors.White, quad, -1f, 1280f, false, data.AlphaBlend ?? DefaultBlend);
public DebugOverlay(Quad3 q, Color32 c) { quad = q; color = c; }
private static void TestLine(NetInfo netInfo, Vector3 startPoint, Vector3 endPoint, Vector3 l1, Vector3 l2, IList <GuideLine> lines, ushort segmentId = 0, ushort nodeId = 0) { var p = Util.LineIntersectionPoint(startPoint.xz(), endPoint.xz(), l1.xz(), l2.xz()); // Lines never meet, discard if (!p.HasValue) { return; } var intersect = new Vector3(p.Value.x, 0, p.Value.y); var intersectDistanceSqr = Vector3Extensions.DistanceSquared(intersect, endPoint.Flatten()); // Discard if intersect is silly distance away if (intersectDistanceSqr > Settings.MaxGuideLineQueryDistanceSqr) { return; } var guideDirection = l1.Flatten().DirectionTo(l2.Flatten()); var intersectDirection = l1.Flatten().DirectionTo(intersect); // Ignore guides in the wrong direction if (Mathf.Abs(Vector3Extensions.GetSignedAngleBetween(guideDirection, intersectDirection, Vector3.up)) > 90f) { return; } intersect.y = TerrainManager.instance.SampleRawHeightSmooth(intersect); var intersectDistance = Mathf.Sqrt(intersectDistanceSqr); var line = new GuideLine(l1, intersect, netInfo.m_halfWidth * 2f, intersectDistance, segmentId); int index; if (IsDuplicate(lines, line, out index)) { var d = lines[index]; // If a duplicate, check if it is closer than the duplicate if (Vector3Extensions.DistanceSquared(d.Origin, endPoint) > Vector3Extensions.DistanceSquared(l1, endPoint)) { lines[index] = line; } return; } // Check for intersection with existing nodes var ra = Vector3.Cross(guideDirection, Vector3.up); var quad = new Quad3(l1 + ra, l1 - ra, intersect + ra, intersect - ra); if (NetManager.instance.OverlapQuad(Quad2.XZ(quad), 0, 1280f, ItemClass.CollisionType.Undefined, netInfo.m_class.m_layer, nodeId, 0, segmentId)) { return; } lines.Add(line); }
public override DistributionInfo Generate(Quad3 selection) { // Create info value var info = new GridDistributionInfo { Cells = new List <ParcelWrapper>(), Road = new List <Bezier3>(), }; var down = (selection.d - selection.a).normalized; var right = (selection.b - selection.a).normalized; // Create roundabout var midPointAB = Vector3.Lerp(selection.a, selection.b, 0.5f); var centerRoundabout = midPointAB + down * 40f; var roundabout = GenerateRoundabout(centerRoundabout, down, right); info.Road.AddRange(roundabout); // Generate distribution roads var leftPos = selection.a + down * 40f; var leftRoad = GenerateRoad(leftPos, roundabout[0].a); info.Road.AddRange(leftRoad); var rightPos = selection.b + down * 40f; var rightRoad = GenerateRoad(roundabout[2].a, rightPos); info.Road.AddRange(rightRoad); var upPos = Vector3.Lerp(selection.c, selection.d, 0.5f); var upRoad = GenerateRoad(roundabout[3].a, upPos); info.Road.AddRange(upRoad); var left = (selection.a - selection.b).normalized; // Generate secondary roads List <Bezier3> lastLeftRoadBranch = null, lastRightRoadBranch = null; foreach (var position in upRoad) { var roadLength = Vector3.Distance(selection.a, selection.b) / 2; var leftRoadBranch = GenerateRoad(position.d, position.d + left * roadLength); info.Road.AddRange(leftRoadBranch); if (lastLeftRoadBranch != null) { for (int pos = 1; pos < leftRoadBranch.Count; pos++) { var startPos = lastLeftRoadBranch[pos].a; var endPos = leftRoadBranch[pos].a; var startDir = (endPos - startPos).normalized; var endDir = (startPos - endPos).normalized; info.Road.Add(GenerateSegment(startPos, startDir, endPos, endDir)); } } lastLeftRoadBranch = leftRoadBranch; var rightRoadBranch = GenerateRoad(position.d, position.d + right * roadLength); info.Road.AddRange(rightRoadBranch); if (lastRightRoadBranch != null) { for (int pos = 1; pos < rightRoadBranch.Count; pos++) { var startPos = lastRightRoadBranch[pos].a; var endPos = rightRoadBranch[pos].a; var startDir = (endPos - startPos).normalized; var endDir = (startPos - endPos).normalized; info.Road.Add(GenerateSegment(startPos, startDir, endPos, endDir)); } } lastRightRoadBranch = rightRoadBranch; } return(info); }
private static void TestLine(NetInfo netInfo, Vector3 startPoint, Vector3 endPoint, Vector3 l1, Vector3 l2, IList<GuideLine> lines, ushort segmentId = 0, ushort nodeId = 0) { var p = Util.LineIntersectionPoint(startPoint.xz(), endPoint.xz(), l1.xz(), l2.xz()); // Lines never meet, discard if (!p.HasValue) return; var intersect = new Vector3(p.Value.x, 0, p.Value.y); var intersectDistanceSqr = Vector3Extensions.DistanceSquared(intersect, endPoint.Flatten()); // Discard if intersect is silly distance away if (intersectDistanceSqr > Settings.MaxGuideLineQueryDistanceSqr) return; var guideDirection = l1.Flatten().DirectionTo(l2.Flatten()); var intersectDirection = l1.Flatten().DirectionTo(intersect); // Ignore guides in the wrong direction if (Mathf.Abs(Vector3Extensions.GetSignedAngleBetween(guideDirection, intersectDirection, Vector3.up)) > 90f) return; intersect.y = TerrainManager.instance.SampleRawHeightSmooth(intersect); var intersectDistance = Mathf.Sqrt(intersectDistanceSqr); var line = new GuideLine(l1, intersect, netInfo.m_halfWidth*2f, intersectDistance, segmentId); int index; if (IsDuplicate(lines, line, out index)) { var d = lines[index]; // If a duplicate, check if it is closer than the duplicate if (Vector3Extensions.DistanceSquared(d.Origin, endPoint) > Vector3Extensions.DistanceSquared(l1, endPoint)) { lines[index] = line; } return; } // Check for intersection with existing nodes var ra = Vector3.Cross(guideDirection, Vector3.up); var quad = new Quad3(l1 + ra, l1 - ra, intersect + ra, intersect - ra); if (NetManager.instance.OverlapQuad(Quad2.XZ(quad), 0, 1280f, netInfo.m_class.m_layer, nodeId, 0, segmentId)) { return; } lines.Add(line); }