private static void EndRenderingImpl(TreeManager tm, RenderManager.CameraInfo cameraInfo) { unsafe { if (Input.GetKeyDown(KeyCode.F5) && Event.current.control) { DebugOutputPanel.AddMessage(PluginManager.MessageType.Message, string.Format("TreeLimit: TreeCount={0}, TreeLimit={1}, CanPlaceMoreTrees={2}", tm.m_treeCount, LimitTreeManager.Helper.TreeLimit, tm.CheckLimits())); Array32<TreeInstance> mTrees = tm.m_trees; DebugOutputPanel.AddMessage(PluginManager.MessageType.Message, string.Format("TreeLimit: ArraySize={0}, ItemCount={1}, UnusedCount={2}", mTrees.m_size, mTrees.ItemCount(), mTrees.GetType().GetField("m_unusedCount", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(mTrees))); } FastList<RenderGroup> mRenderedGroups = Singleton<RenderManager>.instance.m_renderedGroups; for (int i = 0; i < mRenderedGroups.m_size; i++) { RenderGroup mBuffer = mRenderedGroups.m_buffer[i]; if ((mBuffer.m_instanceMask & 1 << (tm.m_treeLayer & 31)) != 0) { int mX = mBuffer.m_x * 540 / 45; int mZ = mBuffer.m_z * 540 / 45; int num = (mBuffer.m_x + 1) * 540 / 45 - 1; int mZ1 = (mBuffer.m_z + 1) * 540 / 45 - 1; for (int j = mZ; j <= mZ1; j++) { for (int k = mX; k <= num; k++) { uint mTreeGrid = tm.m_treeGrid[j * 540 + k]; int num1 = 0; while (mTreeGrid != 0) { tm.m_trees.m_buffer[mTreeGrid].RenderInstance(cameraInfo, mTreeGrid, mBuffer.m_instanceMask); mTreeGrid = tm.m_trees.m_buffer[mTreeGrid].m_nextGridTree; int num2 = num1 + 1; num1 = num2; if (num2 < LimitTreeManager.Helper.TreeLimit) { continue; } CODebugBase<LogChannel>.Error(LogChannel.Core, string.Concat("Invalid list detected!\n", Environment.StackTrace)); break; } } } } } int num3 = PrefabCollection<TreeInfo>.PrefabCount(); for (int l = 0; l < num3; l++) { TreeInfo prefab = PrefabCollection<TreeInfo>.GetPrefab((uint)l); if (prefab != null && prefab.m_lodCount != 0) { TreeInstance.RenderLod(cameraInfo, prefab); } } } }
static bool Prefix(ref RenderManager.CameraInfo cameraInfo, ref TreeInfo info, Vector3 position, float scale, float brightness, Vector4 objectIndex) { if (info.m_prefabInitialized) { if (cameraInfo == null || (UnityEngine.Object)info.m_lodMesh1 == (UnityEngine.Object)null || cameraInfo.CheckRenderDistance(position, info.m_lodRenderDistance)) { var instance = Singleton <TreeManager> .instance; if (instance == null) { return(false); } var materialBlock = instance.m_materialBlock; var matrix = default(Matrix4x4); Quaternion rotation; lock (App.Config.GraphicsLock) { if (App.Config.Graphics.randomTrees) { #if false UInt32 randIdent = ((UInt32)info.GetInstanceID() << 16) | (((UInt32)(BitConverter.DoubleToInt64Bits(position.magnitude) >> 32)) & 0xFFFF) ; var r = new System.Random((int)randIdent); //Log.Debug($"tree rand: {Convert.ToString(randIdent, 2)}, {r.NextDouble() * 360}"); rotation = Quaternion.Euler(0, (float)r.NextDouble() * 360, 0); #endif // same angle as in "Random Tree Rotation" mod long setofBits = BitConverter.DoubleToInt64Bits(position.magnitude); rotation = Quaternion.Euler(0, setofBits % 360, 0); } else { rotation = Quaternion.identity; } } matrix.SetTRS(position, rotation, new Vector3(scale, scale, scale)); var color = info.m_defaultColor * brightness; color.a = Singleton <WeatherManager> .instance.GetWindSpeed(position); lock (App.Config.GraphicsLock) { color.a *= App.Config.Graphics.treeMoveFactor; } materialBlock.Clear(); materialBlock.SetColor(instance.ID_Color, color); materialBlock.SetVector(instance.ID_ObjectIndex, objectIndex); instance.m_drawCallData.m_defaultCalls++; Graphics.DrawMesh(info.m_mesh, matrix, info.m_material, info.m_prefabDataLayer, null, 0, materialBlock); } else { position.y += info.m_generatedInfo.m_center.y * (scale - 1f); var color = info.m_defaultColor * brightness; color.a = Singleton <WeatherManager> .instance.GetWindSpeed(position); lock (App.Config.GraphicsLock) { color.a *= App.Config.Graphics.treeMoveFactor; } info.m_lodLocations[info.m_lodCount] = new Vector4(position.x, position.y, position.z, scale); info.m_lodColors[info.m_lodCount] = color.linear; info.m_lodObjectIndices[info.m_lodCount] = objectIndex; info.m_lodMin = Vector3.Min(info.m_lodMin, position); info.m_lodMax = Vector3.Max(info.m_lodMax, position); if (++info.m_lodCount == info.m_lodLocations.Length) { TreeInstance.RenderLod(cameraInfo, info); } } } return(false); }