Beispiel #1
0
 public static void CalculateGroupData(NetInfo.Segment segmentInfo, ref int vertexCount, ref int triangleCount, ref int objectCount, ref RenderGroup.VertexArrays vertexArrays)
 {
     RenderGroup.MeshData meshData = segmentInfo.m_combinedLod.m_key.m_mesh.m_data;
     vertexCount   += meshData.m_vertices.Length;
     triangleCount += meshData.m_triangles.Length;
     objectCount++;
     vertexArrays |= meshData.VertexArrayMask() | RenderGroup.VertexArrays.Colors | RenderGroup.VertexArrays.Uvs2 | RenderGroup.VertexArrays.Uvs4;
 }
Beispiel #2
0
        /// <summary>
        /// Checks the lod mesh data.
        /// </summary>
        /// <param name="meshData">The mesh data.</param>
        /// <returns>True if mesh has triangles.</returns>
        protected static bool CheckLodMeshData(RenderGroup.MeshData meshData)
        {
            if (meshData == null)
            {
                return(false);
            }

            return(meshData.m_triangles != null && meshData.m_triangles.Length > 0);
        }
Beispiel #3
0
        /// <summary>
        /// Gets the lod mesh.
        /// </summary>
        /// <param name="prefab">The prefab.</param>
        /// <returns>
        /// The lod mesh.
        /// </returns>
        protected override Mesh GetLodMesh(PrefabInfo prefab)
        {
            if (CheckLodMesh(((TreeInfo)prefab).m_lodMesh16))
            {
                return(((TreeInfo)prefab).m_lodMesh16);
            }
            else if (CheckLodMesh(((TreeInfo)prefab).m_lodMesh8))
            {
                return(((TreeInfo)prefab).m_lodMesh8);
            }
            else if (CheckLodMesh(((TreeInfo)prefab).m_lodMesh4))
            {
                return(((TreeInfo)prefab).m_lodMesh4);
            }
            else if (CheckLodMesh(((TreeInfo)prefab).m_lodMesh1))
            {
                return(((TreeInfo)prefab).m_lodMesh1);
            }

            Mesh mesh = new Mesh();

            if (CheckLodMeshData(((TreeInfo)prefab).m_lodMeshData16))
            {
                ((TreeInfo)prefab).m_lodMeshData16.PopulateMesh(mesh);
                return(mesh);
            }
            else if (CheckLodMeshData(((TreeInfo)prefab).m_lodMeshData8))
            {
                ((TreeInfo)prefab).m_lodMeshData8.PopulateMesh(mesh);
                return(mesh);
            }
            else if (CheckLodMeshData(((TreeInfo)prefab).m_lodMeshData4))
            {
                ((TreeInfo)prefab).m_lodMeshData4.PopulateMesh(mesh);
                return(mesh);
            }
            else if (CheckLodMeshData(((TreeInfo)prefab).m_lodMeshData1))
            {
                ((TreeInfo)prefab).m_lodMeshData1.PopulateMesh(mesh);
                return(mesh);
            }

            try
            {
                RenderGroup.MeshData meshData = GenerateLodMeshData((TreeInfo)prefab);

                mesh = new Mesh();
                meshData.PopulateMesh(mesh);
                return(mesh);
            }
            catch
            {
                return(null);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Generates the lod mesh data.
        /// </summary>
        /// <param name="treeInfo">The tree information.</param>
        /// <returns>The mesh data.</returns>
        private static RenderGroup.MeshData GenerateLodMeshData(TreeInfo treeInfo)
        {
            // From game code at 2017-08-02.
            RenderGroup.VertexArrays vertexArrays = (RenderGroup.VertexArrays) 0;
            int vertexCount   = 0;
            int triangleCount = 0;
            int objectCount   = 0;

            TreeInstance.CalculateGroupData(ref vertexCount, ref triangleCount, ref objectCount, ref vertexArrays);
            RenderGroup.MeshData data1 = new RenderGroup.MeshData(vertexArrays, vertexCount, triangleCount);
            RenderGroup.MeshData data2 = new RenderGroup.MeshData(vertexArrays, vertexCount * 4, triangleCount * 4);
            RenderGroup.MeshData data3 = new RenderGroup.MeshData(vertexArrays, vertexCount * 8, triangleCount * 8);
            RenderGroup.MeshData data4 = new RenderGroup.MeshData(vertexArrays, vertexCount * 16, triangleCount * 16);
            Vector3 zero1               = Vector3.zero;
            Vector3 zero2               = Vector3.zero;
            float   maxRenderDistance   = 0.0f;
            float   maxInstanceDistance = 0.0f;
            //int vertexIndex1 = 0;
            //int triangleIndex1 = 0;
            //for (int index = 0; index < 1; ++index)
            //    TreeInstance.PopulateGroupData(treeInfo, new Vector3(0.0f, 0.0f, (float)index), 1f, 1f, ref vertexIndex1, ref triangleIndex1, Vector3.zero, data1, ref zero1, ref zero2, ref maxRenderDistance, ref maxInstanceDistance);
            //int vertexIndex2 = 0;
            //int triangleIndex2 = 0;
            //for (int index = 0; index < 4; ++index)
            //    TreeInstance.PopulateGroupData(treeInfo, new Vector3(0.0f, 0.0f, (float)index), 1f, 1f, ref vertexIndex2, ref triangleIndex2, Vector3.zero, data2, ref zero1, ref zero2, ref maxRenderDistance, ref maxInstanceDistance);
            //int vertexIndex3 = 0;
            //int triangleIndex3 = 0;
            //for (int index = 0; index < 8; ++index)
            //    TreeInstance.PopulateGroupData(treeInfo, new Vector3(0.0f, 0.0f, (float)index), 1f, 1f, ref vertexIndex3, ref triangleIndex3, Vector3.zero, data3, ref zero1, ref zero2, ref maxRenderDistance, ref maxInstanceDistance);
            int vertexIndex4   = 0;
            int triangleIndex4 = 0;

            for (int index = 0; index < 16; ++index)
            {
                TreeInstance.PopulateGroupData(treeInfo, new Vector3(0.0f, 0.0f, (float)index), 1f, 1f, ref vertexIndex4, ref triangleIndex4, Vector3.zero, data4, ref zero1, ref zero2, ref maxRenderDistance, ref maxInstanceDistance);
            }

            return(data4);
        }
Beispiel #5
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);
        }
Beispiel #6
0
        public static void AfterPopulateGroupData(BuildingManager __instance, int groupX, int groupZ, int layer, ref int vertexIndex, ref int triangleIndex, ref Vector3 groupPosition, RenderGroup.MeshData data, ref Vector3 min, ref Vector3 max, ref float maxRenderDistance, ref float maxInstanceDistance)
        {
            if (LoadingManager.instance.m_currentlyLoading)
            {
                return;
            }

            if (WriteTheSignsMod.Controller?.BuildingPropsSingleton == null)
            {
                return;
            }
            int num  = groupX * 270 / 45;
            int num2 = groupZ * 270 / 45;
            int num3 = (groupX + 1) * 270 / 45 - 1;
            int num4 = (groupZ + 1) * 270 / 45 - 1;

            for (int i = num2; i <= num4; i++)
            {
                for (int j = num; j <= num3; j++)
                {
                    int    num5 = i * 270 + j;
                    ushort num6 = __instance.m_buildingGrid[num5];
                    int    num7 = 0;
                    while (num6 != 0)
                    {
                        WriteTheSignsMod.Controller.BuildingPropsSingleton.PopulateGroupData(num6, layer, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance);
                        num6 = __instance.m_buildings.m_buffer[num6].m_nextGridBuilding;
                        if (++num7 >= 49152)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
        }
Beispiel #7
0
        public override void PopulateGroupData(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)
        {
            int num1 = groupX * 270 / 45;
            int num2 = groupZ * 270 / 45;
            int num3 = (groupX + 1) * 270 / 45 - 1;
            int num4 = (groupZ + 1) * 270 / 45 - 1;

            for (int index1 = num2; index1 <= num4; ++index1)
            {
                for (int index2 = num1; index2 <= num3; ++index2)
                {
                    ushort buildingID = this.m_buildingGrid[index1 * 270 + index2];
                    int    num5       = 0;
                    while ((int)buildingID != 0)
                    {
                        //add null check
                        //begin mod
                        if (this.m_buildings.m_buffer[(int)buildingID].Info != null)
                        {
                            this.m_buildings.m_buffer[(int)buildingID].PopulateGroupData(buildingID, groupX, groupZ,
                                                                                         layer, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max,
                                                                                         ref maxRenderDistance, ref maxInstanceDistance);
                        }
                        //end mod
                        buildingID = this.m_buildings.m_buffer[(int)buildingID].m_nextGridBuilding;
                        if (++num5 >= 49152)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core,
                                                            "Invalid list detected!\n" + System.Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
        }
Beispiel #8
0
        static bool Prefix(TreeInfo info, Vector3 position, float scale, float brightness, Vector4 objectIndex, ref int vertexIndex, ref int triangleIndex, Vector3 groupPosition, RenderGroup.MeshData data, ref Vector3 min, ref Vector3 max, ref float maxRenderDistance, ref float maxInstanceDistance)
        {
            float y   = info.m_generatedInfo.m_size.y * scale;
            float num = Mathf.Max(info.m_generatedInfo.m_size.x, info.m_generatedInfo.m_size.z) * scale * 0.5f;

            min = Vector3.Min(min, position - new Vector3(num, 0f, num));
            max = Vector3.Max(max, position + new Vector3(num, y, num));
            maxRenderDistance   = Mathf.Max(maxRenderDistance, 30000f);
            maxInstanceDistance = Mathf.Max(maxInstanceDistance, 425f);
            Color32 color = (info.m_defaultColor * brightness).linear;

            // We must always set this to zero on level load, since the
            // renderer always uses the default value for far trees
            // There's no way for changing this dynamically ingame, because that means
            // we recalculate 200,000 trees periodically
            lock (App.Config.GraphicsLock) {
                if (App.Config.Graphics.stopDistantTrees)
                {
                    color.a = 0;
                }
                else
                {
                    color.a = (byte)Mathf.Clamp(Mathf.RoundToInt(Singleton <WeatherManager> .instance.GetWindSpeed(position) * 128f), 0, 255);
                }
            }

            position   -= groupPosition;
            position.y += info.m_generatedInfo.m_center.y * scale;
            data.m_vertices[vertexIndex] = position + new Vector3(info.m_renderUv0B.x * scale, info.m_renderUv0B.y * scale, 0f);
            data.m_normals[vertexIndex]  = objectIndex;
            data.m_uvs[vertexIndex]      = info.m_renderUv0;
            data.m_uvs2[vertexIndex]     = info.m_renderUv0B * scale;
            data.m_colors[vertexIndex]   = color;
            vertexIndex++;
            data.m_vertices[vertexIndex] = position + new Vector3(info.m_renderUv1B.x * scale, info.m_renderUv1B.y * scale, 0f);
            data.m_normals[vertexIndex]  = objectIndex;
            data.m_uvs[vertexIndex]      = info.m_renderUv1;
            data.m_uvs2[vertexIndex]     = info.m_renderUv1B * scale;
            data.m_colors[vertexIndex]   = color;
            vertexIndex++;
            data.m_vertices[vertexIndex] = position + new Vector3(info.m_renderUv2B.x * scale, info.m_renderUv2B.y * scale, 0f);
            data.m_normals[vertexIndex]  = objectIndex;
            data.m_uvs[vertexIndex]      = info.m_renderUv2;
            data.m_uvs2[vertexIndex]     = info.m_renderUv2B * scale;
            data.m_colors[vertexIndex]   = color;
            vertexIndex++;
            data.m_vertices[vertexIndex] = position + new Vector3(info.m_renderUv3B.x * scale, info.m_renderUv3B.y * scale, 0f);
            data.m_normals[vertexIndex]  = objectIndex;
            data.m_uvs[vertexIndex]      = info.m_renderUv3;
            data.m_uvs2[vertexIndex]     = info.m_renderUv3B * scale;
            data.m_colors[vertexIndex]   = color;
            vertexIndex++;
            data.m_triangles[triangleIndex++] = vertexIndex - 4;
            data.m_triangles[triangleIndex++] = vertexIndex - 3;
            data.m_triangles[triangleIndex++] = vertexIndex - 2;
            data.m_triangles[triangleIndex++] = vertexIndex - 2;
            data.m_triangles[triangleIndex++] = vertexIndex - 3;
            data.m_triangles[triangleIndex++] = vertexIndex - 1;

            return(false);
        }
Beispiel #9
0
        public void PopulateGroupData(
            ushort segmentID, uint laneID, NetInfo.Lane laneInfo, bool destroyed,
            NetNode.Flags startFlags, NetNode.Flags endFlags,
            float startAngle, float endAngle,
            bool invert, bool terrainHeight, 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 hasProps)
        {
            NetLaneProps laneProps = laneInfo.m_laneProps;

            if (laneProps?.m_props == null)
            {
                return;
            }
            bool backward = (laneInfo.m_finalDirection & NetInfo.Direction.Both) == NetInfo.Direction.Backward || (laneInfo.m_finalDirection & NetInfo.Direction.AvoidBoth) == NetInfo.Direction.AvoidForward;
            bool reverse  = backward != invert;

            if (backward)  //swap
            {
                NetNode.Flags flags = startFlags;
                startFlags = endFlags;
                endFlags   = flags;
            }
            int nProps = laneProps.m_props.Length;

            for (int i = 0; i < nProps; i++)
            {
                NetLaneProps.Prop prop = laneProps.m_props[i];
                if (!prop.CheckFlags(m_flags, startFlags, endFlags) || m_length < prop.m_minLength)
                {
                    continue;
                }
                int repeatCountTimes2 = 2;
                if (prop.m_repeatDistance > 1f)
                {
                    repeatCountTimes2 *= Mathf.Max(1, Mathf.RoundToInt(m_length / prop.m_repeatDistance));
                }
                float halfSegmentOffset = prop.m_segmentOffset * 0.5f;
                if (m_length != 0f)
                {
                    halfSegmentOffset = Mathf.Clamp(halfSegmentOffset + prop.m_position.z / m_length, -0.5f, 0.5f);
                }
                if (reverse)
                {
                    halfSegmentOffset = 0f - halfSegmentOffset;
                }
                PropInfo finalProp = prop.m_finalProp;
                if ((object)finalProp != null)
                {
                    hasProps = true;
                    if (finalProp.m_prefabDataLayer == layer || finalProp.m_effectLayer == layer)
                    {
                        Color      color = Color.white;
                        Randomizer r     = new Randomizer((int)laneID + i);
                        for (int j = 1; j <= repeatCountTimes2; j += 2)
                        {
                            if (r.Int32(100u) >= prop.m_probability)
                            {
                                continue;
                            }
                            float    t         = halfSegmentOffset + (float)j / (float)repeatCountTimes2;
                            PropInfo variation = finalProp.GetVariation(ref r);
                            float    scale     = variation.m_minScale + (float)r.Int32(10000u) * (variation.m_maxScale - variation.m_minScale) * 0.0001f;
                            if (prop.m_colorMode == NetLaneProps.ColorMode.Default)
                            {
                                color = variation.GetColor(ref r);
                            }
                            if (!variation.m_isDecal && destroyed)
                            {
                                continue;
                            }
                            Vector3 pos = m_bezier.Position(t);
                            Vector3 tan = m_bezier.Tangent(t);
                            if (!(tan != Vector3.zero))
                            {
                                continue;
                            }
                            if (reverse)
                            {
                                tan = -tan;
                            }
                            tan.y = 0f;
                            if (prop.m_position.x != 0f)
                            {
                                tan    = Vector3.Normalize(tan);
                                pos.x += tan.z * prop.m_position.x;
                                pos.z -= tan.x * prop.m_position.x;
                            }
                            float normalAngle = Mathf.Atan2(tan.x, 0f - tan.z);
                            if (prop.m_cornerAngle != 0f || prop.m_position.x != 0f)
                            {
                                float angleDiff = endAngle - startAngle;
                                if (angleDiff > Mathf.PI)
                                {
                                    angleDiff -= Mathf.PI * 2f;
                                }
                                if (angleDiff < -Mathf.PI)
                                {
                                    angleDiff += Mathf.PI * 2f;
                                }
                                var angle2 = startAngle + angleDiff * t - normalAngle;
                                if (angle2 > Mathf.PI)
                                {
                                    angle2 -= Mathf.PI * 2f;
                                }
                                if (angle2 < -Mathf.PI)
                                {
                                    angle2 += Mathf.PI * 2f;
                                }
                                normalAngle += angle2 * prop.m_cornerAngle;
                                if (angle2 != 0f && prop.m_position.x != 0f)
                                {
                                    float d = Mathf.Tan(angle2);
                                    pos.x += tan.x * d * prop.m_position.x;
                                    pos.z += tan.z * d * prop.m_position.x;
                                }
                            }
                            if (terrainHeight)
                            {
                                if (variation.m_requireWaterMap)
                                {
                                    pos.y = Singleton <TerrainManager> .instance.SampleRawHeightSmoothWithWater(pos, timeLerp : false, 0f);
                                }
                                else
                                {
                                    pos.y = Singleton <TerrainManager> .instance.SampleDetailHeight(pos);
                                }
                            }
                            pos.y += prop.m_position.y;
                            InstanceID id = default(InstanceID);
                            id.NetSegment = segmentID;
                            PropInstance.PopulateGroupData(angle: normalAngle + prop.m_angle * (Mathf.PI / 180f), info: variation, layer: layer, id: id, position: pos, scale: scale, color: color, vertexIndex: ref vertexIndex, triangleIndex: ref triangleIndex, groupPosition: groupPosition, data: data, min: ref min, max: ref max, maxRenderDistance: ref maxRenderDistance, maxInstanceDistance: ref maxInstanceDistance);
                        }
                    }
                }
                if (destroyed)
                {
                    continue;
                }
                TreeInfo finalTree = prop.m_finalTree;
                if ((object)finalTree == null)
                {
                    continue;
                }
                hasProps = true;
                if (finalTree.m_prefabDataLayer != layer)
                {
                    continue;
                }
                Randomizer r2 = new Randomizer((int)laneID + i);
                for (int k = 1; k <= repeatCountTimes2; k += 2)
                {
                    if (r2.Int32(100u) >= prop.m_probability)
                    {
                        continue;
                    }
                    float    t          = halfSegmentOffset + (float)k / (float)repeatCountTimes2;
                    TreeInfo variation2 = finalTree.GetVariation(ref r2);
                    float    scale2     = variation2.m_minScale + (float)r2.Int32(10000u) * (variation2.m_maxScale - variation2.m_minScale) * 0.0001f;
                    float    brightness = variation2.m_minBrightness + (float)r2.Int32(10000u) * (variation2.m_maxBrightness - variation2.m_minBrightness) * 0.0001f;
                    Vector3  vector3    = m_bezier.Position(t);
                    if (prop.m_position.x != 0f)
                    {
                        Vector3 vector4 = m_bezier.Tangent(t);
                        if (reverse)
                        {
                            vector4 = -vector4;
                        }
                        vector4.y  = 0f;
                        vector4    = Vector3.Normalize(vector4);
                        vector3.x += vector4.z * prop.m_position.x;
                        vector3.z -= vector4.x * prop.m_position.x;
                    }
                    if (terrainHeight)
                    {
                        vector3.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector3);
                    }
                    vector3.y += prop.m_position.y;
                    TreeInstance.PopulateGroupData(variation2, vector3, scale2, brightness, RenderManager.DefaultColorLocation, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance);
                }
            }
        }
        // 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;
        }
Beispiel #11
0
        public override void PopulateGroupData(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)
        {
            int num1 = groupX * 270 / 45;
            int num2 = groupZ * 270 / 45;
            int num3 = (groupX + 1) * 270 / 45 - 1;
            int num4 = (groupZ + 1) * 270 / 45 - 1;

            for (int index1 = num2; index1 <= num4; ++index1)
            {
                for (int index2 = num1; index2 <= num3; ++index2)
                {
                    ushort nodeID = this.m_nodeGrid[index1 * 270 + index2];
                    int    num5   = 0;
                    while ((int)nodeID != 0)
                    {
                        //swallow exceptions
                        //begin mod
                        try
                        {
                            this.m_nodes.m_buffer[(int)nodeID].PopulateGroupData(nodeID, groupX, groupZ, layer, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance, ref requireSurfaceMaps);
                        }
                        catch
                        {
                            //swallow
                        }
                        //end mod
                        nodeID = this.m_nodes.m_buffer[(int)nodeID].m_nextGridNode;
                        if (++num5 >= 32768)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            for (int index1 = num2; index1 <= num4; ++index1)
            {
                for (int index2 = num1; index2 <= num3; ++index2)
                {
                    ushort segmentID = this.m_segmentGrid[index1 * 270 + index2];
                    int    num5      = 0;
                    while ((int)segmentID != 0)
                    {
                        //swallow exceptions
                        //begin mod
                        try
                        {
                            this.m_segments.m_buffer[(int)segmentID].PopulateGroupData(segmentID, groupX, groupZ, layer, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance, ref requireSurfaceMaps);
                        }
                        catch
                        {
                            //swallow
                        }
                        segmentID = this.m_segments.m_buffer[(int)segmentID].m_nextGridSegment;
                        if (++num5 >= 36864)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
        }
Beispiel #12
0
 public static void PopulateGroupData(PropInfo info, int layer, InstanceID id, Vector3 position, float scale, float angle, Color color, ref int vertexIndex, ref int triangleIndex, Vector3 groupPosition, RenderGroup.MeshData data, ref Vector3 min, ref Vector3 max, ref float maxRenderDistance, ref float maxInstanceDistance)
 {
     //add null check
     //begin mod
     if (info == null)
     {
         return;
     }
     //end mod
     if (info.m_prefabDataLayer == layer)
     {
         float y   = info.m_generatedInfo.m_size.y * scale;
         float num = (float)((double)Mathf.Max(info.m_generatedInfo.m_size.x, info.m_generatedInfo.m_size.z) * (double)scale * 0.5);
         min = Vector3.Min(min, position - new Vector3(num, 0.0f, num));
         max = Vector3.Max(max, position + new Vector3(num, y, num));
         maxRenderDistance   = Mathf.Max(maxRenderDistance, info.m_maxRenderDistance);
         maxInstanceDistance = Mathf.Max(maxInstanceDistance, info.m_maxRenderDistance);
     }
     else
     {
         if (info.m_effectLayer != layer)
         {
             return;
         }
         Matrix4x4 matrix4x4 = new Matrix4x4();
         matrix4x4.SetTRS(position, Quaternion.AngleAxis(angle * 57.29578f, Vector3.down), new Vector3(scale, scale, scale));
         for (int index = 0; index < info.m_effects.Length; ++index)
         {
             Vector3 pos = matrix4x4.MultiplyPoint(info.m_effects[index].m_position);
             Vector3 dir = matrix4x4.MultiplyVector(info.m_effects[index].m_direction);
             info.m_effects[index].m_effect.PopulateGroupData(layer, id, pos, dir, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance);
         }
     }
 }
        private static bool UpdateMeshDataImpl(ref TransportLine line, ushort lineID)
        {
            bool             flag      = true;
            int              length1   = 0;
            int              num1      = 0;
            int              length2   = 0;
            float            num2      = 0.0f;
            TransportManager instance1 = Singleton <TransportManager> .instance;
            NetManager       instance2 = Singleton <NetManager> .instance;
            PathManager      instance3 = Singleton <PathManager> .instance;
            ushort           stops     = line.m_stops;
            ushort           num3      = stops;
            int              num4      = 0;

            while ((int)num3 != 0)
            {
                ushort num5 = 0;
                for (int index = 0; index < 8; ++index)
                {
                    ushort segment = instance2.m_nodes.m_buffer[(int)num3].GetSegment(index);
                    if ((int)segment != 0 && (int)instance2.m_segments.m_buffer[(int)segment].m_startNode == (int)num3)
                    {
                        uint path = instance2.m_segments.m_buffer[(int)segment].m_path;
                        if ((int)path != 0)
                        {
                            byte pathFindFlags = instance3.m_pathUnits.m_buffer[(int)path].m_pathFindFlags;
                            if (((int)pathFindFlags & 4) != 0)
                            {
                                if (!TransportLine.CalculatePathSegmentCount(path, ref num1, ref length2, ref num2))
                                {
                                    TransportLineAI.StartPathFind(segment, ref instance2.m_segments.m_buffer[(int)segment], line.Info.m_netService, line.Info.m_vehicleType, (uint)(line.m_flags & TransportLine.Flags.Temporary) > 0U);
                                    flag = false;
                                }
                            }
                            else if (((int)pathFindFlags & 8) == 0)
                            {
                                flag = false;
                            }
                        }
                        num5 = instance2.m_segments.m_buffer[(int)segment].m_endNode;
                        break;
                    }
                }
                ++length1;
                ++num1;
                num3 = num5;
                if ((int)num3 != (int)stops && flag)
                {
                    if (++num4 >= 32768)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            TransportLineMod._lineData[(int)lineID].Length = num2;
            if (!flag)
            {
                return(flag);
            }
            RenderGroup.MeshData meshData = new RenderGroup.MeshData();
            meshData.m_vertices  = new Vector3[num1 * 8];
            meshData.m_normals   = new Vector3[num1 * 8];
            meshData.m_tangents  = new Vector4[num1 * 8];
            meshData.m_uvs       = new Vector2[num1 * 8];
            meshData.m_uvs2      = new Vector2[num1 * 8];
            meshData.m_colors    = new Color32[num1 * 8];
            meshData.m_triangles = new int[num1 * 30];
            TransportManager.LineSegment[] lineSegmentArray = new TransportManager.LineSegment[length1];
            Bezier3[] bezier3Array = new Bezier3[length2];
            int       index1       = 0;
            int       num6         = 0;
            int       num7         = 0;
            float     num8         = Mathf.Ceil(num2 / 64f) / num2;
            float     num9         = 0.0f;
            ushort    num10        = stops;
            Vector3   vector3_1    = new Vector3(100000f, 100000f, 100000f);
            Vector3   vector3_2    = new Vector3(-100000f, -100000f, -100000f);
            int       num11        = 0;

            while ((int)num10 != 0)
            {
                ushort num5 = 0;
                for (int index2 = 0; index2 < 8; ++index2)
                {
                    ushort segment = instance2.m_nodes.m_buffer[(int)num10].GetSegment(index2);
                    if ((int)segment != 0 && (int)instance2.m_segments.m_buffer[(int)segment].m_startNode == (int)num10)
                    {
                        uint path = instance2.m_segments.m_buffer[(int)segment].m_path;
                        if ((int)path != 0 && ((int)instance3.m_pathUnits.m_buffer[(int)path].m_pathFindFlags & 4) != 0)
                        {
                            lineSegmentArray[index1].m_curveStart = num7;
                            Vector3 vector3_3;
                            Vector3 vector3_4;
                            TransportLine.FillPathSegments(path, meshData, bezier3Array, ref num6, ref num7, ref num9, num8, ref vector3_3, ref vector3_4);
                            vector3_1 = Vector3.Min(vector3_1, vector3_3);
                            vector3_2 = Vector3.Max(vector3_2, vector3_4);
                            lineSegmentArray[index1].m_bounds.SetMinMax(vector3_3, vector3_4);
                            lineSegmentArray[index1].m_curveEnd = num7;
                        }
                        num5 = instance2.m_segments.m_buffer[(int)segment].m_endNode;
                        break;
                    }
                }
                TransportLine.FillPathNode(instance2.m_nodes.m_buffer[(int)num10].m_position, meshData, num6);
                ++index1;
                ++num6;
                num10 = num5;
                if ((int)num10 != (int)stops)
                {
                    if (++num11 >= 32768)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            do
            {
                ;
            }while (!Monitor.TryEnter((object)instance1.m_lineMeshData, SimulationManager.SYNCHRONIZE_TIMEOUT));
            try
            {
                instance1.m_lineMeshData[(int)lineID] = (RenderGroup.MeshData[])meshData;
                instance1.m_lineSegments[(int)lineID] = lineSegmentArray;
                instance1.m_lineCurves[(int)lineID]   = bezier3Array;
                line.m_bounds.SetMinMax(vector3_1, vector3_2);
            }
            finally
            {
                Monitor.Exit((object)instance1.m_lineMeshData);
            }
            return(flag);
        }
Beispiel #14
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);
                }
            }
        }
        // Run before the original method. Skip the original one if the vehicle is a cable car
        public static bool Prefix(RenderManager.CameraInfo cameraInfo, VehicleInfo info, Vector3 position, ref Quaternion rotation, Vector3 swayPosition, Vector4 lightState, Vector4 tyrePosition, Vector3 velocity, float acceleration, Color color, Vehicle.Flags flags, int variationMask, InstanceID id, bool underground, bool overground)
        {
            // if the vehicle is not a cable car, skip and use the original method
            if ((int)info.m_vehicleType != 0x1000)
            {
                return(true);
            }

            // limit rotation along the x and z axes for all meshes except submesh1
            // submesh1 would rotate in the original way(along with the cable)
            Quaternion originalRotation = rotation;

            rotation.x = 0.0f;
            rotation.z = 0.0f;

            // change how cable cars sway
            // so they don't move up and down on the cables as if they're ships moving in sea waves
            swayPosition.y = 0.0f;

            if ((cameraInfo.m_layerMask & (1 << info.m_prefabDataLayer)) == 0)
            {
                // return false to skip the original method
                return(false);
            }
            Vector3 scale = Vector3.one;

            if ((flags & Vehicle.Flags.Inverted) != 0)
            {
                scale = new Vector3(-1f, 1f, -1f);
                Vector4 vector = lightState;
                lightState.x = vector.y;
                lightState.y = vector.x;
                lightState.z = vector.w;
                lightState.w = vector.z;
            }

            info.m_vehicleAI.RenderExtraStuff(id.Vehicle, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[id.Vehicle], cameraInfo, id, position, rotation, tyrePosition, lightState, scale, swayPosition, underground, overground);

            if (cameraInfo.CheckRenderDistance(position, info.m_lodRenderDistance))
            {
                VehicleManager instance           = Singleton <VehicleManager> .instance;
                Matrix4x4      bodyMatrix         = info.m_vehicleAI.CalculateBodyMatrix(flags, ref position, ref rotation, ref scale, ref swayPosition);
                Matrix4x4      originalBodyMatrix = info.m_vehicleAI.CalculateBodyMatrix(flags, ref position, ref originalRotation, ref scale, ref swayPosition);
                Matrix4x4      value = info.m_vehicleAI.CalculateTyreMatrix(flags, ref position, ref rotation, ref scale, ref bodyMatrix);
                if (Singleton <InfoManager> .instance.CurrentMode == InfoManager.InfoMode.None)
                {
                    RenderGroup.MeshData effectMeshData = info.m_vehicleAI.GetEffectMeshData();
                    EffectInfo.SpawnArea area           = new EffectInfo.SpawnArea(bodyMatrix, effectMeshData, info.m_generatedInfo.m_tyres, info.m_lightPositions);
                    if (info.m_effects != null)
                    {
                        for (int i = 0; i < info.m_effects.Length; i++)
                        {
                            VehicleInfo.Effect effect = info.m_effects[i];
                            if (((effect.m_vehicleFlagsRequired | effect.m_vehicleFlagsForbidden) & flags) == effect.m_vehicleFlagsRequired && effect.m_parkedFlagsRequired == VehicleParked.Flags.None)
                            {
                                effect.m_effect.RenderEffect(id, area, velocity, acceleration, 1f, -1f, Singleton <SimulationManager> .instance.m_simulationTimeDelta, cameraInfo);
                            }
                        }
                    }
                }
                if ((flags & Vehicle.Flags.Inverted) != 0)
                {
                    tyrePosition.x = 0f - tyrePosition.x;
                    tyrePosition.y = 0f - tyrePosition.y;
                }
                MaterialPropertyBlock materialBlock = instance.m_materialBlock;
                materialBlock.Clear();
                materialBlock.SetMatrix(instance.ID_TyreMatrix, value);
                materialBlock.SetVector(instance.ID_TyrePosition, tyrePosition);
                materialBlock.SetVector(instance.ID_LightState, lightState);
                bool flag = Singleton <ToolManager> .instance.m_properties.m_mode == ItemClass.Availability.AssetEditor;
                if (!flag)
                {
                    materialBlock.SetColor(instance.ID_Color, color);
                }
                bool flag2 = true;
                if (flag)
                {
                    flag2 = BuildingDecoration.IsMainMeshRendered();
                }
                if (info.m_subMeshes != null)
                {
                    for (int j = 0; j < info.m_subMeshes.Length; j++)
                    {
                        VehicleInfo.MeshInfo meshInfo = info.m_subMeshes[j];
                        VehicleInfoBase      subInfo  = meshInfo.m_subInfo;
                        if ((!flag && ((meshInfo.m_vehicleFlagsRequired | meshInfo.m_vehicleFlagsForbidden) & flags) == meshInfo.m_vehicleFlagsRequired && (meshInfo.m_variationMask & variationMask) == 0 && meshInfo.m_parkedFlagsRequired == VehicleParked.Flags.None) || (flag && BuildingDecoration.IsSubMeshRendered(subInfo)))
                        {
                            if (!(subInfo != null))
                            {
                                continue;
                            }
                            instance.m_drawCallData.m_defaultCalls++;
                            if (underground)
                            {
                                if (subInfo.m_undergroundMaterial == null && subInfo.m_material != null)
                                {
                                    VehicleProperties properties = instance.m_properties;
                                    if (properties != null)
                                    {
                                        subInfo.m_undergroundMaterial = new Material(properties.m_undergroundShader);
                                        subInfo.m_undergroundMaterial.CopyPropertiesFromMaterial(subInfo.m_material);
                                    }
                                }
                                subInfo.m_undergroundMaterial.SetVectorArray(instance.ID_TyreLocation, subInfo.m_generatedInfo.m_tyres);
                                if (j == 1)
                                {
                                    Graphics.DrawMesh(subInfo.m_mesh, originalBodyMatrix, subInfo.m_undergroundMaterial, instance.m_undergroundLayer, null, 0, materialBlock);
                                }
                                else
                                {
                                    Graphics.DrawMesh(subInfo.m_mesh, bodyMatrix, subInfo.m_undergroundMaterial, instance.m_undergroundLayer, null, 0, materialBlock);
                                }
                            }
                            if (overground)
                            {
                                subInfo.m_material.SetVectorArray(instance.ID_TyreLocation, subInfo.m_generatedInfo.m_tyres);
                                if (j == 1)
                                {
                                    Graphics.DrawMesh(subInfo.m_mesh, originalBodyMatrix, subInfo.m_material, info.m_prefabDataLayer, null, 0, materialBlock);
                                }
                                else
                                {
                                    Graphics.DrawMesh(subInfo.m_mesh, bodyMatrix, subInfo.m_material, info.m_prefabDataLayer, null, 0, materialBlock);
                                }
                            }
                        }
                        else if (subInfo == null)
                        {
                            flag2 = false;
                        }
                    }
                }
                if (!flag2)
                {
                    // return false to skip the original method
                    return(false);
                }
                instance.m_drawCallData.m_defaultCalls++;
                if (underground)
                {
                    if (info.m_undergroundMaterial == null && info.m_material != null)
                    {
                        VehicleProperties properties2 = instance.m_properties;
                        if (properties2 != null)
                        {
                            info.m_undergroundMaterial = new Material(properties2.m_undergroundShader);
                            info.m_undergroundMaterial.CopyPropertiesFromMaterial(info.m_material);
                        }
                    }
                    info.m_undergroundMaterial.SetVectorArray(instance.ID_TyreLocation, info.m_generatedInfo.m_tyres);
                    Graphics.DrawMesh(info.m_mesh, bodyMatrix, info.m_undergroundMaterial, instance.m_undergroundLayer, null, 0, materialBlock);
                }
                if (overground)
                {
                    info.m_material.SetVectorArray(instance.ID_TyreLocation, info.m_generatedInfo.m_tyres);
                    Graphics.DrawMesh(info.m_mesh, bodyMatrix, info.m_material, info.m_prefabDataLayer, null, 0, materialBlock);
                }
                // return false to skip the original method
                return(false);
            }
            Matrix4x4 bodyMatrix2         = info.m_vehicleAI.CalculateBodyMatrix(flags, ref position, ref rotation, ref scale, ref swayPosition);
            Matrix4x4 originalBodyMatrix2 = info.m_vehicleAI.CalculateBodyMatrix(flags, ref position, ref originalRotation, ref scale, ref swayPosition);

            if (Singleton <ToolManager> .instance.m_properties.m_mode == ItemClass.Availability.AssetEditor)
            {
                Matrix4x4             value2         = info.m_vehicleAI.CalculateTyreMatrix(flags, ref position, ref rotation, ref scale, ref bodyMatrix2);
                VehicleManager        instance2      = Singleton <VehicleManager> .instance;
                MaterialPropertyBlock materialBlock2 = instance2.m_materialBlock;
                materialBlock2.Clear();
                materialBlock2.SetMatrix(instance2.ID_TyreMatrix, value2);
                materialBlock2.SetVector(instance2.ID_TyrePosition, tyrePosition);
                materialBlock2.SetVector(instance2.ID_LightState, lightState);
                Mesh     mesh     = null;
                Material material = null;
                if (info.m_lodObject != null)
                {
                    MeshFilter component = info.m_lodObject.GetComponent <MeshFilter>();
                    if (component != null)
                    {
                        mesh = component.sharedMesh;
                    }
                    Renderer component2 = info.m_lodObject.GetComponent <Renderer>();
                    if (component2 != null)
                    {
                        material = component2.sharedMaterial;
                    }
                }
                if (mesh != null && material != null)
                {
                    materialBlock2.SetVectorArray(instance2.ID_TyreLocation, info.m_generatedInfo.m_tyres);
                    Graphics.DrawMesh(mesh, bodyMatrix2, material, info.m_prefabDataLayer, null, 0, materialBlock2);
                }
            }
            else if (Singleton <InfoManager> .instance.CurrentMode == InfoManager.InfoMode.None)
            {
                RenderGroup.MeshData effectMeshData2 = info.m_vehicleAI.GetEffectMeshData();
                EffectInfo.SpawnArea area2           = new EffectInfo.SpawnArea(bodyMatrix2, effectMeshData2, info.m_generatedInfo.m_tyres, info.m_lightPositions);
                if (info.m_effects != null)
                {
                    for (int k = 0; k < info.m_effects.Length; k++)
                    {
                        VehicleInfo.Effect effect2 = info.m_effects[k];
                        if (((effect2.m_vehicleFlagsRequired | effect2.m_vehicleFlagsForbidden) & flags) == effect2.m_vehicleFlagsRequired && effect2.m_parkedFlagsRequired == VehicleParked.Flags.None)
                        {
                            effect2.m_effect.RenderEffect(id, area2, velocity, acceleration, 1f, -1f, Singleton <SimulationManager> .instance.m_simulationTimeDelta, cameraInfo);
                        }
                    }
                }
            }
            bool flag3 = true;

            if (info.m_subMeshes != null)
            {
                for (int l = 0; l < info.m_subMeshes.Length; l++)
                {
                    VehicleInfo.MeshInfo meshInfo2 = info.m_subMeshes[l];
                    VehicleInfoBase      subInfo2  = meshInfo2.m_subInfo;
                    if (((meshInfo2.m_vehicleFlagsRequired | meshInfo2.m_vehicleFlagsForbidden) & flags) == meshInfo2.m_vehicleFlagsRequired && (meshInfo2.m_variationMask & variationMask) == 0 && meshInfo2.m_parkedFlagsRequired == VehicleParked.Flags.None)
                    {
                        if (!(subInfo2 != null))
                        {
                            continue;
                        }
                        if (underground)
                        {
                            if (l == 1)
                            {
                                subInfo2.m_undergroundLodTransforms[subInfo2.m_undergroundLodCount] = originalBodyMatrix2;
                            }
                            else
                            {
                                subInfo2.m_undergroundLodTransforms[subInfo2.m_undergroundLodCount] = bodyMatrix2;
                            }

                            subInfo2.m_undergroundLodLightStates[subInfo2.m_undergroundLodCount] = lightState;
                            subInfo2.m_undergroundLodColors[subInfo2.m_undergroundLodCount]      = color.linear;
                            subInfo2.m_undergroundLodMin = Vector3.Min(subInfo2.m_undergroundLodMin, position);
                            subInfo2.m_undergroundLodMax = Vector3.Max(subInfo2.m_undergroundLodMax, position);
                            if (++subInfo2.m_undergroundLodCount == subInfo2.m_undergroundLodTransforms.Length)
                            {
                                Vehicle.RenderUndergroundLod(cameraInfo, subInfo2);
                            }
                        }
                        if (overground)
                        {
                            if (l == 1)
                            {
                                subInfo2.m_lodTransforms[subInfo2.m_lodCount] = originalBodyMatrix2;
                            }
                            else
                            {
                                subInfo2.m_lodTransforms[subInfo2.m_lodCount] = bodyMatrix2;
                            }
                            subInfo2.m_lodLightStates[subInfo2.m_lodCount] = lightState;
                            subInfo2.m_lodColors[subInfo2.m_lodCount]      = color.linear;
                            subInfo2.m_lodMin = Vector3.Min(subInfo2.m_lodMin, position);
                            subInfo2.m_lodMax = Vector3.Max(subInfo2.m_lodMax, position);
                            if (++subInfo2.m_lodCount == subInfo2.m_lodTransforms.Length)
                            {
                                Vehicle.RenderLod(cameraInfo, subInfo2);
                            }
                        }
                    }
                    else if (subInfo2 == null)
                    {
                        flag3 = false;
                    }
                }
            }
            if (!flag3)
            {
                return(false);
            }
            if (underground)
            {
                info.m_undergroundLodTransforms[info.m_undergroundLodCount]  = bodyMatrix2;
                info.m_undergroundLodLightStates[info.m_undergroundLodCount] = lightState;
                info.m_undergroundLodColors[info.m_undergroundLodCount]      = color.linear;
                info.m_undergroundLodMin = Vector3.Min(info.m_undergroundLodMin, position);
                info.m_undergroundLodMax = Vector3.Max(info.m_undergroundLodMax, position);
                if (++info.m_undergroundLodCount == info.m_undergroundLodTransforms.Length)
                {
                    Vehicle.RenderUndergroundLod(cameraInfo, info);
                }
            }
            if (overground)
            {
                info.m_lodTransforms[info.m_lodCount]  = bodyMatrix2;
                info.m_lodLightStates[info.m_lodCount] = lightState;
                info.m_lodColors[info.m_lodCount]      = color.linear;
                info.m_lodMin = Vector3.Min(info.m_lodMin, position);
                info.m_lodMax = Vector3.Max(info.m_lodMax, position);
                if (++info.m_lodCount == info.m_lodTransforms.Length)
                {
                    Vehicle.RenderLod(cameraInfo, info);
                }
            }
            // return false to skip the original method
            return(false);
        }
		private static void PopulateGroupData(TreeManager tm, 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)
		{
			unsafe
			{
				if (layer != tm.m_treeLayer)
				{
					return;
				}
				int num = groupX * 540 / 45;
				int num1 = groupZ * 540 / 45;
				int num2 = (groupX + 1) * 540 / 45 - 1;
				int num3 = (groupZ + 1) * 540 / 45 - 1;
				for (int i = num1; i <= num3; i++)
				{
					for (int j = num; j <= num2; j++)
					{
						uint mTreeGrid = tm.m_treeGrid[i * 540 + j];
						int num4 = 0;
						while (mTreeGrid != 0)
						{
							tm.m_trees.m_buffer[mTreeGrid].PopulateGroupData(mTreeGrid, layer, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance);
							mTreeGrid = tm.m_trees.m_buffer[mTreeGrid].m_nextGridTree;
							int num5 = num4 + 1;
							num4 = num5;
							if (num5 < LimitTreeManager.Helper.TreeLimit)
							{
								continue;
							}
							CODebugBase<LogChannel>.Error(LogChannel.Core, string.Concat("Invalid list detected!\n", Environment.StackTrace));
							break;
						}
					}
				}
			}
		}
        private void GenerateCombinedLodMesh()
        {
            if (this.m_lodMeshCombined1 == null)
            {
                this.m_lodMeshCombined1 = new Mesh();
            }
            if (this.m_lodMeshCombined4 == null)
            {
                this.m_lodMeshCombined4 = new Mesh();
            }
            if (this.m_lodMeshCombined8 == null)
            {
                this.m_lodMeshCombined8 = new Mesh();
            }
            if (this.m_lodMeshCombined16 == null)
            {
                this.m_lodMeshCombined16 = new Mesh();
            }
            if (this.m_lodMaterialCombined == null)
            {
                string[] shaderKeywords;
                if (this.m_lodMaterial != null)
                {
                    this.m_lodMaterialCombined = new Material(this.m_lodMaterial);
                    shaderKeywords             = this.m_lodMaterial.shaderKeywords;
                }
                else
                {
                    this.m_lodMaterialCombined = new Material(this.m_material);
                    shaderKeywords             = this.m_material.shaderKeywords;
                }
                for (int i = 0; i < shaderKeywords.Length; i++)
                {
                    this.m_lodMaterialCombined.EnableKeyword(shaderKeywords[i]);
                }
                this.m_lodMaterialCombined.EnableKeyword("MULTI_INSTANCE");
            }
            Vector3[] vertices  = this.m_lodMesh.vertices;
            Vector3[] normals   = this.m_lodMesh.normals;
            Vector4[] tangents  = this.m_lodMesh.tangents;
            Vector2[] uv        = this.m_lodMesh.uv;
            Color32[] array     = this.m_lodMesh.colors32;
            int[]     triangles = this.m_lodMesh.triangles;
            if (array.Length != vertices.Length)
            {
                array = new Color32[vertices.Length];
                for (int j = 0; j < array.Length; j++)
                {
                    array[j] = new Color32(255, 255, 255, 255);
                }
            }
            int num  = vertices.Length;
            int num2 = triangles.Length;

            RenderGroup.MeshData meshData  = new RenderGroup.MeshData(RenderGroup.VertexArrays.Vertices | RenderGroup.VertexArrays.Normals | RenderGroup.VertexArrays.Tangents | RenderGroup.VertexArrays.Uvs | RenderGroup.VertexArrays.Colors, num * 1, num2 * 1);
            RenderGroup.MeshData meshData2 = new RenderGroup.MeshData(RenderGroup.VertexArrays.Vertices | RenderGroup.VertexArrays.Normals | RenderGroup.VertexArrays.Tangents | RenderGroup.VertexArrays.Uvs | RenderGroup.VertexArrays.Colors, num * 4, num2 * 4);
            RenderGroup.MeshData meshData3 = new RenderGroup.MeshData(RenderGroup.VertexArrays.Vertices | RenderGroup.VertexArrays.Normals | RenderGroup.VertexArrays.Tangents | RenderGroup.VertexArrays.Uvs | RenderGroup.VertexArrays.Colors, num * 8, num2 * 8);
            RenderGroup.MeshData meshData4 = new RenderGroup.MeshData(RenderGroup.VertexArrays.Vertices | RenderGroup.VertexArrays.Normals | RenderGroup.VertexArrays.Tangents | RenderGroup.VertexArrays.Uvs | RenderGroup.VertexArrays.Colors, num * 16, num2 * 16);
            int num3 = 0;
            int num4 = 0;

            for (int k = 0; k < 16; k++)
            {
                byte a = (byte)(k * 16);
                for (int l = 0; l < num2; l++)
                {
                    if (k < 1)
                    {
                        meshData.m_triangles[num4] = triangles[l] + num3;
                    }
                    if (k < 4)
                    {
                        meshData2.m_triangles[num4] = triangles[l] + num3;
                    }
                    if (k < 8)
                    {
                        meshData3.m_triangles[num4] = triangles[l] + num3;
                    }
                    if (k < 16)
                    {
                        meshData4.m_triangles[num4] = triangles[l] + num3;
                    }
                    num4++;
                }
                for (int m = 0; m < num; m++)
                {
                    Color32 color = array[m];
                    color.a = a;
                    if (k < 1)
                    {
                        meshData.m_vertices[num3] = vertices[m];
                        meshData.m_normals[num3]  = normals[m];
                        meshData.m_tangents[num3] = tangents[m];
                        meshData.m_uvs[num3]      = uv[m];
                        meshData.m_colors[num3]   = color;
                    }
                    if (k < 4)
                    {
                        meshData2.m_vertices[num3] = vertices[m];
                        meshData2.m_normals[num3]  = normals[m];
                        meshData2.m_tangents[num3] = tangents[m];
                        meshData2.m_uvs[num3]      = uv[m];
                        meshData2.m_colors[num3]   = color;
                    }
                    if (k < 8)
                    {
                        meshData3.m_vertices[num3] = vertices[m];
                        meshData3.m_normals[num3]  = normals[m];
                        meshData3.m_tangents[num3] = tangents[m];
                        meshData3.m_uvs[num3]      = uv[m];
                        meshData3.m_colors[num3]   = color;
                    }
                    if (k < 16)
                    {
                        meshData4.m_vertices[num3] = vertices[m];
                        meshData4.m_normals[num3]  = normals[m];
                        meshData4.m_tangents[num3] = tangents[m];
                        meshData4.m_uvs[num3]      = uv[m];
                        meshData4.m_colors[num3]   = color;
                    }
                    num3++;
                }
            }
            meshData.PopulateMesh(this.m_lodMeshCombined1);
            meshData2.PopulateMesh(this.m_lodMeshCombined4);
            meshData3.PopulateMesh(this.m_lodMeshCombined8);
            meshData4.PopulateMesh(this.m_lodMeshCombined16);
        }
Beispiel #18
0
        public static void PopulateArrowGroupData(Vector3 pos, Vector3 dir, ref int vertexIndex, ref int triangleIndex, Vector3 groupPosition, RenderGroup.MeshData data, ref Vector3 min, ref Vector3 max, ref float maxRenderDistance, ref float maxInstanceDistance)
        {
            float   len142 = VectorUtils.LengthXZ(dir) * 1.42f;
            Vector3 dir2   = new Vector3(len142, Mathf.Abs(dir.y), len142);

            min = Vector3.Min(min, pos - dir2);
            max = Vector3.Max(max, pos + dir2);
            maxRenderDistance = Mathf.Max(maxRenderDistance, 20000f);
            Vector3 diff        = pos - groupPosition;
            Vector3 normalRight = new Vector3(dir.z, 0f, -dir.x);

            data.m_vertices[vertexIndex] = diff - dir - normalRight;;
            data.m_normals[vertexIndex]  = pos;
            data.m_uvs[vertexIndex]      = new Vector2(0, 0);

            vertexIndex++;
            data.m_vertices[vertexIndex] = diff - dir + normalRight;
            data.m_normals[vertexIndex]  = pos;
            data.m_uvs[vertexIndex]      = new Vector2(1f, 0f);

            vertexIndex++;
            data.m_vertices[vertexIndex] = diff + dir + normalRight;
            data.m_normals[vertexIndex]  = pos;
            data.m_uvs[vertexIndex]      = new Vector2(1f, 1f);

            vertexIndex++;
            data.m_vertices[vertexIndex] = diff + dir - normalRight;
            data.m_normals[vertexIndex]  = pos;
            data.m_uvs[vertexIndex]      = new Vector2(0f, 1f);

            vertexIndex++;
            data.m_triangles[triangleIndex++] = vertexIndex - 4;
            data.m_triangles[triangleIndex++] = vertexIndex - 1;
            data.m_triangles[triangleIndex++] = vertexIndex - 3;
            data.m_triangles[triangleIndex++] = vertexIndex - 3;
            data.m_triangles[triangleIndex++] = vertexIndex - 1;
            data.m_triangles[triangleIndex++] = vertexIndex - 2;
        }
Beispiel #19
0
        public static void PopulateGroupData(ref PropInstance prop, ushort propID, 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)
        {
            if (prop.Blocked)
            {
                return;
            }
            PropInfo info = prop.Info;

            //add null check
            //begin mod
            if (info == null)
            {
                return;
            }
            //end mod
            Vector3    position = prop.Position;
            Randomizer r        = new Randomizer((int)propID);
            float      scale    = info.m_minScale + (float)((double)r.Int32(10000U) * ((double)info.m_maxScale - (double)info.m_minScale) * 9.99999974737875E-05);
            float      angle    = prop.Angle;
            Color      color    = info.GetColor(ref r);

            PropInstance.PopulateGroupData(info, layer, new InstanceID()
            {
                Prop = propID
            }, position, scale, angle, color, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance);
        }
Beispiel #20
0
        public override void PopulateGroupData(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)
        {
            const int resolutionRatio = NODEGRID_RESOLUTION / RenderManager.GROUP_RESOLUTION; // = 270/45 = 6
            int       net_x0          = groupX * resolutionRatio;
            int       net_z0          = groupZ * resolutionRatio;
            int       net_x1          = (groupX + 1) * resolutionRatio - 1;
            int       net_z1          = (groupZ + 1) * resolutionRatio - 1;

            for (int net_z = net_z0; net_z <= net_z1; net_z++)
            {
                for (int net_x = net_x0; net_x <= net_x1; net_x++)
                {
                    ushort nodeID   = m_nodeGrid[net_z * NODEGRID_RESOLUTION + net_x];
                    int    watchdog = 0;
                    while (nodeID != 0)
                    {
                        nodeID.ToNode().PopulateGroupData(nodeID, groupX, groupZ, layer, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance, ref requireSurfaceMaps);
                        nodeID = nodeID.ToNode().m_nextGridNode;
                        if (++watchdog >= 32768)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            for (int net_z = net_z0; net_z <= net_z1; net_z++)
            {
                for (int net_x = net_x0; net_x <= net_x1; net_x++)
                {
                    ushort segmentID = m_segmentGrid[net_z * 270 + net_x];
                    int    watchdog  = 0;
                    while (segmentID != 0)
                    {
                        segmentID.ToSegment().PopulateGroupData(segmentID, groupX, groupZ, layer, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance, ref requireSurfaceMaps);
                        segmentID = segmentID.ToSegment().m_nextGridSegment;
                        if (++watchdog >= 36864)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
        }
Beispiel #21
0
        public static void PropInstancePopulateGroupData(PropInfo info, int layer, InstanceID id, Vector3 position, Vector3 scale, Vector3 angle, ref int vertexIndex, ref int triangleIndex, Vector3 groupPosition, RenderGroup.MeshData data, ref Vector3 min, ref Vector3 max, ref float maxRenderDistance, ref float maxInstanceDistance)
        {
            LightSystem lightSystem = RenderManager.instance.lightSystem;

            if (info.m_prefabDataLayer == layer)
            {
                float y   = info.m_generatedInfo.m_size.y * scale.y;
                float num = Mathf.Max(info.m_generatedInfo.m_size.x, info.m_generatedInfo.m_size.z) * scale.y * 0.5f;
                min = Vector3.Min(min, position - new Vector3(num, 0f, num));
                max = Vector3.Max(max, position + new Vector3(num, y, num));
                maxRenderDistance   = Mathf.Max(maxRenderDistance, info.m_maxRenderDistance);
                maxInstanceDistance = Mathf.Max(maxInstanceDistance, info.m_maxRenderDistance);
            }
            else if (info.m_effectLayer == layer || (info.m_effectLayer == lightSystem.m_lightLayer && layer == lightSystem.m_lightLayerFloating))
            {
                Matrix4x4 matrix4x = default;
                matrix4x.SetTRS(position, Quaternion.AngleAxis(angle.x, Vector3.left) * Quaternion.AngleAxis(angle.y, Vector3.down) * Quaternion.AngleAxis(angle.z, Vector3.back), scale);
                for (int i = 0; i < info.m_effects.Length; i++)
                {
                    Vector3 pos = matrix4x.MultiplyPoint(info.m_effects[i].m_position);
                    Vector3 dir = matrix4x.MultiplyVector(info.m_effects[i].m_direction);
                    info.m_effects[i].m_effect.PopulateGroupData(layer, id, pos, dir, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance);
                }
            }
        }
Beispiel #22
0
        public static void PopulateGroupData(NetInfo info, NetInfo.Segment segmentInfo, Matrix4x4 leftMatrix, Matrix4x4 rightMatrix, Vector4 meshScale, Vector4 objectIndex,
                                             ref int vertexIndex, ref int triangleIndex, Vector3 groupPosition, RenderGroup.MeshData meshData, ref bool requireSurfaceMaps)
        {
            if (segmentInfo.m_requireSurfaceMaps)
            {
                requireSurfaceMaps = true;
            }
            RenderGroup.MeshData meshData2 = segmentInfo.m_combinedLod.m_key.m_mesh.m_data;
            int[] triangles = meshData2.m_triangles;
            int   num       = triangles.Length;

            for (int i = 0; i < num; i++)
            {
                meshData.m_triangles[triangleIndex++] = triangles[i] + vertexIndex;
            }
            RenderGroup.VertexArrays vertexArrays = meshData2.VertexArrayMask();
            Vector3[] vertices = meshData2.m_vertices;
            Vector3[] normals  = meshData2.m_normals;
            Vector4[] tangents = meshData2.m_tangents;
            Vector2[] uvs      = meshData2.m_uvs;
            Vector2[] uvs2     = meshData2.m_uvs3;
            Color32[] colors   = meshData2.m_colors;
            int       num2     = vertices.Length;
            Vector2   vector   = new Vector2(objectIndex.x, objectIndex.y);
            Vector2   vector2  = new Vector2(objectIndex.z, objectIndex.w);

            for (int i = 0; i < num2; i++)
            {
                Vector3 vertex = vertices[i];
                vertex.x = vertex.x * meshScale.x + 0.5f;
                vertex.z = vertex.z * meshScale.y + 0.5f;
                Vector4   vector4  = new Vector4(vertex.z, 1f - vertex.z, 3f * vertex.z, 0f - vertex.z);
                Vector4   vector5  = new Vector4(vector4.y * vector4.y * vector4.y, vector4.z * vector4.y * vector4.y, vector4.z * vector4.x * vector4.y, vector4.x * vector4.x * vector4.x);
                Vector4   vector6  = new Vector4(vector4.y * (-1f - vector4.w) * 3f, vector4.y * (1f - vector4.z) * 3f, vector4.x * (2f - vector4.z) * 3f, vector4.x * (0f - vector4.w) * 3f);
                Vector4   vector7  = leftMatrix * vector5;
                Vector4   vector8  = vector7 + (rightMatrix * vector5 - vector7) * vertex.x;
                Vector4   vector9  = leftMatrix * vector6;
                Vector3   vector10 = Vector3.Normalize(vector9 + (rightMatrix * vector6 - vector9) * vertex.x);
                Vector3   vector11 = Vector3.Normalize(new Vector3(vector10.z, 0f, 0f - vector10.x));
                Matrix4x4 matrix4x = default(Matrix4x4);
                matrix4x.SetColumn(0, vector11);
                matrix4x.SetColumn(1, Vector3.Cross(vector10, vector11));
                matrix4x.SetColumn(2, vector10);
                if (segmentInfo.m_requireHeightMap)
                {
                    vector8.y = Singleton <TerrainManager> .instance.SampleDetailHeight((Vector3)vector8 + groupPosition);
                }
                meshData.m_vertices[vertexIndex] = new Vector3(vector8.x, vector8.y + vertex.y, vector8.z);
                if ((vertexArrays & RenderGroup.VertexArrays.Normals) != 0)
                {
                    meshData.m_normals[vertexIndex] = matrix4x.MultiplyVector(normals[i]);
                }
                else
                {
                    meshData.m_normals[vertexIndex] = new Vector3(0f, 1f, 0f);
                }
                if ((vertexArrays & RenderGroup.VertexArrays.Tangents) != 0)
                {
                    Vector4 vector12 = tangents[i];
                    Vector3 vector13 = matrix4x.MultiplyVector(vector12);
                    vector12.x = vector13.x;
                    vector12.y = vector13.y;
                    vector12.z = vector13.z;
                    meshData.m_tangents[vertexIndex] = vector12;
                }
                else
                {
                    meshData.m_tangents[vertexIndex] = new Vector4(1f, 0f, 0f, 1f);
                }
                Color32 color = (((vertexArrays & RenderGroup.VertexArrays.Colors) == 0) ? new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue) : colors[i]);
                if ((vertexArrays & RenderGroup.VertexArrays.Uvs) != 0)
                {
                    Vector2 vector14 = uvs[i];
                    vector14.y = Mathf.Lerp(vector14.y, vector8.w, (float)(int)color.g * 0.003921569f);
                    meshData.m_uvs[vertexIndex] = vector14;
                }
                else
                {
                    Vector2 vector15 = default(Vector2);
                    vector15.y = Mathf.Lerp(vector15.y, vector8.w, (float)(int)color.g * 0.003921569f);
                    meshData.m_uvs[vertexIndex] = vector15;
                }
                meshData.m_colors[vertexIndex] = info.m_netAI.GetGroupVertexColor(segmentInfo, i);
                meshData.m_uvs2[vertexIndex]   = vector;
                meshData.m_uvs4[vertexIndex]   = vector2;
                if ((vertexArrays & RenderGroup.VertexArrays.Uvs3) != 0)
                {
                    meshData.m_uvs3[vertexIndex] = uvs2[i];
                }
                vertexIndex++;
            }
        }
 private void GenerateCombinedLodMesh()
 {
     if (this.m_lodMeshCombined1 == null)
     {
         this.m_lodMeshCombined1 = new Mesh();
     }
     if (this.m_lodMeshCombined4 == null)
     {
         this.m_lodMeshCombined4 = new Mesh();
     }
     if (this.m_lodMeshCombined8 == null)
     {
         this.m_lodMeshCombined8 = new Mesh();
     }
     if (this.m_lodMeshCombined16 == null)
     {
         this.m_lodMeshCombined16 = new Mesh();
     }
     if (this.m_lodMaterialCombined == null)
     {
         string[] shaderKeywords;
         if (this.m_lodMaterial != null)
         {
             this.m_lodMaterialCombined = new Material(this.m_lodMaterial);
             shaderKeywords = this.m_lodMaterial.shaderKeywords;
         }
         else
         {
             this.m_lodMaterialCombined = new Material(this.m_material);
             shaderKeywords = this.m_material.shaderKeywords;
         }
         for (int i = 0; i < shaderKeywords.Length; i++)
         {
             this.m_lodMaterialCombined.EnableKeyword(shaderKeywords[i]);
         }
         this.m_lodMaterialCombined.EnableKeyword("MULTI_INSTANCE");
     }
     Vector3[] vertices = this.m_lodMesh.vertices;
     Vector3[] normals = this.m_lodMesh.normals;
     Vector4[] tangents = this.m_lodMesh.tangents;
     Vector2[] uv = this.m_lodMesh.uv;
     Color32[] array = this.m_lodMesh.colors32;
     int[] triangles = this.m_lodMesh.triangles;
     if (array.Length != vertices.Length)
     {
         array = new Color32[vertices.Length];
         for (int j = 0; j < array.Length; j++)
         {
             array[j] = new Color32(255, 255, 255, 255);
         }
     }
     int num = vertices.Length;
     int num2 = triangles.Length;
     RenderGroup.MeshData meshData = new RenderGroup.MeshData(RenderGroup.VertexArrays.Vertices | RenderGroup.VertexArrays.Normals | RenderGroup.VertexArrays.Tangents | RenderGroup.VertexArrays.Uvs | RenderGroup.VertexArrays.Colors, num * 1, num2 * 1);
     RenderGroup.MeshData meshData2 = new RenderGroup.MeshData(RenderGroup.VertexArrays.Vertices | RenderGroup.VertexArrays.Normals | RenderGroup.VertexArrays.Tangents | RenderGroup.VertexArrays.Uvs | RenderGroup.VertexArrays.Colors, num * 4, num2 * 4);
     RenderGroup.MeshData meshData3 = new RenderGroup.MeshData(RenderGroup.VertexArrays.Vertices | RenderGroup.VertexArrays.Normals | RenderGroup.VertexArrays.Tangents | RenderGroup.VertexArrays.Uvs | RenderGroup.VertexArrays.Colors, num * 8, num2 * 8);
     RenderGroup.MeshData meshData4 = new RenderGroup.MeshData(RenderGroup.VertexArrays.Vertices | RenderGroup.VertexArrays.Normals | RenderGroup.VertexArrays.Tangents | RenderGroup.VertexArrays.Uvs | RenderGroup.VertexArrays.Colors, num * 16, num2 * 16);
     int num3 = 0;
     int num4 = 0;
     for (int k = 0; k < 16; k++)
     {
         byte a = (byte)(k * 16);
         for (int l = 0; l < num2; l++)
         {
             if (k < 1)
             {
                 meshData.m_triangles[num4] = triangles[l] + num3;
             }
             if (k < 4)
             {
                 meshData2.m_triangles[num4] = triangles[l] + num3;
             }
             if (k < 8)
             {
                 meshData3.m_triangles[num4] = triangles[l] + num3;
             }
             if (k < 16)
             {
                 meshData4.m_triangles[num4] = triangles[l] + num3;
             }
             num4++;
         }
         for (int m = 0; m < num; m++)
         {
             Color32 color = array[m];
             color.a = a;
             if (k < 1)
             {
                 meshData.m_vertices[num3] = vertices[m];
                 meshData.m_normals[num3] = normals[m];
                 meshData.m_tangents[num3] = tangents[m];
                 meshData.m_uvs[num3] = uv[m];
                 meshData.m_colors[num3] = color;
             }
             if (k < 4)
             {
                 meshData2.m_vertices[num3] = vertices[m];
                 meshData2.m_normals[num3] = normals[m];
                 meshData2.m_tangents[num3] = tangents[m];
                 meshData2.m_uvs[num3] = uv[m];
                 meshData2.m_colors[num3] = color;
             }
             if (k < 8)
             {
                 meshData3.m_vertices[num3] = vertices[m];
                 meshData3.m_normals[num3] = normals[m];
                 meshData3.m_tangents[num3] = tangents[m];
                 meshData3.m_uvs[num3] = uv[m];
                 meshData3.m_colors[num3] = color;
             }
             if (k < 16)
             {
                 meshData4.m_vertices[num3] = vertices[m];
                 meshData4.m_normals[num3] = normals[m];
                 meshData4.m_tangents[num3] = tangents[m];
                 meshData4.m_uvs[num3] = uv[m];
                 meshData4.m_colors[num3] = color;
             }
             num3++;
         }
     }
     meshData.PopulateMesh(this.m_lodMeshCombined1);
     meshData2.PopulateMesh(this.m_lodMeshCombined4);
     meshData3.PopulateMesh(this.m_lodMeshCombined8);
     meshData4.PopulateMesh(this.m_lodMeshCombined16);
 }