internal void Update() { if (!IsUsed()) { return; } bool invalidateLod = false; foreach (var proxyIndex in m_dirtyProxyIndices) { var cellProxy = m_mergedLodMeshProxies[proxyIndex]; if (MyMeshes.CanStartMerge(cellProxy.MeshId, 1)) { Vector3I mergeCell = MyMeshes.GetVoxelInfo(cellProxy.MeshId).Coord; int divideIndex = GetDivideIndexFromMergeCell(ref mergeCell); MyMergedLodMeshId mergedId = MyMeshes.GetMergedLodMesh(cellProxy.MeshId, 0); invalidateLod |= mergedId.Info.MergedLodMeshes.Count > 0; mergedId.Info.PendingLodMeshes.UnionWith(mergedId.Info.MergedLodMeshes); mergedId.Info.MergedLodMeshes.Clear(); TryCancelMergeJob(divideIndex, MeshId.NULL); TryStartMergeJob(divideIndex, 1); } } m_dirtyProxyIndices.Clear(); if (invalidateLod) { InvalidateAllMergedMeshesInLod(); } }
/// <summary> /// Sends a merge job message if mergedMeshId has more than pendingThreshold pending lod meshes. /// </summary> /// <returns>True if message was sent; false otherwise</returns> internal static bool TryStartMerge(this MyMergedLodMeshId mergedLodMeshId, uint clipmapId, int pendingThreshold, List <LodMeshId> outLodMeshesSent, ulong workId) { Debug.Assert(outLodMeshesSent != null && outLodMeshesSent.Count == 0, "Lod mesh list not empty!"); var pendingLodMeshes = mergedLodMeshId.Info.PendingLodMeshes; var mergedLodMeshes = mergedLodMeshId.Info.MergedLodMeshes; bool pendingMeshesOverThreshold = pendingLodMeshes.Count >= pendingThreshold; if (pendingMeshesOverThreshold) { foreach (LodMeshId lodMesh in pendingLodMeshes) { m_tmpBatches.AddArray(lodMesh.Info.DataBatches); outLodMeshesSent.Add(lodMesh); m_tmpMetadata.Add(lodMesh.Info.BatchMetadata); } foreach (LodMeshId lodMesh in mergedLodMeshes) { m_tmpBatches.AddArray(lodMesh.Info.DataBatches); outLodMeshesSent.Add(lodMesh); m_tmpMetadata.Add(lodMesh.Info.BatchMetadata); } pendingLodMeshes.Clear(); mergedLodMeshes.Clear(); MyVoxelCellInfo cellInfo = MyMeshes.GetVoxelInfo(mergedLodMeshId); MyRenderProxy.MergeVoxelMeshes(clipmapId, workId, m_tmpMetadata, new MyCellCoord(cellInfo.Lod, cellInfo.Coord), m_tmpBatches); m_tmpBatches.Clear(); m_tmpMetadata.SetSize(0); } return(pendingMeshesOverThreshold); }
internal bool ShouldHaveFoliage() { var mesh = Owner.GetRenderable().GetModel(); int voxelLod = MyMeshes.GetVoxelInfo(mesh).Lod; bool voxelMeshNotReady = voxelLod > LodLimit; if (voxelMeshNotReady) { return(false); } int partsNum; if (MyMeshes.IsMergedVoxelMesh(mesh)) { partsNum = MyMeshes.GetMergedLodMesh(mesh, 0).Info.PartsNum; } else { partsNum = MyMeshes.GetLodMesh(mesh, 0).Info.PartsNum; } // only stream stones for lod0 if (voxelLod > 0) { bool allStone = true; for (int i = 0; i < partsNum; i++) { var triple = MyMeshes.GetVoxelPart(mesh, i).Info.MaterialTriple; if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage && MyVoxelMaterials1.Table[triple.I0].FoliageType == 0) { allStone = false; break; } if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage && MyVoxelMaterials1.Table[triple.I1].FoliageType == 0) { allStone = false; break; } if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage && MyVoxelMaterials1.Table[triple.I2].FoliageType == 0) { allStone = false; break; } } if (allStone) { return(false); } } return(true); }
internal unsafe void FillStreams() { bool alreadyFilled = m_streams != null && m_streams.Count > 0; if (alreadyFilled) { return; } var mesh = Owner.GetRenderable().GetModel(); int voxelLod = MyMeshes.GetVoxelInfo(mesh).Lod; if (!Owner.IsVisible) { return; } int partsNum; if (MyMeshes.IsMergedVoxelMesh(mesh)) { partsNum = MyMeshes.GetMergedLodMesh(mesh, 0).Info.PartsNum; } else { partsNum = MyMeshes.GetLodMesh(mesh, 0).Info.PartsNum; } m_streams = new Dictionary <int, MyFoliageStream>(); // analyze for (int partIndex = 0; partIndex < partsNum; ++partIndex) { var partInfo = MyMeshes.GetVoxelPart(mesh, partIndex).Info; var triple = partInfo.MaterialTriple; if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage) { PrepareStream(triple.I0, partInfo.IndexCount / 3, voxelLod); } if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage) { PrepareStream(triple.I1, partInfo.IndexCount / 3, voxelLod); } if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage) { PrepareStream(triple.I2, partInfo.IndexCount / 3, voxelLod); } } // prepare foreach (var stream in m_streams.Values) { stream.AllocateStreamOutBuffer(sizeof(Vector3) + sizeof(uint)); } // analyze for (int partIndex = 0; partIndex < partsNum; partIndex++) { var partInfo = MyMeshes.GetVoxelPart(mesh, partIndex).Info; var triple = partInfo.MaterialTriple; if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage) { FillStreamWithTerrainBatch(triple.I0, 0, partInfo.IndexCount, partInfo.StartIndex, 0); } if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage) { FillStreamWithTerrainBatch(triple.I1, 1, partInfo.IndexCount, partInfo.StartIndex, 0); } if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage) { FillStreamWithTerrainBatch(triple.I2, 2, partInfo.IndexCount, partInfo.StartIndex, 0); } } }
internal void FillStreams() { var mesh = m_owner.GetRenderable().GetModel(); bool voxelMeshNotReady = m_owner.m_visible == false || MyMeshes.GetVoxelInfo(mesh).Lod > 4; bool alreadyFilled = m_streams != null; if (voxelMeshNotReady || alreadyFilled) { return; } m_streams = new Dictionary <int, MyFoliageStream>(); // cleanup foreach (var kv in m_streams) { kv.Value.ResetAllocationSize(); } var lodMesh = MyMeshes.GetLodMesh(mesh, 0); // analyze var voxelLod = MyMeshes.GetVoxelInfo(mesh).Lod; for (int i = 0; i < lodMesh.Info.PartsNum; i++) { var partInfo = MyMeshes.GetVoxelPart(mesh, i).Info; var triple = partInfo.MaterialTriple; if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage) { PrepareStream(triple.I0, partInfo.IndexCount / 3, voxelLod); } if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage) { PrepareStream(triple.I1, partInfo.IndexCount / 3, voxelLod); } if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage) { PrepareStream(triple.I2, partInfo.IndexCount / 3, voxelLod); } } // prepare foreach (var kv in m_streams) { kv.Value.AllocateStreamOutBuffer(); } // analyze for (int i = 0; i < lodMesh.Info.PartsNum; i++) { var partInfo = MyMeshes.GetVoxelPart(mesh, i).Info; var triple = partInfo.MaterialTriple; if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage) { FillStreamWithTerrainBatch(triple.I0, 0, partInfo.IndexCount, partInfo.StartIndex, 0);// kv.Value.vertexOffset); } if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage) { FillStreamWithTerrainBatch(triple.I1, 1, partInfo.IndexCount, partInfo.StartIndex, 0);//kv.Value.vertexOffset); } if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage) { FillStreamWithTerrainBatch(triple.I2, 2, partInfo.IndexCount, partInfo.StartIndex, 0);//kv.Value.vertexOffset); } } }