예제 #1
0
            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();
                }
            }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
                }
            }
        }
예제 #5
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);
                }
            }
        }