コード例 #1
0
        /// <summary>
        /// Called 1000s of times every frame! Must be high-performant!
        /// Not called when viewing from distance.
        /// </summary>
        /// <param name="cameraInfo"></param>
        /// <param name="segmentID"></param>
        /// <param name="laneID"></param>
        /// <param name="laneInfo"></param>
        /// <param name="startFlags"></param>
        /// <param name="endFlags"></param>
        /// <param name="startColor"></param>
        /// <param name="endColor"></param>
        /// <param name="startAngle"></param>
        /// <param name="endAngle"></param>
        /// <param name="invert"></param>
        /// <param name="layerMask"></param>
        /// <param name="objectIndex1"></param>
        /// <param name="objectIndex2"></param>
        /// <param name="data"></param>
        /// <param name="propIndex"></param>
        public void RenderInstance(RenderManager.CameraInfo cameraInfo, ushort segmentID, uint laneID, NetInfo.Lane laneInfo, NetNode.Flags startFlags, NetNode.Flags endFlags, Color startColor, Color endColor, float startAngle, float endAngle, bool invert, int layerMask, Vector4 objectIndex1, Vector4 objectIndex2, ref RenderManager.Instance data, ref int propIndex)
        {
            var laneProps = laneInfo.m_laneProps;
            if (laneProps != null && laneProps.m_props != null)
            {
                var flag = (byte)(laneInfo.m_finalDirection & NetInfo.Direction.Both) == 2 || (byte)(laneInfo.m_finalDirection & NetInfo.Direction.Avoid) == 11;
                var flag2 = flag != invert;
                if (flag)
                {
                    var flags = startFlags;
                    startFlags = endFlags;
                    endFlags = flags;
                }
                var num = laneProps.m_props.Length;

                // mod begin
                var _this = NetManager.instance.m_lanes.m_buffer[laneID];
                var streetLightPrefabDataIndices = PropCustomizer.Instance.StreetLightPrefabDataIndices;
                var segmentData = SegmentDataManager.Instance.SegmentToSegmentDataMap?[_this.m_segment];
                // mod end

                for (var i = 0; i < num; i++)
                {
                    var prop = laneProps.m_props[i];
                    if (_this.m_length >= prop.m_minLength)
                    {
                        // mod begin
                        var prop_m_angle = prop.m_angle;
                        var finalProp = prop.m_finalProp;
                        var finalTree = prop.m_finalTree;
                        var repeatDistance = prop.m_repeatDistance;
                        if (segmentData != null)
                        {
                            // custom street lights
                            if (finalProp != null)
                            {
                                var customLight = (segmentData.Features & SegmentData.FeatureFlags.StreetLight) != 0;

                                // Contains seems to be faster than array lookup
                                if ((customLight || segmentData.RepeatDistances.magnitude > 0f) && streetLightPrefabDataIndices.Contains(finalProp.m_prefabDataIndex))
                                {
                                    if (customLight)
                                    {
                                        finalProp = segmentData.StreetLightPrefab;
                                        if (laneInfo.m_position + prop.m_position.x < 0f) prop_m_angle = 180; //rotate street lights on pedestrian paths correctly
                                    }
                                    if (segmentData.RepeatDistances.w > 0f)
                                    {
                                        repeatDistance = segmentData.RepeatDistances.w;
                                    }
                                }
                            }

                            // custom road trees
                            else if (finalTree != null)
                            {
                                if (laneInfo.m_position < 0) // Left Trees
                                {
                                    if ((segmentData.Features & SegmentData.FeatureFlags.TreeLeft) != 0)
                                    {
                                        finalTree = segmentData.TreeLeftPrefab;
                                    }
                                    if (segmentData.RepeatDistances.x > 0f)
                                    {
                                        repeatDistance = segmentData.RepeatDistances.x;
                                    }
                                }
                                else if (laneInfo.m_position == 0) // Middle Trees
                                {
                                    if ((segmentData.Features & SegmentData.FeatureFlags.TreeMiddle) != 0)
                                    {
                                        finalTree = segmentData.TreeMiddlePrefab;
                                    }
                                    if (segmentData.RepeatDistances.y > 0f)
                                    {
                                        repeatDistance = segmentData.RepeatDistances.y;
                                    }
                                }
                                else // Right Trees
                                {
                                    if ((segmentData.Features & SegmentData.FeatureFlags.TreeRight) != 0)
                                    {
                                        finalTree = segmentData.TreeRightPrefab;
                                    }
                                    if (segmentData.RepeatDistances.z > 0f)
                                    {
                                        repeatDistance = segmentData.RepeatDistances.z;
                                    }
                                }
                            }
                        }
                        // mod end

                        var num2 = 2;
                        if (repeatDistance > 1f)
                        {
                            num2 *= Mathf.Max(1, Mathf.RoundToInt(_this.m_length / repeatDistance));
                        }
                        var num3 = propIndex;
                        if (propIndex != -1)
                        {
                            propIndex = num3 + (num2 + 1 >> 1);
                        }
                        if (prop.CheckFlags((NetLane.Flags)_this.m_flags, startFlags, endFlags))
                        {
                            var num4 = prop.m_segmentOffset * 0.5f;
                            if (_this.m_length != 0f)
                            {
                                num4 = Mathf.Clamp(num4 + prop.m_position.z / _this.m_length, -0.5f, 0.5f);
                            }
                            if (flag2)
                            {
                                num4 = -num4;
                            }

                            if (finalProp != null && (layerMask & 1 << finalProp.m_prefabDataLayer) != 0)
                            {
                                var color = (prop.m_colorMode != NetLaneProps.ColorMode.EndState) ? startColor : endColor;
                                var randomizer = new Randomizer((int)(laneID + (uint)i));
                                for (var j = 1; j <= num2; j += 2)
                                {
                                    if (randomizer.Int32(100u) < prop.m_probability)
                                    {
                                        var num5 = num4 + (float)j / (float)num2;
                                        var variation = finalProp.GetVariation(ref randomizer);
                                        var scale = variation.m_minScale + (float)randomizer.Int32(10000u) * (variation.m_maxScale - variation.m_minScale) * 0.0001f;
                                        if (prop.m_colorMode == NetLaneProps.ColorMode.Default)
                                        {
                                            color = variation.GetColor(ref randomizer);
                                        }
                                        var vector = _this.m_bezier.Position(num5);
                                        if (propIndex != -1)
                                        {
                                            vector.y = (float)data.m_extraData.GetUShort(num3++) * 0.015625f;
                                        }
                                        vector.y += prop.m_position.y;
                                        if (cameraInfo.CheckRenderDistance(vector, variation.m_maxRenderDistance))
                                        {
                                            var vector2 = _this.m_bezier.Tangent(num5);
                                            if (vector2 != Vector3.zero)
                                            {
                                                if (flag2)
                                                {
                                                    vector2 = -vector2;
                                                }
                                                vector2.y = 0f;
                                                if (prop.m_position.x != 0f)
                                                {
                                                    vector2 = Vector3.Normalize(vector2);
                                                    vector.x += vector2.z * prop.m_position.x;
                                                    vector.z -= vector2.x * prop.m_position.x;
                                                }
                                                var num6 = Mathf.Atan2(vector2.x, -vector2.z);
                                                if (prop.m_cornerAngle != 0f || prop.m_position.x != 0f)
                                                {
                                                    var num7 = endAngle - startAngle;
                                                    if (num7 > 3.14159274f)
                                                    {
                                                        num7 -= 6.28318548f;
                                                    }
                                                    if (num7 < -3.14159274f)
                                                    {
                                                        num7 += 6.28318548f;
                                                    }
                                                    var num8 = startAngle + num7 * num5;
                                                    num7 = num8 - num6;
                                                    if (num7 > 3.14159274f)
                                                    {
                                                        num7 -= 6.28318548f;
                                                    }
                                                    if (num7 < -3.14159274f)
                                                    {
                                                        num7 += 6.28318548f;
                                                    }
                                                    num6 += num7 * prop.m_cornerAngle;
                                                    if (num7 != 0f && prop.m_position.x != 0f)
                                                    {
                                                        var num9 = Mathf.Tan(num7);
                                                        vector.x += vector2.x * num9 * prop.m_position.x;
                                                        vector.z += vector2.z * num9 * prop.m_position.x;
                                                    }
                                                }
                                                Vector4 objectIndex3 = (num5 <= 0.5f) ? objectIndex1 : objectIndex2;
                                                num6 += prop_m_angle * 0.0174532924f;

                                                PropInstance.RenderInstance(cameraInfo, variation, new InstanceID
                                                {
                                                    NetSegment = segmentID
                                                }, vector, scale, num6, color, objectIndex3, true);
                                                /*
                                                catch // debug code
                                                {
                                                    throw new Exception($"DEBUG: Prop Rendering Error\n" +
                                                              $"Net Name: {NetManager.instance.m_segments.m_buffer[segmentID].Info?.name}\n" +
                                                              $"Prop Name: {finalProp?.name}\n" +
                                                              $"Variation Name: {variation?.name}\n" +
                                                              $"Camera exists? {cameraInfo != null}");
                                                }*/
                                            }
                                        }
                                    }
                                }
                            }

                            if (finalTree != null && (layerMask & 1 << finalTree.m_prefabDataLayer) != 0)
                            {
                                var randomizer2 = new Randomizer((int)(laneID + (uint)i));
                                for (var k = 1; k <= num2; k += 2)
                                {
                                    if (randomizer2.Int32(100u) < prop.m_probability)
                                    {
                                        var t = num4 + (float)k / (float)num2;
                                        var variation2 = finalTree.GetVariation(ref randomizer2);
                                        var scale2 = variation2.m_minScale + (float)randomizer2.Int32(10000u) * (variation2.m_maxScale - variation2.m_minScale) * 0.0001f;
                                        var brightness = variation2.m_minBrightness + (float)randomizer2.Int32(10000u) * (variation2.m_maxBrightness - variation2.m_minBrightness) * 0.0001f;
                                        var position = _this.m_bezier.Position(t);
                                        if (propIndex != -1)
                                        {
                                            position.y = (float)data.m_extraData.GetUShort(num3++) * 0.015625f;
                                        }
                                        position.y += prop.m_position.y;
                                        if (prop.m_position.x != 0f)
                                        {
                                            var vector3 = _this.m_bezier.Tangent(t);
                                            if (flag2)
                                            {
                                                vector3 = -vector3;
                                            }
                                            vector3.y = 0f;
                                            vector3 = Vector3.Normalize(vector3);
                                            position.x += vector3.z * prop.m_position.x;
                                            position.z -= vector3.x * prop.m_position.x;
                                        }
                                        global::TreeInstance.RenderInstance(cameraInfo, variation2, position, scale2, brightness);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #2
0
        // NetSegment
        private void RenderInstance(RenderManager.CameraInfo cameraInfo, ushort segmentID, int layerMask, NetInfo info, ref RenderManager.Instance data)
        {
            var _this = NetManager.instance.m_segments.m_buffer[segmentID];

            NetManager instance = Singleton<NetManager>.instance;
            if (data.m_dirty)
            {
                data.m_dirty = false;
                Vector3 position = instance.m_nodes.m_buffer[(int)_this.m_startNode].m_position;
                Vector3 position2 = instance.m_nodes.m_buffer[(int)_this.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(_this.m_startNode))
                {
                    colorLocation = RenderManager.GetColorLocation(86016u + (uint)_this.m_startNode);
                }
                if (NetNode.BlendJunction(_this.m_endNode))
                {
                    vector = RenderManager.GetColorLocation(86016u + (uint)_this.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 ((_this.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
                        {
                            invert = true;
                            NetInfo info2 = instance.m_nodes.m_buffer[(int)_this.m_endNode].Info;
                            NetNode.Flags flags;
                            Color color;
                            info2.m_netAI.GetNodeState(_this.m_endNode, ref instance.m_nodes.m_buffer[(int)_this.m_endNode], segmentID, ref _this, out flags, out color);
                            NetInfo info3 = instance.m_nodes.m_buffer[(int)_this.m_startNode].Info;
                            NetNode.Flags flags2;
                            Color color2;
                            info3.m_netAI.GetNodeState(_this.m_startNode, ref instance.m_nodes.m_buffer[(int)_this.m_startNode], segmentID, ref _this, out flags2, out color2);
                        }
                        else
                        {
                            invert = false;
                            NetInfo info4 = instance.m_nodes.m_buffer[(int)_this.m_startNode].Info;
                            NetNode.Flags flags;
                            Color color;
                            info4.m_netAI.GetNodeState(_this.m_startNode, ref instance.m_nodes.m_buffer[(int)_this.m_startNode], segmentID, ref _this, out flags, out color);
                            NetInfo info5 = instance.m_nodes.m_buffer[(int)_this.m_endNode].Info;
                            NetNode.Flags flags2;
                            Color color2;
                            info5.m_netAI.GetNodeState(_this.m_endNode, ref instance.m_nodes.m_buffer[(int)_this.m_endNode], segmentID, ref _this, out flags2, out color2);
                        }
                        float startAngle = (float)_this.m_cornerAngleStart * 0.0245436933f;
                        float endAngle = (float)_this.m_cornerAngleEnd * 0.0245436933f;
                        int num = 0;
                        uint num2 = _this.m_lanes;
                        int num3 = 0;
                        while (num3 < info.m_lanes.Length && num2 != 0u)
                        {
                            instance.m_lanes.m_buffer[(int)((UIntPtr)num2)].RefreshInstance(num2, info.m_lanes[num3], startAngle, endAngle, invert, ref data, ref num);
                            num2 = instance.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_nextLane;
                            num3++;
                        }
                    }
                }
                else
                {
                    float vScale = info.m_netAI.GetVScale();
                    Vector3 vector2;
                    Vector3 startDir;
                    bool smoothStart;
                    _this.CalculateCorner(segmentID, true, true, true, out vector2, out startDir, out smoothStart);
                    Vector3 vector3;
                    Vector3 endDir;
                    bool smoothEnd;
                    _this.CalculateCorner(segmentID, true, false, true, out vector3, out endDir, out smoothEnd);
                    Vector3 vector4;
                    Vector3 startDir2;
                    _this.CalculateCorner(segmentID, true, true, false, out vector4, out startDir2, out smoothStart);
                    Vector3 vector5;
                    Vector3 endDir2;
                    _this.CalculateCorner(segmentID, true, false, false, out vector5, out endDir2, out smoothEnd);
                    Vector3 vector6;
                    Vector3 vector7;
                    NetSegment.CalculateMiddlePoints(vector2, startDir, vector5, endDir2, smoothStart, smoothEnd, out vector6, out vector7);
                    Vector3 vector8;
                    Vector3 vector9;
                    NetSegment.CalculateMiddlePoints(vector4, startDir2, vector3, endDir, smoothStart, smoothEnd, out vector8, out vector9);
                    data.m_dataMatrix0 = NetSegment.CalculateControlMatrix(vector2, vector6, vector7, vector5, vector4, vector8, vector9, vector3, data.m_position, vScale);
                    data.m_dataMatrix1 = NetSegment.CalculateControlMatrix(vector4, vector8, vector9, vector3, vector2, vector6, vector7, vector5, 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);
                }
            }
            if (info.m_segments != null)
            {
                for (int i = 0; i < info.m_segments.Length; i++)
                {
                    NetInfo.Segment segment = info.m_segments[i];
                    bool flag;
                    if (segment.CheckFlags(_this.m_flags, out flag))
                    {
                        Vector4 dataVector = data.m_dataVector3;
                        Vector4 dataVector2 = data.m_dataVector0;
                        if (segment.m_requireWindSpeed)
                        {
                            dataVector.w = data.m_dataFloat0;
                        }
                        if (flag)
                        {
                            dataVector2.x = -dataVector2.x;
                            dataVector2.y = -dataVector2.y;
                        }
                        if (cameraInfo.CheckRenderDistance(data.m_position, segment.m_lodRenderDistance))
                        {
                            instance.m_materialBlock.Clear();
                            instance.m_materialBlock.AddMatrix(instance.ID_LeftMatrix, data.m_dataMatrix0);
                            instance.m_materialBlock.AddMatrix(instance.ID_RightMatrix, data.m_dataMatrix1);
                            instance.m_materialBlock.AddVector(instance.ID_MeshScale, dataVector2);
                            instance.m_materialBlock.AddVector(instance.ID_ObjectIndex, dataVector);
                            instance.m_materialBlock.AddColor(instance.ID_Color, data.m_dataColor0);
                            if (segment.m_requireSurfaceMaps && data.m_dataTexture0 != null)
                            {
                                instance.m_materialBlock.AddTexture(instance.ID_SurfaceTexA, data.m_dataTexture0);
                                instance.m_materialBlock.AddTexture(instance.ID_SurfaceTexB, data.m_dataTexture1);
                                instance.m_materialBlock.AddVector(instance.ID_SurfaceMapping, data.m_dataVector1);
                            }
                            NetManager expr_5D7_cp_0 = instance;
                            expr_5D7_cp_0.m_drawCallData.m_defaultCalls = expr_5D7_cp_0.m_drawCallData.m_defaultCalls + 1;
                            Graphics.DrawMesh(segment.m_segmentMesh, data.m_position, data.m_rotation, segment.m_segmentMaterial, segment.m_layer, null, 0, instance.m_materialBlock); // TODO
                        }
                        else
                        {
                            NetInfo.LodValue combinedLod = segment.m_combinedLod;
                            if (combinedLod != null)
                            {
                                if (segment.m_requireSurfaceMaps && data.m_dataTexture0 != combinedLod.m_surfaceTexA)
                                {
                                    if (combinedLod.m_lodCount != 0)
                                    {
                                        NetSegment.RenderLod(cameraInfo, combinedLod);
                                    }
                                    combinedLod.m_surfaceTexA = data.m_dataTexture0;
                                    combinedLod.m_surfaceTexB = data.m_dataTexture1;
                                    combinedLod.m_surfaceMapping = data.m_dataVector1;
                                }
                                combinedLod.m_leftMatrices[combinedLod.m_lodCount] = data.m_dataMatrix0;
                                combinedLod.m_rightMatrices[combinedLod.m_lodCount] = data.m_dataMatrix1;
                                combinedLod.m_meshScales[combinedLod.m_lodCount] = dataVector2;
                                combinedLod.m_objectIndices[combinedLod.m_lodCount] = dataVector;
                                combinedLod.m_meshLocations[combinedLod.m_lodCount] = data.m_position;
                                combinedLod.m_lodMin = Vector3.Min(combinedLod.m_lodMin, data.m_position);
                                combinedLod.m_lodMax = Vector3.Max(combinedLod.m_lodMax, data.m_position);
                                if (++combinedLod.m_lodCount == combinedLod.m_leftMatrices.Length)
                                {
                                    NetSegment.RenderLod(cameraInfo, combinedLod);
                                }
                            }
                        }
                    }
                }
            }
            if (info.m_lanes != null && ((layerMask & info.m_treeLayers) != 0 || cameraInfo.CheckRenderDistance(data.m_position, info.m_maxPropDistance + 128f)))
            {
                bool invert2;
                NetNode.Flags startFlags;
                Color startColor;
                NetNode.Flags endFlags;
                Color endColor;
                if ((_this.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
                {
                    invert2 = true;
                    NetInfo info6 = instance.m_nodes.m_buffer[(int)_this.m_endNode].Info;
                    info6.m_netAI.GetNodeState(_this.m_endNode, ref instance.m_nodes.m_buffer[(int)_this.m_endNode], segmentID, ref _this, out startFlags, out startColor);
                    NetInfo info7 = instance.m_nodes.m_buffer[(int)_this.m_startNode].Info;
                    info7.m_netAI.GetNodeState(_this.m_startNode, ref instance.m_nodes.m_buffer[(int)_this.m_startNode], segmentID, ref _this, out endFlags, out endColor);
                }
                else
                {
                    invert2 = false;
                    NetInfo info8 = instance.m_nodes.m_buffer[(int)_this.m_startNode].Info;
                    info8.m_netAI.GetNodeState(_this.m_startNode, ref instance.m_nodes.m_buffer[(int)_this.m_startNode], segmentID, ref _this, out startFlags, out startColor);
                    NetInfo info9 = instance.m_nodes.m_buffer[(int)_this.m_endNode].Info;
                    info9.m_netAI.GetNodeState(_this.m_endNode, ref instance.m_nodes.m_buffer[(int)_this.m_endNode], segmentID, ref _this, out endFlags, out endColor);
                }
                float startAngle2 = (float)_this.m_cornerAngleStart * 0.0245436933f;
                float endAngle2 = (float)_this.m_cornerAngleEnd * 0.0245436933f;
                Vector4 objectIndex = new Vector4(data.m_dataVector3.x, data.m_dataVector3.y, 1f, data.m_dataFloat0);
                Vector4 objectIndex2 = new Vector4(data.m_dataVector3.z, data.m_dataVector3.w, 1f, data.m_dataFloat0);
                InfoManager.InfoMode currentMode = Singleton<InfoManager>.instance.CurrentMode;
                if (currentMode != InfoManager.InfoMode.None && !info.m_netAI.ColorizeProps(currentMode))
                {
                    objectIndex.z = 0f;
                    objectIndex2.z = 0f;
                }
                int num4 = (info.m_segments != null && info.m_segments.Length != 0) ? -1 : 0;
                uint num5 = _this.m_lanes;
                int num6 = 0;
                while (num6 < info.m_lanes.Length && num5 != 0u)
                {
                    instance.m_lanes.m_buffer[(int)((UIntPtr)num5)].RenderInstance(cameraInfo, segmentID, num5, info.m_lanes[num6], startFlags, endFlags, startColor, endColor, startAngle2, endAngle2, invert2, layerMask, objectIndex, objectIndex2, ref data, ref num4);
                    num5 = instance.m_lanes.m_buffer[(int)((UIntPtr)num5)].m_nextLane;
                    num6++;
                }
            }
        }
コード例 #3
0
        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;
        }