Exemplo n.º 1
0
        public bool NodeInsertion(ushort segment, float time)  // time is in the range (0, 1) inclusive
        {
            Bezier3    bezier = new Bezier3();
            NetSegment s1     = GetSegment(segment);

            bezier.a = NetManager.instance.m_nodes.m_buffer[s1.m_startNode].m_position;
            bezier.d = NetManager.instance.m_nodes.m_buffer[s1.m_endNode].m_position;

            bool smoothStart = (Singleton <NetManager> .instance.m_nodes.m_buffer[s1.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
            bool smoothEnd   = (Singleton <NetManager> .instance.m_nodes.m_buffer[s1.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;

            NetSegment.CalculateMiddlePoints(bezier.a, s1.m_startDirection, bezier.d, s1.m_endDirection, smoothStart, smoothEnd, out Vector3 b, out Vector3 c);

            bezier.b = b;
            bezier.c = c;

            Vector3 timePoint = bezier.Position(time);

            ushort  seg1ls  = s1.m_startNode;
            Vector3 seg1lsd = s1.m_startDirection;
            Vector3 seg1led = -bezier.Tangent(time).normalized;

            ushort  seg1rs  = s1.m_endNode;
            Vector3 seg1rsd = s1.m_endDirection;
            Vector3 seg1red = bezier.Tangent(time).normalized;

            Manager.CreateNode(out ushort timePointNode, ref SimulationManager.instance.m_randomizer, s1.Info, timePoint, SimulationManager.instance.m_currentBuildIndex++);
            Manager.CreateSegment(out ushort seg1, ref SimulationManager.instance.m_randomizer, s1.Info, timePointNode, seg1ls, seg1led, seg1lsd, SimulationManager.instance.m_currentBuildIndex++, SimulationManager.instance.m_currentBuildIndex - 1, false);
            Manager.CreateSegment(out ushort seg2, ref SimulationManager.instance.m_randomizer, s1.Info, seg1rs, timePointNode, seg1rsd, seg1red, SimulationManager.instance.m_currentBuildIndex++, SimulationManager.instance.m_currentBuildIndex - 1, false);

            Manager.UpdateNode(timePointNode);
            Manager.UpdateSegment(seg1);
            Manager.UpdateSegment(seg2);

            Manager.ReleaseSegment(segment, true);
            m_newSeg1 = seg1;
            m_newSeg2 = seg2;
            return(true);
        }
Exemplo n.º 2
0
        private void RenderConnectLineOverlay(RenderManager.CameraInfo cameraInfo)
        {
            if (!IsSelectPoint)
            {
                return;
            }

            var   bezier = new Bezier3();
            Color color;

            if (IsHoverPoint)
            {
                var pointPair = new MarkupPointPair(SelectPoint, HoverPoint);
                color = EditMarkup.ExistConnection(pointPair) ? Color.red : Color.green;

                bezier.a = SelectPoint.Position;
                bezier.b = HoverPoint.Enter == SelectPoint.Enter ? HoverPoint.Position - SelectPoint.Position : SelectPoint.Direction;
                bezier.c = HoverPoint.Enter == SelectPoint.Enter ? SelectPoint.Position - HoverPoint.Position : HoverPoint.Direction;
                bezier.d = HoverPoint.Position;
            }
            else
            {
                color = Color.white;

                RaycastInput input = new RaycastInput(MouseRay, MouseRayLength);
                RayCast(input, out RaycastOutput output);

                bezier.a = SelectPoint.Position;
                bezier.b = SelectPoint.Direction;
                bezier.c = SelectPoint.Direction.Turn90(true);
                bezier.d = output.m_hitPos;

                Line2.Intersect(VectorUtils.XZ(bezier.a), VectorUtils.XZ(bezier.a + bezier.b), VectorUtils.XZ(bezier.d), VectorUtils.XZ(bezier.d + bezier.c), out _, out float v);
                bezier.c = v >= 0 ? bezier.c : -bezier.c;
            }

            NetSegment.CalculateMiddlePoints(bezier.a, bezier.b, bezier.d, bezier.c, true, true, out bezier.b, out bezier.c);
            RenderManager.OverlayEffect.DrawBezier(cameraInfo, color, bezier, 0.5f, 0f, 0f, -1f, 1280f, false, true);
        }
Exemplo n.º 3
0
        private void RenderSegmentParkings(RenderManager.CameraInfo cameraInfo)
        {
            bool  allowed = parkingManager.IsParkingAllowed(renderInfo_.SegmentId, renderInfo_.FinalDirection);
            bool  pressed = Input.GetMouseButton(0);
            Color color;

            if (pressed)
            {
                color = MainTool.GetToolColor(true, false);
            }
            else if (allowed)
            {
                color = Color.green;
            }
            else
            {
                color = Color.red;
            }

            Bezier3 bezier = default;

            netService.IterateSegmentLanes(
                renderInfo_.SegmentId,
                (uint laneId,
                 ref NetLane lane,
                 NetInfo.Lane laneInfo,
                 ushort _,
                 ref NetSegment segment,
                 byte laneIndex) => {
                bool isParking = laneInfo.m_laneType.IsFlagSet(NetInfo.LaneType.Parking);
                if (isParking && laneInfo.m_finalDirection == renderInfo_.FinalDirection)
                {
                    bezier      = lane.m_bezier;
                    laneMarker_ = new SegmentLaneMarker(bezier);
                    laneMarker_.RenderOverlay(cameraInfo, color, enlarge: pressed);
                }
                return(true);
            });
        }
Exemplo n.º 4
0
        public static void ClosestPositionAndDirection(this Bezier3 bezier, Vector3 point, out Vector3 position, out Vector3 direction, out float t)
        {
            var distance = 1E+11f;

            t = 0f;
            var prevPosition = bezier.a;

            for (var i = 1; i <= 16; i += 1)
            {
                var currentPosition = bezier.Position(i / 16f);
                var currentDistance = Segment3.DistanceSqr(prevPosition, currentPosition, point, out var u);
                if (currentDistance < distance)
                {
                    distance = currentDistance;
                    t        = (i - 1f + u) / 16f;
                }
                prevPosition = currentPosition;
            }

            float delta = 0.03125f;

            for (var i = 0; i < 4; i += 1)
            {
                var minPosition     = bezier.Position(Mathf.Max(0f, t - delta));
                var currentPosition = bezier.Position(t);
                var maxPosition     = bezier.Position(Mathf.Min(1f, t + delta));

                var minDistance = Segment3.DistanceSqr(minPosition, currentPosition, point, out var minU);
                var maxDistance = Segment3.DistanceSqr(currentPosition, maxPosition, point, out var maxU);

                t = minDistance >= maxDistance?Mathf.Min(1f, t + delta *maxU) : Mathf.Max(0f, t - delta * (1f - minU));

                delta *= 0.5f;
            }

            position  = bezier.Position(t);
            direction = NormalizeXZ(bezier.Tangent(t));
        }
Exemplo n.º 5
0
        void MakeRoad(Vector3 start, Vector3 end, Vector3 startDirection, Vector3 endDirection, bool flip, uint prefabId)
        {
            DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "making bezier road");
            if (flip)
            {
                Vector3 temp = start;
                start = end;
                end   = temp;

                temp           = -startDirection;
                startDirection = -endDirection;
                endDirection   = temp;
            }
            float   length   = (end - start).magnitude;
            var     curve    = new Bezier3(start, start + startDirection * length / 3, end + endDirection * length / 3, end);
            Vector3 priorPos = curve.Position(0);
            Vector3 priorDir = curve.Tangent(0).normalized;
            float   t        = curve.Travel(0, pitch);

            DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, t.ToString());

            while (t < .9999)
            {
                Vector3 pos = curve.Position(t);
                Vector3 dir = curve.Tangent(t);
                MakeSegment(priorPos, pos, priorDir, -dir, prefabId);
                t = curve.Travel(t, pitch);
                DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, t.ToString());
                priorPos = pos;
                priorDir = dir;
            }
            {
                Vector3 pos = curve.Position(1);
                Vector3 dir = curve.Tangent(1).normalized;
                MakeSegment(priorPos, pos, priorDir, -dir, prefabId);
            }
        }
Exemplo n.º 6
0
        private static Bezier3 GetBezier(Vector3 startPos, Vector3 startDir, Vector3 endPos)
        {
            var startAngle   = startDir.AbsoluteAngle();
            var dir          = endPos - startPos;
            var strangeAngle = dir.AbsoluteAngle();
            var endAngle     = strangeAngle + Mathf.PI + (strangeAngle - startAngle);

            var bezier = new Bezier3()
            {
                a = startPos,
                d = endPos,
            };

            if (Vector3.Dot(startDir, dir) < 0)
            {
                NetSegment.CalculateMiddlePoints(bezier.a, dir, bezier.d, -dir, true, true, out bezier.b, out bezier.c);
            }
            else
            {
                NetSegment.CalculateMiddlePoints(bezier.a, startDir, bezier.d, endAngle.Direction(), true, true, out bezier.b, out bezier.c);
            }

            return(bezier);
        }
 private static bool CheckOverlap(ushort ignoreParked, ref Bezier3 bezier, float offset, float length, out float minPos, out float maxPos)
 {
     throw new NotImplementedException("CheckOverlap is target of redirection and is not implemented.");
 }
Exemplo n.º 8
0
        // FIXME: Lines aren't always drawn
        void RenderUndergroundLane(Bezier3 bezier, Color color, float size)
        {
            Material mat = new Material(Shader.Find("Legacy Shaders/VertexLit"));
            mat.color = color;
            Mesh quadMesh = new Mesh();
            Vector3 start = bezier.Position(0f);
            for (int i = 1; i <= 10; i++)
            {
                Vector3 end = bezier.Position(i / 10f);
                Vector3 normal = Vector3.up; //Vector3.Cross(start, end);
                Vector3 side = Vector3.Cross(normal, end - start);
                side.Normalize();

                Vector3[] vertices = new Vector3[]
                {
                    start + side * (size / 2f) + Vector3.up * 0.1f,
                    start + side * (-size / 2f) + Vector3.up * 0.1f,
                    end + side * (size / 2f) + Vector3.up * 0.1f,
                    end + side * (-size / 2f) + Vector3.up * 0.1f,
                };
                quadMesh.vertices = vertices;

                int[] tri = new int[]
                {
                    0, 1, 3,
                    3, 2, 0
                };
                quadMesh.triangles = tri;

                Vector3[] normals = new Vector3[]
                {
                    normal, normal, normal, normal
                };
                quadMesh.normals = normals;

                if (mat.SetPass(0))
                    Graphics.DrawMeshNow(quadMesh, Matrix4x4.identity);
                start = end;
            }
        }
        private void _renderOverlayDraw(RenderManager.CameraInfo cameraInfo, Bezier3 bezier, Color color)
        {
            const float width = 8f;

            var exprEaCp0 = Singleton<ToolManager>.instance;
            exprEaCp0.m_drawCallData.m_overlayCalls = exprEaCp0.m_drawCallData.m_overlayCalls + 1;
            Singleton<RenderManager>.instance.OverlayEffect.DrawBezier(cameraInfo, color, bezier,
                width * 2f, width, width, -1f, 1280f, false, false);

            // 8 - small roads; 16 - big roads
        }
Exemplo n.º 10
0
        // from TransportLine

        public static bool UpdateMeshData(ref TransportLine transportLine, ushort lineID)
        {
            //return transportLine.UpdateMeshData(lineID);
            bool             flag      = true;
            int              num       = 0;
            int              num2      = 0;
            int              num3      = 0;
            float            num4      = 0f;
            TransportManager instance  = Singleton <TransportManager> .instance;
            NetManager       instance2 = Singleton <NetManager> .instance;
            PathManager      instance3 = Singleton <PathManager> .instance;
            ushort           stops     = transportLine.m_stops;
            ushort           num5      = stops;
            int              num6      = 0;

            while (num5 != 0)
            {
                ushort num7 = 0;
                for (int i = 0; i < 8; i++)
                {
                    ushort segment = instance2.m_nodes.m_buffer[(int)num5].GetSegment(i);
                    if (segment != 0 && instance2.m_segments.m_buffer[(int)segment].m_startNode == num5)
                    {
                        uint path = instance2.m_segments.m_buffer[(int)segment].m_path;
                        if (path != 0u)
                        {
                            byte pathFindFlags = instance3.m_pathUnits.m_buffer[(int)((UIntPtr)path)].m_pathFindFlags;
                            if ((pathFindFlags & 4) != 0)
                            {
                                if (!TransportLine.CalculatePathSegmentCount(path, ref num2, ref num3, ref num4))
                                {
                                    TransportInfo info = transportLine.Info;
                                    BusTransportLineAI.StartPathFind(segment, ref instance2.m_segments.m_buffer[(int)segment], info.m_netService, info.m_vehicleType, (transportLine.m_flags & TransportLine.Flags.Temporary) != TransportLine.Flags.None);
                                    flag = false;
                                }
                            }
                            else if ((pathFindFlags & 8) == 0)
                            {
                                flag = false;
                            }
                        }
                        num7 = instance2.m_segments.m_buffer[(int)segment].m_endNode;
                        break;
                    }
                }
                num++;
                num2++;
                num5 = num7;
                if (num5 == stops)
                {
                    break;
                }
                if (!flag)
                {
                    break;
                }
                if (++num6 >= 32768)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }
            if (!flag)
            {
                return(flag);
            }
            RenderGroup.MeshData meshData = new RenderGroup.MeshData();
            meshData.m_vertices  = new Vector3[num2 * 8];
            meshData.m_normals   = new Vector3[num2 * 8];
            meshData.m_tangents  = new Vector4[num2 * 8];
            meshData.m_uvs       = new Vector2[num2 * 8];
            meshData.m_uvs1      = new Vector2[num2 * 8];
            meshData.m_colors    = new Color32[num2 * 8];
            meshData.m_triangles = new int[num2 * 30];
            TransportManager.LineSegment[] array = new TransportManager.LineSegment[num];
            Bezier3[] array2      = new Bezier3[num3];
            int       num8        = 0;
            int       num9        = 0;
            int       num10       = 0;
            float     lengthScale = Mathf.Ceil(num4 / 64f) / num4;
            float     num11       = 0f;

            num5 = stops;
            Vector3 vector  = new Vector3(100000f, 100000f, 100000f);
            Vector3 vector2 = new Vector3(-100000f, -100000f, -100000f);

            num6 = 0;
            while (num5 != 0)
            {
                ushort num12 = 0;
                for (int j = 0; j < 8; j++)
                {
                    ushort segment2 = instance2.m_nodes.m_buffer[(int)num5].GetSegment(j);
                    if (segment2 != 0 && instance2.m_segments.m_buffer[(int)segment2].m_startNode == num5)
                    {
                        uint path2 = instance2.m_segments.m_buffer[(int)segment2].m_path;
                        if (path2 != 0u && (instance3.m_pathUnits.m_buffer[(int)((UIntPtr)path2)].m_pathFindFlags & 4) != 0)
                        {
                            array[num8].m_curveStart = num10;
                            Vector3 vector3;
                            Vector3 vector4;
                            TransportLine.FillPathSegments(path2, meshData, array2, ref num9, ref num10, ref num11, lengthScale, out vector3, out vector4);
                            vector  = Vector3.Min(vector, vector3);
                            vector2 = Vector3.Max(vector2, vector4);
                            array[num8].m_bounds.SetMinMax(vector3, vector4);
                            array[num8].m_curveEnd = num10;
                        }
                        num12 = instance2.m_segments.m_buffer[(int)segment2].m_endNode;
                        break;
                    }
                }
                TransportLine.FillPathNode(instance2.m_nodes.m_buffer[(int)num5].m_position, meshData, num9);
                num8++;
                num9++;
                num5 = num12;
                if (num5 == stops)
                {
                    break;
                }
                if (++num6 >= 32768)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }
            while (!Monitor.TryEnter(instance.m_lineMeshData, SimulationManager.SYNCHRONIZE_TIMEOUT))
            {
            }
            try
            {
                instance.m_lineMeshData[(int)lineID] = meshData;
                instance.m_lineSegments[(int)lineID] = array;
                instance.m_lineCurves[(int)lineID]   = array2;
                transportLine.m_bounds.SetMinMax(vector, vector2);
            }
            finally
            {
                Monitor.Exit(instance.m_lineMeshData);
            }

            return(flag);
        }
Exemplo n.º 11
0
        public static bool RenderInstancePrefix(Vehicle __instance, RenderManager.CameraInfo cameraInfo, ushort vehicleID, ref bool __result)
        {
            if ((__instance.m_flags & Flags.Spawned) == 0)
            {
                __result = false;
                return(false);
            }
            VehicleInfo info = __instance.Info;

            if (info == null)
            {
                __result = false;
                return(false);
            }
            uint    targetFrame   = __instance.GetTargetFrame(info, vehicleID);
            Vector3 framePosition = __instance.GetFramePosition(targetFrame - 32);
            float   maxDistance   = Mathf.Min(Mathf.Max(info.m_maxRenderDistance, RenderManager.LevelOfDetailFactor * 5000f), info.m_maxRenderDistance * (1f + cameraInfo.m_height * 0.0005f) + cameraInfo.m_height * 0.4f);

            if (!cameraInfo.CheckRenderDistance(framePosition, maxDistance))
            {
                __result = false;
                return(false);
            }
            if (!cameraInfo.Intersect(framePosition, info.m_generatedInfo.m_size.z * 0.5f + 15f))
            {
                __result = false;
                return(false);
            }
            Frame frameData  = __instance.GetFrameData(targetFrame - 32);
            Frame frameData2 = __instance.GetFrameData(targetFrame - 16);
            float num        = ((float)(double)(targetFrame & 0xF) + Singleton <SimulationManager> .instance.m_referenceTimer) * 0.0625f;
            bool  flag       = frameData2.m_underground && frameData.m_underground;
            bool  flag2      = frameData2.m_insideBuilding && frameData.m_insideBuilding;
            bool  flag3      = frameData2.m_transition || frameData.m_transition;

            if (flag2 && !flag3)
            {
                __result = false;
                return(false);
            }
            if (flag && !flag3)
            {
                if ((cameraInfo.m_layerMask & (1 << Singleton <VehicleManager> .instance.m_undergroundLayer)) == 0)
                {
                    __result = false;
                    return(false);
                }
            }
            else if ((cameraInfo.m_layerMask & (1 << info.m_prefabDataLayer)) == 0)
            {
                __result = false;
                return(false);
            }
            Bezier3 bezier = default(Bezier3);

            bezier.a = frameData.m_position;
            bezier.b = frameData.m_position + frameData.m_velocity * 0.333f;
            bezier.c = frameData2.m_position - frameData2.m_velocity * 0.333f;
            bezier.d = frameData2.m_position;
            Vector3 position = bezier.Position(num);
            Bezier3 bezier2  = default(Bezier3);

            bezier2.a = frameData.m_swayPosition;
            bezier2.b = frameData.m_swayPosition + frameData.m_swayVelocity * 0.333f;
            bezier2.c = frameData2.m_swayPosition - frameData2.m_swayVelocity * 0.333f;
            bezier2.d = frameData2.m_swayPosition;
            Vector3 swayPosition = bezier2.Position(num);

            swayPosition.x *= info.m_leanMultiplier / Mathf.Max(1f, info.m_generatedInfo.m_wheelGauge);
            swayPosition.z *= info.m_nodMultiplier / Mathf.Max(1f, info.m_generatedInfo.m_wheelBase);
            Vector4    lightState = (!(num >= 0.5f)) ? frameData.m_lightIntensity : frameData2.m_lightIntensity;
            Quaternion rotation   = Quaternion.Lerp(frameData.m_rotation, frameData2.m_rotation, num);
            Color      color      = info.m_vehicleAI.GetColor(vehicleID, ref __instance, Singleton <InfoManager> .instance.CurrentMode);

            color.a = ((!(num >= 0.5f)) ? frameData.m_blinkState : frameData2.m_blinkState);
            Vector4 tyrePosition = default(Vector4);

            tyrePosition.x = frameData.m_steerAngle + (frameData2.m_steerAngle - frameData.m_steerAngle) * num;
            tyrePosition.y = frameData.m_travelDistance + (frameData2.m_travelDistance - frameData.m_travelDistance) * num;
            tyrePosition.z = 0f;
            tyrePosition.w = 0f;
            Vector3    velocity     = Vector3.Lerp(frameData.m_velocity, frameData2.m_velocity, num) * 3.75f;
            float      acceleration = frameData2.m_velocity.magnitude - frameData.m_velocity.magnitude;
            InstanceID id           = default(InstanceID);

            id.Vehicle = vehicleID;
#if UseTask
            Patcher.Dispatcher.Add(() => Vehicle.RenderInstance(cameraInfo, info, position, rotation, swayPosition, lightState, tyrePosition, velocity, acceleration, color, __instance.m_flags, ~(1 << (int)__instance.m_gateIndex), id, flag || flag3, !flag || flag3));
#else
            Vehicle.RenderInstance(cameraInfo, info, position, rotation, swayPosition, lightState, tyrePosition, velocity, acceleration, color, __instance.m_flags, ~(1 << (int)__instance.m_gateIndex), id, flag || flag3, !flag || flag3);
#endif
            __result = true;
            return(false);
        }
Exemplo n.º 12
0
        public static bool RenderInstancePrefix(CitizenInstance __instance, RenderManager.CameraInfo cameraInfo, ushort instanceID, ref bool __result)
        {
            if ((__instance.m_flags & Flags.Character) == 0)
            {
                __result = false;
                return(false);
            }
            CitizenInfo info = __instance.Info;

            if (info == null)
            {
                __result = false;
                return(false);
            }
            uint  num         = (uint)(instanceID << 4) / 65536u;
            uint  num2        = Singleton <SimulationManager> .instance.m_referenceFrameIndex - num;
            Frame frameData   = __instance.GetFrameData(num2 - 32);
            float maxDistance = Mathf.Min(RenderManager.LevelOfDetailFactor * 800f, info.m_maxRenderDistance + cameraInfo.m_height * 0.5f);

            if (!cameraInfo.CheckRenderDistance(frameData.m_position, maxDistance))
            {
                __result = false;
                return(false);
            }
            if (!cameraInfo.Intersect(frameData.m_position, 10f))
            {
                __result = false;
                return(false);
            }
            Frame frameData2 = __instance.GetFrameData(num2 - 16);
            float t          = ((float)(double)(num2 & 0xF) + Singleton <SimulationManager> .instance.m_referenceTimer) * 0.0625f;
            bool  flag       = frameData2.m_underground && frameData.m_underground;
            bool  flag2      = frameData2.m_insideBuilding && frameData.m_insideBuilding;
            bool  flag3      = frameData2.m_transition || frameData.m_transition;

            if ((flag2 && !flag3) || (flag && !flag3 && (cameraInfo.m_layerMask & (1 << Singleton <CitizenManager> .instance.m_undergroundLayer)) == 0))
            {
                __result = false;
                return(false);
            }
            Bezier3 bezier = default(Bezier3);

            bezier.a = frameData.m_position;
            bezier.b = frameData.m_position + frameData.m_velocity * 0.333f;
            bezier.c = frameData2.m_position - frameData2.m_velocity * 0.333f;
            bezier.d = frameData2.m_position;
            Vector3    vector     = bezier.Position(t);
            Quaternion quaternion = Quaternion.Lerp(frameData.m_rotation, frameData2.m_rotation, t);
            Color      color      = info.m_citizenAI.GetColor(instanceID, ref __instance, Singleton <InfoManager> .instance.CurrentMode);

            var action = new Action(() =>
            {
                if (cameraInfo.CheckRenderDistance(vector, info.m_lodRenderDistance))
                {
                    InstanceID empty        = InstanceID.Empty;
                    empty.CitizenInstance   = instanceID;
                    CitizenInfo citizenInfo = info.ObtainPrefabInstance <CitizenInfo>(empty, 255);
                    if (citizenInfo != null)
                    {
                        Vector3 velocity = Vector3.Lerp(frameData.m_velocity, frameData2.m_velocity, t);
                        citizenInfo.m_citizenAI.SetRenderParameters(cameraInfo, instanceID, ref __instance, vector, quaternion, velocity, color, (flag || flag3) && (cameraInfo.m_layerMask & (1 << Singleton <CitizenManager> .instance.m_undergroundLayer)) != 0);
                        return;
                    }
                }
                if (flag || flag3)
                {
                    info.m_undergroundLodLocations[info.m_undergroundLodCount].SetTRS(vector, quaternion, Vector3.one);
                    info.m_undergroundLodColors[info.m_undergroundLodCount] = color.linear;
                    info.m_undergroundLodMin = Vector3.Min(info.m_undergroundLodMin, vector);
                    info.m_undergroundLodMax = Vector3.Max(info.m_undergroundLodMax, vector);
                    if (++info.m_undergroundLodCount == info.m_undergroundLodLocations.Length)
                    {
                        RenderUndergroundLod(cameraInfo, info);
                    }
                }
                if (!flag || flag3)
                {
                    info.m_lodLocations[info.m_lodCount].SetTRS(vector, quaternion, Vector3.one);
                    info.m_lodColors[info.m_lodCount] = color.linear;
                    info.m_lodMin = Vector3.Min(info.m_lodMin, vector);
                    info.m_lodMax = Vector3.Max(info.m_lodMax, vector);
                    if (++info.m_lodCount == info.m_lodLocations.Length)
                    {
                        RenderLod(cameraInfo, info);
                    }
                }
            });

#if UseTask
            Patcher.Dispatcher.Add(action);
#else
            action.Invoke();
#endif
            __result = true;
            return(false);
        }
Exemplo n.º 13
0
 public BezierBounds(Bezier3 bezier, float size)
 {
     Bezier = bezier;
     Size   = size;
     CalculateBounds();
 }
Exemplo n.º 14
0
        public static void CalculateCorner(NetInfo info, Vector3 startPos, Vector3 endPos, Vector3 startDir, Vector3 endDir, NetInfo extraInfo1, Vector3 extraEndPos1, Vector3 extraStartDir1, Vector3 extraEndDir1, NetInfo extraInfo2, Vector3 extraEndPos2, Vector3 extraStartDir2, Vector3 extraEndDir2, ushort ignoreSegmentID, ushort startNodeID, bool heightOffset, bool leftSide, out Vector3 cornerPos, out Vector3 cornerDirection, out bool smooth)
        {
            //add null check
            //begin mod
            if (info == null)
            {
                cornerPos       = new Vector3();
                cornerDirection = new Vector3();
                smooth          = false;
                return;
            }
            //end mod
            NetManager instance = Singleton <NetManager> .instance;
            Bezier3    bezier1  = new Bezier3();
            Bezier3    bezier2  = new Bezier3();

            NetNode.Flags flags = NetNode.Flags.End;
            ushort        num1  = 0;

            if ((int)startNodeID != 0)
            {
                flags = instance.m_nodes.m_buffer[(int)startNodeID].m_flags;
                num1  = instance.m_nodes.m_buffer[(int)startNodeID].m_building;
            }
            cornerDirection = startDir;
            float num2 = !leftSide ? -info.m_halfWidth : info.m_halfWidth;

            smooth = (flags & NetNode.Flags.Middle) != NetNode.Flags.None;
            if (extraInfo1 != null)
            {
                flags = (flags & NetNode.Flags.End) == NetNode.Flags.None || !info.IsCombatible(extraInfo1) || extraInfo2 != null ? flags & ~(NetNode.Flags.Middle | NetNode.Flags.Bend) | NetNode.Flags.Junction : ((double)startDir.x * (double)extraStartDir1.x + (double)startDir.z * (double)extraStartDir1.z >= -0.999000012874603 ? flags & ~NetNode.Flags.End | NetNode.Flags.Bend : flags & ~NetNode.Flags.End | NetNode.Flags.Middle);
            }
            if ((flags & NetNode.Flags.Middle) != NetNode.Flags.None)
            {
                int num3 = extraInfo1 == null ? 0 : -1;
                int num4 = (int)startNodeID == 0 ? 0 : 8;
                for (int index = num3; index < num4; ++index)
                {
                    Vector3 vector3;
                    if (index == -1)
                    {
                        vector3 = extraStartDir1;
                    }
                    else
                    {
                        ushort segment = instance.m_nodes.m_buffer[(int)startNodeID].GetSegment(index);
                        if ((int)segment != 0 && (int)segment != (int)ignoreSegmentID)
                        {
                            ushort num5 = instance.m_segments.m_buffer[(int)segment].m_startNode;
                            vector3 = (int)startNodeID == (int)num5 ? instance.m_segments.m_buffer[(int)segment].m_startDirection : instance.m_segments.m_buffer[(int)segment].m_endDirection;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    cornerDirection = VectorUtils.NormalizeXZ(cornerDirection - vector3);
                    break;
                }
            }
            Vector3 lhs = Vector3.Cross(cornerDirection, Vector3.up).normalized;

            if (info.m_twistSegmentEnds && (int)num1 != 0)
            {
                float   f   = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)num1].m_angle;
                Vector3 rhs = new Vector3(Mathf.Cos(f), 0.0f, Mathf.Sin(f));
                lhs = (double)Vector3.Dot(lhs, rhs) < 0.0 ? -rhs : rhs;
            }
            bezier1.a = startPos + lhs * num2;
            bezier2.a = startPos - lhs * num2;
            cornerPos = bezier1.a;
            if ((flags & NetNode.Flags.Junction) != NetNode.Flags.None && info.m_clipSegmentEnds || (flags & (NetNode.Flags.Bend | NetNode.Flags.Outside)) != NetNode.Flags.None)
            {
                Vector3 vector3_1   = endDir;
                Vector3 normalized1 = Vector3.Cross(vector3_1, Vector3.up).normalized;
                bezier1.d = endPos - normalized1 * num2;
                bezier2.d = endPos + normalized1 * num2;
                NetSegment.CalculateMiddlePoints(bezier1.a, cornerDirection, bezier1.d, vector3_1, false, false, out bezier1.b, out bezier1.c);
                NetSegment.CalculateMiddlePoints(bezier2.a, cornerDirection, bezier2.d, vector3_1, false, false, out bezier2.b, out bezier2.c);
                Bezier2 bezier2_1 = Bezier2.XZ(bezier1);
                Bezier2 bezier2_2 = Bezier2.XZ(bezier2);
                float   a1        = -1f;
                float   num3      = -1f;
                bool    flag      = false;
                int     num4      = extraInfo1 == null ? 0 : (extraInfo2 == null ? -1 : -2);
                int     num5      = (int)startNodeID == 0 ? 0 : 8;
                float   a2        = info.m_halfWidth * 0.5f;
                for (int index = num4; index < num5; ++index)
                {
                    NetInfo netInfo;
                    if (index == -2)
                    {
                        netInfo = extraInfo2;
                        Vector3 vector3_2 = extraEndPos2;
                        Vector3 vector3_3 = extraEndDir2;
                        if (vector3_2 == endPos && vector3_3 == endDir)
                        {
                            continue;
                        }
                    }
                    else if (index == -1)
                    {
                        netInfo = extraInfo1;
                        Vector3 vector3_2 = extraEndPos1;
                        Vector3 vector3_3 = extraEndDir1;
                        if (vector3_2 == endPos && vector3_3 == endDir)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        ushort segment = instance.m_nodes.m_buffer[(int)startNodeID].GetSegment(index);
                        if ((int)segment != 0 && (int)segment != (int)ignoreSegmentID)
                        {
                            netInfo = instance.m_segments.m_buffer[(int)segment].Info;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    if (netInfo != null)
                    {
                        a2 = Mathf.Max(a2, netInfo.m_halfWidth * 0.5f);
                    }
                }
                for (int index = num4; index < num5; ++index)
                {
                    NetInfo netInfo;
                    Vector3 vector3_2;
                    Vector3 vector3_3;
                    Vector3 vector3_4;
                    if (index == -2)
                    {
                        netInfo   = extraInfo2;
                        vector3_2 = extraEndPos2;
                        vector3_3 = extraStartDir2;
                        vector3_4 = extraEndDir2;
                        if (vector3_2 == endPos && vector3_4 == endDir)
                        {
                            continue;
                        }
                    }
                    else if (index == -1)
                    {
                        netInfo   = extraInfo1;
                        vector3_2 = extraEndPos1;
                        vector3_3 = extraStartDir1;
                        vector3_4 = extraEndDir1;
                        if (vector3_2 == endPos && vector3_4 == endDir)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        ushort segment = instance.m_nodes.m_buffer[(int)startNodeID].GetSegment(index);
                        if ((int)segment != 0 && (int)segment != (int)ignoreSegmentID)
                        {
                            ushort num6 = instance.m_segments.m_buffer[(int)segment].m_startNode;
                            ushort num7 = instance.m_segments.m_buffer[(int)segment].m_endNode;
                            vector3_3 = instance.m_segments.m_buffer[(int)segment].m_startDirection;
                            vector3_4 = instance.m_segments.m_buffer[(int)segment].m_endDirection;
                            if ((int)startNodeID != (int)num6)
                            {
                                num7 = num6;
                                Vector3 vector3_5 = vector3_3;
                                vector3_3 = vector3_4;
                                vector3_4 = vector3_5;
                            }
                            netInfo   = instance.m_segments.m_buffer[(int)segment].Info;
                            vector3_2 = instance.m_nodes.m_buffer[(int)num7].m_position;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    if (netInfo != null)
                    {
                        if ((double)vector3_3.z * (double)cornerDirection.x - (double)vector3_3.x * (double)cornerDirection.z > 0.0 == leftSide)
                        {
                            Bezier3 bezier3 = new Bezier3();
                            float   num6    = Mathf.Max(a2, netInfo.m_halfWidth);
                            if (!leftSide)
                            {
                                num6 = -num6;
                            }
                            Vector3 normalized2 = Vector3.Cross(vector3_3, Vector3.up).normalized;
                            bezier3.a = startPos - normalized2 * num6;
                            Vector3 normalized3 = Vector3.Cross(vector3_4, Vector3.up).normalized;
                            bezier3.d = vector3_2 + normalized3 * num6;
                            NetSegment.CalculateMiddlePoints(bezier3.a, vector3_3, bezier3.d, vector3_4, false, false, out bezier3.b, out bezier3.c);
                            Bezier2 b2 = Bezier2.XZ(bezier3);
                            float   t1;
                            float   t2;
                            if (bezier2_1.Intersect(b2, out t1, out t2, 6))
                            {
                                a1 = Mathf.Max(a1, t1);
                            }
                            else if (bezier2_1.Intersect(b2.a, b2.a - VectorUtils.XZ(vector3_3) * 16f, out t1, out t2, 6))
                            {
                                a1 = Mathf.Max(a1, t1);
                            }
                            else if (b2.Intersect(bezier2_1.d + (bezier2_1.d - bezier2_2.d) * 0.01f, bezier2_2.d, out t1, out t2, 6))
                            {
                                a1 = Mathf.Max(a1, 1f);
                            }
                            if ((double)cornerDirection.x * (double)vector3_3.x + (double)cornerDirection.z * (double)vector3_3.z >= -0.75)
                            {
                                flag = true;
                            }
                        }
                        else
                        {
                            Bezier3 bezier3 = new Bezier3();
                            float   num6    = (float)((double)cornerDirection.x * (double)vector3_3.x + (double)cornerDirection.z * (double)vector3_3.z);
                            if ((double)num6 >= 0.0)
                            {
                                vector3_3.x -= (float)((double)cornerDirection.x * (double)num6 * 2.0);
                                vector3_3.z -= (float)((double)cornerDirection.z * (double)num6 * 2.0);
                            }
                            float num7 = Mathf.Max(a2, netInfo.m_halfWidth);
                            if (!leftSide)
                            {
                                num7 = -num7;
                            }
                            Vector3 normalized2 = Vector3.Cross(vector3_3, Vector3.up).normalized;
                            bezier3.a = startPos + normalized2 * num7;
                            Vector3 normalized3 = Vector3.Cross(vector3_4, Vector3.up).normalized;
                            bezier3.d = vector3_2 - normalized3 * num7;
                            NetSegment.CalculateMiddlePoints(bezier3.a, vector3_3, bezier3.d, vector3_4, false, false, out bezier3.b, out bezier3.c);
                            Bezier2 b2 = Bezier2.XZ(bezier3);
                            float   t1;
                            float   t2;
                            if (bezier2_2.Intersect(b2, out t1, out t2, 6))
                            {
                                num3 = Mathf.Max(num3, t1);
                            }
                            else if (bezier2_2.Intersect(b2.a, b2.a - VectorUtils.XZ(vector3_3) * 16f, out t1, out t2, 6))
                            {
                                num3 = Mathf.Max(num3, t1);
                            }
                            else if (b2.Intersect(bezier2_1.d, bezier2_2.d + (bezier2_2.d - bezier2_1.d) * 0.01f, out t1, out t2, 6))
                            {
                                num3 = Mathf.Max(num3, 1f);
                            }
                        }
                    }
                }
                if ((flags & NetNode.Flags.Junction) != NetNode.Flags.None)
                {
                    if (!flag)
                    {
                        a1 = Mathf.Max(a1, num3);
                    }
                }
                else if ((flags & NetNode.Flags.Bend) != NetNode.Flags.None && !flag)
                {
                    a1 = Mathf.Max(a1, num3);
                }
                float num8;
                if ((flags & NetNode.Flags.Outside) != NetNode.Flags.None)
                {
                    float   num6      = 8640f;
                    Vector2 vector2_1 = new Vector2(-num6, -num6);
                    Vector2 vector2_2 = new Vector2(-num6, num6);
                    Vector2 vector2_3 = new Vector2(num6, num6);
                    Vector2 vector2_4 = new Vector2(num6, -num6);
                    float   t1;
                    float   t2;
                    if (bezier2_1.Intersect(vector2_1, vector2_2, out t1, out t2, 6))
                    {
                        a1 = Mathf.Max(a1, t1);
                    }
                    if (bezier2_1.Intersect(vector2_2, vector2_3, out t1, out t2, 6))
                    {
                        a1 = Mathf.Max(a1, t1);
                    }
                    if (bezier2_1.Intersect(vector2_3, vector2_4, out t1, out t2, 6))
                    {
                        a1 = Mathf.Max(a1, t1);
                    }
                    if (bezier2_1.Intersect(vector2_4, vector2_1, out t1, out t2, 6))
                    {
                        a1 = Mathf.Max(a1, t1);
                    }
                    num8 = Mathf.Clamp01(a1);
                }
                else
                {
                    if ((double)a1 < 0.0)
                    {
                        a1 = (double)info.m_halfWidth >= 4.0 ? bezier2_1.Travel(0.0f, 8f) : 0.0f;
                    }
                    float num6 = Mathf.Clamp01(a1);
                    float num7 = VectorUtils.LengthXZ(bezier1.Position(num6) - bezier1.a);
                    num8 = bezier2_1.Travel(num6, Mathf.Max(info.m_minCornerOffset - num7, 2f));
                    if (info.m_straightSegmentEnds)
                    {
                        if ((double)num3 < 0.0)
                        {
                            num3 = (double)info.m_halfWidth >= 4.0 ? bezier2_2.Travel(0.0f, 8f) : 0.0f;
                        }
                        float num9  = Mathf.Clamp01(num3);
                        float num10 = VectorUtils.LengthXZ(bezier2.Position(num9) - bezier2.a);
                        float b     = bezier2_2.Travel(num9, Mathf.Max(info.m_minCornerOffset - num10, 2f));
                        num8 = Mathf.Max(num8, b);
                    }
                }
                float num11 = cornerDirection.y;
                cornerDirection   = bezier1.Tangent(num8);
                cornerDirection.y = 0.0f;
                cornerDirection.Normalize();
                if (!info.m_flatJunctions)
                {
                    cornerDirection.y = num11;
                }
                cornerPos   = bezier1.Position(num8);
                cornerPos.y = startPos.y;
            }
            if (!heightOffset || (int)startNodeID == 0)
            {
                return;
            }
            cornerPos.y += (float)instance.m_nodes.m_buffer[(int)startNodeID].m_heightOffset * (1f / 64f);
        }
Exemplo n.º 15
0
 public static void Render(this Bezier3 bezier, RenderManager.CameraInfo cameraInfo, Color color, float hw, bool alphaBlend = false)
 {
     bezier.Render(cameraInfo, color, hw, hw, hw, alphaBlend);
 }
Exemplo n.º 16
0
        private OSMWay CreateWay(int index, NetSegment segment)
        {
            OSMWay returnWay = null;
            NetSegment.Flags segmentFlags = segment.m_flags;
            NetManager netManager = Singleton<NetManager>.instance;
            List<OSMWayND> wayPaths = new List<OSMWayND>();
            List<OSMWayTag> wayTags;
            ushort startNodeId = segment.m_startNode, endNodeId = segment.m_endNode;

            if(startNodeId != 0 && endNodeId != 0)
            {
                Vector3 startNodeDirection = segment.m_startDirection;
                Vector3 endNodeDirection = segment.m_endDirection;

                if(segmentFlags.IsFlagSet(NetSegment.Flags.Invert))
                {
                    startNodeId = segment.m_endNode;
                    endNodeId = segment.m_startNode;
                    startNodeDirection = segment.m_endDirection;
                    endNodeDirection = segment.m_startDirection;
                }

                NetNode startNode = netManager.m_nodes.m_buffer[startNodeId];
                NetNode endNode = netManager.m_nodes.m_buffer[endNodeId];
                Vector3 startNodePosition = startNode.m_position;
                Vector3 endNodePosition = endNode.m_position;

                wayPaths.Add(new OSMWayND { @ref = startNodeId });

                if (Vector3.Angle(startNodeDirection, -endNodeDirection) > 3f)
                {
                    Vector3 midPointA = Vector3.zero, midPointB = Vector3.zero;
                    NetSegment.CalculateMiddlePoints(startNodePosition, startNodeDirection, endNodePosition, endNodeDirection, false, false, out midPointA, out midPointB);
                    Bezier3 bezier = new Bezier3(startNodePosition, midPointA, midPointB, endNodePosition);

                    osmNodes.Add(CreateNode(unindexedNodeOffset++, bezier.Position(0.25f)));
                    osmNodes.Add(CreateNode(unindexedNodeOffset++, bezier.Position(0.5f)));
                    osmNodes.Add(CreateNode(unindexedNodeOffset++, bezier.Position(0.75f)));

                    wayPaths.Add(new OSMWayND { @ref = (uint)unindexedNodeOffset - 3 });
                    wayPaths.Add(new OSMWayND { @ref = (uint)unindexedNodeOffset - 2 });
                    wayPaths.Add(new OSMWayND { @ref = (uint)unindexedNodeOffset - 1 });
                }

                wayPaths.Add(new OSMWayND { @ref = endNodeId });

                if(Tagger.CreateWayTags(segment, out wayTags))
                {
                    returnWay = new OSMWay { changeset = 50000000, id = (uint)index, timestamp = DateTime.Now, user = "******", nd = wayPaths.ToArray(), tag = wayTags.ToArray(), version = 1 };
                }
                else
                {
                    UniqueLogger.AddLog("Road names missing from search", segment.Info.name, "");
                }
            }

            return returnWay;
        }
Exemplo n.º 17
0
        // from TransportLine
        public static bool UpdateMeshData(ref TransportLine transportLine, ushort lineID)
        {
            bool flag = true;
            int num = 0;
            int num2 = 0;
            int num3 = 0;
            float num4 = 0f;
            TransportManager instance = Singleton<TransportManager>.instance;
            NetManager instance2 = Singleton<NetManager>.instance;
            PathManager instance3 = Singleton<PathManager>.instance;
            ushort stops = transportLine.m_stops;
            ushort num5 = stops;
            int num6 = 0;
            while (num5 != 0)
            {
                ushort num7 = 0;
                for (int i = 0; i < 8; i++)
                {
                    ushort segment = instance2.m_nodes.m_buffer[(int)num5].GetSegment(i);
                    if (segment != 0 && instance2.m_segments.m_buffer[(int)segment].m_startNode == num5)
                    {
                        uint path = instance2.m_segments.m_buffer[(int)segment].m_path;
                        if (path != 0u)
                        {
                            byte pathFindFlags = instance3.m_pathUnits.m_buffer[(int)((UIntPtr)path)].m_pathFindFlags;
                            if ((pathFindFlags & 4) != 0)
                            {
                                if (!TransportLine.CalculatePathSegmentCount(path, ref num2, ref num3, ref num4))
                                {
                                    TransportInfo info = transportLine.Info;
                                    BusTransportLineAI.StartPathFind(segment, ref instance2.m_segments.m_buffer[(int)segment], info.m_netService, info.m_vehicleType, (transportLine.m_flags & TransportLine.Flags.Temporary) != TransportLine.Flags.None);
                                    flag = false;
                                }
                            }
                            else if ((pathFindFlags & 8) == 0)
                            {
                                flag = false;
                            }
                        }
                        num7 = instance2.m_segments.m_buffer[(int)segment].m_endNode;
                        break;
                    }
                }
                num++;
                num2++;
                num5 = num7;
                if (num5 == stops)
                {
                    break;
                }
                if (!flag)
                {
                    break;
                }
                if (++num6 >= 32768)
                {
                    CODebugBase<LogChannel>.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                    break;
                }
            }
            if (!flag)
            {
                return flag;
            }
            RenderGroup.MeshData meshData = new RenderGroup.MeshData();
            meshData.m_vertices = new Vector3[num2 * 8];
            meshData.m_normals = new Vector3[num2 * 8];
            meshData.m_tangents = new Vector4[num2 * 8];
            meshData.m_uvs = new Vector2[num2 * 8];
            meshData.m_uvs1 = new Vector2[num2 * 8];
            meshData.m_colors = new Color32[num2 * 8];
            meshData.m_triangles = new int[num2 * 30];
            TransportManager.LineSegment[] array = new TransportManager.LineSegment[num];
            Bezier3[] array2 = new Bezier3[num3];
            int num8 = 0;
            int num9 = 0;
            int num10 = 0;
            float lengthScale = Mathf.Ceil(num4 / 64f) / num4;
            float num11 = 0f;
            num5 = stops;
            Vector3 vector = new Vector3(100000f, 100000f, 100000f);
            Vector3 vector2 = new Vector3(-100000f, -100000f, -100000f);
            num6 = 0;
            while (num5 != 0)
            {
                ushort num12 = 0;
                for (int j = 0; j < 8; j++)
                {
                    ushort segment2 = instance2.m_nodes.m_buffer[(int)num5].GetSegment(j);
                    if (segment2 != 0 && instance2.m_segments.m_buffer[(int)segment2].m_startNode == num5)
                    {
                        uint path2 = instance2.m_segments.m_buffer[(int)segment2].m_path;
                        if (path2 != 0u && (instance3.m_pathUnits.m_buffer[(int)((UIntPtr)path2)].m_pathFindFlags & 4) != 0)
                        {
                            array[num8].m_curveStart = num10;
                            Vector3 vector3;
                            Vector3 vector4;
                            TransportLine.FillPathSegments(path2, meshData, array2, ref num9, ref num10, ref num11, lengthScale, out vector3, out vector4);
                            vector = Vector3.Min(vector, vector3);
                            vector2 = Vector3.Max(vector2, vector4);
                            array[num8].m_bounds.SetMinMax(vector3, vector4);
                            array[num8].m_curveEnd = num10;
                        }
                        num12 = instance2.m_segments.m_buffer[(int)segment2].m_endNode;
                        break;
                    }
                }
                TransportLine.FillPathNode(instance2.m_nodes.m_buffer[(int)num5].m_position, meshData, num9);
                num8++;
                num9++;
                num5 = num12;
                if (num5 == stops)
                {
                    break;
                }
                if (++num6 >= 32768)
                {
                    CODebugBase<LogChannel>.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                    break;
                }
            }
            while (!Monitor.TryEnter(instance.m_lineMeshData, SimulationManager.SYNCHRONIZE_TIMEOUT))
            {
            }
            try
            {
                instance.m_lineMeshData[(int)lineID] = meshData;
                instance.m_lineSegments[(int)lineID] = array;
                instance.m_lineCurves[(int)lineID] = array2;
                transportLine.m_bounds.SetMinMax(vector, vector2);
            }
            finally
            {
                Monitor.Exit(instance.m_lineMeshData);
            }

            return flag;
        }
Exemplo n.º 18
0
        // Essential Tool Functions
        protected override void OnToolUpdate()
        {
            base.OnToolUpdate();

            Ray          ray   = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastInput input = new RaycastInput(ray, Camera.main.farClipPlane);

            input.m_ignoreSegmentFlags       = NetSegment.Flags.None;
            input.m_ignoreNodeFlags          = NetNode.Flags.All;
            input.m_ignoreParkFlags          = DistrictPark.Flags.All;
            input.m_ignorePropFlags          = PropInstance.Flags.All;
            input.m_ignoreTreeFlags          = TreeInstance.Flags.All;
            input.m_ignoreCitizenFlags       = CitizenInstance.Flags.All;
            input.m_ignoreVehicleFlags       = Vehicle.Flags.Created;
            input.m_ignoreBuildingFlags      = Building.Flags.All;
            input.m_ignoreDisasterFlags      = DisasterData.Flags.All;
            input.m_ignoreTransportFlags     = TransportLine.Flags.All;
            input.m_ignoreParkedVehicleFlags = VehicleParked.Flags.All;
            input.m_ignoreTerrain            = true;
            RayCast(input, out RaycastOutput output);
            m_hover = output.m_netSegment;

            if (m_newSeg1 != 0 && m_newSeg2 != 0)
            {
                NetSegment s1 = GetSegment(m_newSeg1);
                NetSegment s2 = GetSegment(m_newSeg2);

                NetNode a = GetNode(s1.m_startNode);
                NetNode b = GetNode(s2.m_endNode);
                NetNode c = GetNode(s2.m_startNode);

                if ((a.m_problems | b.m_problems | c.m_problems) == Notification.Problem.RoadNotConnected)
                {
                    InvertSegment(m_newSeg1);
                    InvertSegment(m_newSeg2);
                }

                m_newSeg1 = 0;
                m_newSeg2 = 0;
                enabled   = false;
                UIView.Find("E3A").Unfocus();
                UIView.Find("E3B").Unfocus();
                mode = 0;
                ToolsModifierControl.SetTool <DefaultTool>();
            }

            if (m_hover != 0)
            {
                if (mode == 1)
                {
                    //Snap to location on segment
                    Bezier3    bezierx = new Bezier3();
                    NetSegment seg     = GetSegment(m_hover);
                    bezierx.a = NetManager.instance.m_nodes.m_buffer[seg.m_startNode].m_position;
                    bezierx.d = NetManager.instance.m_nodes.m_buffer[seg.m_endNode].m_position;

                    bool smoothStart = (Singleton <NetManager> .instance.m_nodes.m_buffer[seg.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
                    bool smoothEnd   = (Singleton <NetManager> .instance.m_nodes.m_buffer[seg.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;

                    NetSegment.CalculateMiddlePoints(bezierx.a, seg.m_startDirection, bezierx.d, seg.m_endDirection, smoothStart, smoothEnd, out Vector3 b, out Vector3 c);

                    bezierx.b = b;
                    bezierx.c = c;

                    float iterations       = 40f; // Could be anywhere 0-100. Maybe configurable at a later point.
                    float time             = 0f;
                    float shortestDistance = 1000f;
                    for (float i = 0f; i < iterations; i++)
                    {
                        float   ttime     = (i + 1f) / iterations;
                        Vector3 testPoint = bezierx.Position(ttime);
                        float   distance  = Vector3.Distance(testPoint, output.m_hitPos);
                        if (distance < shortestDistance)
                        {
                            shortestDistance = distance;
                            time             = ttime;
                            m_snapFakeNode   = testPoint;
                        }
                    }

                    // If x < 0.1f or x > 0.9f, display a warning telling people the segment may start to glitch out? perhaps over a certain length? <0.1m?
                    m_errors = time * seg.m_averageLength < 3.0f || seg.m_averageLength - (time * seg.m_averageLength) < 3.0f;
                    pulsating++;

                    if (Input.GetMouseButtonUp(0) && Mathf.Abs(0.5f - time) < 0.5)
                    {
                        if (!NodeInsertion(m_hover, time))
                        {
                            Debug.LogError(":(");
                            return;
                        }
                    }
                }
                else
                {
                    if (Input.GetMouseButtonUp(0))
                    {
                        if (m_seg1 == 0)
                        {
                            m_seg1 = m_hover;
                        }
                        else
                        {
                            m_seg2 = m_hover;
                        }
                    }
                    else if (Input.GetMouseButtonUp(1))
                    {
                        if (m_seg2 != 0)
                        {
                            m_seg2 = 0;
                        }
                        else if (m_seg1 != 0)
                        {
                            m_seg1 = 0;
                        }
                    }
                }
            }

            if (Input.GetKeyUp(KeyCode.Return))
            {
                if (!Intersection(m_seg1, m_seg2))
                {
                    Debug.LogError(":(");
                }
                enabled = false;
                ToolsModifierControl.SetTool <DefaultTool>();
                m_seg1 = 0;
                m_seg2 = 0;
                UIView.Find("E3A").Unfocus();
                UIView.Find("E3B").Unfocus();
            }
        }
Exemplo n.º 19
0
        public bool Intersection(ushort segment1, ushort segment2)
        {
            Bezier3    bezier  = new Bezier3();
            Bezier3    bezier2 = new Bezier3();
            NetSegment s1      = GetSegment(segment1);
            NetSegment s2      = GetSegment(segment2);

            // Turn the segment data into a Bezier2 for easier calculations supported by the game
            bezier.a = NetManager.instance.m_nodes.m_buffer[s1.m_startNode].m_position;
            bezier.d = NetManager.instance.m_nodes.m_buffer[s1.m_endNode].m_position;

            bool smoothStart = (Singleton <NetManager> .instance.m_nodes.m_buffer[s1.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
            bool smoothEnd   = (Singleton <NetManager> .instance.m_nodes.m_buffer[s1.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;

            NetSegment.CalculateMiddlePoints(bezier.a, s1.m_startDirection, bezier.d, s1.m_endDirection, smoothStart, smoothEnd, out Vector3 b, out Vector3 c);

            bezier.b = b;
            bezier.c = c;

            Bezier2 xz = Bezier2.XZ(bezier);

            // Second segment:
            bezier2.a = NetManager.instance.m_nodes.m_buffer[s2.m_startNode].m_position;
            bezier2.d = NetManager.instance.m_nodes.m_buffer[s2.m_endNode].m_position;

            smoothStart = (Singleton <NetManager> .instance.m_nodes.m_buffer[s2.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
            smoothEnd   = (Singleton <NetManager> .instance.m_nodes.m_buffer[s2.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;

            NetSegment.CalculateMiddlePoints(bezier2.a, s2.m_startDirection, bezier2.d, s2.m_endDirection, smoothStart, smoothEnd, out Vector3 _b, out Vector3 _c);

            bezier2.b = _b;
            bezier2.c = _c;

            Bezier2 xz2 = Bezier2.XZ(bezier2);

            if (!xz.Intersect(xz2, out float t1, out float t2, 8))
            {
                return(ThrowError("Could not find an intersection between these two roads. Remember, T-junctions do not count as intersections. Try extending the segment, creating the intersection, and deleting the excess."));
            }

            Vector3 intersectionPoint = bezier.Position(t1);

            ushort  seg1ls  = s1.m_startNode;
            Vector3 seg1lsd = s1.m_startDirection;
            Vector3 seg1led = -bezier.Tangent(t1).normalized;

            ushort  seg1rs  = s1.m_endNode;
            Vector3 seg1rsd = s1.m_endDirection;
            Vector3 seg1red = bezier.Tangent(t1).normalized;

            ushort  seg2ls  = s2.m_startNode;
            Vector3 seg2lsd = s2.m_startDirection;
            Vector3 seg2led = -bezier2.Tangent(t2).normalized;

            ushort  seg2rs  = s2.m_endNode;
            Vector3 seg2rsd = s2.m_endDirection;
            Vector3 seg2red = bezier2.Tangent(t2).normalized;


            // place segments and nodes
            Manager.CreateNode(out ushort intersectionNode, ref SimulationManager.instance.m_randomizer, s1.Info, intersectionPoint, SimulationManager.instance.m_currentBuildIndex);
            Manager.CreateSegment(out ushort seg1, ref SimulationManager.instance.m_randomizer, s1.Info, seg1ls, intersectionNode, seg1lsd, seg1led, SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex, false);
            Manager.CreateSegment(out ushort seg2, ref SimulationManager.instance.m_randomizer, s1.Info, seg1rs, intersectionNode, seg1rsd, seg1red, SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex, false);
            Manager.CreateSegment(out ushort seg3, ref SimulationManager.instance.m_randomizer, s2.Info, seg2ls, intersectionNode, seg2lsd, seg2led, SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex, false);
            Manager.CreateSegment(out ushort seg4, ref SimulationManager.instance.m_randomizer, s2.Info, seg2rs, intersectionNode, seg2rsd, seg2red, SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex, false);

            List <ushort> newSegments = new List <ushort>();

            newSegments.Add(seg1);
            newSegments.Add(seg2);
            newSegments.Add(seg3);
            newSegments.Add(seg4);

            if (seg1 == 0 || seg2 == 0 || seg3 == 0 || seg4 == 0)
            {
                return(Revert(newSegments, intersectionNode));
            }

            Manager.ReleaseSegment(segment1, true);
            Manager.ReleaseSegment(segment2, true);

            FixTJunctions(newSegments);
            return(true);
        }
Exemplo n.º 20
0
 public static void RenderBezier(RenderManager.CameraInfo cameraInfo, Color color, Bezier3 bezier, float width = 0.2f, bool cut = false, bool alphaBlend = true) =>
 RenderManager.OverlayEffect.DrawBezier(cameraInfo, color, bezier, width, cut ? width / 2 : 0f, cut ? width / 2 : 0f, -1f, 1280f, false, alphaBlend);
        public static StopPointDescriptorLanes[] MapStopPoints(BuildingInfo buildingInfo, float thresold)
        {
            var result = new List <StopPointDescriptorLanes>();

            if (buildingInfo?.m_paths != null)
            {
                foreach (BuildingInfo.PathInfo path in buildingInfo.m_paths)
                {
                    if (path.m_nodes.Length < 2)
                    {
                        continue;
                    }

                    Vector3 position  = path.m_nodes[0];
                    Vector3 position2 = path.m_nodes[1];


                    position.z  *= -1;
                    position2.z *= -1;
                    Vector3 directionPath = Quaternion.AngleAxis(90, Vector3.up) * (position2 - position).normalized;

                    foreach (NetInfo.Lane refLane in path.m_netInfo.m_lanes)
                    {
                        if (refLane.m_stopType == VehicleInfo.VehicleType.None)
                        {
                            continue;
                        }
                        NetInfo.Lane lane = FindNearestVehicleStopLane(path.m_netInfo.m_lanes, refLane, out ushort laneId);
                        if (lane == null)
                        {
                            continue;
                        }


                        LogUtils.DoLog($"[{buildingInfo}] pos + dir = ({position} {position2} + {directionPath})");
                        Vector3 lanePos = position + (lane.m_position / 2 * directionPath) + new Vector3(0, lane.m_verticalOffset);
                        Vector3 lanePos2 = position2 + (lane.m_position / 2 * directionPath) + new Vector3(0, lane.m_verticalOffset);
                        Vector3 b3, c;
                        if (path.m_curveTargets == null || path.m_curveTargets.Length == 0)
                        {
                            NetSegment.CalculateMiddlePoints(lanePos, Vector3.zero, lanePos2, Vector3.zero, true, true, out b3, out c);
                        }
                        else
                        {
                            GetMiddlePointsFor(path, out b3, out c);
                            LogUtils.DoLog($"[{buildingInfo}] GetMiddlePointsFor path =  ({b3} {c})");
                            b3  += (lane.m_position * directionPath) + new Vector3(0, lane.m_verticalOffset);
                            c   += (lane.m_position * directionPath) + new Vector3(0, lane.m_verticalOffset);
                            b3.y = c.y = (lanePos.y + lanePos2.y) / 2;
                        }
                        var refBezier = new Bezier3(lanePos, b3, c, lanePos2);
                        LogUtils.DoLog($"[{buildingInfo}]refBezier = {refBezier} ({lanePos} {b3} {c} {lanePos2})");


                        Vector3 positionR = refBezier.Position(m_defaultStopOffset);
                        Vector3 direction = refBezier.Tangent(m_defaultStopOffset);
                        LogUtils.DoLog($"[{buildingInfo}]1positionR = {positionR}; direction = {direction}");

                        Vector3 normalized = Vector3.Cross(Vector3.up, direction).normalized;
                        positionR += normalized * (MathUtils.SmootherStep(0.5f, 0f, Mathf.Abs(m_defaultStopOffset - 0.5f)) * lane.m_stopOffset);
                        LogUtils.DoLog($"[{buildingInfo}]2positionR = {positionR}; direction = {direction}; {normalized}");
                        result.Add(new StopPointDescriptorLanes
                        {
                            platformLine  = refBezier,
                            width         = lane.m_width,
                            vehicleType   = refLane.m_stopType,
                            laneId        = laneId,
                            subbuildingId = -1,
                            directionPath = directionPath * (path.m_invertSegments == (refLane.m_finalDirection == NetInfo.Direction.AvoidForward || refLane.m_finalDirection == NetInfo.Direction.Backward) ? 1 : -1)
                        });
                    }
                }
            }
            for (int i = 0; i < (buildingInfo.m_subBuildings?.Length ?? 0); i++)
            {
                StopPointDescriptorLanes[] subPlats = MapStopPoints(buildingInfo.m_subBuildings[i].m_buildingInfo, thresold);
                if (subPlats != null)
                {
                    var rotationToApply = Quaternion.AngleAxis(buildingInfo.m_subBuildings[i].m_angle, Vector3.up);
                    result.AddRange(subPlats.Select(x =>
                    {
                        x.platformLine.a = (rotationToApply * x.platformLine.a) + buildingInfo.m_subBuildings[i].m_position;
                        x.platformLine.b = (rotationToApply * x.platformLine.b) + buildingInfo.m_subBuildings[i].m_position;
                        x.platformLine.c = (rotationToApply * x.platformLine.c) + buildingInfo.m_subBuildings[i].m_position;
                        x.platformLine.d = (rotationToApply * x.platformLine.d) + buildingInfo.m_subBuildings[i].m_position;
                        x.subbuildingId  = (sbyte)i;
                        x.directionPath  = (rotationToApply * x.directionPath).normalized;
                        return(x);
                    }));
                }
            }
            result.Sort((x, y) =>
            {
                int priorityX = VehicleToPriority(x.vehicleType);
                int priorityY = VehicleToPriority(y.vehicleType);
                if (priorityX != priorityY)
                {
                    return(priorityX.CompareTo(priorityY));
                }

                Vector3 centerX = (x.platformLine.Position(0.5f));
                Vector3 centerY = (y.platformLine.Position(0.5f));
                if (Mathf.Abs(centerX.y - centerY.y) >= thresold)
                {
                    return(-centerX.y.CompareTo(centerY.y));
                }

                if (Mathf.Abs(centerX.z - centerY.z) >= thresold)
                {
                    return(-centerX.z.CompareTo(centerY.z));
                }

                return(-centerX.x.CompareTo(centerY.x));
            });
            if (CommonProperties.DebugMode)
            {
                LogUtils.DoLog($"{buildingInfo.name} PLAT ORDER:\n{string.Join("\n", result.Select((x, y) => $"{y}=> {x.ToString()}").ToArray())}");
            }
            return(result.ToArray());
        }
        public static bool RenderInstance(ref CitizenInstance instance, RenderManager.CameraInfo cameraInfo, ushort instanceID)
        {
            if ((instance.m_flags & CitizenInstance.Flags.Character) == CitizenInstance.Flags.None)
                return false;
            CitizenInfo info = instance.Info;
            if ((UnityEngine.Object)info == (UnityEngine.Object)null)
                return false;
            uint num = Singleton<SimulationManager>.instance.m_referenceFrameIndex - ((uint)instanceID << 4) / 65536U;
            CitizenInstance.Frame frameData1 = instance.GetFrameData(num - 32U);
            float maxDistance = Mathf.Min(RenderManager.LevelOfDetailFactor * 800f, info.m_maxRenderDistance + cameraInfo.m_height * 0.5f);
            if (!cameraInfo.CheckRenderDistance(frameData1.m_position, maxDistance) || !cameraInfo.Intersect(frameData1.m_position, 10f))
                return false;

            CitizenInstance.Frame frameData2 = instance.GetFrameData(num - 16U);
            float t = (float)(((double)(num & 15U) + (double)Singleton<SimulationManager>.instance.m_referenceTimer) * (1.0 / 16.0));
            bool flag1 = frameData2.m_underground && frameData1.m_underground;
            bool flag2 = frameData2.m_insideBuilding && frameData1.m_insideBuilding;
            bool flag3 = frameData2.m_transition || frameData1.m_transition;
            if (flag2 && !flag3 || flag1 && !flag3 && (cameraInfo.m_layerMask & 1 << Singleton<CitizenManager>.instance.m_undergroundLayer) == 0)
                return false;
            //begin mod
            info = GetUpdatedInfo(instance, instanceID);
            //end mod
            Vector3 vector3 = new Bezier3()
            {
                a = frameData1.m_position,
                b = (frameData1.m_position + frameData1.m_velocity * 0.333f),
                c = (frameData2.m_position - frameData2.m_velocity * 0.333f),
                d = frameData2.m_position
            }.Position(t);
            Quaternion quaternion = Quaternion.Lerp(frameData1.m_rotation, frameData2.m_rotation, t);
            Color color = info.m_citizenAI.GetColor(instanceID, ref instance, Singleton<InfoManager>.instance.CurrentMode);
            if (cameraInfo.CheckRenderDistance(vector3, info.m_lodRenderDistance))
            {
                InstanceID id = InstanceID.Empty;
                id.CitizenInstance = instanceID;
                CitizenInfo citizenInfo = info.ObtainPrefabInstance<CitizenInfo>(id, (int)byte.MaxValue);
                if ((UnityEngine.Object)citizenInfo != (UnityEngine.Object)null)
                {
                    Vector3 velocity = Vector3.Lerp(frameData1.m_velocity, frameData2.m_velocity, t);
                    //begin mod
                    if (info.m_subCulture == Citizen.SubCulture.Generic)
                    {
                        citizenInfo.m_citizenAI.SetRenderParameters(cameraInfo, instanceID, ref instance, vector3,
                            quaternion, velocity, color,
                            (flag1 || flag3) &&
                            (cameraInfo.m_layerMask & 1 << Singleton<CitizenManager>.instance.m_undergroundLayer) != 0);
                    }
                    else
                    {
                        citizenInfo.SetRenderParameters(vector3, quaternion, velocity, color, 5,
                            (flag1 || flag3) &&
                            (cameraInfo.m_layerMask & 1 << Singleton<CitizenManager>.instance.m_undergroundLayer) != 0);
                    }
                    //end mod
                    return true;
                }
            }
            if (flag1 || flag3)
            {
                info.m_undergroundLodLocations[info.m_undergroundLodCount].SetTRS(vector3, quaternion, Vector3.one);
                info.m_undergroundLodColors[info.m_undergroundLodCount] = color;
                info.m_undergroundLodMin = Vector3.Min(info.m_undergroundLodMin, vector3);
                info.m_undergroundLodMax = Vector3.Max(info.m_undergroundLodMax, vector3);
                if (++info.m_undergroundLodCount == info.m_undergroundLodLocations.Length)
                    CitizenInstance.RenderUndergroundLod(cameraInfo, info);
            }
            if (!flag1 || flag3)
            {
                info.m_lodLocations[info.m_lodCount].SetTRS(vector3, quaternion, Vector3.one);
                info.m_lodColors[info.m_lodCount] = color;
                info.m_lodMin = Vector3.Min(info.m_lodMin, vector3);
                info.m_lodMax = Vector3.Max(info.m_lodMax, vector3);
                if (++info.m_lodCount == info.m_lodLocations.Length)
                    CitizenInstance.RenderLod(cameraInfo, info);
            }
            return true;
        }
Exemplo n.º 23
0
        /// <summary>
        /// This method marks zone cells overlapped by network segments as invalid. Called by CalculateBlock1.
        /// </summary>
        /// <param name="_this"></param>
        /// <param name="blockID"></param>
        /// <param name="segmentID"></param>
        /// <param name="data"></param>
        /// <param name="valid"></param>
        /// <param name="minX"></param>
        /// <param name="minZ"></param>
        /// <param name="maxX"></param>
        /// <param name="maxZ"></param>
        private static void CalculateImplementation1(ref ZoneBlock _this, ushort blockID, ushort segmentID, ref NetSegment data, ref ulong valid, float minX, float minZ, float maxX, float maxZ)
        {
            // do nothing if the block belongs to the network segment
            if ((int)data.m_blockStartLeft == (int)blockID || (int)data.m_blockStartRight == (int)blockID ||
                ((int)data.m_blockEndLeft == (int)blockID || (int)data.m_blockEndRight == (int)blockID))
            {
                return;
            }

            NetInfo info = data.Info;
            if (!info.m_canCollide) return; // water pipes etc.

            float collisionHalfWidth = info.m_netAI.GetCollisionHalfWidth();

            NetNode[] netNodeArray = Singleton<NetManager>.instance.m_nodes.m_buffer;

            // calculate network bezier curve
            Bezier3 bezier = new Bezier3();
            bezier.a = netNodeArray[(int)data.m_startNode].m_position;
            bezier.d = netNodeArray[(int)data.m_endNode].m_position;
            NetSegment.CalculateMiddlePoints(bezier.a, data.m_startDirection, bezier.d, data.m_endDirection, true, true, out bezier.b, out bezier.c);

            // remove vertical component
            Bezier2 bezierXZ = Bezier2.XZ(bezier);

            // do nothing if the collision hitbox is outside of the hitbox of the zone block
            Vector2 collisionAreaMin = bezierXZ.Min() + new Vector2(-collisionHalfWidth, -collisionHalfWidth);
            Vector2 collisionAreaMax = bezierXZ.Max() + new Vector2(collisionHalfWidth, collisionHalfWidth);
            if ((double)collisionAreaMin.x > (double)maxX || (double)collisionAreaMin.y > (double)maxZ
                || ((double)minX > (double)collisionAreaMax.x || (double)minZ > (double)collisionAreaMax.y))
            {
                return;
            }

            // width of the zone block
            int rowCount = _this.RowCount;

            // directions of the rows and columns based on zone block angle, multiplied by 8 (cell size)
            Vector2 columnDirection = new Vector2(Mathf.Cos(_this.m_angle), Mathf.Sin(_this.m_angle)) * 8f;
            Vector2 rowDirection = new Vector2(columnDirection.y, -columnDirection.x);

            // origin of the zone block
            // this position is in the center of the 8x8 zone block (4 columns and 4 rows away from the lower corner)
            Vector2 positionXZ = VectorUtils.XZ(_this.m_position);

            // area of the zone block (8x8 cells)
            Quad2 zoneBlockQuad = new Quad2
            {
                a = positionXZ - 4f * columnDirection - 4f * rowDirection,
                b = positionXZ + 4f * columnDirection - 4f * rowDirection,
                c = positionXZ + 4f * columnDirection + (float)(rowCount - 4) * rowDirection,
                d = positionXZ - 4f * columnDirection + (float)(rowCount - 4) * rowDirection
            };

            // Calculate the bounds of the network segment at the start node
            float start;
            float end;
            info.m_netAI.GetTerrainModifyRange(out start, out end);
            float halfStart = start * 0.5f; // e.g. 0.25f ---> 0.125f
            float halfEnd = (float)(1.0 - (1.0 - (double)end) * 0.5); // e.g. 0.75f --> 0.875f
            float t = halfStart;
            Vector2 startBezierPos = bezierXZ.Position(halfStart);
            Vector2 startBezierTan = bezierXZ.Tangent(halfStart);
            Vector2 startOrthogonalNormalized = new Vector2(-startBezierTan.y, startBezierTan.x).normalized; // tangent rotated by -90 deg = orthogonal

            Quad2 bezierQuad = new Quad2();

            // set the initial a/b bounds
            if ((double)t < 0.00999999977648258 && (info.m_clipSegmentEnds || (netNodeArray[(int)data.m_startNode].m_flags & NetNode.Flags.Bend) != NetNode.Flags.None))
            {
                Vector2 ortho4m = startOrthogonalNormalized * 4f;
                bezierQuad.a = startBezierPos + ortho4m - VectorUtils.XZ(data.m_startDirection) * 4f;
                bezierQuad.d = startBezierPos - ortho4m - VectorUtils.XZ(data.m_startDirection) * 4f;
            }
            else
            {
                Vector2 orthoHalfWidth = startOrthogonalNormalized * collisionHalfWidth;
                bezierQuad.a = startBezierPos + orthoHalfWidth;
                bezierQuad.d = startBezierPos - orthoHalfWidth;
            }

            // overlap 8 quads describing the position
            int steps = 8;
            for (int step = 1; step <= steps; ++step)
            {
                float interp = halfStart + (halfEnd - halfStart) * (float)step / (float)steps;
                Vector2 interpBezierPos = bezierXZ.Position(interp);
                Vector2 interpBezierTangent = bezierXZ.Tangent(interp);
                interpBezierTangent = new Vector2(-interpBezierTangent.y, interpBezierTangent.x).normalized;

                // set the c/d bounds
                if ((double)interp > 0.990000009536743 && (info.m_clipSegmentEnds || (netNodeArray[(int)data.m_endNode].m_flags & NetNode.Flags.Bend) != NetNode.Flags.None))
                {
                    interpBezierTangent *= 4f;
                    bezierQuad.b = interpBezierPos + interpBezierTangent - VectorUtils.XZ(data.m_endDirection) * 4f;
                    bezierQuad.c = interpBezierPos - interpBezierTangent - VectorUtils.XZ(data.m_endDirection) * 4f;
                }
                else
                {
                    interpBezierTangent *= collisionHalfWidth;
                    bezierQuad.b = interpBezierPos + interpBezierTangent;
                    bezierQuad.c = interpBezierPos - interpBezierTangent;
                }
                Vector2 quadMin = bezierQuad.Min();
                Vector2 quadMax = bezierQuad.Max();

                // Overlap the quad with the zone block quad
                if ((double)quadMin.x <= (double)maxX && (double)quadMin.y <= (double)maxZ && ((double)minX <= (double)quadMax.x && (double)minZ <= (double)quadMax.y) && zoneBlockQuad.Intersect(bezierQuad))
                {
                    // mark colliding cells as invalid
                    valid = valid & ~OverlapQuad(ref _this, bezierQuad);
                }

                // set the a/b bounds for the next quad
                bezierQuad.a = bezierQuad.b;
                bezierQuad.d = bezierQuad.c;
            }
        }
Exemplo n.º 24
0
        /// <summary>
        /// Create curved zone blocks.
        /// </summary>
        /// <param name="info">Network prefab</param>
        /// <param name="randomizer">Randomizer</param>
        /// <param name="segment">Network segment</param>
        private static void CurvedZoneBlocks(NetInfo info, Randomizer randomizer, ref NetSegment segment)
        {
#pragma warning disable IDE0018 // Inline variable declaration

            // TODO: Basically game code with some NExT2 modifications.  Could do with a good refactor, and possible replacement with Transpiler.

            var minHalfWidth = MIN_HALFWIDTH_TINY_CURVE;

            NetManager instance       = Singleton <NetManager> .instance;
            Vector3    startPosition  = instance.m_nodes.m_buffer[(int)segment.m_startNode].m_position;
            Vector3    endPosition    = instance.m_nodes.m_buffer[(int)segment.m_endNode].m_position;
            Vector3    startDirection = segment.m_startDirection;
            Vector3    endDirection   = segment.m_endDirection;


            float num      = startDirection.x * endDirection.x + startDirection.z * endDirection.z;
            float num2     = Mathf.Max(minHalfWidth, info.m_halfWidth); // minHalfWidth here.
            float num3     = 32f;
            int   distance = Mathf.RoundToInt(num2);

            float num4  = VectorUtils.LengthXZ(endPosition - startPosition);
            bool  flag2 = startDirection.x * endDirection.z - startDirection.z * endDirection.x > 0f;
            bool  flag3 = num <-0.8f || num4> 50f;
            if (flag2)
            {
                num2 = -num2;
                num3 = -num3;
            }
            Vector3 vector  = startPosition - new Vector3(startDirection.z, 0f, -startDirection.x) * num2;
            Vector3 vector2 = endPosition + new Vector3(endDirection.z, 0f, -endDirection.x) * num2;
            Vector3 vector3;
            Vector3 vector4;
            NetSegment.CalculateMiddlePoints(vector, startDirection, vector2, endDirection, true, true, out vector3, out vector4);
            if (flag3)
            {
                float num5 = num * 0.025f + 0.04f;
                float num6 = num * 0.025f + 0.06f;
                if (num < -0.9f)
                {
                    num6 = num5;
                }
                Bezier3 bezier = new Bezier3(vector, vector3, vector4, vector2);
                vector  = bezier.Position(num5);
                vector3 = bezier.Position(0.5f - num6);
                vector4 = bezier.Position(0.5f + num6);
                vector2 = bezier.Position(1f - num5);
            }
            else
            {
                Bezier3 bezier2 = new Bezier3(vector, vector3, vector4, vector2);
                vector3 = bezier2.Position(0.86f);
                vector  = bezier2.Position(0.14f);
            }
            float   num7;
            Vector3 vector5 = VectorUtils.NormalizeXZ(vector3 - vector, out num7);
            int     num8    = Mathf.FloorToInt(num7 / 8f + 0.01f);
            float   num9    = num7 * 0.5f + (float)(num8 - 8) * ((!flag2) ? -4f : 4f);
            if (num8 != 0)
            {
                float   angle     = (!flag2) ? Mathf.Atan2(vector5.x, -vector5.z) : Mathf.Atan2(-vector5.x, vector5.z);
                Vector3 position3 = vector + new Vector3(vector5.x * num9 - vector5.z * num3, 0f, vector5.z * num9 + vector5.x * num3);
                if (flag2)
                {
                    Singleton <ZoneManager> .instance.CreateBlock(
                        out segment.m_blockStartRight,
                        ref randomizer,
                        position3,
                        angle,
                        num8,
                        distance,
                        segment.m_buildIndex);
                }
                else
                {
                    Singleton <ZoneManager> .instance.CreateBlock(
                        out segment.m_blockStartLeft,
                        ref randomizer,
                        position3,
                        angle,
                        num8,
                        distance,
                        segment.m_buildIndex);
                }
            }
            if (flag3)
            {
                vector5 = VectorUtils.NormalizeXZ(vector2 - vector4, out num7);
                num8    = Mathf.FloorToInt(num7 / 8f + 0.01f);
                num9    = num7 * 0.5f + (float)(num8 - 8) * ((!flag2) ? -4f : 4f);
                if (num8 != 0)
                {
                    float   angle2    = (!flag2) ? Mathf.Atan2(vector5.x, -vector5.z) : Mathf.Atan2(-vector5.x, vector5.z);
                    Vector3 position4 = vector4 + new Vector3(vector5.x * num9 - vector5.z * num3, 0f, vector5.z * num9 + vector5.x * num3);
                    if (flag2)
                    {
                        Singleton <ZoneManager> .instance.CreateBlock(
                            out segment.m_blockEndRight,
                            ref randomizer,
                            position4,
                            angle2,
                            num8,
                            distance,
                            segment.m_buildIndex + 1u);
                    }
                    else
                    {
                        Singleton <ZoneManager> .instance.CreateBlock(
                            out segment.m_blockEndLeft,
                            ref randomizer,
                            position4,
                            angle2,
                            num8,
                            distance,
                            segment.m_buildIndex + 1u);
                    }
                }
            }
            Vector3 vector6 = startPosition + new Vector3(startDirection.z, 0f, -startDirection.x) * num2;
            Vector3 vector7 = endPosition - new Vector3(endDirection.z, 0f, -endDirection.x) * num2;
            Vector3 b;
            Vector3 c;
            NetSegment.CalculateMiddlePoints(vector6, startDirection, vector7, endDirection, true, true, out b, out c);
            Bezier3 bezier3 = new Bezier3(vector6, b, c, vector7);
            Vector3 vector8 = bezier3.Position(0.5f);
            Vector3 vector9 = bezier3.Position(0.25f);
            vector9 = Line2.Offset(VectorUtils.XZ(vector6), VectorUtils.XZ(vector8), VectorUtils.XZ(vector9));
            Vector3 vector10 = bezier3.Position(0.75f);
            vector10 = Line2.Offset(VectorUtils.XZ(vector7), VectorUtils.XZ(vector8), VectorUtils.XZ(vector10));
            Vector3 vector11 = vector6;
            Vector3 a        = vector7;
            float   d;
#pragma warning disable IDE0059 // Unnecessary assignment of a value
            float num10;
            if (Line2.Intersect(VectorUtils.XZ(startPosition), VectorUtils.XZ(vector6), VectorUtils.XZ(vector11 - vector9), VectorUtils.XZ(vector8 - vector9), out d, out num10))
            {
                vector6 = startPosition + (vector6 - startPosition) * d;
            }
            if (Line2.Intersect(VectorUtils.XZ(endPosition), VectorUtils.XZ(vector7), VectorUtils.XZ(a - vector10), VectorUtils.XZ(vector8 - vector10), out d, out num10))
            {
                vector7 = endPosition + (vector7 - endPosition) * d;
            }
            if (Line2.Intersect(VectorUtils.XZ(vector11 - vector9), VectorUtils.XZ(vector8 - vector9), VectorUtils.XZ(a - vector10), VectorUtils.XZ(vector8 - vector10), out d, out num10))
#pragma warning restore IDE0059 // Unnecessary assignment of a value
            {
                vector8 = vector11 - vector9 + (vector8 - vector11) * d;
            }
            float   num11;
            Vector3 vector12 = VectorUtils.NormalizeXZ(vector8 - vector6, out num11);
            int     num12    = Mathf.FloorToInt(num11 / 8f + 0.01f);
            float   num13    = num11 * 0.5f + (float)(num12 - 8) * ((!flag2) ? 4f : -4f);
            if (num12 != 0)
            {
                float   angle3    = (!flag2) ? Mathf.Atan2(-vector12.x, vector12.z) : Mathf.Atan2(vector12.x, -vector12.z);
                Vector3 position5 = vector6 + new Vector3(vector12.x * num13 + vector12.z * num3, 0f, vector12.z * num13 - vector12.x * num3);
                if (flag2)
                {
                    Singleton <ZoneManager> .instance.CreateBlock(
                        out segment.m_blockStartLeft,
                        ref randomizer,
                        position5,
                        angle3,
                        num12,
                        distance,
                        segment.m_buildIndex);
                }
                else
                {
                    Singleton <ZoneManager> .instance.CreateBlock(
                        out segment.m_blockStartRight,
                        ref randomizer,
                        position5,
                        angle3,
                        num12,
                        distance,
                        segment.m_buildIndex);
                }
            }
            vector12 = VectorUtils.NormalizeXZ(vector7 - vector8, out num11);
            num12    = Mathf.FloorToInt(num11 / 8f + 0.01f);
            num13    = num11 * 0.5f + (float)(num12 - 8) * ((!flag2) ? 4f : -4f);
            if (num12 != 0)
            {
                float   angle4    = (!flag2) ? Mathf.Atan2(-vector12.x, vector12.z) : Mathf.Atan2(vector12.x, -vector12.z);
                Vector3 position6 = vector8 + new Vector3(vector12.x * num13 + vector12.z * num3, 0f, vector12.z * num13 - vector12.x * num3);
                if (flag2)
                {
                    Singleton <ZoneManager> .instance.CreateBlock(
                        out segment.m_blockEndLeft,
                        ref randomizer,
                        position6,
                        angle4,
                        num12,
                        distance,
                        segment.m_buildIndex + 1u);
                }
                else
                {
                    Singleton <ZoneManager> .instance.CreateBlock(
                        out segment.m_blockEndRight,
                        ref randomizer,
                        position6,
                        angle4,
                        num12,
                        distance,
                        segment.m_buildIndex + 1u);
                }
            }
#pragma warning restore IDE0018 // Inline variable declaration
        }
        private static void CreateZoneBlocksTiny_Curve(NetInfo info, Randomizer randomizer, ref NetSegment segment)
        {
            var minHalfWidth = MIN_HALFWIDTH_TINY_CURVE;

            NetManager instance = Singleton<NetManager>.instance;
            Vector3 startPosition = instance.m_nodes.m_buffer[(int)segment.m_startNode].m_position;
            Vector3 endPosition = instance.m_nodes.m_buffer[(int)segment.m_endNode].m_position;
            Vector3 startDirection = segment.m_startDirection;
            Vector3 endDirection = segment.m_endDirection;
            float num = startDirection.x * endDirection.x + startDirection.z * endDirection.z;
            float num2 = Mathf.Max(minHalfWidth, info.m_halfWidth);
            float num3 = 32f;

            float num4 = VectorUtils.LengthXZ(endPosition - startPosition);
            bool flag2 = startDirection.x * endDirection.z - startDirection.z * endDirection.x > 0f;
            bool flag3 = num < -0.8f || num4 > 50f;
            if (flag2)
            {
                num2 = -num2;
                num3 = -num3;
            }
            Vector3 vector = startPosition - new Vector3(startDirection.z, 0f, -startDirection.x) * num2;
            Vector3 vector2 = endPosition + new Vector3(endDirection.z, 0f, -endDirection.x) * num2;
            Vector3 vector3;
            Vector3 vector4;
            NetSegment.CalculateMiddlePoints(vector, startDirection, vector2, endDirection, true, true, out vector3, out vector4);
            if (flag3)
            {
                float num5 = num * 0.025f + 0.04f;
                float num6 = num * 0.025f + 0.06f;
                if (num < -0.9f)
                {
                    num6 = num5;
                }
                Bezier3 bezier = new Bezier3(vector, vector3, vector4, vector2);
                vector = bezier.Position(num5);
                vector3 = bezier.Position(0.5f - num6);
                vector4 = bezier.Position(0.5f + num6);
                vector2 = bezier.Position(1f - num5);
            }
            else
            {
                Bezier3 bezier2 = new Bezier3(vector, vector3, vector4, vector2);
                vector3 = bezier2.Position(0.86f);
                vector = bezier2.Position(0.14f);
            }
            float num7;
            Vector3 vector5 = VectorUtils.NormalizeXZ(vector3 - vector, out num7);
            int num8 = Mathf.FloorToInt(num7 / 8f + 0.01f);
            float num9 = num7 * 0.5f + (float)(num8 - 8) * ((!flag2) ? -4f : 4f);
            if (num8 != 0)
            {
                float angle = (!flag2) ? Mathf.Atan2(vector5.x, -vector5.z) : Mathf.Atan2(-vector5.x, vector5.z);
                Vector3 position3 = vector + new Vector3(vector5.x * num9 - vector5.z * num3, 0f, vector5.z * num9 + vector5.x * num3);
                if (flag2)
                {
                    Singleton<ZoneManager>.instance.CreateBlock(
                        out segment.m_blockStartRight, 
                        ref randomizer, 
                        position3, 
                        angle, 
                        num8, 
                        segment.m_buildIndex);
                }
                else
                {
                    Singleton<ZoneManager>.instance.CreateBlock(
                        out segment.m_blockStartLeft, 
                        ref randomizer, 
                        position3, 
                        angle, 
                        num8, 
                        segment.m_buildIndex);
                }
            }
            if (flag3)
            {
                vector5 = VectorUtils.NormalizeXZ(vector2 - vector4, out num7);
                num8 = Mathf.FloorToInt(num7 / 8f + 0.01f);
                num9 = num7 * 0.5f + (float)(num8 - 8) * ((!flag2) ? -4f : 4f);
                if (num8 != 0)
                {
                    float angle2 = (!flag2) ? Mathf.Atan2(vector5.x, -vector5.z) : Mathf.Atan2(-vector5.x, vector5.z);
                    Vector3 position4 = vector4 + new Vector3(vector5.x * num9 - vector5.z * num3, 0f, vector5.z * num9 + vector5.x * num3);
                    if (flag2)
                    {
                        Singleton<ZoneManager>.instance.CreateBlock(
                            out segment.m_blockEndRight, 
                            ref randomizer, 
                            position4, 
                            angle2, 
                            num8, 
                            segment.m_buildIndex + 1u);
                    }
                    else
                    {
                        Singleton<ZoneManager>.instance.CreateBlock(
                            out segment.m_blockEndLeft, 
                            ref randomizer, 
                            position4, 
                            angle2, 
                            num8, 
                            segment.m_buildIndex + 1u);
                    }
                }
            }
            Vector3 vector6 = startPosition + new Vector3(startDirection.z, 0f, -startDirection.x) * num2;
            Vector3 vector7 = endPosition - new Vector3(endDirection.z, 0f, -endDirection.x) * num2;
            Vector3 b;
            Vector3 c;
            NetSegment.CalculateMiddlePoints(vector6, startDirection, vector7, endDirection, true, true, out b, out c);
            Bezier3 bezier3 = new Bezier3(vector6, b, c, vector7);
            Vector3 vector8 = bezier3.Position(0.5f);
            Vector3 vector9 = bezier3.Position(0.25f);
            vector9 = Line2.Offset(VectorUtils.XZ(vector6), VectorUtils.XZ(vector8), VectorUtils.XZ(vector9));
            Vector3 vector10 = bezier3.Position(0.75f);
            vector10 = Line2.Offset(VectorUtils.XZ(vector7), VectorUtils.XZ(vector8), VectorUtils.XZ(vector10));
            Vector3 vector11 = vector6;
            Vector3 a = vector7;
            float d;
            float num10;
            if (Line2.Intersect(VectorUtils.XZ(startPosition), VectorUtils.XZ(vector6), VectorUtils.XZ(vector11 - vector9), VectorUtils.XZ(vector8 - vector9), out d, out num10))
            {
                vector6 = startPosition + (vector6 - startPosition) * d;
            }
            if (Line2.Intersect(VectorUtils.XZ(endPosition), VectorUtils.XZ(vector7), VectorUtils.XZ(a - vector10), VectorUtils.XZ(vector8 - vector10), out d, out num10))
            {
                vector7 = endPosition + (vector7 - endPosition) * d;
            }
            if (Line2.Intersect(VectorUtils.XZ(vector11 - vector9), VectorUtils.XZ(vector8 - vector9), VectorUtils.XZ(a - vector10), VectorUtils.XZ(vector8 - vector10), out d, out num10))
            {
                vector8 = vector11 - vector9 + (vector8 - vector11) * d;
            }
            float num11;
            Vector3 vector12 = VectorUtils.NormalizeXZ(vector8 - vector6, out num11);
            int num12 = Mathf.FloorToInt(num11 / 8f + 0.01f);
            float num13 = num11 * 0.5f + (float)(num12 - 8) * ((!flag2) ? 4f : -4f);
            if (num12 != 0)
            {
                float angle3 = (!flag2) ? Mathf.Atan2(-vector12.x, vector12.z) : Mathf.Atan2(vector12.x, -vector12.z);
                Vector3 position5 = vector6 + new Vector3(vector12.x * num13 + vector12.z * num3, 0f, vector12.z * num13 - vector12.x * num3);
                if (flag2)
                {
                    Singleton<ZoneManager>.instance.CreateBlock(
                        out segment.m_blockStartLeft, 
                        ref randomizer, 
                        position5, 
                        angle3, 
                        num12, 
                        segment.m_buildIndex);
                }
                else
                {
                    Singleton<ZoneManager>.instance.CreateBlock(
                        out segment.m_blockStartRight, 
                        ref randomizer, 
                        position5, 
                        angle3, 
                        num12, 
                        segment.m_buildIndex);
                }
            }
            vector12 = VectorUtils.NormalizeXZ(vector7 - vector8, out num11);
            num12 = Mathf.FloorToInt(num11 / 8f + 0.01f);
            num13 = num11 * 0.5f + (float)(num12 - 8) * ((!flag2) ? 4f : -4f);
            if (num12 != 0)
            {
                float angle4 = (!flag2) ? Mathf.Atan2(-vector12.x, vector12.z) : Mathf.Atan2(vector12.x, -vector12.z);
                Vector3 position6 = vector8 + new Vector3(vector12.x * num13 + vector12.z * num3, 0f, vector12.z * num13 - vector12.x * num3);
                if (flag2)
                {
                    Singleton<ZoneManager>.instance.CreateBlock(
                        out segment.m_blockEndLeft, 
                        ref randomizer, 
                        position6, 
                        angle4, 
                        num12, 
                        segment.m_buildIndex + 1u);
                }
                else
                {
                    Singleton<ZoneManager>.instance.CreateBlock(
                        out segment.m_blockEndRight, 
                        ref randomizer, 
                        position6, 
                        angle4, 
                        num12, 
                        segment.m_buildIndex + 1u);
                }
            }
        }
Exemplo n.º 26
0
        public string ExportSegment(NetSegment a_seg, ref int segId, ref System.Reflection.PropertyInfo[] properties)
        {
            var startNodeId    = a_seg.m_startNode;
            var endNodeId      = a_seg.m_endNode;
            var startDirection = a_seg.m_startDirection;
            var endDirection   = a_seg.m_endDirection;

            if ((a_seg.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
            {
                startNodeId    = a_seg.m_endNode;
                endNodeId      = a_seg.m_startNode;
                startDirection = a_seg.m_endDirection;
                endDirection   = a_seg.m_startDirection;
            }

            var road_name = net_manager.GetSegmentName((ushort)segId);

            if (road_name == null || road_name == "")
            {
                road_name = "no name " + segId.ToString();
            }

            var    startPos   = net_manager.m_nodes.m_buffer[startNodeId].m_position;
            LatLng startRwoLL = GamePosition2LatLng(startPos);

            var    endPos   = net_manager.m_nodes.m_buffer[endNodeId].m_position;
            LatLng endRwoLL = GamePosition2LatLng(endPos);

            string wkt = "";

            if (Vector3.Angle(startDirection, -endDirection) > 3f)
            {
                Vector3 a = Vector3.zero;
                Vector3 b = Vector3.zero;
                NetSegment.CalculateMiddlePoints(startPos, startDirection, endPos, endDirection, false, false, out a, out b);
                var bezier = new Bezier3(startPos, a, b, endPos);

                var p1      = bezier.Position(0.25f);
                var p1RwoLL = GamePosition2LatLng(p1);
                var p2      = bezier.Position(0.5f);
                var p2RwoLL = GamePosition2LatLng(p2);
                var p3      = bezier.Position(0.5f);
                var p3RwoLL = GamePosition2LatLng(p3);

                LatLng[] listOfPositions = new LatLng[] { startRwoLL, p1RwoLL, p2RwoLL, p3RwoLL, endRwoLL };

                wkt = CreateWkt(listOfPositions);
            }
            else
            {
                wkt = CreateWkt(new LatLng[] { startRwoLL, endRwoLL });
            }

            float tmpY  = tm.SampleRawHeightSmoothWithWater(startPos, false, 0f);
            float elevS = startPos.y - tmpY;

            tmpY = tm.SampleRawHeightSmoothWithWater(endPos, false, 0f);
            float elevE = endPos.y - tmpY;

            string rowTxt = string.Format("{0},{1},{2},{3},{4}", segId, road_name, wkt, elevS, elevE);

            string field_info = "";

            foreach (var prop in properties)
            {
                var prop_val = prop.GetValue(a_seg, null);
                if (prop_val.ToString().Contains(","))
                {
                    prop_val = "\"" + prop_val.ToString() + "\"";
                }
                field_info += string.Format(",{0}", prop_val);
            }
            rowTxt += field_info;
            return(rowTxt);
        }
        void SetLaneMarkers()
        {
            m_hoveredLaneMarkers.Clear();
            if (m_segments.Count == 0)
            {
                return;
            }

            NetSegment segment    = NetManager.instance.m_segments.m_buffer[m_segments.Values.First().m_segmentId];
            NetInfo    info       = segment.Info;
            int        laneCount  = info.m_lanes.Length;
            bool       bothWays   = info.m_hasBackwardVehicleLanes && info.m_hasForwardVehicleLanes;
            bool       isInverted = false;

            for (ushort i = 0; i < laneCount; i++)
            {
                m_hoveredLaneMarkers[i] = new FastList <SegmentLaneMarker>();
            }

            foreach (Segment seg in m_segments.Values)
            {
                segment = NetManager.instance.m_segments.m_buffer[seg.m_segmentId];
                uint laneId = segment.m_lanes;

                if (bothWays)
                {
                    isInverted = seg.m_targetNode == segment.m_startNode;
                    if ((segment.m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.Invert)
                    {
                        isInverted = !isInverted;
                    }
                }

                for (int j = 0; j < laneCount && laneId != 0; j++)
                {
                    NetLane lane = NetManager.instance.m_lanes.m_buffer[laneId];

                    //if ((info.m_lanes[j].m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != NetInfo.LaneType.None)
                    if ((info.m_lanes[j].m_laneType & NetInfo.LaneType.Vehicle) == NetInfo.LaneType.Vehicle)
                    {
                        Bezier3 bezier = lane.m_bezier;
                        bezier.GetBounds().Expand(1f);

                        int index = j;
                        if (bothWays && isInverted)
                        {
                            index += (j % 2 == 0) ? 1 : -1;
                        }

                        m_hoveredLaneMarkers[index].Add(new SegmentLaneMarker()
                        {
                            m_bezier    = bezier,
                            m_lane      = laneId,
                            m_laneIndex = index
                        });
                    }

                    laneId = lane.m_nextLane;
                }
            }
        }
Exemplo n.º 28
0
        public void PopulateGroupData(ushort segmentID, int groupX, int groupZ, int layer, ref int vertexIndex, ref int triangleIndex, Vector3 groupPosition, RenderGroup.MeshData data, ref Vector3 min, ref Vector3 max, ref float maxRenderDistance, ref float maxInstanceDistance, ref bool requireSurfaceMaps)
        {
            bool       hasProps = false;
            NetInfo    info     = Info;
            NetManager instance = Singleton <NetManager> .instance;

            if (m_problems != Notification.Problem.None && layer == Singleton <NotificationManager> .instance.m_notificationLayer)
            {
                Vector3 middlePosition = m_middlePosition;
                middlePosition.y += info.m_maxHeight;
                Notification.PopulateGroupData(m_problems, middlePosition, 1f, groupX, groupZ, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance);
            }
            if (info.m_hasForwardVehicleLanes != info.m_hasBackwardVehicleLanes && layer == Singleton <NetManager> .instance.m_arrowLayer)
            {
                Bezier3 bezier = default(Bezier3);
                bezier.a = Singleton <NetManager> .instance.m_nodes.m_buffer[m_startNode].m_position;
                bezier.d = Singleton <NetManager> .instance.m_nodes.m_buffer[m_endNode].m_position;
                CalculateMiddlePoints(bezier.a, m_startDirection, bezier.d, m_endDirection, smoothStart: true, smoothEnd: true, out bezier.b, out bezier.c);
                Vector3 pos = bezier.Position(0.5f);
                pos.y += info.m_netAI.GetSnapElevation();
                Vector3 vector = VectorUtils.NormalizeXZ(bezier.Tangent(0.5f)) * (4f + info.m_halfWidth * 0.5f);
                if ((m_flags & Flags.Invert) != 0 == info.m_hasForwardVehicleLanes)
                {
                    vector = -vector;
                }
                PopulateArrowGroupData(pos, vector, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance);
            }
            if (info.m_lanes != null)
            {
                bool          invert;
                NetNode.Flags flags;
                NetNode.Flags flags2;
                if ((m_flags & Flags.Invert) != 0)
                {
                    invert = true;
                    instance.m_nodes.m_buffer[m_endNode].Info.m_netAI.GetNodeFlags(m_endNode, ref instance.m_nodes.m_buffer[m_endNode], segmentID, ref this, out flags);
                    instance.m_nodes.m_buffer[m_startNode].Info.m_netAI.GetNodeFlags(m_startNode, ref instance.m_nodes.m_buffer[m_startNode], segmentID, ref this, out flags2);
                }
                else
                {
                    invert = false;
                    instance.m_nodes.m_buffer[m_startNode].Info.m_netAI.GetNodeFlags(m_startNode, ref instance.m_nodes.m_buffer[m_startNode], segmentID, ref this, out flags);
                    instance.m_nodes.m_buffer[m_endNode].Info.m_netAI.GetNodeFlags(m_endNode, ref instance.m_nodes.m_buffer[m_endNode], segmentID, ref this, out flags2);
                }
                bool  terrainHeight = info.m_segments == null || info.m_segments.Length == 0;
                float startAngle    = (float)(int)m_cornerAngleStart * ((float)Math.PI / 128f);
                float endAngle      = (float)(int)m_cornerAngleEnd * ((float)Math.PI / 128f);
                bool  destroyed     = (m_flags & Flags.Collapsed) != 0;
                uint  num           = m_lanes;
                for (int i = 0; i < info.m_lanes.Length; i++)
                {
                    if (num == 0)
                    {
                        break;
                    }
                    instance.m_lanes.m_buffer[num].PopulateGroupData(segmentID, num, info.m_lanes[i], destroyed, flags, flags2, startAngle, endAngle, invert, terrainHeight, layer, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance, ref hasProps);
                    num = instance.m_lanes.m_buffer[num].m_nextLane;
                }
            }
            if ((info.m_netLayers & (1 << layer)) == 0)
            {
                return;
            }
            bool flag = info.m_segments != null && info.m_segments.Length != 0;

            if (!flag && !hasProps)
            {
                return;
            }
            min = Vector3.Min(min, m_bounds.min);
            max = Vector3.Max(max, m_bounds.max);
            maxRenderDistance   = Mathf.Max(maxRenderDistance, 30000f);
            maxInstanceDistance = Mathf.Max(maxInstanceDistance, 1000f);
            if (!flag)
            {
                return;
            }
            float vScale = info.m_netAI.GetVScale();

            CalculateCorner(segmentID, heightOffset: true, start: true, leftSide: true, out var cornerPosSL, out var cornerDirectionSL, out var smoothStart);
            CalculateCorner(segmentID, heightOffset: true, start: false, leftSide: true, out var cornerPosEL, out var cornerDirectionEL, out var smoothEnd);
            CalculateCorner(segmentID, heightOffset: true, start: true, leftSide: false, out var cornerPosSR, out var cornerDirectionSR, out smoothStart);
            CalculateCorner(segmentID, heightOffset: true, start: false, leftSide: false, out var cornerPosER, out var cornerDirectionER, out smoothEnd);
            CalculateMiddlePoints(cornerPosSL, cornerDirectionSL, cornerPosER, cornerDirectionER, smoothStart, smoothEnd, out var b1, out var c1);
            CalculateMiddlePoints(cornerPosSR, cornerDirectionSR, cornerPosEL, cornerDirectionEL, smoothStart, smoothEnd, out var b2, out var c2);
            Vector3 position           = instance.m_nodes.m_buffer[m_startNode].m_position;
            Vector3 position2          = instance.m_nodes.m_buffer[m_endNode].m_position;
            Vector4 meshScale          = new Vector4(0.5f / info.m_halfWidth, 1f / info.m_segmentLength, 1f, 1f);
            Vector4 colorLocationStart = RenderManager.GetColorLocation((uint)(49152 + segmentID));
            Vector4 colorlocationEnd   = colorLocationStart;

            if (NetNode.BlendJunction(m_startNode))
            {
                colorLocationStart = RenderManager.GetColorLocation((uint)(86016 + m_startNode));
            }
            if (NetNode.BlendJunction(m_endNode))
            {
                colorlocationEnd = RenderManager.GetColorLocation((uint)(86016 + m_endNode));
            }
            Vector4 objectIndex0 = new Vector4(colorLocationStart.x, colorLocationStart.y, colorlocationEnd.x, colorlocationEnd.y);

            for (int j = 0; j < info.m_segments.Length; j++)
            {
                NetInfo.Segment segment    = info.m_segments[j];
                bool            turnAround = false;
                if (segment.m_layer == layer && segment.CheckFlags(m_flags, out turnAround) && segment.m_combinedLod != null)
                {
                    Vector4 objectIndex = objectIndex0;
                    if (segment.m_requireWindSpeed)
                    {
                        objectIndex.w = Singleton <WeatherManager> .instance.GetWindSpeed((position + position2) * 0.5f);
                    }
                    else if (turnAround)
                    {
                        objectIndex = new Vector4(objectIndex.z, objectIndex.w, objectIndex.x, objectIndex.y);
                    }
                    Matrix4x4 leftMatrix;
                    Matrix4x4 rightMatrix;
                    if (turnAround)
                    {
                        leftMatrix  = CalculateControlMatrix(cornerPosEL, c2, b2, cornerPosSR, cornerPosER, c1, b1, cornerPosSL, groupPosition, vScale);
                        rightMatrix = CalculateControlMatrix(cornerPosER, c1, b1, cornerPosSL, cornerPosEL, c2, b2, cornerPosSR, groupPosition, vScale);
                    }
                    else
                    {
                        leftMatrix  = CalculateControlMatrix(cornerPosSL, b1, c1, cornerPosER, cornerPosSR, b2, c2, cornerPosEL, groupPosition, vScale);
                        rightMatrix = CalculateControlMatrix(cornerPosSR, b2, c2, cornerPosEL, cornerPosSL, b1, c1, cornerPosER, groupPosition, vScale);
                    }
                    PopulateGroupData(info, segment, leftMatrix, rightMatrix, meshScale, objectIndex, ref vertexIndex, ref triangleIndex, groupPosition, data, ref requireSurfaceMaps);
                }
            }
        }
Exemplo n.º 29
0
        public void CustomCheckNextLane(ushort vehicleID, ref Vehicle vehicleData, ref float maxSpeed, PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID, byte prevOffset, Bezier3 bezier)
        {
            if ((Options.prioritySignsEnabled || Options.timedLightsEnabled) && Options.simAccuracy <= 1)
            {
                try {
                    VehicleStateManager.Instance().UpdateVehiclePos(vehicleID, ref vehicleData, ref prevPos, ref position);
                } catch (Exception e) {
                    Log.Error("TrainAI CustomCheckNextLane Error: " + e.ToString());
                }
            }

            NetManager instance = Singleton <NetManager> .instance;

            Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
            Vector3       a             = lastFrameData.m_position;
            Vector3       a2            = lastFrameData.m_position;
            Vector3       b             = lastFrameData.m_rotation * new Vector3(0f, 0f, this.m_info.m_generatedInfo.m_wheelBase * 0.5f);

            a  += b;
            a2 -= b;
            float num = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking;
            float a3  = Vector3.Distance(a, bezier.a);
            float b2  = Vector3.Distance(a2, bezier.a);

            if (Mathf.Min(a3, b2) >= num - 5f)
            {
                if (!instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(1000f, vehicleID))
                {
                    maxSpeed = 0f;
                    return;
                }
                Vector3  vector = bezier.Position(0.5f);
                Segment3 segment;
                if (Vector3.SqrMagnitude(vehicleData.m_segment.a - vector) < Vector3.SqrMagnitude(bezier.a - vector))
                {
                    segment = new Segment3(vehicleData.m_segment.a, vector);
                }
                else
                {
                    segment = new Segment3(bezier.a, vector);
                }
                if (segment.LengthSqr() >= 3f)
                {
                    segment.a += (segment.b - segment.a).normalized * 2.5f;
                    if (CustomTrainAI.CheckOverlap(vehicleID, ref vehicleData, segment, vehicleID))
                    {
                        maxSpeed = 0f;
                        return;
                    }
                }
                segment = new Segment3(vector, bezier.d);
                if (segment.LengthSqr() >= 1f && CustomTrainAI.CheckOverlap(vehicleID, ref vehicleData, segment, vehicleID))
                {
                    maxSpeed = 0f;
                    return;
                }
                ushort targetNodeId;
                if (offset < position.m_offset)
                {
                    targetNodeId = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                }
                else
                {
                    targetNodeId = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                }
                ushort prevTargetNodeId;
                if (prevOffset == 0)
                {
                    prevTargetNodeId = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode;
                }
                else
                {
                    prevTargetNodeId = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode;
                }
                if (targetNodeId == prevTargetNodeId)
                {
                    float oldMaxSpeed = maxSpeed;
#if DEBUG
                    bool debug = false;                    // targetNodeId == 14527 || targetNodeId == 15048;
                    if (debug)
                    {
                        Log._Debug($"Train {vehicleID} wants to change segment. seg. {prevPos.m_segment} -> node {targetNodeId} -> seg. {position.m_segment}");
                    }
#else
                    bool debug = false;
#endif
                    bool mayChange = CustomVehicleAI.MayChangeSegment(vehicleID, ref vehicleData, ref lastFrameData, false, ref prevPos, prevTargetNodeId, prevLaneID, ref position, targetNodeId, laneID, out maxSpeed, debug);
                    if (!mayChange)
                    {
                        return;
                    }
                    maxSpeed = oldMaxSpeed;
                }
            }
        }
        public static bool NetSegmentRayCastMasked(NetSegment mysegment, ushort segmentID, Segment3 ray, float snapElevation, bool bothSides, out float t, out float priority)
        {
            bool lht = false;

            //if (SimulationManager.instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True) lht = true;
            //Debug.Log(mysegment.m_flags);
            if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
            {
                lht = true;
            }
            bool    isMasked = false;
            NetInfo info     = mysegment.Info;

            t        = 0f;
            priority = 0f;
            Bounds bounds = mysegment.m_bounds;

            bounds.Expand(16f);
            if (!bounds.IntersectRay(new Ray(ray.a, ray.b - ray.a)))
            {
                return(false);
            }
            NetManager instance = Singleton <NetManager> .instance;
            Bezier3    bezier   = default(Bezier3);

            bezier.a = instance.m_nodes.m_buffer[mysegment.m_startNode].m_position;
            bezier.d = instance.m_nodes.m_buffer[mysegment.m_endNode].m_position;
            bool result = false;

            info.m_netAI.GetRayCastHeights(segmentID, ref mysegment, out float leftMin, out float rightMin, out float max);
            bezier.a.y += max;
            bezier.d.y += max;
            bool flag  = (instance.m_nodes.m_buffer[mysegment.m_startNode].m_flags & NetNode.Flags.Middle) != 0;
            bool flag2 = (instance.m_nodes.m_buffer[mysegment.m_endNode].m_flags & NetNode.Flags.Middle) != 0;

            NetSegment.CalculateMiddlePoints(bezier.a, mysegment.m_startDirection, bezier.d, mysegment.m_endDirection, flag, flag2, out bezier.b, out bezier.c);
            float minNodeDistance = info.GetMinNodeDistance();
            //
            float collisionHalfWidth = info.m_halfWidth;
            float maskHalfWidth      = info.m_pavementWidth;
            //
            float num4 = (int)instance.m_nodes.m_buffer[mysegment.m_startNode].m_elevation;
            float num5 = (int)instance.m_nodes.m_buffer[mysegment.m_endNode].m_elevation;

            if (info.m_netAI.IsUnderground())
            {
                num4 = 0f - num4;
                num5 = 0f - num5;
            }
            num4 += info.m_netAI.GetSnapElevation();
            num5 += info.m_netAI.GetSnapElevation();
            float a    = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num4) / 12f));
            float b2   = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num5) / 12f));
            float am   = Mathf.Lerp(minNodeDistance, maskHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num4) / 12f));
            float b2m  = Mathf.Lerp(minNodeDistance, maskHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num5) / 12f));
            float num6 = Mathf.Min(leftMin, rightMin);

            t        = 1000000f;
            priority = 1000000f;
            Segment3 segment = default(Segment3);

            segment.a = bezier.a;
            Segment2 segment2 = default(Segment2);

            //Debug.Log($"mouse ray: {ray.a} --> {ray.b}");
            //Debug.Log($"segment direction: {bezier.a} --> {bezier.b}");
            for (int i = 1; i <= 16; i++)
            {
                segment.b = bezier.Position((float)i / 16f);
                float   num7         = ray.DistanceSqr(segment, out float u2, out float v2);
                float   num8         = Mathf.Lerp(a, b2, ((float)(i - 1) + v2) / 16f);
                float   num8m        = Mathf.Lerp(am, b2m, ((float)(i - 1) + v2) / 16f);
                Vector3 vector2      = segment.Position(v2);
                bool    atOffsetSide = bothSides || IsTrafficHandSideOf(segment, ray, u2, lht);
                if (atOffsetSide && num7 < priority && Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2))
                {
                    Vector3 vector3 = ray.Position(u2);
                    num7 = Vector3.SqrMagnitude(vector3 - vector2);
                    //Debug.Log($"num7: {num7}, num8: {num8}, num8m: {num8m}");
                    if (num7 < priority && num7 < num8 * num8)
                    {
                        if (flag && i == 1 && v2 < 0.001f)
                        {
                            Vector3 rhs = segment.a - segment.b;
                            u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs.sqrMagnitude * ray.LengthSqr()));
                        }
                        if (flag2 && i == 16 && v2 > 0.999f)
                        {
                            Vector3 rhs2 = segment.b - segment.a;
                            u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs2)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs2.sqrMagnitude * ray.LengthSqr()));
                        }
                        priority = num7;
                        t        = u2;
                        result   = true;
                        if (num7 < num8m * num8m)
                        {
                            isMasked = true;
                        }
                    }
                }
                if (atOffsetSide && num6 < max)
                {
                    float num9 = vector2.y + num6 - max;
                    if (Mathf.Max(ray.a.y, ray.b.y) > num9 && Mathf.Min(ray.a.y, ray.b.y) < vector2.y)
                    {
                        float num10;
                        if (Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2))
                        {
                            segment2.a = VectorUtils.XZ(ray.Position(u2));
                            num10      = u2;
                        }
                        else
                        {
                            segment2.a = VectorUtils.XZ(ray.a);
                            num10      = 0f;
                        }
                        float num11;
                        if (Segment1.Intersect(ray.a.y, ray.b.y, num9, out u2))
                        {
                            segment2.b = VectorUtils.XZ(ray.Position(u2));
                            num11      = u2;
                        }
                        else
                        {
                            segment2.b = VectorUtils.XZ(ray.b);
                            num11      = 1f;
                        }
                        num7 = segment2.DistanceSqr(VectorUtils.XZ(vector2), out u2);
                        if (num7 < priority && num7 < num8 * num8)
                        {
                            u2 = num10 + (num11 - num10) * u2;
                            Vector3 lhs = ray.Position(u2);
                            if (flag && i == 1 && v2 < 0.001f)
                            {
                                Vector3 rhs3 = segment.a - segment.b;
                                u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs3)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs3.sqrMagnitude * ray.LengthSqr()));
                            }
                            if (flag2 && i == 16 && v2 > 0.999f)
                            {
                                Vector3 rhs4 = segment.b - segment.a;
                                u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs4)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs4.sqrMagnitude * ray.LengthSqr()));
                            }
                            priority = num7;
                            t        = u2;
                            result   = true;
                            if (num7 < num8m * num8m)
                            {
                                isMasked = true;
                            }
                        }
                    }
                }
                segment.a = segment.b;
            }
            priority = Mathf.Max(0f, Mathf.Sqrt(priority) - collisionHalfWidth);

            if (isMasked)
            {
                result = false;
            }
            return(result);
        }
        public static bool Prefix(ref NetSegment __instance, ushort segmentID, Quad2 quad, float minY, float maxY, ItemClass.CollisionType collisionType)
        {
            if ((__instance.m_flags & (NetSegment.Flags.Created | NetSegment.Flags.Deleted)) != NetSegment.Flags.Created)
            {
                return(false);
            }
            NetInfo info = __instance.Info;

            if (!info.m_canCollide)
            {
                return(false);
            }
            float   collisionHalfWidth = info.m_netAI.GetCollisionHalfWidth();
            Vector2 vector             = quad.Min();
            Vector2 vector2            = quad.Max();
            Bezier3 bezier             = default(Bezier3);

            bezier.a = Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].m_position;
            bezier.d = Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].m_position;
            // NON-STOCK CODE STARTS
            if (CSURUtil.IsCSUROffset(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info))
            {
                var     width     = (Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info.m_halfWidth + Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info.m_pavementWidth) / 2f;
                bool    lht       = false;
                Vector3 direction = __instance.m_startDirection;
                if ((__instance.m_flags & NetSegment.Flags.Invert) != 0)
                {
                    lht = true;
                }
                // normal to the right hand side
                Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                bezier.a = bezier.a + (lht ? -width : width) * normal;
            }
            if (CSURUtil.IsCSUROffset(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].Info))
            {
                bool    lht       = false;
                var     width     = (Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].Info.m_halfWidth + Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].Info.m_pavementWidth) / 2f;
                Vector3 direction = -__instance.m_endDirection;
                if ((__instance.m_flags & NetSegment.Flags.Invert) != 0)
                {
                    lht = true;
                }
                // normal to the right hand side
                Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                bezier.d = bezier.d + (lht ? -width : width) * normal;
            }
            // NON-STOCK CODE ENDS
            NetSegment.CalculateMiddlePoints(bezier.a, __instance.m_startDirection, bezier.d, __instance.m_endDirection, true, true, out bezier.b, out bezier.c);
            // NON-STOCK CODE STARTS
            float   laneOffsetS  = 0;
            float   startOffsetS = 0;
            float   endOffsetS   = 0;
            bool    IsCSURSLaneS = CSURUtil.IsCSURSLane(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info, ref laneOffsetS, ref startOffsetS, ref endOffsetS);
            float   laneOffsetE  = 0;
            float   startOffsetE = 0;
            float   endOffsetE   = 0;
            bool    IsCSURSLaneE = CSURUtil.IsCSURSLane(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].Info, ref laneOffsetE, ref startOffsetE, ref endOffsetE);
            Vector3 newBezierA1  = Vector3.zero;
            Vector3 newBezierB1  = Vector3.zero;
            Vector3 newBezierC1  = Vector3.zero;
            Vector3 newBezierD1  = Vector3.zero;

            if (IsCSURSLaneS || IsCSURSLaneE)
            {
                float vehicleLaneNum = CSURUtil.CountCSURSVehicleLanes(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info);
                float otherLaneNum   = CSURUtil.CountCSURSOtherLanes(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info);
                float laneNum        = vehicleLaneNum + otherLaneNum;
                startOffsetS = startOffsetS * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                endOffsetE   = endOffsetE * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                if ((__instance.m_flags & NetSegment.Flags.Invert) != 0)
                {
                    startOffsetS = -startOffsetS;
                    endOffsetE   = -endOffsetE;
                }

                if (!IsCSURSLaneS)
                {
                    startOffsetS = 0;
                }
                if (!IsCSURSLaneE)
                {
                    endOffsetE = 0;
                }
                //EG: before patch: point1-point4 is 1.5*3.75
                //After patch, point1-point4 is (1 1.3333 1.6667 2)*3.75
                newBezierA1 = bezier.a + (new Vector3(__instance.m_startDirection.z, 0, -__instance.m_startDirection.x).normalized) * (startOffsetS);
                Vector3 newBezierBDir = VectorUtils.NormalizeXZ(bezier.Tangent(0.333f));
                newBezierB1 = bezier.b + (new Vector3(newBezierBDir.z, 0, -newBezierBDir.x).normalized) * (startOffsetS * 0.667f + endOffsetE * 0.333f);
                Vector3 newBezierCDir = VectorUtils.NormalizeXZ(bezier.Tangent(0.667f));
                newBezierC1 = bezier.c + (new Vector3(newBezierCDir.z, 0, -newBezierCDir.x).normalized) * (startOffsetS * 0.333f + endOffsetE * 0.667f);
                newBezierD1 = bezier.d + (new Vector3(-__instance.m_endDirection.z, 0, __instance.m_endDirection.x).normalized) * (endOffsetE);

                bezier.a = newBezierA1;
                bezier.b = newBezierB1;
                bezier.c = newBezierC1;
                bezier.d = newBezierD1;
            }
            // NON-STOCK CODE ENDS

            Vector3 vector3 = bezier.Min() + new Vector3(0f - collisionHalfWidth, info.m_minHeight, 0f - collisionHalfWidth);
            Vector3 vector4 = bezier.Max() + new Vector3(collisionHalfWidth, info.m_maxHeight, collisionHalfWidth);

            ItemClass.CollisionType collisionType2 = info.m_netAI.GetCollisionType();
            if (vector3.x <= vector2.x && vector3.z <= vector2.y && vector.x <= vector4.x && vector.y <= vector4.z && ItemClass.CheckCollisionType(minY, maxY, vector3.y, vector4.y, collisionType, collisionType2))
            {
                int num = 16;
                info.m_netAI.GetTerrainModifyRange(out float start, out float end);
                start *= 0.5f;
                end    = 1f - (1f - end) * 0.5f;
                float   t       = start;
                Vector3 vector5 = bezier.Position(t);
                Vector3 vector6 = bezier.Tangent(t);
                vector6 = new Vector3(0f - vector6.z, 0f, vector6.x).normalized *collisionHalfWidth;
                Vector3 a         = vector5 + vector6;
                Vector3 vector7   = vector5 - vector6;
                float   endRadius = info.m_netAI.GetEndRadius();
                if (info.m_clipSegmentEnds && endRadius != 0f && start == 0f && (Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].m_flags & (NetNode.Flags.End | NetNode.Flags.Bend | NetNode.Flags.Junction)) != 0)
                {
                    Vector3 vector8 = vector5;
                    vector8.x += vector6.x * 0.8f - vector6.z * 0.6f * endRadius / collisionHalfWidth;
                    vector8.z += vector6.z * 0.8f + vector6.x * 0.6f * endRadius / collisionHalfWidth;
                    Vector3 vector9 = vector5;
                    vector9.x -= vector6.x * 0.8f + vector6.z * 0.6f * endRadius / collisionHalfWidth;
                    vector9.z -= vector6.z * 0.8f - vector6.x * 0.6f * endRadius / collisionHalfWidth;
                    Vector3 d = vector5;
                    d.x += vector6.x * 0.3f - vector6.z * endRadius / collisionHalfWidth;
                    d.z += vector6.z * 0.3f + vector6.x * endRadius / collisionHalfWidth;
                    Vector3 c = vector5;
                    c.x      -= vector6.x * 0.3f + vector6.z * endRadius / collisionHalfWidth;
                    c.z      -= vector6.z * 0.3f - vector6.x * endRadius / collisionHalfWidth;
                    vector3.y = vector5.y + info.m_minHeight;
                    vector4.y = vector5.y + info.m_maxHeight;
                    if (ItemClass.CheckCollisionType(minY, maxY, vector3.y, vector4.y, collisionType, collisionType2))
                    {
                        if (quad.Intersect(Quad2.XZ(a, vector7, vector9, vector8)))
                        {
                            return(true);
                        }
                        if (quad.Intersect(Quad2.XZ(vector8, vector9, c, d)))
                        {
                            return(true);
                        }
                    }
                }
                for (int i = 1; i <= num; i++)
                {
                    t       = start + (end - start) * (float)i / (float)num;
                    vector5 = bezier.Position(t);
                    vector6 = bezier.Tangent(t);
                    vector6 = new Vector3(0f - vector6.z, 0f, vector6.x).normalized *collisionHalfWidth;
                    Vector3 vector10 = vector5 + vector6;
                    Vector3 vector11 = vector5 - vector6;
                    vector3.y = Mathf.Min(Mathf.Min(a.y, vector10.y), Mathf.Min(vector11.y, vector7.y)) + info.m_minHeight;
                    vector4.y = Mathf.Max(Mathf.Max(a.y, vector10.y), Mathf.Max(vector11.y, vector7.y)) + info.m_maxHeight;
                    if (ItemClass.CheckCollisionType(minY, maxY, vector3.y, vector4.y, collisionType, collisionType2) && quad.Intersect(Quad2.XZ(a, vector10, vector11, vector7)))
                    {
                        return(true);
                    }
                    a       = vector10;
                    vector7 = vector11;
                }
                if (info.m_clipSegmentEnds && endRadius != 0f && end == 1f && (Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].m_flags & (NetNode.Flags.End | NetNode.Flags.Bend | NetNode.Flags.Junction)) != 0)
                {
                    Vector3 vector12 = vector5;
                    vector12.x += vector6.x * 0.8f + vector6.z * 0.6f * endRadius / collisionHalfWidth;
                    vector12.z += vector6.z * 0.8f - vector6.x * 0.6f * endRadius / collisionHalfWidth;
                    Vector3 vector13 = vector5;
                    vector13.x -= vector6.x * 0.8f - vector6.z * 0.6f * endRadius / collisionHalfWidth;
                    vector13.z -= vector6.z * 0.8f + vector6.x * 0.6f * endRadius / collisionHalfWidth;
                    Vector3 b = vector5;
                    b.x += vector6.x * 0.3f + vector6.z * endRadius / collisionHalfWidth;
                    b.z += vector6.z * 0.3f - vector6.x * endRadius / collisionHalfWidth;
                    Vector3 c2 = vector5;
                    c2.x     -= vector6.x * 0.3f - vector6.z * endRadius / collisionHalfWidth;
                    c2.z     -= vector6.z * 0.3f + vector6.x * endRadius / collisionHalfWidth;
                    vector3.y = vector5.y + info.m_minHeight;
                    vector4.y = vector5.y + info.m_maxHeight;
                    if (ItemClass.CheckCollisionType(minY, maxY, vector3.y, vector4.y, collisionType, collisionType2))
                    {
                        if (quad.Intersect(Quad2.XZ(a, vector12, vector13, vector7)))
                        {
                            return(true);
                        }
                        if (quad.Intersect(Quad2.XZ(vector12, b, c2, vector13)))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Exemplo n.º 32
0
 public abstract IEnumerable <MarkupStyleDash> Calculate(Bezier3 trajectory);
Exemplo n.º 33
0
 public static float DeltaAngle(this Bezier3 bezier) => 180 - Vector3.Angle(bezier.b - bezier.a, bezier.c - bezier.d);
Exemplo n.º 34
0
 public BezierTrajectory(Bezier3 trajectory)
 {
     Trajectory = trajectory;
 }
Exemplo n.º 35
0
        private bool TrySnapNodeDirections(ushort node, Vector3 newPosition, Vector3 moveDelta, out Vector3 newMoveDelta, out bool autoCurve)
        {
            string snapType = "";

            m_segmentGuide = default;

            NetManager netManager = NetManager.instance;

            NetSegment[] segmentBuffer = netManager.m_segments.m_buffer;
            NetNode[]    nodeBuffer    = netManager.m_nodes.m_buffer;

            float minSqDistance = nodeBuffer[node].Info.GetMinNodeDistance() / 2f;

            minSqDistance *= minSqDistance;

            autoCurve    = false;
            newMoveDelta = moveDelta;
            float distanceSq = minSqDistance;

            bool snap = false;

            // Snap to curve
            for (int i = 0; i < 8; i++)
            {
                ushort segmentA = nodeBuffer[node].GetSegment(i);
                if (segmentA != 0)
                {
                    for (int j = i + 1; j < 8; j++)
                    {
                        ushort segmentB = nodeBuffer[node].GetSegment(j);

                        if (segmentB != 0 && segmentB != segmentA)
                        {
                            NetSegment segment = default;
                            segment.m_startNode = segmentBuffer[segmentA].m_startNode == node ? segmentBuffer[segmentA].m_endNode : segmentBuffer[segmentA].m_startNode;
                            segment.m_endNode   = segmentBuffer[segmentB].m_startNode == node ? segmentBuffer[segmentB].m_endNode : segmentBuffer[segmentB].m_startNode;

                            segment.m_startDirection = (nodeBuffer[segment.m_endNode].m_position - nodeBuffer[segment.m_startNode].m_position).normalized;
                            segment.m_endDirection   = -segment.m_startDirection;

                            segment.GetClosestPositionAndDirection(newPosition, out Vector3 testPos, out Vector3 direction);
                            // Straight
                            if (TrySnapping(testPos, newPosition, minSqDistance, ref distanceSq, moveDelta, ref newMoveDelta))
                            {
                                autoCurve      = true;
                                m_segmentGuide = segment;
                                snapType       = "Straight";
                                snap           = true;
                            }

                            for (int k = 0; k < 8; k++)
                            {
                                ushort segmentC = nodeBuffer[segment.m_startNode].GetSegment(k);
                                if (segmentC != 0 && segmentC != segmentA)
                                {
                                    for (int l = 0; l < 8; l++)
                                    {
                                        ushort segmentD = nodeBuffer[segment.m_endNode].GetSegment(l);

                                        if (segmentD != 0 && segmentD != segmentB)
                                        {
                                            segment.m_startDirection = segmentBuffer[segmentC].m_startNode == segment.m_startNode ? -segmentBuffer[segmentC].m_startDirection : -segmentBuffer[segmentC].m_endDirection;
                                            segment.m_endDirection   = segmentBuffer[segmentD].m_startNode == segment.m_endNode ? -segmentBuffer[segmentD].m_startDirection : -segmentBuffer[segmentD].m_endDirection;

                                            Vector2 A     = VectorUtils.XZ(nodeBuffer[segment.m_endNode].m_position - nodeBuffer[segment.m_startNode].m_position).normalized;
                                            Vector2 B     = VectorUtils.XZ(segment.m_startDirection);
                                            float   side1 = A.x * B.y - A.y * B.x;

                                            B = VectorUtils.XZ(segment.m_endDirection);
                                            float side2 = A.x * B.y - A.y * B.x;

                                            if (Mathf.Sign(side1) != Mathf.Sign(side2) ||
                                                (side1 != side2 && (side1 == 0 || side2 == 0)) ||
                                                Vector2.Dot(A, VectorUtils.XZ(segment.m_startDirection)) < 0 ||
                                                Vector2.Dot(A, VectorUtils.XZ(segment.m_endDirection)) > 0)
                                            {
                                                continue;
                                            }

                                            Bezier3 bezier = default;
                                            bezier.a = Singleton <NetManager> .instance.m_nodes.m_buffer[segment.m_startNode].m_position;
                                            bezier.d = Singleton <NetManager> .instance.m_nodes.m_buffer[segment.m_endNode].m_position;
                                            bool smoothStart = (Singleton <NetManager> .instance.m_nodes.m_buffer[segment.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
                                            bool smoothEnd   = (Singleton <NetManager> .instance.m_nodes.m_buffer[segment.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
                                            NetSegment.CalculateMiddlePoints(bezier.a, segment.m_startDirection, bezier.d, segment.m_endDirection, smoothStart, smoothEnd, out bezier.b, out bezier.c);

                                            testPos = bezier.Position(0.5f);
                                            // Curve Middle
                                            if (TrySnapping(testPos, newPosition, minSqDistance, ref distanceSq, moveDelta, ref newMoveDelta))
                                            {
                                                autoCurve      = true;
                                                m_segmentGuide = segment;
                                                snapType       = "Curve Middle";
                                                snap           = true;
                                            }
                                            else
                                            {
                                                segment.GetClosestPositionAndDirection(newPosition, out testPos, out direction);
                                                // Curve
                                                if (TrySnapping(testPos, newPosition, minSqDistance, ref distanceSq, moveDelta, ref newMoveDelta))
                                                {
                                                    autoCurve      = true;
                                                    m_segmentGuide = segment;
                                                    snapType       = "Curve";
                                                    snap           = true;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Snap to tangent
            for (int i = 0; i < 8; i++)
            {
                ushort segment = nodeBuffer[node].GetSegment(i);
                if (segment != 0)
                {
                    ushort  testNode = segmentBuffer[segment].m_startNode == node ? segmentBuffer[segment].m_endNode : segmentBuffer[segment].m_startNode;
                    Vector3 testPos  = nodeBuffer[testNode].m_position;

                    for (int j = 0; j < 8; j++)
                    {
                        ushort segmentA = nodeBuffer[testNode].GetSegment(j);
                        if (segmentA != 0 && segmentA != segment)
                        {
                            // Straight
                            Vector3 startDir = segmentBuffer[segmentA].m_startNode == testNode ? segmentBuffer[segmentA].m_startDirection : segmentBuffer[segmentA].m_endDirection;
                            Vector3 offset   = Line2.Offset(startDir, testPos - newPosition);
                            offset = newPosition + offset - testPos;
                            float num = offset.x * startDir.x + offset.z * startDir.z;

                            if (TrySnapping(testPos + startDir * num, newPosition, minSqDistance, ref distanceSq, moveDelta, ref newMoveDelta))
                            {
                                m_segmentGuide = default;

                                m_segmentGuide.m_startNode = node;
                                m_segmentGuide.m_endNode   = testNode;

                                m_segmentGuide.m_startDirection = startDir;
                                m_segmentGuide.m_endDirection   = -startDir;
                                snapType  = "Tangent Straight";
                                autoCurve = false;
                                snap      = true;
                            }
                            else
                            {
                                // 90°
                                startDir = new Vector3(-startDir.z, startDir.y, startDir.x);
                                offset   = Line2.Offset(startDir, testPos - newPosition);
                                offset   = newPosition + offset - testPos;
                                num      = offset.x * startDir.x + offset.z * startDir.z;

                                if (TrySnapping(testPos + startDir * num, newPosition, minSqDistance, ref distanceSq, moveDelta, ref newMoveDelta))
                                {
                                    m_segmentGuide = default;

                                    m_segmentGuide.m_startNode = node;
                                    m_segmentGuide.m_endNode   = testNode;

                                    m_segmentGuide.m_startDirection = startDir;
                                    m_segmentGuide.m_endDirection   = -startDir;
                                    snapType  = "Tangent 90°";
                                    autoCurve = false;
                                    snap      = true;
                                }
                            }
                        }
                    }
                }
            }

            if (snap)
            {
                DebugUtils.Log("Snapping " + snapType + " " + autoCurve);
            }

            return(snap);
        }
Exemplo n.º 36
0
        private osmWay AddWay(int i, NetSegment netSegment)
        {
            var nm = Singleton<NetManager>.instance;
            if (netSegment.m_startNode == 0 || netSegment.m_endNode == 0)
            {
                return null;
            }
            var startNode = netSegment.m_startNode;
            var endNode = netSegment.m_endNode;
            var startDirection = netSegment.m_startDirection;
            var endDirection = netSegment.m_endDirection;

            if ((netSegment.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
            {
                startNode = netSegment.m_endNode;
                endNode = netSegment.m_startNode;
                startDirection = netSegment.m_endDirection;
                endDirection = netSegment.m_startDirection;
            }
            osmWayND[] nd;
            if (Vector3.Angle(startDirection, -endDirection) > 3f)
            {
                var start = nm.m_nodes.m_buffer[startNode].m_position;
                var end = nm.m_nodes.m_buffer[endNode].m_position;
                Vector3 a = Vector3.zero;
                Vector3 b = Vector3.zero;
                NetSegment.CalculateMiddlePoints(start, startDirection, end, endDirection, false, false, out a, out b);

                var bezier = new Bezier3(start, a, b, end);

                nd = new osmWayND[5];
                nd[0] = new osmWayND { @ref = startNode };
                nd[1] = new osmWayND { @ref = AddNode(bezier.Position(0.25f)) };
                nd[2] = new osmWayND { @ref = AddNode(bezier.Position(0.5f)) };
                nd[3] = new osmWayND { @ref = AddNode(bezier.Position(0.75f)) };
                nd[4] = new osmWayND { @ref = endNode };
            }
            else
            {
                nd = new osmWayND[2];
                nd[0] = new osmWayND { @ref = startNode };
                nd[1] = new osmWayND { @ref = endNode };
            }

            byte elevation = (byte)(Mathf.Clamp((nm.m_nodes.m_buffer[startNode].m_elevation + nm.m_nodes.m_buffer[endNode].m_elevation) / 2, 0, 255));
            var tags = new List<osmWayTag>();
            if (!mapping.GetTags(elevation, netSegment, tags))
            {
                return null;
            }
            return new osmWay { changeset = 50000000, id = (uint)i, timestamp = DateTime.Now, user = "******", version = 1, nd = nd, tag = tags.ToArray() };
        }
Exemplo n.º 37
0
 private static bool Intersect(List <MarkupIntersect> results, Bezier3 first, Bezier3 second, int fIdx = 0, int fOf = 1, int sIdx = 0, int sOf = 1)
 {
     CalcParts(first, out int fParts, out float[] fPoints, out Vector3[] fPos);
Exemplo n.º 38
0
 private List<Vector2> BezierToPoints(List<Segment> list)
 {
     var result = new List<Vector2>();
     result.Add(list[0].startPoint);
     foreach (var seg in list)
     {
         if (seg.controlA == Vector2.zero)
         {
             result.Add(seg.endPoint);
         }
         else
         {
             var bezier = new Bezier3(seg.startPoint,seg.controlA,seg.controlB,seg.endPoint);
             var steps = Mathf.RoundToInt((seg.endPoint - seg.startPoint).magnitude / 50) + 1;
             for (var i = 0; i <= steps; i += 1)
             {
                 if (i == 0)
                 {
                     continue;
                 }
                 result.Add(bezier.Position(i / (float)steps));
             }
         }
     }
     return result;
 }
Exemplo n.º 39
0
        private OSMWay CreateWay(int index, NetSegment segment, ushort segmentId)
        {
            OSMWay returnWay = null;
            NetSegment.Flags segmentFlags = segment.m_flags;
            NetManager netManager = Singleton<NetManager>.instance;
            List<OSMWayND> wayPaths = new List<OSMWayND>();
            List<OSMWayTag> wayTags;
            ushort startNodeId = segment.m_startNode, endNodeId = segment.m_endNode;

            if(startNodeId != 0 && endNodeId != 0)
            {
                Vector3 startNodeDirection = segment.m_startDirection;
                Vector3 endNodeDirection = segment.m_endDirection;

                if(segmentFlags.IsFlagSet(NetSegment.Flags.Invert))
                {
                    startNodeId = segment.m_endNode;
                    endNodeId = segment.m_startNode;
                    startNodeDirection = segment.m_endDirection;
                    endNodeDirection = segment.m_startDirection;
                }

                NetNode startNode = netManager.m_nodes.m_buffer[startNodeId];
                NetNode endNode = netManager.m_nodes.m_buffer[endNodeId];
                Vector3 startNodePosition = startNode.m_position;
                Vector3 endNodePosition = endNode.m_position;

                wayPaths.Add(new OSMWayND { @ref = startNodeId });

                if (Vector3.Angle(startNodeDirection, -endNodeDirection) > 3f)
                {
                    Vector3 midPointA = Vector3.zero, midPointB = Vector3.zero;
                    NetSegment.CalculateMiddlePoints(startNodePosition, startNodeDirection, endNodePosition, endNodeDirection, false, false, out midPointA, out midPointB);
                    Bezier3 bezier = new Bezier3(startNodePosition, midPointA, midPointB, endNodePosition);

                    osmNodes.Add(CreateNode(unindexedNodeOffset++, bezier.Position(0.25f)));
                    osmNodes.Add(CreateNode(unindexedNodeOffset++, bezier.Position(0.5f)));
                    osmNodes.Add(CreateNode(unindexedNodeOffset++, bezier.Position(0.75f)));

                    wayPaths.Add(new OSMWayND { @ref = (uint)unindexedNodeOffset - 3 });
                    wayPaths.Add(new OSMWayND { @ref = (uint)unindexedNodeOffset - 2 });
                    wayPaths.Add(new OSMWayND { @ref = (uint)unindexedNodeOffset - 1 });
                }

                wayPaths.Add(new OSMWayND { @ref = endNodeId });

                if(Tagger.CreateWayTags(segment, out wayTags))
                {
                    if (haveRoadNamerMod)
                    {
                        // If road namer mod is available, then attempt to get the name asscociated with the segment, if any
                        string roadName = RoadNamerManager.Instance().getSegmentName((ushort)(segmentId));
                        if (roadName != null)
                        {
                            //If a name is available, add a name tag
                            wayTags.Add(new OSMWayTag { k = "name", v = StringUtilities.RemoveTags(roadName) });
                        }
                    }
                    returnWay = new OSMWay { changeset = 50000000, id = (uint)index, timestamp = DateTime.Now, user = "******", nd = wayPaths.ToArray(), tag = wayTags.ToArray(), version = 1 };
                }
                else
                {
                    UniqueLogger.AddLog("Road names missing from search", segment.Info.name, "");
                }
            }

            return returnWay;
        }
            /// <summary>
            /// Initializes/recalculates bezier bounds.
            /// </summary>
            /// <param name="hitH">vertical raycast hit position.</param>
            private void CalculateBounds(float hitH)
            {
                // maximum vertical postion of the bezier.
                float maxH = Mathf.Max(raycastBezier.a.y, raycastBezier.d.y);

                float mouseH = UIBase.GetTrafficManagerTool(false).MousePosition.y;

                if ((hitH == prev_H || hitH == maxH || prev_H == mouseH) && bounds != null)
                {
                    // use cached results if mouse has not moved or hitH is ignored.
                    return;
                }

                Bezier3 bezier0 = raycastBezier;

                if (hitH < mouseH - MAX_HIT_ERROR)
                {
                    // For Metros use projection on the terrain.
                    bezier0.a.y = bezier0.b.y = bezier0.c.y = bezier0.d.y = mouseH;
                    prev_H      = mouseH;
                }
                else if (hitH > maxH + MAX_HIT_ERROR)
                {
                    // if marker is projected on another road plane then modify its height
                    bezier0.a.y = bezier0.b.y = bezier0.c.y = bezier0.d.y = hitH;
                    prev_H      = hitH;
                }
                else
                {
                    // ignore hitH
                    prev_H = maxH;
                }

                float angle = Vector3.Angle(bezier0.a, bezier0.b);

                if (Mathf.Approximately(angle, 0f) || Mathf.Approximately(angle, 180f))
                {
                    angle = Vector3.Angle(bezier0.b, bezier0.c);
                    if (Mathf.Approximately(angle, 0f) || Mathf.Approximately(angle, 180f))
                    {
                        angle = Vector3.Angle(bezier0.c, bezier0.d);
                        if (Mathf.Approximately(angle, 0f) || Mathf.Approximately(angle, 180f))
                        {
                            // linear bezier
                            Bounds bounds = bezier0.GetBounds();
                            bounds.Expand(0.4f);
                            this.bounds = new Bounds[] { bounds };
                            return;
                        }
                    }
                }

                // split bezier in 10 parts to correctly raycast curves
                int n = 10;

                bounds = new Bounds[n];
                float size = 1f / n;

                for (int i = 0; i < n; i++)
                {
                    Bezier3 bezier = bezier0.Cut(i * size, (i + 1) * size);
                    Bounds  bounds = bezier.GetBounds();
                    bounds.Expand(1f);
                    this.bounds[i] = bounds;
                }
            }
        private void CreateZoneBlocks(int segment, ref NetSegment data, NetInfo info)
        {
            var instance = Singleton<NetManager>.instance;
            var randomizer = new Randomizer(segment);
            var position = instance.m_nodes.m_buffer[data.m_startNode].m_position;
            var position2 = instance.m_nodes.m_buffer[data.m_endNode].m_position;
            var startDirection = data.m_startDirection;
            var endDirection = data.m_endDirection;
            var num = startDirection.x * endDirection.x + startDirection.z * endDirection.z;
            var flag = !NetSegment.IsStraight(position, startDirection, position2, endDirection);
            var num2 = Mathf.Max(8f, info.m_halfWidth);
            var num3 = 32f;
            if (flag)
            {
                var num4 = VectorUtils.LengthXZ(position2 - position);
                var flag2 = startDirection.x * endDirection.z - startDirection.z * endDirection.x > 0f;
                var flag3 = num < -0.8f || num4 > 50f;
                if (flag2)
                {
                    num2 = -num2;
                    num3 = -num3;
                }
                var vector = position - new Vector3(startDirection.z, 0f, -startDirection.x) * num2;
                var vector2 = position2 + new Vector3(endDirection.z, 0f, -endDirection.x) * num2;
                Vector3 vector3;
                Vector3 vector4;
                NetSegment.CalculateMiddlePoints(vector, startDirection, vector2, endDirection, true, true, out vector3, out vector4);
                if (flag3)
                {
                    var num5 = num * 0.025f + 0.04f;
                    var num6 = num * 0.025f + 0.06f;
                    if (num < -0.9f)
                    {
                        num6 = num5;
                    }
                    var bezier = new Bezier3(vector, vector3, vector4, vector2);
                    vector = bezier.Position(num5);
                    vector3 = bezier.Position(0.5f - num6);
                    vector4 = bezier.Position(0.5f + num6);
                    vector2 = bezier.Position(1f - num5);
                }
                else
                {
                    var bezier2 = new Bezier3(vector, vector3, vector4, vector2);
                    vector3 = bezier2.Position(0.86f);
                    vector = bezier2.Position(0.14f);
                }
                float num7;
                var vector5 = VectorUtils.NormalizeXZ(vector3 - vector, out num7);
                var num8 = Mathf.FloorToInt(num7 / 8f + 0.01f);
                var num9 = num7 * 0.5f + (num8 - 8) * ((!flag2) ? -4f : 4f);
                if (num8 != 0)
                {
                    var angle = (!flag2) ? Mathf.Atan2(vector5.x, -vector5.z) : Mathf.Atan2(-vector5.x, vector5.z);
                    var position3 = vector + new Vector3(vector5.x * num9 - vector5.z * num3, 0f, vector5.z * num9 + vector5.x * num3);
                    if (flag2)
                    {
                        Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockStartRight, ref randomizer, position3, angle, num8, data.m_buildIndex);
                    }
                    else
                    {
                        Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockStartLeft, ref randomizer, position3, angle, num8, data.m_buildIndex);
                    }
                }
                if (flag3)
                {
                    vector5 = VectorUtils.NormalizeXZ(vector2 - vector4, out num7);
                    num8 = Mathf.FloorToInt(num7 / 8f + 0.01f);
                    num9 = num7 * 0.5f + (num8 - 8) * ((!flag2) ? -4f : 4f);
                    if (num8 != 0)
                    {
                        var angle2 = (!flag2) ? Mathf.Atan2(vector5.x, -vector5.z) : Mathf.Atan2(-vector5.x, vector5.z);
                        var position4 = vector4 + new Vector3(vector5.x * num9 - vector5.z * num3, 0f, vector5.z * num9 + vector5.x * num3);
                        if (flag2)
                        {
                            Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockEndRight, ref randomizer, position4, angle2, num8, data.m_buildIndex + 1u);
                        }
                        else
                        {
                            Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockEndLeft, ref randomizer, position4, angle2, num8, data.m_buildIndex + 1u);
                        }
                    }
                }
                var vector6 = position + new Vector3(startDirection.z, 0f, -startDirection.x) * num2;
                var vector7 = position2 - new Vector3(endDirection.z, 0f, -endDirection.x) * num2;
                Vector3 b;
                Vector3 c;
                NetSegment.CalculateMiddlePoints(vector6, startDirection, vector7, endDirection, true, true, out b, out c);
                var bezier3 = new Bezier3(vector6, b, c, vector7);
                var vector8 = bezier3.Position(0.5f);
                var vector9 = bezier3.Position(0.25f);
                vector9 = Line2.Offset(VectorUtils.XZ(vector6), VectorUtils.XZ(vector8), VectorUtils.XZ(vector9));
                var vector10 = bezier3.Position(0.75f);
                vector10 = Line2.Offset(VectorUtils.XZ(vector7), VectorUtils.XZ(vector8), VectorUtils.XZ(vector10));
                var vector11 = vector6;
                var a = vector7;
                float d;
                float num10;
                if (Line2.Intersect(VectorUtils.XZ(position), VectorUtils.XZ(vector6), VectorUtils.XZ(vector11 - vector9), VectorUtils.XZ(vector8 - vector9), out d, out num10))
                {
                    vector6 = position + (vector6 - position) * d;
                }
                if (Line2.Intersect(VectorUtils.XZ(position2), VectorUtils.XZ(vector7), VectorUtils.XZ(a - vector10), VectorUtils.XZ(vector8 - vector10), out d, out num10))
                {
                    vector7 = position2 + (vector7 - position2) * d;
                }
                if (Line2.Intersect(VectorUtils.XZ(vector11 - vector9), VectorUtils.XZ(vector8 - vector9), VectorUtils.XZ(a - vector10), VectorUtils.XZ(vector8 - vector10), out d, out num10))
                {
                    vector8 = vector11 - vector9 + (vector8 - vector11) * d;
                }
                float num11;
                var vector12 = VectorUtils.NormalizeXZ(vector8 - vector6, out num11);
                var num12 = Mathf.FloorToInt(num11 / 8f + 0.01f);
                var num13 = num11 * 0.5f + (num12 - 8) * ((!flag2) ? 4f : -4f);
                if (num12 != 0)
                {
                    var angle3 = (!flag2) ? Mathf.Atan2(-vector12.x, vector12.z) : Mathf.Atan2(vector12.x, -vector12.z);
                    var position5 = vector6 + new Vector3(vector12.x * num13 + vector12.z * num3, 0f, vector12.z * num13 - vector12.x * num3);
                    if (flag2)
                    {
                        Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockStartLeft, ref randomizer, position5, angle3, num12, data.m_buildIndex);
                    }
                    else
                    {
                        Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockStartRight, ref randomizer, position5, angle3, num12, data.m_buildIndex);
                    }
                }
                vector12 = VectorUtils.NormalizeXZ(vector7 - vector8, out num11);
                num12 = Mathf.FloorToInt(num11 / 8f + 0.01f);
                num13 = num11 * 0.5f + (num12 - 8) * ((!flag2) ? 4f : -4f);

                if (num12 == 0) return;

                var angle4 = (!flag2) ? Mathf.Atan2(-vector12.x, vector12.z) : Mathf.Atan2(vector12.x, -vector12.z);
                var position6 = vector8 + new Vector3(vector12.x * num13 + vector12.z * num3, 0f, vector12.z * num13 - vector12.x * num3);
                if (flag2)
                {
                    Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockEndLeft, ref randomizer, position6, angle4, num12, data.m_buildIndex + 1u);
                }
                else
                {
                    Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockEndRight, ref randomizer, position6, angle4, num12, data.m_buildIndex + 1u);
                }
            }
            else
            {
                num2 += num3;
                var vector13 = new Vector2(position2.x - position.x, position2.z - position.z);
                var magnitude = vector13.magnitude;
                var num14 = Mathf.FloorToInt(magnitude / 8f + 0.1f);
                var num15 = (num14 <= 8) ? num14 : (num14 + 1 >> 1);
                var num16 = (num14 <= 8) ? 0 : (num14 >> 1);
                if (num15 > 0)
                {
                    var num17 = Mathf.Atan2(startDirection.x, -startDirection.z);
                    var position7 = position + new Vector3(startDirection.x * 32f - startDirection.z * num2, 0f, startDirection.z * 32f + startDirection.x * num2);
                    Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockStartLeft, ref randomizer, position7, num17, num15, data.m_buildIndex);
                    position7 = position + new Vector3(startDirection.x * (num15 - 4) * 8f + startDirection.z * num2, 0f, startDirection.z * (num15 - 4) * 8f - startDirection.x * num2);
                    Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockStartRight, ref randomizer, position7, num17 + 3.14159274f, num15, data.m_buildIndex);
                }

                if (num16 <= 0) return;

                var num18 = magnitude - num14 * 8f;
                var num19 = Mathf.Atan2(endDirection.x, -endDirection.z);
                var position8 = position2 + new Vector3(endDirection.x * (32f + num18) - endDirection.z * num2, 0f, endDirection.z * (32f + num18) + endDirection.x * num2);
                Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockEndLeft, ref randomizer, position8, num19, num16, data.m_buildIndex + 1u);
                position8 = position2 + new Vector3(endDirection.x * ((num16 - 4) * 8f + num18) + endDirection.z * num2, 0f, endDirection.z * ((num16 - 4) * 8f + num18) - endDirection.x * num2);
                Singleton<ZoneManager>.instance.CreateBlock(out data.m_blockEndRight, ref randomizer, position8, num19 + 3.14159274f, num16, data.m_buildIndex + 1u);
            }
        }
        private static List <NodeLaneMarker> GetNodeMarkers(ushort nodeId, ref NetNode node)
        {
            if (nodeId == 0)
            {
                return(null);
            }

            if ((node.m_flags & NetNode.Flags.Created) == NetNode.Flags.None)
            {
                return(null);
            }

            List <NodeLaneMarker> nodeMarkers = new List <NodeLaneMarker>();
            int nodeMarkerColorIndex          = 0;
            LaneConnectionManager connManager = LaneConnectionManager.Instance;

            int offsetMultiplier = node.CountSegments() <= 2 ? 3 : 1;

            for (int i = 0; i < 8; i++)
            {
                ushort segmentId = node.GetSegment(i);

                if (segmentId == 0)
                {
                    continue;
                }

                NetSegment[] segmentsBuffer = NetManager.instance.m_segments.m_buffer;
                bool         startNode      = segmentsBuffer[segmentId].m_startNode == nodeId;
                Vector3      offset         = segmentsBuffer[segmentId]
                                              .FindDirection(segmentId, nodeId) * offsetMultiplier;
                NetInfo.Lane[] lanes  = segmentsBuffer[segmentId].Info.m_lanes;
                uint           laneId = segmentsBuffer[segmentId].m_lanes;

                for (byte laneIndex = 0; (laneIndex < lanes.Length) && (laneId != 0); laneIndex++)
                {
                    NetInfo.Lane laneInfo = lanes[laneIndex];

                    if (((laneInfo.m_laneType & LaneConnectionManager.LANE_TYPES) != NetInfo.LaneType.None) &&
                        ((laneInfo.m_vehicleType & LaneConnectionManager.VEHICLE_TYPES)
                         != VehicleInfo.VehicleType.None))
                    {
                        if (connManager.GetLaneEndPoint(
                                segmentId,
                                startNode,
                                laneIndex,
                                laneId,
                                laneInfo,
                                out bool isSource,
                                out bool isTarget,
                                out Vector3? pos))
                        {
                            pos = pos.Value + offset;

                            float terrainY =
                                Singleton <TerrainManager> .instance.SampleDetailHeightSmooth(pos.Value);

                            var finalPos = new Vector3(pos.Value.x, terrainY, pos.Value.z);

                            Color32 nodeMarkerColor
                                = isSource
                                      ? COLOR_CHOICES[nodeMarkerColorIndex % COLOR_CHOICES.Length]
                                      : default; // or black (not used while rendering)

                            NetLane lane   = NetManager.instance.m_lanes.m_buffer[laneId];
                            Bezier3 bezier = lane.m_bezier;
                            if (startNode)
                            {
                                bezier.a = (Vector3)pos;
                            }
                            else
                            {
                                bezier.d = (Vector3)pos;
                            }
                            SegmentLaneMarker segmentLaneMarker = new SegmentLaneMarker {
                                renderBezier  = bezier,
                                raycastBezier = bezier,
                                laneID        = laneId,
                                laneIndex     = laneIndex,
                            };

                            nodeMarkers.Add(
                                new NodeLaneMarker {
                                SegmentId             = segmentId,
                                LaneId                = laneId,
                                NodeId                = nodeId,
                                StartNode             = startNode,
                                Position              = finalPos,
                                SecondaryPosition     = (Vector3)pos,
                                Color                 = nodeMarkerColor,
                                IsSource              = isSource,
                                IsTarget              = isTarget,
                                LaneType              = laneInfo.m_laneType,
                                VehicleType           = laneInfo.m_vehicleType,
                                InnerSimilarLaneIndex =
                                    ((byte)(laneInfo.m_direction & NetInfo.Direction.Forward) != 0)
                                            ? laneInfo.m_similarLaneIndex
                                            : laneInfo.m_similarLaneCount -
                                    laneInfo.m_similarLaneIndex - 1,
                                SegmentIndex      = i,
                                segmentLaneMarker = segmentLaneMarker,
                            });

                            if (isSource)
                            {
                                nodeMarkerColorIndex++;
                            }
                        }
                    }

                    laneId = NetManager.instance.m_lanes.m_buffer[laneId].m_nextLane;
                }
            }

            if (nodeMarkers.Count == 0)
            {
                return(null);
            }

            foreach (NodeLaneMarker laneMarker1 in nodeMarkers)
            {
                if (!laneMarker1.IsSource)
                {
                    continue;
                }

                uint[] connections =
                    LaneConnectionManager.Instance.GetLaneConnections(
                        laneMarker1.LaneId,
                        laneMarker1.StartNode);

                if ((connections == null) || (connections.Length == 0))
                {
                    continue;
                }

                foreach (NodeLaneMarker laneMarker2 in nodeMarkers)
                {
                    if (!laneMarker2.IsTarget)
                    {
                        continue;
                    }

                    if (connections.Contains(laneMarker2.LaneId))
                    {
                        laneMarker1.ConnectedMarkers.Add(laneMarker2);
                    }
                }
            }

            return(nodeMarkers);
        }