Exemplo n.º 1
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);
        }
Exemplo n.º 2
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();
                }
            }
Exemplo n.º 3
0
        internal static bool UnmergeLodMesh(this MyMergedLodMeshId mergedLodMesh, LodMeshId lodMesh)
        {
            var pendingLodMeshes = mergedLodMesh.Info.PendingLodMeshes;
            var mergedLodMeshes  = mergedLodMesh.Info.MergedLodMeshes;

            bool alreadyMerged = mergedLodMeshes.Contains(lodMesh);

            if (alreadyMerged)
            {
                MyMeshes.UnlinkLodMeshFromMerged(lodMesh);
            }

            if (pendingLodMeshes.Remove(lodMesh))
            {
                Debug.Assert(!alreadyMerged, "Lod mesh set as pending and merged at the same time!");
            }

            if (alreadyMerged)
            {
                mergedLodMeshes.Remove(lodMesh);
                pendingLodMeshes.UnionWith(mergedLodMeshes);
                mergedLodMeshes.Clear();
            }

            return(alreadyMerged);
        }
Exemplo n.º 4
0
 internal void Clear()
 {
     WorldMatrix           = MatrixD.Zero;
     CommonObjectData      = default(MyObjectDataCommon);
     NonVoxelObjectData    = MyObjectDataNonVoxel.Invalid;
     VoxelCommonObjectData = MyObjectDataVoxelCommon.Invalid;
     Mesh             = LodMeshId.NULL;
     MergedMesh       = MyMergedLodMeshId.NULL;
     Instancing       = InstancingId.NULL;
     DepthShaders     = MyMaterialShadersBundleId.NULL;
     Shaders          = MyMaterialShadersBundleId.NULL;
     ForwardShaders   = MyMaterialShadersBundleId.NULL;
     DrawSubmesh      = default(MyDrawSubmesh);
     PerMaterialIndex = 0;
     SectionSubmeshes = null;
     InstanceCount    = 0;
     StartInstance    = 0;
     SkinningMatrices = null;
     Type             = MyMaterialType.OPAQUE;
     Flags            = 0;
     Lod          = 0;
     ObjectBuffer = null;
     Parent       = null;
     Material     = MyStringId.NullOrEmpty;
 }
            internal void UpdateMesh(MyRenderMessageUpdateMergedVoxelMesh updateMessage)
            {
                int divideIndex = GetDivideIndexFromMergeCell(ref updateMessage.Metadata.Cell.CoordInLod);

                // A job wasn't cancelled in time and made it here
                if (m_mergeJobs[divideIndex].CurrentWorkId != updateMessage.WorkId)
                {
                    return;
                }

                MyMergedLodMeshId mergedId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0);
                bool mergeSuccessful       = m_mergedLodMeshProxies[divideIndex].UpdateMergedMesh(updateMessage);

                if (mergeSuccessful)
                {
                    Debug.Assert(mergedId.Info.MergedLodMeshes.Count == 0, "Merging into an already merged mesh");
                    mergedId.Info.MergedLodMeshes.UnionWith(m_mergeJobs[divideIndex].LodMeshesBeingMerged);
                    SwitchMergeState(divideIndex, true);
                }
                else
                {
                    mergedId.Info.PendingLodMeshes.UnionWith(m_mergeJobs[divideIndex].LodMeshesBeingMerged);
                }

                ResetMerge(divideIndex);
            }
Exemplo n.º 6
0
            internal bool OnAddedToScene(MyClipmapCellProxy cellProxy)
            {
                if (!IsUsed())
                {
                    return(false);
                }

                bool         lodAabbChanged = false;
                int          rootProxy      = m_boundingBoxes.GetRoot();
                BoundingBoxD lodAabbBefore  = BoundingBoxD.CreateInvalid();

                if (rootProxy != -1)
                {
                    lodAabbBefore = m_boundingBoxes.GetAabb(rootProxy);
                }

                BoundingBoxD cellAabb = (BoundingBoxD)cellProxy.LocalAabb;

                m_cellProxyToAabbProxy.Add(cellProxy, m_boundingBoxes.AddProxy(ref cellAabb, null, 0));

                if (rootProxy != -1)
                {
                    BoundingBoxD lodAabbAfter = m_boundingBoxes.GetAabb(rootProxy);
                    lodAabbChanged = lodAabbBefore.Equals(lodAabbAfter);
                }

                if (lodAabbChanged)
                {
                    InvalidateAllMergedMeshesInLod();
                }

                Vector3D translation = cellProxy.Translation;
                int      divideIndex = GetDivideIndex(ref translation);

                m_trackedActors[divideIndex].Add(cellProxy.Actor);

                MyMergedLodMeshId mergedLodMeshId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0);
                LodMeshId         lodMeshToMerge  = MyMeshes.GetLodMesh(cellProxy.MeshId, 0);
                bool mergedMesh = mergedLodMeshId.MergeLodMesh(lodMeshToMerge);

                if (mergedMesh)
                {
                    InvalidateAllMergedMeshesInLod();
                }

                TryCancelMergeJob(divideIndex, MeshId.NULL);
                bool startedMerge = TryStartMergeJob(divideIndex, 1000);

                bool shouldMarkDirty = !mergedMesh && !startedMerge;

                if (shouldMarkDirty)
                {
                    m_dirtyProxyIndices.Add(divideIndex);
                }

                return(shouldMarkDirty);
            }
Exemplo n.º 7
0
            internal bool OnDeleteCell(MyClipmapCellProxy cellProxy)
            {
                if (!IsUsed())
                {
                    return(false);
                }

                bool     unloadedCell = false;
                Vector3D translation  = cellProxy.Translation;
                int      divideIndex;

                if (TryGetDivideIndex(ref translation, out divideIndex))
                {
                    MyMergedLodMeshId mergedLodMeshId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0);
                    LodMeshId         lodMeshId       = MyMeshes.GetLodMesh(cellProxy.MeshId, 0);

                    bool unmergedMesh = mergedLodMeshId.UnmergeLodMesh(lodMeshId);
                    if (unmergedMesh)
                    {
                        InvalidateAllMergedMeshesInLod();
                    }

                    TryCancelMergeJob(divideIndex, cellProxy.MeshId);

                    cellProxy.Unload();
                    unloadedCell = true;

                    TryStartMergeJob(divideIndex, 1000);

                    if (unmergedMesh && unloadedCell)
                    {
                        m_dirtyProxyIndices.Add(divideIndex);
                    }

                    m_trackedActors[divideIndex].Remove(cellProxy.Actor);
                }

                int proxyId;

                if (m_cellProxyToAabbProxy.TryGetValue(cellProxy, out proxyId))
                {
                    m_boundingBoxes.RemoveProxy(m_cellProxyToAabbProxy[cellProxy]);
                    m_cellProxyToAabbProxy.Remove(cellProxy);
                }

                return(unloadedCell);
            }
Exemplo n.º 8
0
            private void InvalidateAllMergedMeshesInLod()
            {
                // TODO: Redistribute actors
                for (int divideIndex = 0; divideIndex < m_lodDivisions; ++divideIndex)
                {
                    MyMergedLodMeshId mergedLodMeshId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0);
                    bool markDirty = mergedLodMeshId.Info.MergedLodMeshes.Count > 0;
                    mergedLodMeshId.Info.PendingLodMeshes.UnionWith(mergedLodMeshId.Info.MergedLodMeshes);
                    mergedLodMeshId.Info.MergedLodMeshes.Clear();
                    SwitchMergeState(divideIndex, false);

                    if (markDirty)
                    {
                        m_dirtyProxyIndices.Add(divideIndex);
                    }
                }
            }
Exemplo n.º 9
0
        internal static bool MergeLodMesh(this MyMergedLodMeshId mergedLodMesh, LodMeshId lodMesh)
        {
            var pendingLodMeshes = mergedLodMesh.Info.PendingLodMeshes;
            var mergedLodMeshes  = mergedLodMesh.Info.MergedLodMeshes;

            bool alreadyMerged = mergedLodMeshes.Contains(lodMesh);

            if (alreadyMerged)
            {
                pendingLodMeshes.UnionWith(mergedLodMeshes);
                mergedLodMeshes.Clear();
            }
            else
            {
                pendingLodMeshes.Add(lodMesh);
            }

            MyMeshes.LinkLodMeshToMerged(lodMesh, mergedLodMesh);
            return(alreadyMerged);
        }
Exemplo n.º 10
0
        internal static bool CanStartMerge(this MyMergedLodMeshId mergedLodMeshId, int pendingThreshold)
        {
            var pendingLodMeshes = mergedLodMeshId.Info.PendingLodMeshes;

            return(pendingLodMeshes.Count >= pendingThreshold);
        }
        internal override bool RebuildLodProxy(int lodNum, bool skinningEnabled, MySkinningComponent skinning)
        {
            Debug.Assert(Mesh.Info.LodsNum == 1);

            MyRenderLod lod = null;

            int               partCount;
            LodMeshId         lodMesh       = new LodMeshId();
            MyMergedLodMeshId mergedLodMesh = new MyMergedLodMeshId();
            VertexLayoutId    vertexLayout;

            bool isMergedMesh = MyMeshes.IsMergedVoxelMesh(Mesh);

            if (!isMergedMesh)
            {
                if (!Owner.IsVisible)
                {
                    return(false);
                }

                lodMesh      = MyMeshes.GetLodMesh(Mesh, 0);
                vertexLayout = lodMesh.VertexLayout;
                partCount    = lodMesh.Info.PartsNum;
            }
            else
            {
                mergedLodMesh = MyMeshes.GetMergedLodMesh(Mesh, 0);
                if (mergedLodMesh.VertexLayout == VertexLayoutId.NULL || mergedLodMesh.Info.MergedLodMeshes.Count == 0)
                {
                    return(false);
                }

                partCount    = mergedLodMesh.Info.PartsNum;
                vertexLayout = mergedLodMesh.VertexLayout;
            }

            MyObjectPoolManager.Init(ref m_lods[lodNum]);
            lod = m_lods[lodNum];
            lod.VertexLayout1 = vertexLayout;

            // Hide proxies when they will already be rendered in a merged mesh
            if (!MyMeshes.IsLodMeshMerged(lodMesh))
            {
                AddToRenderables();
            }

            Debug.Assert(partCount > 0);

            lod.VertexShaderFlags = MyShaderUnifiedFlags.USE_VOXEL_DATA | MyShaderUnifiedFlags.USE_VOXEL_MORPHING | MyShaderUnifiedFlags.DITHERED;

            bool initializeProxies    = true; //isMergedMesh || !MyMeshes.IsLodMeshMerged(lodMesh);
            bool initializeDepthProxy = true; //!isMergedMesh && Num > 0;

            int numToInitialize = (initializeProxies ? partCount : 0) + (initializeDepthProxy ? 1 : 0);

            if (numToInitialize > 0)
            {
                lod.AllocateProxies(numToInitialize);
            }

            AnyDrawOutsideViewDistance = false;

            int constantBufferSize = GetConstantBufferSize(lod, skinningEnabled);

            if (initializeProxies)
            {
                for (int partIndex = 0; partIndex < partCount; partIndex++)
                {
                    CreateRenderableProxyForPart(lodNum, constantBufferSize, partIndex, partIndex, false);
                }
            }
            if (initializeDepthProxy)
            {
                CreateRenderableProxyForPart(lodNum, constantBufferSize, numToInitialize - 1, 0, true);
            }

            return(true);
        }
Exemplo n.º 12
0
 internal void Clear()
 {
     WorldMatrix = MatrixD.Zero;
     CommonObjectData = default(MyObjectDataCommon);
     NonVoxelObjectData = MyObjectDataNonVoxel.Invalid;
     VoxelCommonObjectData = MyObjectDataVoxelCommon.Invalid;
     Mesh = LodMeshId.NULL;
     MergedMesh = MyMergedLodMeshId.NULL;
     Instancing = InstancingId.NULL;
     DepthShaders = MyMaterialShadersBundleId.NULL;
     Shaders = MyMaterialShadersBundleId.NULL;
     ForwardShaders = MyMaterialShadersBundleId.NULL;
     DrawSubmesh = default(MyDrawSubmesh);
     PerMaterialIndex = 0;
     SectionSubmeshes = null;
     InstanceCount = 0;
     StartInstance = 0;
     SkinningMatrices = null;
     Type = MyMaterialType.OPAQUE;
     Flags = 0;
     Lod = 0;
     ObjectBuffer = null;
     Parent = null;
     Material = MyMeshMaterialId.NULL;
     UnusedMaterials = UnusedMaterials ?? new HashSet<string>();
     UnusedMaterials.Clear();
 }
        internal override unsafe bool RebuildLodProxy(int lodNum, bool skinningEnabled, MySkinningComponent skinning)
        {
            Debug.Assert(Mesh.Info.LodsNum == 1);

            MyRenderLod lod = null;

            int partCount;
            LodMeshId lodMesh = new LodMeshId();
            MyMergedLodMeshId mergedLodMesh = new MyMergedLodMeshId();
            VertexLayoutId vertexLayout;

            bool isMergedMesh = MyMeshes.IsMergedVoxelMesh(Mesh);
            if (!isMergedMesh)
            {
                lodMesh = MyMeshes.GetLodMesh(Mesh, 0);
                // Don't create proxies when they will already be rendered in a merged mesh
                if (MyMeshes.IsLodMeshMerged(lodMesh) || !Owner.IsVisible)
                    return false;

                vertexLayout = lodMesh.VertexLayout;
                partCount = lodMesh.Info.PartsNum;
            }
            else
            {
                mergedLodMesh = MyMeshes.GetMergedLodMesh(Mesh, 0);
                if (mergedLodMesh.VertexLayout == VertexLayoutId.NULL || mergedLodMesh.Info.MergedLodMeshes.Count == 0)
                    return false;

                partCount = mergedLodMesh.Info.PartsNum;
                vertexLayout = mergedLodMesh.VertexLayout;
            }

            MyObjectPoolManager.Init(ref m_lods[lodNum]);
            lod = m_lods[lodNum];
            lod.VertexLayout1 = vertexLayout;

            AddToRenderables();

            Debug.Assert(partCount > 0);

            lod.VertexShaderFlags = MyShaderUnifiedFlags.USE_VOXEL_DATA | MyShaderUnifiedFlags.USE_VOXEL_MORPHING | MyShaderUnifiedFlags.DITHERED;

            bool initializeProxies = true;//isMergedMesh || !MyMeshes.IsLodMeshMerged(lodMesh);
            bool initializeDepthProxy = true;//!isMergedMesh && Num > 0;

            int numToInitialize = (initializeProxies ? partCount : 0) + (initializeDepthProxy ? 1 : 0);
            if (numToInitialize > 0)
                lod.AllocateProxies(numToInitialize);

            AnyDrawOutsideViewDistance = false;

            if (initializeProxies)
            {
                for (int partIndex = 0; partIndex < partCount; partIndex++)
                {
                    CreateRenderableProxyForPart(lod, GetConstantBufferSize(lod, skinningEnabled), partIndex, partIndex, false);
                }
            }
            if (initializeDepthProxy)
                CreateRenderableProxyForPart(lod, GetConstantBufferSize(lod, skinningEnabled), numToInitialize - 1, 0, true);

            return true;
        }