Пример #1
0
    // NetNode
    // Token: 0x060034C5 RID: 13509 RVA: 0x0023CECC File Offset: 0x0023B2CC
    private void RefreshJunctionData(ushort nodeID, int segmentIndex, int segmentIndex2, NetInfo info, NetInfo info2, ushort segmentID, ushort segmentID2, ref uint instanceIndex, ref RenderManager.Instance data)
    {
        data.m_position    = this.m_position;
        data.m_rotation    = Quaternion.identity;
        data.m_initialized = true;
        float   vscale      = info.m_netAI.GetVScale();
        Vector3 CornerPos2L = Vector3.zero;
        Vector3 CornerPos2R = Vector3.zero;
        Vector3 CornerDir2L = Vector3.zero;
        Vector3 CornerDir2R = Vector3.zero;
        bool    startNode   = Singleton <NetManager> .instance.m_segments.m_buffer[(int)segmentID].m_startNode == nodeID;

        Singleton <NetManager> .instance.m_segments.m_buffer[(int)segmentID].CalculateCorner(segmentID, true, startNode, false, out var CornerPosL, out var CornerDirL, out _);
        Singleton <NetManager> .instance.m_segments.m_buffer[(int)segmentID].CalculateCorner(segmentID, true, startNode, true, out var CornerPosR, out var CornerDirR, out _);
        bool startNode2 = (Singleton <NetManager> .instance.m_segments.m_buffer[(int)segmentID2].m_startNode == nodeID);

        Singleton <NetManager> .instance.m_segments.m_buffer[(int)segmentID2].CalculateCorner(segmentID2, true, startNode2, true, out CornerPos2L, out CornerDir2L, out _);
        Singleton <NetManager> .instance.m_segments.m_buffer[(int)segmentID2].CalculateCorner(segmentID2, true, startNode2, false, out CornerPos2R, out CornerDir2R, out _);
        Vector3 b = (CornerPos2R - CornerPos2L) * (info.m_halfWidth / info2.m_halfWidth * 0.5f - 0.5f);

        CornerPos2L -= b;
        CornerPos2R += b;
        NetSegment.CalculateMiddlePoints(CornerPosL, -CornerDirL, CornerPos2L, -CornerDir2L, true, true, out var bpointL, out var cpointL);
        NetSegment.CalculateMiddlePoints(CornerPosR, -CornerDirR, CornerPos2R, -CornerDir2R, true, true, out var bpointR, out var cpointR);
        data.m_dataMatrix0             = NetSegment.CalculateControlMatrix(CornerPosL, bpointL, cpointL, CornerPos2L, CornerPosR, bpointR, cpointR, CornerPos2R, this.m_position, vscale);
        data.m_extraData.m_dataMatrix2 = NetSegment.CalculateControlMatrix(CornerPosR, bpointR, cpointR, CornerPos2R, CornerPosL, bpointL, cpointL, CornerPos2L, this.m_position, vscale);
        data.m_dataVector0             = new Vector4(0.5f / info.m_halfWidth, 1f / info.m_segmentLength, 1f, 1f);
        Vector4 colorLocation;
        Vector4 vector7;

        if (NetNode.BlendJunction(nodeID))
        {
            colorLocation = RenderManager.GetColorLocation(86016u + (uint)nodeID);
            vector7       = colorLocation;
        }
        else
        {
            colorLocation = RenderManager.GetColorLocation((uint)(49152 + segmentID));
            vector7       = RenderManager.GetColorLocation((uint)(49152 + segmentID2));
        }
        data.m_dataVector3  = new Vector4(colorLocation.x, colorLocation.y, vector7.x, vector7.y);
        data.m_dataInt0     = (8 | segmentIndex | segmentIndex2 << 4);
        data.m_dataColor0   = info.m_color;
        data.m_dataColor0.a = 0f;
        data.m_dataFloat0   = Singleton <WeatherManager> .instance.GetWindSpeed(data.m_position);

        if (info.m_requireSurfaceMaps)
        {
            Singleton <TerrainManager> .instance.GetSurfaceMapping(data.m_position, out data.m_dataTexture0, out data.m_dataTexture1, out data.m_dataVector1);
        }
        instanceIndex = (uint)data.m_nextInstance;
    }
Пример #2
0
        private void RenderInstance(ref NetSegment This, RenderManager.CameraInfo cameraInfo, ushort segmentID, int layerMask, NetInfo info, ref RenderManager.Instance data)
        {
            NetManager instance = Singleton <NetManager> .instance;

            if (data.m_dirty)
            {
                data.m_dirty = false;
                Vector3 position  = instance.m_nodes.m_buffer[m_startNode].m_position;
                Vector3 position2 = instance.m_nodes.m_buffer[m_endNode].m_position;
                data.m_position     = (position + position2) * 0.5f;
                data.m_rotation     = Quaternion.identity;
                data.m_dataColor0   = info.m_color;
                data.m_dataColor0.a = 0f;
                data.m_dataFloat0   = Singleton <WeatherManager> .instance.GetWindSpeed(data.m_position);

                data.m_dataVector0 = new Vector4(0.5f / info.m_halfWidth, 1f / info.m_segmentLength, 1f, 1f);
                Vector4 colorLocation = RenderManager.GetColorLocation((uint)(49152 + segmentID));
                Vector4 vector        = colorLocation;
                if (NetNode.BlendJunction(m_startNode))
                {
                    colorLocation = RenderManager.GetColorLocation((uint)(86016 + m_startNode));
                }
                if (NetNode.BlendJunction(m_endNode))
                {
                    vector = RenderManager.GetColorLocation((uint)(86016 + m_endNode));
                }
                data.m_dataVector3 = new Vector4(colorLocation.x, colorLocation.y, vector.x, vector.y);
                if (info.m_segments == null || info.m_segments.Length == 0)
                {
                    if (info.m_lanes != null)
                    {
                        bool invert;
                        if ((m_flags & Flags.Invert) != 0)
                        {
                            invert = true;
                            instance.m_nodes.m_buffer[m_endNode].Info.m_netAI.GetNodeState(m_endNode, ref instance.m_nodes.m_buffer[m_endNode], segmentID, ref This, out _, out _);       // unused code
                            instance.m_nodes.m_buffer[m_startNode].Info.m_netAI.GetNodeState(m_startNode, ref instance.m_nodes.m_buffer[m_startNode], segmentID, ref This, out _, out _); // unused code
                        }
                        else
                        {
                            invert = false;
                            instance.m_nodes.m_buffer[m_startNode].Info.m_netAI.GetNodeState(m_startNode, ref instance.m_nodes.m_buffer[m_startNode], segmentID, ref This, out _, out _); // unused code
                            instance.m_nodes.m_buffer[m_endNode].Info.m_netAI.GetNodeState(m_endNode, ref instance.m_nodes.m_buffer[m_endNode], segmentID, ref This, out _, out _);       // unused code
                        }
                        float startAngle = (float)(int)m_cornerAngleStart * ((float)Math.PI / 128f);
                        float endAngle   = (float)(int)m_cornerAngleEnd * ((float)Math.PI / 128f);
                        int   propIndex  = 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].RefreshInstance(num, info.m_lanes[i], startAngle, endAngle, invert, ref data, ref propIndex);
                            num = instance.m_lanes.m_buffer[num].m_nextLane;
                        }
                    }
                }
                else
                {
                    float vScale = info.m_netAI.GetVScale();
                    CalculateCorner(segmentID, heightOffset: true, start: true, leftSide: true, out var posSL, out var dirSL, out var smoothStart);
                    CalculateCorner(segmentID, heightOffset: true, start: false, leftSide: true, out var posEL, out var dirEL, out var smoothEnd);
                    CalculateCorner(segmentID, heightOffset: true, start: true, leftSide: false, out var posSR, out var dirSR, out smoothStart);
                    CalculateCorner(segmentID, heightOffset: true, start: false, leftSide: false, out var posER, out var dirER, out smoothEnd);
                    CalculateMiddlePoints(posSL, dirSL, posER, dirER, smoothStart, smoothEnd, out var b1, out var c1);
                    CalculateMiddlePoints(posSR, dirSR, posEL, dirEL, smoothStart, smoothEnd, out var b2, out var c2);
                    data.m_dataMatrix0 = CalculateControlMatrix(posSL, b1, c1, posER, posSR, b2, c2, posEL, data.m_position, vScale);
                    data.m_dataMatrix1 = CalculateControlMatrix(posSR, b2, c2, posEL, posSL, b1, c1, posER, data.m_position, vScale);
                }
                if (info.m_requireSurfaceMaps)
                {
                    Singleton <TerrainManager> .instance.GetSurfaceMapping(data.m_position, out data.m_dataTexture0, out data.m_dataTexture1, out data.m_dataVector1);
                }
                else if (info.m_requireHeightMap)
                {
                    Singleton <TerrainManager> .instance.GetHeightMapping(data.m_position, out data.m_dataTexture0, out data.m_dataVector1, out data.m_dataVector2);
                }
            }
            if (info.m_segments != null && (layerMask & info.m_netLayers) != 0)
            {
                for (int j = 0; j < info.m_segments.Length; j++)
                {
                    NetInfo.Segment segment = info.m_segments[j];
                    if (!segment.CheckFlags(m_flags, out var turnAround))
                    {
                        continue;
                    }
                    Vector4 objectIndex = data.m_dataVector3;
                    Vector4 meshScale   = data.m_dataVector0;
                    if (segment.m_requireWindSpeed)
                    {
                        objectIndex.w = data.m_dataFloat0;
                    }
                    if (turnAround)
                    {
                        meshScale.x = 0f - meshScale.x;
                        meshScale.y = 0f - meshScale.y;
                    }
                    if (cameraInfo.CheckRenderDistance(data.m_position, segment.m_lodRenderDistance))
                    {
                        instance.m_materialBlock.Clear();
                        instance.m_materialBlock.SetMatrix(instance.ID_LeftMatrix, data.m_dataMatrix0);
                        instance.m_materialBlock.SetMatrix(instance.ID_RightMatrix, data.m_dataMatrix1);
                        instance.m_materialBlock.SetVector(instance.ID_MeshScale, meshScale);
                        instance.m_materialBlock.SetVector(instance.ID_ObjectIndex, objectIndex);
                        instance.m_materialBlock.SetColor(instance.ID_Color, data.m_dataColor0);
                        if (segment.m_requireSurfaceMaps && data.m_dataTexture0 != null)
                        {
                            instance.m_materialBlock.SetTexture(instance.ID_SurfaceTexA, data.m_dataTexture0);
                            instance.m_materialBlock.SetTexture(instance.ID_SurfaceTexB, data.m_dataTexture1);
                            instance.m_materialBlock.SetVector(instance.ID_SurfaceMapping, data.m_dataVector1);
                        }
                        else if (segment.m_requireHeightMap && data.m_dataTexture0 != null)
                        {
                            instance.m_materialBlock.SetTexture(instance.ID_HeightMap, data.m_dataTexture0);
                            instance.m_materialBlock.SetVector(instance.ID_HeightMapping, data.m_dataVector1);
                            instance.m_materialBlock.SetVector(instance.ID_SurfaceMapping, data.m_dataVector2);
                        }
                        instance.m_drawCallData.m_defaultCalls++;
                        Graphics.DrawMesh(segment.m_segmentMesh, data.m_position, data.m_rotation, segment.m_segmentMaterial, segment.m_layer, null, 0, instance.m_materialBlock);
                        continue;
                    }
                    NetInfo.LodValue combinedLod = segment.m_combinedLod;
                    if (combinedLod == null)
                    {
                        continue;
                    }
                    if (segment.m_requireSurfaceMaps)
                    {
                        if (data.m_dataTexture0 != combinedLod.m_surfaceTexA)
                        {
                            if (combinedLod.m_lodCount != 0)
                            {
                                RenderLod(cameraInfo, combinedLod);
                            }
                            combinedLod.m_surfaceTexA    = data.m_dataTexture0;
                            combinedLod.m_surfaceTexB    = data.m_dataTexture1;
                            combinedLod.m_surfaceMapping = data.m_dataVector1;
                        }
                    }
                    else if (segment.m_requireHeightMap && data.m_dataTexture0 != combinedLod.m_heightMap)
                    {
                        if (combinedLod.m_lodCount != 0)
                        {
                            RenderLod(cameraInfo, combinedLod);
                        }
                        combinedLod.m_heightMap      = data.m_dataTexture0;
                        combinedLod.m_heightMapping  = data.m_dataVector1;
                        combinedLod.m_surfaceMapping = data.m_dataVector2;
                    }
                    ref Matrix4x4 reference = ref combinedLod.m_leftMatrices[combinedLod.m_lodCount];
                    reference = data.m_dataMatrix0;
                    ref Matrix4x4 reference2 = ref combinedLod.m_rightMatrices[combinedLod.m_lodCount];
                    reference2 = data.m_dataMatrix1;
                    combinedLod.m_meshScales[combinedLod.m_lodCount]    = meshScale;
                    combinedLod.m_objectIndices[combinedLod.m_lodCount] = objectIndex;
                    ref Vector4 reference3 = ref combinedLod.m_meshLocations[combinedLod.m_lodCount];
Пример #3
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);
                }
            }
        }
Пример #4
0
    // NetNode
    // Token: 0x060034C6 RID: 13510 RVA: 0x0023D1EC File Offset: 0x0023B5EC

    /// <param name="centerPos">position between left corner and right corner of segmentID (or something like that).</param>
    private static void RefreshJunctionData(ref NetNode This, ushort nodeID, int segmentIndex, ushort SegmentID, Vector3 centerPos, ref uint instanceIndex, ref RenderManager.Instance data)
    {
        Vector3 cornerPos_right = Vector3.zero, cornerDir_right = Vector3.zero, cornerPos_left = Vector3.zero, cornerDir_left = Vector3.zero,
                cornerPosA_right = Vector3.zero, cornerDirA_right = Vector3.zero, cornerPosA_left = Vector3.zero, cornerDirA_left = Vector3.zero,
                cornerPosB_right = Vector3.zero, cornerDirB_right = Vector3.zero, cornerPosB_left = Vector3.zero, cornerDirB_left = Vector3.zero;

        NetManager instance = Singleton <NetManager> .instance;

        data.m_position    = This.m_position;
        data.m_rotation    = Quaternion.identity;
        data.m_initialized = true;
        NetSegment segment         = SegmentID.ToSegment();
        NetInfo    info            = segment.Info;
        float      vscale          = info.m_netAI.GetVScale();
        ItemClass  connectionClass = info.GetConnectionClass();
        bool       bStartNode      = nodeID == segment.m_startNode;
        Vector3    dir             = !bStartNode ? segment.m_endDirection : segment.m_startDirection;
        float      dot_A           = -4f;
        float      dot_B           = -4f;
        ushort     segmentID_A     = 0;
        ushort     segmentID_B     = 0;

        for (int i = 0; i < 8; i++)
        {
            ushort segmentID2 = This.GetSegment(i);
            if (segmentID2 != 0 && segmentID2 != SegmentID)
            {
                NetInfo   info2            = instance.m_segments.m_buffer[(int)segmentID2].Info;
                ItemClass connectionClass2 = info2.GetConnectionClass();
                if (connectionClass.m_service == connectionClass2.m_service)
                {
                    NetSegment segment2    = segmentID2.ToSegment();
                    bool       bStartNode2 = nodeID != segment2.m_startNode;
                    Vector3    dir2        = !bStartNode2 ? segment2.m_endDirection : segment2.m_startDirection;
                    float      dot         = dir.x * dir2.x + dir.z * dir2.z;
                    float      determinent = dir2.z * dir.x - dir2.x * dir.z;
                    bool       bRight      = determinent > 0;
                    bool       bWide       = dot < 0;
                    // 180 -> det=0 dot=-1
                    if (!bRight)
                    {
                        if (dot > dot_A) // most accute
                        {
                            dot_A       = dot;
                            segmentID_A = segmentID2;
                        }
                        dot = -2f - dot;
                        if (dot > dot_B) // widest
                        {
                            dot_B       = dot;
                            segmentID_B = segmentID2;
                        }
                    }
                    else
                    {
                        if (dot > dot_B) // most accute
                        {
                            dot_B       = dot;
                            segmentID_B = segmentID2;
                        }
                        dot = -2f - dot;
                        if (dot > dot_A) // widest
                        {
                            dot_A       = dot;
                            segmentID_A = segmentID2;
                        }
                    }
                }
            }
        }
        segment.CalculateCorner(SegmentID, true, bStartNode, false, out cornerPos_right, out cornerDir_right, out _);
        segment.CalculateCorner(SegmentID, true, bStartNode, true, out cornerPos_left, out cornerDir_left, out _);
        if (segmentID_A != 0 && segmentID_B != 0)
        {
            float pavementRatio_avgA = info.m_pavementWidth / info.m_halfWidth * 0.5f;
            float averageWidthA      = 1f;
            if (segmentID_A != 0)
            {
                NetSegment segment_A = instance.m_segments.m_buffer[(int)segmentID_A];
                NetInfo    infoA     = segment_A.Info;
                bStartNode = (segment_A.m_startNode == nodeID);
                segment_A.CalculateCorner(segmentID_A, true, bStartNode, true, out cornerPosA_right, out cornerDirA_right, out _);
                segment_A.CalculateCorner(segmentID_A, true, bStartNode, false, out cornerPosA_left, out cornerDirA_left, out _);
                float pavementRatioA = infoA.m_pavementWidth / infoA.m_halfWidth * 0.5f;
                pavementRatio_avgA = (pavementRatio_avgA + pavementRatioA) * 0.5f;
                averageWidthA      = 2f * info.m_halfWidth / (info.m_halfWidth + infoA.m_halfWidth);
            }
            float pavementRatio_avgB = info.m_pavementWidth / info.m_halfWidth * 0.5f;
            float averageWithB       = 1f;
            if (segmentID_B != 0)
            {
                NetSegment segment_B = instance.m_segments.m_buffer[(int)segmentID_B];
                NetInfo    infoB     = segment_B.Info;
                bStartNode = (segment_B.m_startNode == nodeID);
                segment_B.CalculateCorner(segmentID_B, true, bStartNode, true, out cornerPosB_right, out cornerDirB_right, out _);
                segment_B.CalculateCorner(segmentID_B, true, bStartNode, false, out cornerPosB_left, out cornerDirB_left, out _);
                float pavementRatioB = infoB.m_pavementWidth / infoB.m_halfWidth * 0.5f;
                pavementRatio_avgB = (pavementRatio_avgB + pavementRatioB) * 0.5f;
                averageWithB       = 2f * info.m_halfWidth / (info.m_halfWidth + infoB.m_halfWidth);
            }

            Bezier3 bezierA_right = new Bezier3
            {
                a = cornerPos_right,
                d = cornerPosA_right,
            };

            NetSegment.CalculateMiddlePoints(bezierA_right.a, -cornerDir_right, bezierA_right.d, -cornerDirA_right, true, true, out bezierA_right.b, out bezierA_right.c);
            NetSegment.CalculateMiddlePoints(cornerPos_left, -cornerDir_left, cornerPosA_left, -cornerDirA_left, true, true, out var cpoint2_Aleft, out var cpoint3_Aleft);
            NetSegment.CalculateMiddlePoints(cornerPos_right, -cornerDir_right, cornerPosB_right, -cornerDirB_right, true, true, out var cpoint2_Bright, out var cpoint3_Bright);
            NetSegment.CalculateMiddlePoints(cornerPos_left, -cornerDir_left, cornerPosB_left, -cornerDirB_left, true, true, out var cpoint2_Bleft, out var cpoint3_Bleft);

            data.m_dataMatrix0             = NetSegment.CalculateControlMatrix(bezierA_right.a, bezierA_right.b, bezierA_right.c, bezierA_right.d, bezierA_right.a, bezierA_right.b, bezierA_right.c, bezierA_right.d, This.m_position, vscale);
            data.m_extraData.m_dataMatrix2 = NetSegment.CalculateControlMatrix(cornerPos_left, cpoint2_Aleft, cpoint3_Aleft, cornerPosA_left, cornerPos_left, cpoint2_Aleft, cpoint3_Aleft, cornerPosA_left, This.m_position, vscale);
            data.m_extraData.m_dataMatrix3 = NetSegment.CalculateControlMatrix(cornerPos_right, cpoint2_Bright, cpoint3_Bright, cornerPosB_right, cornerPos_right, cpoint2_Bright, cpoint3_Bright, cornerPosB_right, This.m_position, vscale);
            data.m_dataMatrix1             = NetSegment.CalculateControlMatrix(cornerPos_left, cpoint2_Bleft, cpoint3_Bleft, cornerPosB_left, cornerPos_left, cpoint2_Bleft, cpoint3_Bleft, cornerPosB_left, This.m_position, vscale);

            // Vector4(1/width | 1/length | 0.5 - pavement/width | pavement/width )
            data.m_dataVector0   = new Vector4(0.5f / info.m_halfWidth, 1f / info.m_segmentLength, 0.5f - info.m_pavementWidth / info.m_halfWidth * 0.5f, info.m_pavementWidth / info.m_halfWidth * 0.5f);
            data.m_dataVector1   = centerPos - data.m_position;
            data.m_dataVector1.w = (data.m_dataMatrix0.m31 + data.m_dataMatrix0.m32 + data.m_extraData.m_dataMatrix2.m31 + data.m_extraData.m_dataMatrix2.m32 + data.m_extraData.m_dataMatrix3.m31 + data.m_extraData.m_dataMatrix3.m32 + data.m_dataMatrix1.m31 + data.m_dataMatrix1.m32) * 0.125f;
            data.m_dataVector2   = new Vector4(pavementRatio_avgA, averageWidthA, pavementRatio_avgB, averageWithB);
        }
        else
        {
            centerPos.x = (cornerPos_right.x + cornerPos_left.x) * 0.5f;
            centerPos.z = (cornerPos_right.z + cornerPos_left.z) * 0.5f;
            var cornerPos_left_prev  = cornerPos_left;
            var cornerPos_right_prev = cornerPos_right;
            cornerDirB_right = cornerDir_left;
            cornerDirB_left  = cornerDir_right;
            float   d        = info.m_netAI.GetEndRadius() * 1.33333337f;
            Vector3 vector13 = cornerPos_right - cornerDir_right * d;
            Vector3 vector14 = cornerPos_left_prev - cornerDirB_right * d;
            Vector3 vector15 = cornerPos_left - cornerDir_left * d;
            Vector3 vector16 = cornerPos_right_prev - cornerDirB_left * d;
            Vector3 vector17 = cornerPos_right + cornerDir_right * d;
            Vector3 vector18 = cornerPos_left_prev + cornerDirB_right * d;
            Vector3 vector19 = cornerPos_left + cornerDir_left * d;
            Vector3 vector20 = cornerPos_right_prev + cornerDirB_left * d;
            data.m_dataMatrix0             = NetSegment.CalculateControlMatrix(cornerPos_right, vector13, vector14, cornerPos_left_prev, cornerPos_right, vector13, vector14, cornerPos_left_prev, This.m_position, vscale);
            data.m_extraData.m_dataMatrix2 = NetSegment.CalculateControlMatrix(cornerPos_left, vector19, vector20, cornerPos_right_prev, cornerPos_left, vector19, vector20, cornerPos_right_prev, This.m_position, vscale);
            data.m_extraData.m_dataMatrix3 = NetSegment.CalculateControlMatrix(cornerPos_right, vector17, vector18, cornerPos_left_prev, cornerPos_right, vector17, vector18, cornerPos_left_prev, This.m_position, vscale);
            data.m_dataMatrix1             = NetSegment.CalculateControlMatrix(cornerPos_left, vector15, vector16, cornerPos_right_prev, cornerPos_left, vector15, vector16, cornerPos_right_prev, This.m_position, vscale);
            data.m_dataMatrix0.SetRow(3, data.m_dataMatrix0.GetRow(3) + new Vector4(0.2f, 0.2f, 0.2f, 0.2f));
            data.m_extraData.m_dataMatrix2.SetRow(3, data.m_extraData.m_dataMatrix2.GetRow(3) + new Vector4(0.2f, 0.2f, 0.2f, 0.2f));
            data.m_extraData.m_dataMatrix3.SetRow(3, data.m_extraData.m_dataMatrix3.GetRow(3) + new Vector4(0.2f, 0.2f, 0.2f, 0.2f));
            data.m_dataMatrix1.SetRow(3, data.m_dataMatrix1.GetRow(3) + new Vector4(0.2f, 0.2f, 0.2f, 0.2f));
            data.m_dataVector0   = new Vector4(0.5f / info.m_halfWidth, 1f / info.m_segmentLength, 0.5f - info.m_pavementWidth / info.m_halfWidth * 0.5f, info.m_pavementWidth / info.m_halfWidth * 0.5f);
            data.m_dataVector1   = centerPos - data.m_position;
            data.m_dataVector1.w = (data.m_dataMatrix0.m31 + data.m_dataMatrix0.m32 + data.m_extraData.m_dataMatrix2.m31 + data.m_extraData.m_dataMatrix2.m32 + data.m_extraData.m_dataMatrix3.m31 + data.m_extraData.m_dataMatrix3.m32 + data.m_dataMatrix1.m31 + data.m_dataMatrix1.m32) * 0.125f;
            data.m_dataVector2   = new Vector4(info.m_pavementWidth / info.m_halfWidth * 0.5f, 1f, info.m_pavementWidth / info.m_halfWidth * 0.5f, 1f);
        }
        Vector4 colorLocation;
        Vector4 vector21;

        if (NetNode.BlendJunction(nodeID))
        {
            colorLocation = RenderManager.GetColorLocation(86016u + (uint)nodeID);
            vector21      = colorLocation;
        }
        else
        {
            colorLocation = RenderManager.GetColorLocation((uint)(49152 + SegmentID));
            vector21      = RenderManager.GetColorLocation(86016u + (uint)nodeID);
        }
        data.m_extraData.m_dataVector4 = new Vector4(colorLocation.x, colorLocation.y, vector21.x, vector21.y);
        data.m_dataInt0     = segmentIndex;
        data.m_dataColor0   = info.m_color;
        data.m_dataColor0.a = 0f;
        data.m_dataFloat0   = Singleton <WeatherManager> .instance.GetWindSpeed(data.m_position);

        if (info.m_requireSurfaceMaps)
        {
            Singleton <TerrainManager> .instance.GetSurfaceMapping(data.m_position, out data.m_dataTexture0, out data.m_dataTexture1, out data.m_dataVector3);
        }
        instanceIndex = (uint)data.m_nextInstance;
    }