internal MyIsoMesh CreateMesh(IMyStorage storage, MyCellCoord coord)
        {
            // mk:NOTE This method must be thread safe. Called from worker threads.

            coord.CoordInLod += m_cellsOffset >> coord.Lod;

            if (m_voxelMap is MyVoxelPhysics)
            {
                var clipmapId     = ((MyVoxelPhysics)m_voxelMap).Parent.Render.RenderObjectIDs[0];
                var clipmapCellId = MyCellCoord.GetClipmapCellHash(clipmapId, coord.PackId64());
                var isoMesh       = MyPrecalcJobRender.IsoMeshCache.Read(clipmapCellId);
                if (isoMesh != null)
                {
                    return(isoMesh);
                }
            }

            var min = coord.CoordInLod << MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;
            var max = min + MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS;

            // overlap to neighbor; introduces extra data but it makes logic for raycasts and collisions simpler (no need to check neighbor cells)
            min -= 1;
            max += 2;
            return(MyPrecalcComponent.IsoMesher.Precalc(storage, coord.Lod, min, max, false, false));
        }
Beispiel #2
0
            internal void DiscardClippedCells(RequestCollector collector)
            {
                foreach (var entry in m_clippedCells)
                {
                    var data = entry.Value;

                    data.ClippedOut = true;

                    if (UseCache)
                    {
                        var clipmapCellId = MyCellCoord.GetClipmapCellHash(m_clipmap.Id, entry.Key);

                        CellsCache.Write(clipmapCellId, data);
                        Delete(entry.Key, data, false);
                    }
                    else
                    {
                        if (data.Cell != null)
                        {
                            Delete(entry.Key, data);
                        }

                        data.ReadyInClipmap = false;
                    }
                }

                m_clippedCells.Clear();
            }
Beispiel #3
0
            internal void InvalidateRange(Vector3I lodMin, Vector3I lodMax)
            {
                //              MyLog.Default.WriteLine("InvalidateRange Lod: " + m_lodIndex + " Min: " + lodMin + " Max: " + lodMax);

                var cell = new MyCellCoord(m_lodIndex, lodMin);

                for (var it = new Vector3I_RangeIterator(ref lodMin, ref lodMax);
                     it.IsValid(); it.GetNext(out cell.CoordInLod))
                {
                    MyClipmap_CellData data;
                    var id = cell.PackId64();
//                    MyLog.Default.WriteLine("Setting to: m_lodIndex " + cell.Lod + " Coord: " + cell.CoordInLod);


                    if (m_storedCellData.TryGetValue(id, out data))
                    {
                        data.State = CellState.Invalid;
                        //MyLog.Default.WriteLine("Really set to: m_lodIndex " + cell.Lod + " Coord: " + cell.CoordInLod);
                    }

                    if (MyClipmap.UseCache)
                    {
                        var clipmapCellId = MyCellCoord.GetClipmapCellHash(m_clipmap.Id, id);
                        var cachedCell    = MyClipmap.CellsCache.Read(clipmapCellId);
                        if (cachedCell != null)
                        {
                            cachedCell.State = CellState.Invalid;
                        }
                    }
                }
            }
Beispiel #4
0
        public override void DoWork()
        {
            ProfilerShort.Begin("MyPrecalcJobRender.DoWork");
            try
            {
                if (m_isCancelled)
                {
                    return;
                }

                m_metadata.Cell      = m_args.Cell;
                m_metadata.LocalAabb = BoundingBox.CreateInvalid();

                var cellSize = MyVoxelCoordSystems.RenderCellSizeInLodVoxels(m_args.Cell.Lod);
                var min      = m_args.Cell.CoordInLod * cellSize - 1;
                var max      = min + cellSize - 1
                               + 1  // overlap to neighbor so geometry is stitched together within same LOD
                               + 1  // extra overlap so there are more vertices for mapping to parent LOD
                               + 1; // for eg. 9 vertices in row we need 9 + 1 samples (voxels)
                //    + 1 // why not
                //  + 1 // martin kroslak approved

                var       clipmapCellId = MyCellCoord.GetClipmapCellHash(m_args.ClipmapId, m_args.Cell.PackId64());
                MyIsoMesh highResMesh   = IsoMeshCache.Read(clipmapCellId);

                if (highResMesh == null)
                {
                    highResMesh = MyPrecalcComponent.IsoMesher.Precalc(m_args.Storage, m_args.Cell.Lod, min, max, true, MyFakes.ENABLE_VOXEL_COMPUTED_OCCLUSION);
                    if (UseIsoCache && highResMesh != null)
                    {
                        IsoMeshCache.Write(clipmapCellId, highResMesh);
                    }
                }

                if (m_isCancelled || highResMesh == null)
                {
                    return;
                }

                MyIsoMesh lowResMesh = null;

                if (m_args.Cell.Lod < 15 && MyFakes.ENABLE_VOXEL_LOD_MORPHING)
                {
                    var nextLodCell = m_args.Cell;
                    nextLodCell.Lod++;
                    clipmapCellId = MyCellCoord.GetClipmapCellHash(m_args.ClipmapId, nextLodCell.PackId64());

                    lowResMesh = IsoMeshCache.Read(clipmapCellId);

                    if (lowResMesh == null)
                    {
                        // Less detailed mesh for vertex morph targets
                        min >>= 1;
                        max >>= 1;
                        min  -= 1;
                        max  += 2;

                        lowResMesh = MyPrecalcComponent.IsoMesher.Precalc(m_args.Storage, m_args.Cell.Lod + 1, min, max, true, MyFakes.ENABLE_VOXEL_COMPUTED_OCCLUSION);

                        if (UseIsoCache && lowResMesh != null)
                        {
                            IsoMeshCache.Write(clipmapCellId, lowResMesh);
                        }
                    }
                }

                if (m_isCancelled)
                {
                    return;
                }

                RenderCellBuilder.BuildCell(m_args, highResMesh, lowResMesh, m_batches, out m_metadata);
            }
            finally
            {
                ProfilerShort.End();
            }
        }
Beispiel #5
0
            internal void SetCellMesh(MyRenderMessageUpdateClipmapCell msg)
            {
                var cellId = msg.Metadata.Cell.PackId64();
                MyClipmap_CellData data;
                var clipmapCellId = MyCellCoord.GetClipmapCellHash(m_clipmap.Id, cellId);

                //  MyCellCoord cellc = new MyCellCoord();
                //  cellc.SetUnpack(cellId);

                //MyLog.Default.WriteLine("SetCellMesh Lod: " + cellc.Lod + " Coord: " + cellc.CoordInLod);

                if (m_storedCellData.TryGetValue(cellId, out data))
                {
                    PendingCacheCellData.Remove(clipmapCellId);

                    if (data.State == CellState.Invalid)
                    {
//                        MyLog.Default.WriteLine("Invalid");
                        //Cell was invalidated while calculating from old data
                        return;
                    }

                    if (data.Cell == null && msg.Batches.Count != 0)
                    {
                        //MyLog.Default.WriteLine("added to nonempty");
                        data.Cell = m_clipmap.m_cellHandler.CreateCell(m_clipmap.m_scaleGroup, msg.Metadata.Cell, ref m_clipmap.m_worldMatrix);
                        System.Diagnostics.Debug.Assert(data.Cell != null, "Cell not created");
                        if (data.Cell != null)
                        {
                            if (data.Cell.IsValid())
                            {
                                data.CellHandler        = m_clipmap.m_cellHandler;
                                m_nonEmptyCells[cellId] = data;
                            }
                        }
                    }
                    else if (data.Cell != null && msg.Batches.Count == 0)
                    {
                        //MyLog.Default.WriteLine("removed");
                        RemoveFromScene(cellId, data);
                        m_nonEmptyCells.Remove(cellId);
                        m_clipmap.m_cellHandler.DeleteCell(data.Cell);
                        m_blendedCells.Remove(cellId);
                        data.Cell        = null;
                        data.CellHandler = null;
                        if (UseCache)
                        {
                            CellsCache.Remove(cellId);
                        }
                    }

                    if (data.Cell != null)
                    {
                        //MyLog.Default.WriteLine("mesh updated");
                        if (data.Cell.IsValid())
                        {
                            m_clipmap.m_cellHandler.UpdateMesh(data.Cell, msg);
                        }
                    }
                    data.State     = CellState.Loaded;
                    data.WasLoaded = true;
                }
                else
                if (PendingCacheCellData.TryGetValue(clipmapCellId, out data))
                {
                    if (msg.Batches.Count != 0)
                    {
                        data.Cell = m_clipmap.m_cellHandler.CreateCell(m_clipmap.m_scaleGroup, msg.Metadata.Cell, ref m_clipmap.m_worldMatrix);
                        m_clipmap.m_cellHandler.UpdateMesh(data.Cell, msg);
                        data.CellHandler = m_clipmap.m_cellHandler;
                    }

                    CellsCache.Write(clipmapCellId, data);
                    PendingCacheCellData.Remove(clipmapCellId);

                    data.State     = CellState.Loaded;
                    data.WasLoaded = true;
                }
            }
Beispiel #6
0
            private void UnclipCell(RequestCollector collector, MyCellCoord cell, bool isVisible)
            {
                var cellId        = cell.PackId64();
                var clipmapCellId = MyCellCoord.GetClipmapCellHash(m_clipmap.Id, cellId);
                MyClipmap_CellData data;

                if (isVisible)
                {
                    bool highPriority = true;

                    if (m_clippedCells.TryGetValue(cellId, out data))
                    {
                        m_clippedCells.Remove(cellId);
                    }
                    else
                    {
                        highPriority = false;

                        CellBlendData blendData;
                        if (!m_blendedCells.TryGetValue(cellId, out blendData))
                        {
                            data = CellsCache.Read(clipmapCellId);

                            if (data == null) //cache miss
                            {
                                data = new MyClipmap_CellData();
                                ClippingCacheMisses++;
                            }
                            else
                            {
                                //cache hit
                                ClippingCacheHits++;

                                //System.Diagnostics.Debug.Assert((!data.InScene && data.Cell != null) || data.Cell == null, "Not allowed cell state");
                                data.InScene = false;
                                if (data.Cell != null)
                                {
                                    m_nonEmptyCells[cellId] = data;
                                }
                            }
                        }
                        else
                        {
                            data = blendData.CellData;
                            if (blendData.State == BlendState.Removing)
                            {
                                blendData.UndoAfterFinish = true;
                            }
                            if (data.Cell != null)
                            {
                                m_nonEmptyCells[cellId] = data;
                            }
                        }
                    }

                    if (data.State == CellState.Invalid)
                    {
                        if (MyClipmap.UseQueries)
                        {
                            BoundingBoxD bbd;
                            MyVoxelCoordSystems.RenderCellCoordToLocalAABB(ref cell, out bbd);
                            BoundingBox bb = new BoundingBox(bbd);
                            if (m_clipmap.m_prunningFunc == null || m_clipmap.m_prunningFunc(ref bb, false) == ContainmentType.Intersects)
                            {
                                collector.AddRequest(cellId, data, highPriority);
                            }
                            else
                            {
                                data.State     = CellState.Loaded;
                                data.WasLoaded = true;
                            }
                        }
                        else
                        {
                            collector.AddRequest(cellId, data, highPriority);
                        }
                    }

                    m_storedCellData.Add(cellId, data);
                    data.ReadyInClipmap = true;
                    data.ClippedOut     = false;
                }
                else
                {
                    if (!m_storedCellData.ContainsKey(cellId) && (!PendingCacheCellData.ContainsKey(clipmapCellId) || PendingCacheCellData[clipmapCellId].State == CellState.Invalid) && CellsCache.Read(clipmapCellId) == null)
                    {
                        if (!PendingCacheCellData.TryGetValue(clipmapCellId, out data))
                        {
                            data = new MyClipmap_CellData();
                            PendingCacheCellData.Add(clipmapCellId, data);
                        }

                        if (MyClipmap.UseQueries)
                        {
                            BoundingBoxD bbd;
                            MyVoxelCoordSystems.RenderCellCoordToLocalAABB(ref cell, out bbd);
                            BoundingBox bb = new BoundingBox(bbd);
                            if (m_clipmap.m_prunningFunc == null || m_clipmap.m_prunningFunc(ref bb, false) == ContainmentType.Intersects)
                            {
                                data.State = CellState.Invalid;

                                collector.AddRequest(cellId, data, false);
                            }
                            else
                            {
                                data.State     = CellState.Loaded;
                                data.WasLoaded = true;
                            }
                        }
                        else
                        {
                            data.State = CellState.Invalid;
                            collector.AddRequest(cellId, data, false);
                        }
                    }
                }
            }