public override void Init(MyObjectBuilder_EntityBase objectBuilder)
        {
            ProfilerShort.Begin("MyEntity.Init(objectBuilder)");
            if (objectBuilder != null)
            {
                if (objectBuilder.PositionAndOrientation.HasValue)
                {
                    var     posAndOrient = objectBuilder.PositionAndOrientation.Value;
                    MatrixD matrix       = MatrixD.CreateWorld(posAndOrient.Position, posAndOrient.Forward, posAndOrient.Up);
                    MyUtils.AssertIsValid(matrix);

                    Container.Entity.PositionComp.SetWorldMatrix(matrix);
                }
                // Do not copy EntityID if it gets overwritten later. It might
                // belong to some existing entity that we're making copy of.
                if (objectBuilder.EntityId != 0)
                {
                    Container.Entity.EntityId = objectBuilder.EntityId;
                }
                Container.Entity.Name = objectBuilder.Name;
                Container.Entity.Render.PersistentFlags = objectBuilder.PersistentFlags;
            }

            AllocateEntityID();

            Container.Entity.InScene = false;

            MyEntities.SetEntityName(m_entity, false);

            if (m_entity.SyncFlag)
            {
                m_entity.CreateSync();
            }
            GameLogic.Init(objectBuilder);
            ProfilerShort.End();
        }
示例#2
0
        public virtual void UpdateAfterSimulation()
        {
            ProfilerShort.Begin("MyEnvironmentalParticleLogic.UpdateAfterSimulation");
            for (int index = 0; index < m_activeParticles.Count; ++index)
            {
                var particle = m_activeParticles[index];
                if (MySandboxGame.TotalGamePlayTimeInMilliseconds - particle.BirthTime >= particle.LifeTime ||
                    (particle.Position - MySector.MainCamera.Position).Length() > m_particleDespawnDistance ||
                    !particle.Active)
                {
                    m_particlesToRemove.Add(index);
                }
            }

            for (int index = m_particlesToRemove.Count - 1; index >= 0; --index)
            {
                var particleIndex = m_particlesToRemove[index];
                m_nonActiveParticles.Add(m_activeParticles[particleIndex]);
                m_activeParticles[particleIndex].Deactivate();
                m_activeParticles.RemoveAt(particleIndex);
            }
            m_particlesToRemove.Clear();
            ProfilerShort.End();
        }
            void IWork.DoWork()
            {
                ProfilerShort.Begin("MyPrecalcWork");
                m_timer.Start();
                MyPrecalcJob work;

                while (Queue.TryDequeueFront(out work))
                {
                    work.DoWork();
                    m_finishedList.Add(work);
                    if (m_timer.ElapsedMilliseconds >= MaxPrecalcTime)
                    {
                        break;
                    }
                    if (MyFakes.ENABLE_YIELDING_IN_PRECALC_TASK)
                    {
                        Thread.Yield();
                    }
                }

                m_timer.Stop();
                m_timer.Reset();
                ProfilerShort.End();
            }
示例#4
0
        //  Method finds intersection with line and any voxel triangleVertexes in this voxel map. Closes intersection is returned.
        internal override bool GetIntersectionWithLine(ref LineD worldLine, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            t = null;

            double intersectionDistance;
            LineD  line = (LineD)worldLine;

            if (!PositionComp.WorldAABB.Intersects(line, out intersectionDistance))
            {
                return(false);
            }

            ProfilerShort.Begin("VoxelMap.LineIntersection");
            try
            {
                Line localLine = new Line(worldLine.From - PositionLeftBottomCorner,
                                          worldLine.To - PositionLeftBottomCorner, true);
                MyIntersectionResultLineTriangle tmpResult;
                if (Storage.Geometry.Intersect(ref localLine, out tmpResult, flags))
                {
                    t = new MyIntersectionResultLineTriangleEx(tmpResult, this, ref worldLine);
                    var tmp = t.Value.IntersectionPointInWorldSpace;
                    tmp.AssertIsValid();
                    return(true);
                }
                else
                {
                    t = null;
                    return(false);
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
 public void OnNodeRemoved(MyEntity entity)
 {
     if (m_weldParent == null)
     {
         return;
     }
     ProfilerShort.Begin("WeldGroup.OnNodeRemoved");
     if (m_weldParent == entity)
     {
         if (m_group.Nodes.Count == 1 && m_group.Nodes.First().NodeData.MarkedForClose)
         {
         }
         else
         if (m_group.Nodes.Count > 0)
         {
             ReplaceParent(null);
         }
     }
     else if (m_weldParent.Physics != null)
     {
         if (!entity.MarkedForClose)
         {
             (m_weldParent.Physics as MyPhysicsBody).Unweld(entity.Physics as MyPhysicsBody);
         }
     }
     if (m_weldParent != null && m_weldParent.Physics != null && m_weldParent.Physics.RigidBody != null)
     {
         Debug.Assert(m_weldParent.Physics.RigidBody.Layer > 0);
         m_weldParent.Physics.RigidBody.Activate();
         m_weldParent.RaisePhysicsChanged();
     }
     entity.RaisePhysicsChanged();
     Debug.Assert(entity.MarkedForClose || entity.Physics == null || !(entity.Physics as MyPhysicsBody).IsWelded);
     Debug.Assert(entity.MarkedForClose || entity.Physics == null || entity.Physics.RigidBody == null || entity.Physics.RigidBody.Layer > 0);
     ProfilerShort.End();
 }
        private static void SetupReading(
            int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod,
            out float lodVoxelSizeHalf, out BoundingBox queryBox, out BoundingSphere querySphere)
        {
            ProfilerShort.Begin("SetupReading");
            lodVoxelSizeHalf = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (1 << lodIndex);
            Vector3 localMin, localMax;

            {
                Vector3D localPositionD;
                var      min = minInLod << lodIndex;
                var      max = maxInLod << lodIndex;
                MyVoxelCoordSystems.VoxelCoordToLocalPosition(ref min, out localPositionD);
                localMin = localPositionD;
                MyVoxelCoordSystems.VoxelCoordToLocalPosition(ref max, out localPositionD);
                localMax = localPositionD;

                localMin -= lodVoxelSizeHalf;
                localMax += lodVoxelSizeHalf;
            }
            queryBox    = new BoundingBox(localMin, localMax);
            querySphere = BoundingSphere.CreateFromBoundingBox(queryBox);
            ProfilerShort.End();
        }
示例#7
0
        public static MyEntity Spawn(MyPhysicalInventoryItem item, BoundingSphereD sphere, MyPhysicsComponentBase motionInheritedFrom = null, MyVoxelMaterialDefinition voxelMaterial = null)
        {
            ProfilerShort.Begin("MyFloatingObjects.Spawn");
            var floatingBuilder = PrepareBuilder(ref item);

            ProfilerShort.Begin("Create");
            var thrownEntity = MyEntities.CreateFromObjectBuilder(floatingBuilder);

            ProfilerShort.End();
            ((MyFloatingObject)thrownEntity).VoxelMaterial = voxelMaterial;

            var size       = thrownEntity.PositionComp.LocalVolume.Radius;
            var sphereSize = sphere.Radius - size;

            sphereSize = Math.Max(sphereSize, 0);

            sphere = new BoundingSphereD(sphere.Center, sphereSize);

            var pos = MyUtils.GetRandomBorderPosition(ref sphere);

            AddToPos(thrownEntity, pos, motionInheritedFrom);
            ProfilerShort.End();
            return(thrownEntity);
        }
示例#8
0
        internal void OnCellRequest(MyCellCoord cell, Func <int> priorityFunction, Action <Color> debugDraw)
        {
            ProfilerShort.Begin("OnCellRequest");

            try
            {
                var workId = cell.PackId64();

                MyPrecalcJobRender.Start(new MyPrecalcJobRender.Args
                {
                    Storage           = m_voxelMap.Storage,
                    ClipmapId         = ClipmapId,
                    Cell              = cell,
                    WorkId            = workId,
                    RenderWorkTracker = m_renderWorkTracker,
                    Priority          = priorityFunction,
                    DebugDraw         = debugDraw,
                });
            }
            finally
            {
                ProfilerShort.End();
            }
        }
        internal static void Preprocess(MyStringId material, MyStringId pass, MyVertexLayoutInfo vertexLayout, out string vsSource, out string psSource)
        {
            ProfilerShort.Begin("MyShaders.MaterialPreprocess");

            Debug.Assert(m_vertexTemplateBase != null);
            Debug.Assert(m_pixelTemplateBase != null);

            PrefetchMaterialSources(material);
            PrefetchPassSources(pass);

            StringBuilder source = new StringBuilder();

            // vertex shader
            source.Append(m_vertexTemplateBase);
            source.Replace("__VERTEXINPUT_DECLARATIONS__", vertexLayout.SourceDeclarations);
            source.Replace("__VERTEXINPUT_TRANSFER__", vertexLayout.SourceDataMove);
            source.Replace("__MATERIAL_DECLARATIONS__", MaterialSources[material].Declarations);
            source.Replace("__MATERIAL_VERTEXPROGRAM__", MaterialSources[material].VertexShaderSource);
            source.AppendLine();
            source.AppendLine(MaterialPassSources[pass].VertexStageTemplate);

            vsSource = source.ToString();

            source.Clear();

            // pixel shader
            source.Append(m_pixelTemplateBase);
            source.Replace("__MATERIAL_DECLARATIONS__", MaterialSources[material].Declarations);
            source.Replace("__MATERIAL_PIXELPROGRAM__", MaterialSources[material].PixelShaderSource);
            source.AppendLine();
            source.AppendLine(MaterialPassSources[pass].PixelStageTemplate);

            psSource = source.ToString();

            ProfilerShort.End();
        }
示例#10
0
        //  This is real initialization of this class!!! Instead of constructor.
        public virtual void Init(StringBuilder displayName,
                                 string model,
                                 MyEntity parentObject,
                                 float?scale,
                                 string modelCollision = null)
        {
            ProfilerShort.Begin("MyEntity.Init(...models...)");
            MarkedForClose = false;
            Closed         = false;
            this.Render.PersistentFlags = MyPersistentEntityFlags2.CastShadows;
            this.DisplayName            = displayName != null?displayName.ToString() : null;

            RefreshModels(model, modelCollision);

            if (parentObject != null)
            {
                parentObject.Hierarchy.AddChild(this, false, false);
            }

            PositionComp.Scale = scale;

            AllocateEntityID();
            ProfilerShort.End();
        }
示例#11
0
            public void Submit()
            {
                ProfilerShort.Begin("RequestCollector.Submit");

                MyCellCoord cell = default(MyCellCoord);

                foreach (var cellId in m_cancelRequests)
                {
                    cell.SetUnpack(cellId);
                    MyRenderProxy.CancelClipmapCell(m_clipmapId, cell);
                    bool removed = m_sentRequests.Remove(cellId);
                    Debug.Assert(removed);
                }

                foreach (var highPriorityRequest in m_unsentRequestsHigh)
                {
                    cell.SetUnpack(highPriorityRequest);
                    MyRenderProxy.RequireClipmapCell(m_clipmapId, cell, highPriority: true);
                }
                m_unsentRequestsHigh.Clear();

                int addedCount = 0;

                for (int i = m_unsentRequestsLow.Length - 1; i >= 0; i--)
                {
                    var unsent = m_unsentRequestsLow[i];
                    while (0 < unsent.Count && m_sentRequests.Count < m_maxRequests)
                    {
                        var cellId = unsent.FirstElement();

                        cell.SetUnpack(cellId);
                        // Do Z-order style iteration of siblings that also need to
                        // be requested. This ensures faster processing of cells and
                        // shorter time when both lods are rendered.
                        var baseCoord = (cell.CoordInLod >> 1) << 1;
                        var offset    = Vector3I.Zero;
                        for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref Vector3I.One);
                             it.IsValid(); it.GetNext(out offset))
                        {
                            cell.CoordInLod = baseCoord + offset;
                            cellId          = cell.PackId64();
                            if (!unsent.Remove(cellId))
                            {
                                continue;
                            }

                            Debug.Assert(!m_cancelRequests.Contains(cellId));
                            MyRenderProxy.RequireClipmapCell(m_clipmapId, cell, highPriority: false);
                            bool added = m_sentRequests.Add(cellId);
                            Debug.Assert(added);
                            addedCount++;
                        }
                    }

                    // When set reaches reasonably small size, stop freeing memory
                    if (unsent.Count > 100)
                    {
                        unsent.TrimExcess();
                    }
                }

                m_cancelRequests.Clear();

                ProfilerShort.End();
            }
示例#12
0
        private void Update(ref Vector3D cameraPos, float farPlaneDistance)
        {
            ProfilerShort.Begin("MyRenderClipmap.Update");

            var mostDetailedLod = (uint)DebugClipmapMostDetailedLod;

            if (m_lastMostDetailedLod != mostDetailedLod)
            {
                m_updateClipping = true;
            }
            m_lastMostDetailedLod = mostDetailedLod;
            for (uint lod = 0; lod < m_lodLevels.Length; ++lod)
            {
                m_lodLevels[lod].Visible = lod >= mostDetailedLod;
            }

            Vector3D localPosition;

            Vector3D.Transform(ref cameraPos, ref m_invWorldMatrix, out localPosition);

            double cellSizeHalf = MyVoxelCoordSystems.RenderCellSizeInMetersHalf(0);
            double threshold    = cellSizeHalf * cellSizeHalf;

            if (!m_updateClipping && Vector3D.DistanceSquared(localPosition, m_lastClippingPosition) > threshold)
            {
                m_updateClipping = true;
            }

            if (m_updateClipping)
            {
                ProfilerShort.Begin("DoClipping");
                Debug.Assert(m_scaleGroup == MyClipmapScaleEnum.Normal || m_scaleGroup == MyClipmapScaleEnum.Massive);
                for (int lod = m_lodLevels.Length - 1; lod >= mostDetailedLod; --lod)
                {
                    ProfilerShort.Begin("Lod " + lod);
                    m_lodLevels[lod].DoClipping(localPosition, farPlaneDistance, m_requestCollector);
                    ProfilerShort.End();
                }
                ProfilerShort.End();

                ProfilerShort.Begin("KeepOrDiscardClippedCells");
                for (int lod = m_lodLevels.Length - 1; lod >= mostDetailedLod; --lod)
                {
                    m_lodLevels[lod].KeepOrDiscardClippedCells(m_requestCollector);
                }
                ProfilerShort.End();

                m_lastClippingPosition = localPosition;
                m_updateClipping       = false;
            }

            ProfilerShort.Begin("UpdateCellsInScene");
            for (int lod = m_lodLevels.Length - 1; lod >= mostDetailedLod; --lod)
            {
                m_lodLevels[lod].UpdateCellsInScene(localPosition);
            }
            ProfilerShort.End();

            m_requestCollector.Submit();
            if (m_requestCollector.SentRequestsEmpty)
            {
                m_notReady.Remove(this);
            }

            ProfilerShort.End();
        }
示例#13
0
        //  Update all physics objects - AFTER physics simulation
        public static void UpdateAfterSimulation()
        {
            if (MySandboxGame.IsGameReady == false)
            {
                return;
            }
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("UpdateAfterSimulation");
            {
                System.Diagnostics.Debug.Assert(MyEntities.UpdateInProgress == false);
                MyEntities.UpdateInProgress = true;

                ProfilerShort.Begin("UpdateAfter1");
                m_entitiesForUpdate.List.ApplyChanges();
                MySimpleProfiler.Begin("Blocks");
                m_entitiesForUpdate.Iterate((x) =>
                {
                    ProfilerShort.Begin(x.GetType().Name);
                    if (x.MarkedForClose == false)
                    {
                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.Begin(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.Begin("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.Begin("&&GRID&&" + grid.DisplayName);
                            }
                        }

                        x.UpdateAfterSimulation();

                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.End(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.End("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.End("&&GRID&&" + grid.DisplayName);
                            }
                        }
                    }
                    ProfilerShort.End();
                });
                ProfilerShort.End();

                ProfilerShort.Begin("UpdateAfter10");
                m_entitiesForUpdate10.List.ApplyChanges();
                m_entitiesForUpdate10.Iterate((x) =>
                {
                    ProfilerShort.Begin(x.GetType().Name);
                    if (x.MarkedForClose == false)
                    {
                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.Begin(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.Begin("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.Begin("&&GRID&&" + grid.DisplayName);
                            }
                        }

                        x.UpdateAfterSimulation10();

                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.End(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.End("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.End("&&GRID&&" + grid.DisplayName);
                            }
                        }
                    }
                    ProfilerShort.End();
                });
                ProfilerShort.End();

                ProfilerShort.Begin("UpdateAfter100");
                m_entitiesForUpdate100.List.ApplyChanges();
                m_entitiesForUpdate100.Iterate((x) =>
                {
                    ProfilerShort.Begin(x.GetType().Name);
                    if (x.MarkedForClose == false)
                    {
                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.Begin(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.Begin("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.Begin("&&GRID&&" + grid.DisplayName);
                            }
                        }

                        x.UpdateAfterSimulation100();

                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.End(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.End("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.End("&&GRID&&" + grid.DisplayName);
                            }
                        }
                    }
                    ProfilerShort.End();
                });
                ProfilerShort.End();
                MySimpleProfiler.End("Blocks");

                MyEntities.UpdateInProgress = false;

                MyEntities.DeleteRememberedEntities();
            }

            if (m_creationThread != null)
            {
                while (m_creationThread.ConsumeResult())
                {
                    ;                                  // Add entities created asynchronously
                }
            }
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
        public override void Draw()
        {
            ProfilerShort.Begin("base.Draw()");
            base.Draw();

            ProfilerShort.BeginNextBlock("DebugDraw");
            DebugDraw();

            if (BlockCreationIsActivated)
            {
                MyHud.Crosshair.Recenter();
            }

            if (!IsActivated || CurrentBlockDefinition == null)
            {
                this.ClearRenderData();
                ProfilerShort.End();
                return;
            }


            this.DrawGuiIndicators();

            if (!BuildInputValid)
            {
                this.ClearRenderData();
                ProfilerShort.End();
                return;
            }


            ProfilerShort.BeginNextBlock("DrawBuildingStepsCount");
            DrawBuildingStepsCount(m_gizmo.SpaceDefault.m_startBuild, m_gizmo.SpaceDefault.m_startRemove, m_gizmo.SpaceDefault.m_continueBuild, ref m_gizmo.SpaceDefault.m_localMatrixAdd);
            ProfilerShort.End();

            bool addPos    = m_gizmo.SpaceDefault.m_startBuild.HasValue;
            bool removePos = false;

            float gridSize = 0;

            if (CurrentBlockDefinition != null)
            {
                gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize);
            }

            if (DynamicMode)
            {
                Vector3D freePlacementIntersectionPoint = IntersectionStart + IntersectionDistance * IntersectionDirection;
                if (m_hitInfo != null)
                {
                    freePlacementIntersectionPoint = m_hitInfo.Value.Position;
                }

                addPos = this.CaluclateDynamicModePos(freePlacementIntersectionPoint, IsDynamicOverride());
                MyCoordinateSystem.Static.Visible = false;
            }
            else
            {
                if (m_gizmo.SpaceDefault.m_startBuild == null && m_gizmo.SpaceDefault.m_startRemove == null)
                {
                    if (!FreezeGizmo)
                    {
                        if (CurrentGrid != null)
                        {
                            MyCoordinateSystem.Static.Visible = false;
                            ProfilerShort.Begin("MyCubeBuilder.Draw() - Calculate for grid");
                            addPos = GetAddAndRemovePositions(gridSize, PlacingSmallGridOnLargeStatic,
                                                              out m_gizmo.SpaceDefault.m_addPos, out m_gizmo.SpaceDefault.m_addPosSmallOnLarge,
                                                              out m_gizmo.SpaceDefault.m_addDir,
                                                              out m_gizmo.SpaceDefault.m_removePos, out m_gizmo.SpaceDefault.m_removeBlock,
                                                              out m_gizmo.SpaceDefault.m_blockIdInCompound,
                                                              m_gizmo.SpaceDefault.m_removeBlocksInMultiBlock);

                            if (addPos)
                            {
                                if (PlacingSmallGridOnLargeStatic)
                                {
                                    m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPosSmallOnLarge.Value;
                                }
                                else
                                {
                                    m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPos;
                                }

                                m_gizmo.SpaceDefault.m_worldMatrixAdd = m_gizmo.SpaceDefault.m_localMatrixAdd * CurrentGrid.WorldMatrix;

                                var normal = GetSingleMountPointNormal();
                                // Gizmo add dir can be zero in some cases
                                if (normal.HasValue && GridAndBlockValid && m_gizmo.SpaceDefault.m_addDir != Vector3I.Zero)
                                {
                                    m_gizmo.SetupLocalAddMatrix(m_gizmo.SpaceDefault, normal.Value);
                                }
                            }
                            ProfilerShort.End();
                        }
                        else
                        {
                            MyCoordinateSystem.Static.Visible = true;
                            ProfilerShort.Begin("MyCubeBuilder.Draw() - Calculate for voxel");
                            Vector3D localSnappedPos = m_lastLocalCoordSysData.LocalSnappedPos;
                            if (!CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter)
                            {
                                localSnappedPos -= new Vector3D(0.5 * gridSize, 0.5 * gridSize, -0.5 * gridSize);
                            }

                            Vector3I gridCoord = Vector3I.Round(localSnappedPos / gridSize);

                            m_gizmo.SpaceDefault.m_addPos = gridCoord;
                            m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_lastLocalCoordSysData.LocalSnappedPos;
                            m_gizmo.SpaceDefault.m_worldMatrixAdd             = m_lastLocalCoordSysData.Origin.TransformMatrix;

                            addPos = true;
                            ProfilerShort.End();
                        }
                    }

                    Debug.Assert(!m_gizmo.SpaceDefault.m_worldMatrixAdd.IsNan(), "Invalid gizmo matrix");

                    if (m_gizmo.SpaceDefault.m_removeBlock != null)
                    {
                        removePos = true;
                    }
                }
            }

            ProfilerShort.Begin("buildingDisabledByCockpit");
            bool buildingDisabledByCockpit = MySession.Static.ControlledEntity != null && MySession.Static.ControlledEntity is MyCockpit && !SpectatorIsBuilding;

            if (!buildingDisabledByCockpit)
            {
                if (IsInSymmetrySettingMode)
                {
                    m_gizmo.SpaceDefault.m_continueBuild = null;
                    addPos    = false;
                    removePos = false;

                    if (m_gizmo.SpaceDefault.m_removeBlock != null)
                    {
                        var min = (m_gizmo.SpaceDefault.m_removeBlock.Min * CurrentGrid.GridSize);
                        var max = (m_gizmo.SpaceDefault.m_removeBlock.Max * CurrentGrid.GridSize);

                        Vector3 center = (min + max) * 0.5f;

                        Color color = DrawSymmetryPlane(m_symmetrySettingMode, CurrentGrid, center);

                        DrawSemiTransparentBox(CurrentGrid, m_gizmo.SpaceDefault.m_removeBlock, color.ToVector4());
                    }
                }

                if (CurrentGrid != null && (UseSymmetry || IsInSymmetrySettingMode))
                {
                    if (CurrentGrid.XSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.XSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.XSymmetryOdd ? MySymmetrySettingModeEnum.XPlaneOdd : MySymmetrySettingModeEnum.XPlane, CurrentGrid, center);
                    }

                    if (CurrentGrid.YSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.YSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.YSymmetryOdd ? MySymmetrySettingModeEnum.YPlaneOdd : MySymmetrySettingModeEnum.YPlane, CurrentGrid, center);
                    }

                    if (CurrentGrid.ZSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.ZSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.ZSymmetryOdd ? MySymmetrySettingModeEnum.ZPlaneOdd : MySymmetrySettingModeEnum.ZPlane, CurrentGrid, center);
                    }
                }
            }

            ProfilerShort.BeginNextBlock("UpdateGizmos");
            UpdateGizmos(addPos, removePos, true);

            ProfilerShort.BeginNextBlock("UpdateRenderInstanceData");
            m_renderData.UpdateRenderInstanceData();

            ProfilerShort.BeginNextBlock("CurrentVoxelBase");
            if (CurrentGrid == null || (DynamicMode && CurrentGrid != null))
            {
                MatrixD  drawMatrix = m_gizmo.SpaceDefault.m_worldMatrixAdd;
                Vector3D rotatedModelOffset;
                Vector3D.TransformNormal(ref CurrentBlockDefinition.ModelOffset, ref drawMatrix, out rotatedModelOffset);
                drawMatrix.Translation = drawMatrix.Translation + rotatedModelOffset;

                m_renderData.UpdateRenderEntitiesData(drawMatrix, UseTransparency, CurrentBlockScale);
            }
            else
            {
                m_renderData.UpdateRenderEntitiesData(CurrentGrid.WorldMatrix, UseTransparency);
            }

            ProfilerShort.BeginNextBlock("UpdateBlockInfoHud");
            UpdateBlockInfoHud();
            ProfilerShort.End();
        }
示例#15
0
        public static void CutOutShapeWithProperties(
            MyVoxelBase voxelMap,
            MyShape shape,
            out float voxelsCountInPercent,
            out MyVoxelMaterialDefinition voxelMaterial,
            Dictionary <MyVoxelMaterialDefinition, int> exactCutOutMaterials = null,
            bool updateSync          = false,
            bool onlyCheck           = false,
            bool applyDamageMaterial = false,
            bool onlyApplyMaterial   = false)
        {
            if (MySession.Static.EnableVoxelDestruction == false)
            {
                voxelsCountInPercent = 0;
                voxelMaterial        = null;
                return;
            }

            ProfilerShort.Begin("MyVoxelGenerator::CutOutShapeWithProperties()");

            int  originalSum = 0;
            int  removedSum  = 0;
            bool materials   = exactCutOutMaterials != null;

            // Bring the shape into voxel space.
            var oldTranmsform = shape.Transformation;
            var newTransf     = oldTranmsform * voxelMap.PositionComp.WorldMatrixInvScaled;

            newTransf.Translation += voxelMap.SizeInMetresHalf;
            shape.Transformation   = newTransf;

            // This boundary should now be in our local space
            var bbox = shape.GetWorldBoundaries();

            Vector3I minCorner, maxCorner;

            ComputeShapeBounds(voxelMap, ref bbox, Vector3.Zero, voxelMap.Storage.Size, out minCorner, out maxCorner);

            bool readMaterial = exactCutOutMaterials != null || applyDamageMaterial;

            var cacheMin = minCorner - 1;
            var cacheMax = maxCorner + 1;

            //try on making the read/write cell alligned see MyOctreeStorage.WriteRange - Micro octree leaf

            /*const int SHIFT = 4;
             * const int REM = (1 << SHIFT) - 1;
             * const int MASK = ~REM;
             * cacheMin &= MASK;
             * cacheMax = (cacheMax + REM) & MASK;*/

            voxelMap.Storage.ClampVoxelCoord(ref cacheMin);
            voxelMap.Storage.ClampVoxelCoord(ref cacheMax);
            m_cache.Resize(cacheMin, cacheMax);
            m_cache.ClearMaterials(0);

            // Advise that the read content shall be cached
            MyVoxelRequestFlags flags = MyVoxelRequestFlags.AdviseCache;

            voxelMap.Storage.ReadRange(m_cache, readMaterial ? MyStorageDataTypeFlags.ContentAndMaterial : MyStorageDataTypeFlags.Content, 0, ref cacheMin, ref cacheMax, ref flags);

            Vector3I center;

            if (materials)
            {
                center        = m_cache.Size3D / 2;
                voxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref center));
            }
            else
            {
                center        = (cacheMin + cacheMax) / 2;
                voxelMaterial = voxelMap.Storage.GetMaterialAt(ref center);
            }

            MyVoxelMaterialDefinition voxelMat = null;

            ProfilerShort.Begin("Main loop");
            Vector3I pos;

            for (pos.X = minCorner.X; pos.X <= maxCorner.X; ++pos.X)
            {
                for (pos.Y = minCorner.Y; pos.Y <= maxCorner.Y; ++pos.Y)
                {
                    for (pos.Z = minCorner.Z; pos.Z <= maxCorner.Z; ++pos.Z)
                    {
                        // get original amount
                        var relPos   = pos - cacheMin;
                        var lin      = m_cache.ComputeLinear(ref relPos);
                        var original = m_cache.Content(lin);

                        if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY) // if there is nothing to remove
                        {
                            continue;
                        }

                        Vector3D spos   = (Vector3D)(pos - voxelMap.StorageMin) * MyVoxelConstants.VOXEL_SIZE_IN_METRES;
                        var      volume = shape.GetVolume(ref spos);

                        if (volume == 0f) // if there is no intersection
                        {
                            continue;
                        }

                        var maxRemove = (int)(volume * MyVoxelConstants.VOXEL_CONTENT_FULL);
                        var toRemove  = maxRemove;                        // (int)(maxRemove * voxelMat.DamageRatio);
                        var newVal    = Math.Max(original - toRemove, 0); //MathHelper.Clamp(original - toRemove, 0, original-maxRemove);
                        var removed   = original - newVal;

                        if (!onlyCheck && !onlyApplyMaterial)
                        {
                            m_cache.Content(lin, (byte)newVal);
                        }

                        originalSum += original;
                        removedSum  += removed;

                        if (readMaterial)
                        {
                            voxelMat = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(lin));
                        }

                        if (exactCutOutMaterials != null)
                        {
                            int value = 0;
                            exactCutOutMaterials.TryGetValue(voxelMat, out value);
                            value += (MyFakes.ENABLE_REMOVED_VOXEL_CONTENT_HACK ? (int)(removed * 3.9f) : removed);
                            exactCutOutMaterials[voxelMat] = value;
                        }

                        if (applyDamageMaterial && voxelMat.HasDamageMaterial && !onlyCheck)
                        {
                            m_cache.Material(lin, voxelMat.DamagedMaterialId);
                        }
                    }
                }
            }

            if (removedSum > 0 && updateSync && Sync.IsServer)
            {
                shape.SendDrillCutOutRequest(voxelMap, applyDamageMaterial);
            }

            ProfilerShort.BeginNextBlock("Write");


            if (removedSum > 0 && !onlyCheck)
            {
                //  Clear all small voxel that may have been created during explosion. They can be created even outside the range of
                //  explosion sphere, e.g. if you have three voxels in a row A, B, C, where A is 255, B is 60, and C is 255. During the
                //  explosion you change C to 0, so now we have 255, 60, 0. Than another explosion that will change A to 0, so we
                //  will have 0, 60, 0. But B was always outside the range of the explosion. So this is why we need to do -1/+1 and remove
                //  B voxels too.
                //!! TODO AR & MK : check if this is needed !!
                //RemoveSmallVoxelsUsingChachedVoxels();

                var dataTypeFlags = applyDamageMaterial ? MyStorageDataTypeFlags.ContentAndMaterial : MyStorageDataTypeFlags.Content;
                if (MyFakes.LOG_NAVMESH_GENERATION)
                {
                    MyAIComponent.Static.Pathfinding.VoxelPathfinding.DebugLog.LogStorageWrite(voxelMap, m_cache, dataTypeFlags, cacheMin, cacheMax);
                }
                voxelMap.Storage.WriteRange(m_cache, dataTypeFlags, ref cacheMin, ref cacheMax);
            }
            ProfilerShort.End();


            voxelsCountInPercent = (originalSum > 0f) ? (float)removedSum / (float)originalSum : 0f;

            shape.Transformation = oldTranmsform;

            if (removedSum > 0)
            {
                OnVoxelChanged(MyVoxelBase.OperationType.Cut, voxelMap, shape);
            }

            ProfilerShort.End();
        }
示例#16
0
        internal static void Run()
        {
            ProfilerShort.Begin("MyOutline.Run");
            MyGpuProfiler.IC_BeginBlock("MyOutline.Run");
            // set resolved depth/ stencil
            // render all with proper depth-stencil state
            // blur
            // blend to main target testing with stencil again

            MyOutlinePass.Instance.ViewProjection = MyEnvironment.ViewProjectionAt0;
            MyOutlinePass.Instance.Viewport       = new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y);

            MyOutlinePass.Instance.PerFrame();
            MyOutlinePass.Instance.Begin();

            RC.Clear();
            RC.DeviceContext.VertexShader.SetShaderResources(0, null, null, null, null, null, null);
            RC.DeviceContext.GeometryShader.SetShaderResources(0, null, null, null, null, null, null);
            RC.DeviceContext.PixelShader.SetShaderResources(0, null, null, null, null, null, null);
            RC.DeviceContext.ComputeShader.SetShaderResources(0, null, null, null, null, null, null);

            if (MyRender11.MultisamplingEnabled)
            {
                RC.DeviceContext.ClearRenderTargetView(MyRender11.m_rgba8_ms.m_RTV, new SharpDX.Color4(0, 0, 0, 0));

                RC.DeviceContext.OutputMerger.SetTargets(MyGBuffer.Main.DepthStencil.m_DSV, MyRender11.m_rgba8_ms.m_RTV);
            }
            else
            {
                RC.DeviceContext.ClearRenderTargetView(MyRender11.m_rgba8_1.m_RTV, new SharpDX.Color4(0, 0, 0, 0));

                RC.DeviceContext.OutputMerger.SetTargets(MyGBuffer.Main.DepthStencil.m_DSV, MyRender11.m_rgba8_1.m_RTV);
            }

            float maxThickness = 0f;

            foreach (var pair in m_outlines)
            {
                MyActor actor = MyIDTracker <MyActor> .FindByID(pair.Key);

                MyRenderableComponent renderableComponent;
                if (actor == null || (renderableComponent = actor.GetRenderable()) == null)
                {
                    // If an actor has been removed without removing outlines, just remove the outlines too
                    m_keysToRemove.Add(pair.Key);
                    continue;
                }

                var renderLod = renderableComponent.Lods[renderableComponent.CurrentLod];
                var model     = renderableComponent.GetModel();

                LodMeshId currentModelId;
                if (!MyMeshes.TryGetLodMesh(model, renderableComponent.CurrentLod, out currentModelId))
                {
                    Debug.Fail("Mesh for outlining not found!");
                    continue;
                }

                foreach (MyOutlineDesc descriptor in pair.Value)
                {
                    if (!renderableComponent.IsRenderedStandAlone)
                    {
                        MyGroupLeafComponent leafComponent  = actor.GetGroupLeaf();
                        MyGroupRootComponent groupComponent = leafComponent.RootGroup;
                        if (groupComponent != null)
                        {
                            RecordMeshPartCommands(model, actor, groupComponent, groupComponent.m_proxy, descriptor, ref maxThickness);
                        }

                        continue;
                    }

                    if (descriptor.SectionIndex == -1)
                    {
                        RecordMeshPartCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness);
                    }
                    else
                    {
                        RecordMeshSectionCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness);
                    }
                }
            }

            MyOutlinePass.Instance.End();
            RC.SetBS(null);

            foreach (var outlineKey in m_keysToRemove)
            {
                m_outlines.Remove(outlineKey);
            }

            m_keysToRemove.SetSize(0);

            ShaderResourceView initialSourceView = MyRender11.MultisamplingEnabled ? MyRender11.m_rgba8_ms.m_SRV : MyRender11.m_rgba8_1.m_SRV;
            RenderTargetView   renderTargetview  = MyRender11.MultisamplingEnabled ? MyRender11.m_rgba8_ms.m_RTV : MyRender11.m_rgba8_1.m_RTV;

            if (maxThickness > 0)
            {
                MyBlur.Run(renderTargetview, MyRender11.m_rgba8_2.m_RTV, MyRender11.m_rgba8_2.m_SRV, initialSourceView,
                           (int)Math.Round(5 * maxThickness),
                           MyBlur.MyBlurDensityFunctionType.Exponential, 0.25f,
                           null, MyFoliageRenderingPass.GrassStencilMask, MyRender11.Settings.BlurCopyOnDepthStencilFail);
            }

            MyGpuProfiler.IC_EndBlock();
            ProfilerShort.End();
        }
示例#17
0
        protected override void CalculateTransforms()
        {
            ProfilerShort.Begin("MyCharacter.CalculateTransforms");

            base.CalculateTransforms();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("UpdateLeftHandItemPosition");
            if (m_leftHandItem != null)
            {
                UpdateLeftHandItemPosition();
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().StartNextBlock("Calculate Hand IK");

            m_aimedPoint = GetAimedPointFromCamera();

            if (m_currentWeapon != null)
            {
                if (!MyPerGameSettings.UseAnimationInsteadOfIK)
                {
                    UpdateWeaponPosition(); //mainly IK and some zoom + ironsight stuff
                    if (m_handItemDefinition.SimulateLeftHand && m_leftHandIKStartBone != -1 && m_leftHandIKEndBone != -1 && (!UseAnimationForWeapon && m_animationToIKState == 0))
                    {
                        MatrixD leftHand = (MatrixD)m_handItemDefinition.LeftHand * ((MyEntity)m_currentWeapon).WorldMatrix;
                        CalculateHandIK(m_leftHandIKStartBone, m_leftForearmBone, m_leftHandIKEndBone, ref leftHand);
                    }

                    if (m_handItemDefinition.SimulateRightHand && m_rightHandIKStartBone != -1 && m_rightHandIKEndBone != -1 && (!UseAnimationForWeapon || m_animationToIKState != 0))
                    {
                        MatrixD rightHand = (MatrixD)m_handItemDefinition.RightHand * ((MyEntity)m_currentWeapon).WorldMatrix;
                        CalculateHandIK(m_rightHandIKStartBone, m_rightForearmBone, m_rightHandIKEndBone, ref rightHand);
                    }
                }
                else
                {
                    Debug.Assert(m_rightHandItemBone != -1, "Invalid bone for weapon.");
                    if (m_rightHandItemBone != -1)
                    {
                        //use animation for right hand item
                        MatrixD rightHandItemMatrix = Bones[m_rightHandItemBone].AbsoluteTransform * WorldMatrix;
                        //var rightHandItemMatrix = ((MyEntity)m_currentWeapon).PositionComp.WorldMatrix; //use with UpdateWeaponPosition() but not working for barbarians
                        Vector3D up = rightHandItemMatrix.Up;
                        rightHandItemMatrix.Up      = rightHandItemMatrix.Forward;
                        rightHandItemMatrix.Forward = up;
                        rightHandItemMatrix.Right   = -rightHandItemMatrix.Right;
                        ((MyEntity)m_currentWeapon).PositionComp.WorldMatrix = rightHandItemMatrix;
                    }
                }
            }


            VRageRender.MyRenderProxy.GetRenderProfiler().StartNextBlock("ComputeBoneTransform");

            for (int i = 0; i < Bones.Count; i++)
            {
                MyCharacterBone bone = Bones[i];
                BoneRelativeTransforms[i] = bone.ComputeBoneTransform();
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            ProfilerShort.End();
        }
示例#18
0
        void Scan()
        {
            m_lastScan = MySession.Static.GameplayFrameCounter;
            ProfilerShort.Begin("QueryTargets");
            BoundingSphereD bs = new BoundingSphereD(Vector3D.Transform(m_queryLocal.Center, m_grid.WorldMatrix), m_queryLocal.Radius);

            m_targetRoots.Clear();
            m_targetBlocks.Clear();

            ProfilerShort.Begin("MyGamePruningStructure.GetAllTop...");
            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref bs, m_targetRoots);
            ProfilerShort.End();

            int targetCount = m_targetRoots.Count;

            m_ownersA.AddList(m_grid.SmallOwners);
            m_ownersA.AddList(m_grid.BigOwners);
            for (int i = 0; i < targetCount; i++)
            {
                var grid = m_targetRoots[i] as MyCubeGrid; //perf: using grid owners to not querry friendly ships for blocks
                if (grid != null)
                {
                    if (grid.Physics != null && !grid.Physics.Enabled)
                    {
                        continue;
                    }

                    ProfilerShort.Begin("Friend checks");
                    bool enemy = false;
                    if (grid.BigOwners.Count == 0 && grid.SmallOwners.Count == 0)
                    {
                        foreach (var owner in m_ownersA)
                        {
                            if (MyIDModule.GetRelation(owner, 0) == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies)
                            {
                                enemy = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        m_ownersB.AddList(grid.BigOwners);
                        m_ownersB.AddList(grid.SmallOwners);


                        foreach (var owner in m_ownersA)
                        {
                            foreach (var other in m_ownersB)
                            {
                                if (MyIDModule.GetRelation(owner, other) == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies)
                                {
                                    enemy = true;
                                    break;
                                }
                            }
                        }
                        m_ownersB.Clear();
                    }
                    ProfilerShort.End();
                    if (enemy)
                    {
                        ProfilerShort.Begin("grid.Hierarchy.QuerySphere");
                        var list = m_targetBlocks.GetOrAddList(grid);
                        grid.Hierarchy.QuerySphere(ref bs, list);
                        ProfilerShort.End();
                    }
                    else
                    {
                        MyIDModule module;
                        //performance unfriendly case when grid is not clearly neutral or enemy
                        foreach (var block in grid.GetFatBlocks())
                        {
                            var moduleOwner = ((MyEntity)block) as IMyComponentOwner <MyIDModule>;
                            if (!(moduleOwner != null && moduleOwner.GetComponent(out module)))
                            {
                                continue;
                            }

                            var myID = block.OwnerId;
                            foreach (var owner in m_ownersA)
                            {
                                if (MyIDModule.GetRelation(owner, myID) == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies)
                                {
                                    enemy = true;
                                    break;
                                }
                            }
                            if (enemy)
                            {
                                break;
                            }
                        }

                        if (enemy)
                        {
                            ProfilerShort.Begin("grid.Hierarchy.QuerySphere");
                            var list = m_targetBlocks.GetOrAddList(grid);
                            grid.Hierarchy.QuerySphere(ref bs, list);
                            ProfilerShort.End();
                        }
                    }
                }
            }
            m_ownersA.Clear();

            ProfilerShort.Begin("Filter small objects");
            for (int i = m_targetRoots.Count - 1; i >= 0; i--)
            {
                var target = m_targetRoots[i];
                if (target is Sandbox.Game.Entities.Debris.MyDebrisBase ||
                    target is MyFloatingObject ||
                    (target.Physics != null && !target.Physics.Enabled) ||
                    target.GetTopMostParent().Physics == null || !target.GetTopMostParent().Physics.Enabled)
                {
                    m_targetRoots.RemoveAtFast(i);
                }
            }
            ProfilerShort.End();
            ProfilerShort.End();
        }
        public static void FixPosition(MyFracturedPiece fp)
        {
            //return;
            ProfilerShort.Begin("FixPosition");
            var shape = fp.Physics.BreakableBody.BreakableShape;

            if (shape.GetChildrenCount() == 0)
            {
                ProfilerShort.End();
                return;
            }
            shape.GetChildren(m_tmpInfos);
            var offset = m_tmpInfos[0].GetTransform().Translation;

            if (offset.LengthSquared() < 1)
            {
                m_tmpInfos.Clear();
                ProfilerShort.End();
                return;
            }
            var lst  = new List <HkdConnection>();
            var set  = new HashSet <HkdBreakableShape>();
            var set2 = new HashSet <HkdBreakableShape>();

            set.Add(shape);
            shape.GetConnectionList(lst);
            fp.PositionComp.SetPosition(Vector3D.Transform(offset, fp.PositionComp.WorldMatrix));
            foreach (var child in m_tmpInfos)
            {
                var m = child.GetTransform();
                m.Translation -= offset;
                child.SetTransform(ref m);
                m_tmpInfos2.Add(child);
                HkdBreakableShape par = child.Shape;
                par.GetConnectionList(lst);
                while (par.HasParent)
                {
                    par = par.GetParent();
                    if (set.Add(par))
                    {
                        par.GetConnectionList(lst);
                    }
                    else
                    {
                    }
                }
                set2.Add(child.Shape);
            }
            m_tmpInfos.Clear();
            HkdBreakableShape compound = new HkdCompoundBreakableShape(shape, m_tmpInfos2);

            //HkMassProperties mp = new HkMassProperties();
            ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();
            compound.SetChildrenParent(compound);
            foreach (var c in lst)
            {
                HkBaseSystem.EnableAssert(390435339, true);
                if (!set2.Contains(c.ShapeA) || !set2.Contains(c.ShapeB))
                {
                    continue;
                }
                var cref = c;
                compound.AddConnection(ref cref);
            }
            fp.Physics.BreakableBody.BreakableShape = compound;
            m_tmpInfos2.Clear();

            ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();

            ProfilerShort.End();
        }
示例#20
0
        public static void CutOutShapeWithProperties(
            MyVoxelBase voxelMap,
            MyShape shape,
            out float voxelsCountInPercent,
            out MyVoxelMaterialDefinition voxelMaterial,
            Dictionary <MyVoxelMaterialDefinition, int> exactCutOutMaterials = null,
            bool updateSync = false,
            bool onlyCheck  = false)
        {
            ProfilerShort.Begin("MyVoxelGenerator::CutOutShapeWithProperties()");

            int originalSum = 0;
            int removedSum  = 0;

            var      bbox = shape.GetWorldBoundaries();
            Vector3I minCorner, maxCorner;

            ComputeShapeBounds(ref bbox, voxelMap.PositionLeftBottomCorner, voxelMap.Storage.Size, out minCorner, out maxCorner);

            var cacheMin = minCorner - 1;
            var cacheMax = maxCorner + 1;

            voxelMap.Storage.ClampVoxelCoord(ref cacheMin);
            voxelMap.Storage.ClampVoxelCoord(ref cacheMax);
            m_cache.Resize(cacheMin, cacheMax);
            voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, ref cacheMin, ref cacheMax);

            {
                var      shapeCenter = bbox.Center;
                Vector3I exactCenter;
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref shapeCenter, out exactCenter);
                exactCenter  -= cacheMin;
                exactCenter   = Vector3I.Clamp(exactCenter, Vector3I.Zero, m_cache.Size3D - 1);
                voxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref exactCenter));
            }

            for (var it = new Vector3I.RangeIterator(ref minCorner, ref maxCorner); it.IsValid(); it.MoveNext())
            {
                var relPos   = it.Current - cacheMin; // get original amount
                var original = m_cache.Content(ref relPos);

                if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY) // if there is nothing to remove
                {
                    continue;
                }

                Vector3D vpos;
                MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxelMap.PositionLeftBottomCorner, ref it.Current, out vpos);
                var volume = shape.GetVolume(ref vpos);

                if (volume == 0f) // if there is no intersection
                {
                    continue;
                }

                var maxRemove = (int)(volume * MyVoxelConstants.VOXEL_CONTENT_FULL);
                var voxelMat  = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref relPos));
                var toRemove  = (int)(maxRemove * voxelMat.DamageRatio);
                var newVal    = MathHelper.Clamp(original - toRemove, 0, maxRemove);
                var removed   = Math.Abs(original - newVal);

                if (!onlyCheck)
                {
                    m_cache.Content(ref relPos, (byte)newVal);
                }

                originalSum += original;
                removedSum  += removed;

                if (exactCutOutMaterials != null)
                {
                    int value = 0;
                    exactCutOutMaterials.TryGetValue(voxelMat, out value);
                    value += (MyFakes.ENABLE_REMOVED_VOXEL_CONTENT_HACK ? (int)(removed * 3.9f) : removed);
                    exactCutOutMaterials[voxelMat] = value;
                }
            }

            if (removedSum > 0 && !onlyCheck)
            {
                //  Clear all small voxel that may have been created during explosion. They can be created even outside the range of
                //  explosion sphere, e.g. if you have three voxels in a row A, B, C, where A is 255, B is 60, and C is 255. During the
                //  explosion you change C to 0, so now we have 255, 60, 0. Than another explosion that will change A to 0, so we
                //  will have 0, 60, 0. But B was always outside the range of the explosion. So this is why we need to do -1/+1 and remove
                //  B voxels too.
                //!! TODO AR & MK : check if this is needed !!
                RemoveSmallVoxelsUsingChachedVoxels();

                voxelMap.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.Content, ref cacheMin, ref cacheMax);
            }

            if (removedSum > 0 && updateSync && Sync.IsServer)
            {
                shape.SendDrillCutOutRequest(voxelMap.SyncObject);
            }

            voxelsCountInPercent = (originalSum > 0f) ? (float)removedSum / (float)originalSum : 0f;
            ProfilerShort.End();
        }
示例#21
0
        internal static byte[] Compile(string filepath, ShaderMacro[] macros, MyShaderProfile profile, string sourceDescriptor, bool optimize, bool invalidateCache, out bool wasCached, out string compileLog)
        {
            ProfilerShort.Begin("MyShaders.Compile");

            var globalMacros = GlobalShaderMacros;

            if (globalMacros.Length != 0)
            {
                var macroList = new List <ShaderMacro>();
                macroList.AddRange(globalMacros);
                macroList.AddRange(macros);
                macros = macroList.ToArray();
            }

            string function    = ProfileEntryPoint(profile);
            string profileName = ProfileToString(profile);

            wasCached  = false;
            compileLog = null;

            ProfilerShort.Begin("MyShaders.Preprocess");
            string errors;
            string preprocessedSource = PreprocessShader(filepath, macros, out errors);

            if (preprocessedSource == null)
            {
                compileLog = errors;
                return(null);
            }

            // modify preprocessor to be readable for NSight
            if (MyCompilationSymbols.EnableShaderDebuggingInNSight)
            {
                preprocessedSource = Regex.Replace(preprocessedSource, "#line [^\n]*\n", "");
            }

            MyShaderIdentity identity = null;

            if (!invalidateCache && !MyCompilationSymbols.EnableShaderDebuggingInNSight)
            {
                identity = MyShaderCache.ComputeShaderIdentity(preprocessedSource, profile);
                byte[] cached;
                if (MyShaderCache.TryFetch(identity, out cached))
                {
                    wasCached = true;
                    ProfilerShort.End();
                    ProfilerShort.End();
                    return(cached);
                }
            }
            ProfilerShort.End();

            try
            {
                string            descriptor = sourceDescriptor + " " + profile + " " + macros.GetString();
                CompilationResult compilationResult;
                if (MyCompilationSymbols.EnableShaderDebuggingInNSight)
                {
                    if (MyCompilationSymbols.EnableShaderPreprocessorInNSight)
                    {
                        compilationResult = ShaderBytecode.Compile(preprocessedSource, function, profileName, 0, 0, macros, new MyIncludeProcessor(filepath));
                    }
                    else
                    {
                        compilationResult = ShaderBytecode.CompileFromFile(filepath, function, profileName, 0, 0, macros, new MyIncludeProcessor(filepath));
                    }
                }
                else
                {
                    compilationResult = ShaderBytecode.Compile(preprocessedSource, function, profileName,
                                                               optimize ? ShaderFlags.OptimizationLevel3 : ShaderFlags.None,
                                                               EffectFlags.None, filepath);
                }

                if (DUMP_CODE)
                {
                    var disassembly = compilationResult.Bytecode.Disassemble(DisassemblyFlags.EnableColorCode |
                                                                             DisassemblyFlags.EnableInstructionNumbering);
                    string asmPath;
                    if (MyRender11.DebugMode)
                    {
                        asmPath = Path.GetFileName(descriptor + "__DEBUG.html");
                    }
                    else
                    {
                        asmPath = Path.GetFileName(descriptor + "__O3.html");
                    }

                    using (var writer = new StreamWriter(Path.Combine(MyFileSystem.ContentPath, "ShaderOutput", asmPath)))
                    {
                        writer.Write(disassembly);
                    }
                }

                if (compilationResult.Message != null)
                {
                    compileLog = compilationResult.Message;
                }

                if (!MyCompilationSymbols.EnableShaderDebuggingInNSight && compilationResult.Bytecode != null &&
                    compilationResult.Bytecode.Data.Length > 0)
                {
                    MyShaderCache.Store(identity, compilationResult.Bytecode.Data);
                }

                return(compilationResult.Bytecode != null ? compilationResult.Bytecode.Data : null);
            }
            catch (Exception e)
            {
                Debug.WriteLine(preprocessedSource);
                compileLog = e.Message;
            }
            finally
            {
                ProfilerShort.End();
            }
            return(null);
        }
示例#22
0
        public override void Init(MyObjectBuilder_EntityBase builder, Sandbox.Engine.Voxels.IMyStorage storage)
        {
            ProfilerShort.Begin("MyPlanet::Init()");
            if (MyFakes.ENABLE_PLANETS == false)
            {
                throw new PlanetsNotEnabledException();
            }

            ProfilerShort.Begin("MyVoxelBase Init");

            SyncFlag = true;

            base.Init(builder);

            ProfilerShort.BeginNextBlock("Load Saved Data");

            var ob = (MyObjectBuilder_Planet)builder;

            if (ob == null)
            {
                return;
            }

            if (ob.MutableStorage)
            {
                StorageName = ob.StorageName;
            }
            else
            {
                StorageName = string.Format("{0}", ob.StorageName);
            }

            m_planetInitValues.StorageName           = StorageName;
            m_planetInitValues.PositionMinCorner     = ob.PositionAndOrientation.Value.Position;
            m_planetInitValues.HasAtmosphere         = ob.HasAtmosphere;
            m_planetInitValues.AtmosphereRadius      = ob.AtmosphereRadius;
            m_planetInitValues.AtmosphereWavelengths = ob.AtmosphereWavelengths;
            m_planetInitValues.GravityFalloff        = ob.GravityFalloff;
            m_planetInitValues.MarkAreaEmpty         = ob.MarkAreaEmpty;
            m_planetInitValues.SurfaceGravity        = ob.SurfaceGravity;
            m_planetInitValues.AddGps = ob.ShowGPS;
            m_planetInitValues.SpherizeWithDistance = ob.SpherizeWithDistance;
            m_planetInitValues.Generator            = ob.PlanetGenerator == "" ? null : MyDefinitionManager.Static.GetDefinition <MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(ob.PlanetGenerator));
            if (m_planetInitValues.Generator == null)
            {
                string message = string.Format("No definition found for planet generator {0}.", ob.PlanetGenerator);
                MyLog.Default.WriteLine(message);
                throw new Exception(message);
            }

            m_planetInitValues.AtmosphereSettings = m_planetInitValues.Generator.AtmosphereSettings.HasValue ? m_planetInitValues.Generator.AtmosphereSettings.Value : MyAtmosphereSettings.Defaults();
            m_planetInitValues.UserCreated        = false;

            ProfilerShort.BeginNextBlock("Load Storage");
            if (storage != null)
            {
                m_planetInitValues.Storage = storage;
            }
            else
            {
                m_planetInitValues.Storage = MyStorageBase.Load(ob.StorageName);
            }

            ProfilerShort.BeginNextBlock("Init Internal");
            Init(m_planetInitValues);
            ProfilerShort.End();

            ProfilerShort.End();
        }
示例#23
0
        public static void MakeCrater(MyVoxelBase voxelMap, BoundingSphereD sphere, Vector3 normal, MyVoxelMaterialDefinition material)
        {
            ProfilerShort.Begin("MakeCrater");

            Vector3I minCorner, maxCorner;

            {
                Vector3D sphereMin = sphere.Center - (sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES);
                Vector3D sphereMax = sphere.Center + (sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES);
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMin, out minCorner);
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMax, out maxCorner);
            }


            voxelMap.Storage.ClampVoxelCoord(ref minCorner);
            voxelMap.Storage.ClampVoxelCoord(ref maxCorner);

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            bool changed = false;

            ProfilerShort.Begin("Reading cache");
            m_cache.Resize(minCorner, maxCorner);
            voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, ref minCorner, ref maxCorner);
            ProfilerShort.End();

            ProfilerShort.Begin("Changing cache");
            int      removedVoxelContent = 0;
            Vector3I tempVoxelCoord;
            Vector3I cachePos;

            for (tempVoxelCoord.Z = minCorner.Z, cachePos.Z = 0; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++, ++cachePos.Z)
            {
                for (tempVoxelCoord.Y = minCorner.Y, cachePos.Y = 0; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++, ++cachePos.Y)
                {
                    for (tempVoxelCoord.X = minCorner.X, cachePos.X = 0; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++, ++cachePos.X)
                    {
                        Vector3D voxelPosition;
                        MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxelMap.PositionLeftBottomCorner, ref tempVoxelCoord, out voxelPosition);

                        float addDist = (float)(voxelPosition - sphere.Center).Length();
                        float addDiff = (float)(addDist - sphere.Radius);

                        byte newContent;
                        if (addDiff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (addDiff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            //  This formula will work even if diff is positive or negative
                            newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - addDiff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                        byte originalContent = m_cache.Content(ref cachePos);

                        if (newContent > originalContent && originalContent > 0)
                        {
                            if (material != null)
                            {
                                m_cache.Material(ref cachePos, material.Index);
                            }

                            changed = true;
                            m_cache.Content(ref cachePos, newContent);
                        }

                        float delDist = (float)(voxelPosition - (sphere.Center + (float)sphere.Radius * 0.7f * normal)).Length();
                        float delDiff = (float)(delDist - sphere.Radius);

                        byte contentToRemove;
                        if (delDiff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (delDiff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            //  This formula will work even if diff is positive or negative
                            contentToRemove = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - delDiff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                        originalContent = m_cache.Content(ref cachePos);

                        if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY && contentToRemove > MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                        {
                            changed = true;

                            int newVal = originalContent - contentToRemove;
                            if (newVal < MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                            {
                                newVal = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            m_cache.Content(ref cachePos, (byte)newVal);

                            removedVoxelContent += originalContent - newVal;
                        }

                        float setDist = (float)(voxelPosition - (sphere.Center - (float)sphere.Radius * 0.5f * normal)).Length();
                        float setDiff = (float)(setDist - sphere.Radius / 4f);

                        if (setDiff <= MyVoxelConstants.VOXEL_SIZE_IN_METRES * 1.5f)  // could be VOXEL_SIZE_IN_METRES_HALF, but we want to set material in empty cells correctly
                        {
                            byte indestructibleContentToSet = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            if (setDiff >= MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)  // outside
                            {
                                indestructibleContentToSet = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else if (setDiff >= -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)  // boundary
                            {
                                indestructibleContentToSet = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - setDiff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            }

                            MyVoxelMaterialDefinition originalMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref cachePos));

                            // Change the material:
                            // - always on boundaries between material and nothing
                            // - smoothly on inner boundaries
                            MyVoxelMaterialDefinition newMaterial = material;
                            if (setDiff > 0)
                            {
                                byte content = m_cache.Content(ref cachePos);
                                if (content == MyVoxelConstants.VOXEL_CONTENT_FULL)
                                {
                                    newMaterial = originalMaterial;
                                }
                                if (setDiff >= MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF && content != MyVoxelConstants.VOXEL_CONTENT_EMPTY)  // set material behind boundary only for empty voxels
                                {
                                    newMaterial = originalMaterial;
                                }
                            }

                            if (originalMaterial == newMaterial)
                            {
                                continue;
                            }

                            m_cache.Material(ref cachePos, newMaterial.Index);
                            changed = true;
                        }

                        float dist = (float)(voxelPosition - sphere.Center).Length();
                        float diff = (float)(dist - sphere.Radius);

                        if (diff <= 0f)
                        {
                            originalContent = m_cache.Content(ref cachePos);
                            if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                            {
                                bool wrinkled = m_cache.WrinkleVoxelContent(ref cachePos, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_ADD, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_REMOVE);
                                if (wrinkled)
                                {
                                    changed = true;
                                }
                            }
                        }
                    }
                }
            }
            ProfilerShort.End();

            if (changed)
            {
                ProfilerShort.Begin("RemoveSmallVoxelsUsingChachedVoxels");
                RemoveSmallVoxelsUsingChachedVoxels();
                ProfilerShort.BeginNextBlock("Writing cache");
                voxelMap.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, ref minCorner, ref maxCorner);
                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
示例#24
0
        private void Update(ref Vector3D cameraPos, ref Vector3 cameraForward, float farPlaneDistance)
        {
            ProfilerShort.Begin("MyRenderClipmap.Update");

            LastCameraPosition = cameraPos;

            if (!Environment.Is64BitProcess)
            {
                UseCache = false;
            }

            if (NeedsResetCache)
            {
                MyClipmap.CellsCache.Reset();
                NeedsResetCache = false;
            }

            for (uint lod = 0; lod < m_lodLevels.Length; lod++)
            {
                if (m_lodLevels[lod].IsDitheringInProgress())
                {
                    m_lodLevels[lod].UpdateDithering();
                }
            }

            Vector3D localPosition;

            Vector3D.Transform(ref cameraPos, ref m_invWorldMatrix, out localPosition);

            Vector3 localForward;

            Vector3.TransformNormal(ref cameraForward, ref m_invWorldMatrix, out localForward);

            double cellSizeHalf      = MyVoxelCoordSystems.RenderCellSizeInMetersHalf(0);
            double threshold         = cellSizeHalf / 4.0f;
            float  thresholdRotation = 0.03f;

            if (!m_updateClippingFrustum && (Vector3D.DistanceSquared(localPosition, m_lastClippingPosition) > threshold) || (Vector3.DistanceSquared(localForward, m_lastClippingForward) > thresholdRotation) || m_invalidated > 0)
            {
                ResetClipping();

                m_lastClippingPosition = localPosition;
                m_lastClippingForward  = localForward;
            }

            float camDistanceFromCenter = Vector3.Distance(m_massiveCenter, cameraPos);

            if (m_requestCollector.SentRequestsEmpty && m_updateClippingFrustum)
            {
                ProfilerShort.Begin("DoClipping");
                //Top priority for 0 lod when invalidated (drill)
                if (m_invalidated == 2)
                {
                    m_lodLevels[0].DoClipping(camDistanceFromCenter, localPosition, farPlaneDistance, m_requestCollector, true, 1);
                    m_lodLevels[0].DiscardClippedCells(m_requestCollector);
                    m_lodLevels[0].UpdateCellsInScene(camDistanceFromCenter, localPosition);

                    if (!m_requestCollector.SentRequestsEmpty)
                    {
                        m_requestCollector.Submit();
                        ProfilerShort.End();    // DoClipping
                        ProfilerShort.End();    // Update
                        return;
                    }

                    m_updateClippingFrustum = false;
                    m_invalidated           = 1;
                }
                else
                {
                    //Most important frustum culling
                    for (int lod = m_lodLevels.Length - 1; lod >= 0; --lod)
                    {
                        ProfilerShort.Begin("Lod " + lod);
                        m_lodLevels[lod].DoClipping(camDistanceFromCenter, localPosition, farPlaneDistance, m_requestCollector, true, 1);
                        ProfilerShort.End();
                    }
                    //ProfilerShort.End();

                    ProfilerShort.Begin("KeepOrDiscardClippedCells");
                    for (int lod = m_lodLevels.Length - 1; lod >= 0; --lod)
                    {
                        m_lodLevels[lod].DiscardClippedCells(m_requestCollector);
                    }
                    ProfilerShort.End();

                    ProfilerShort.Begin("UpdateCellsInScene");
                    for (int lod = m_lodLevels.Length - 1; lod >= 0; --lod)
                    {
                        m_lodLevels[lod].UpdateCellsInScene(camDistanceFromCenter, localPosition);
                    }
                    ProfilerShort.End();

                    if (!m_requestCollector.SentRequestsEmpty)
                    {
                        m_requestCollector.Submit();
                        ProfilerShort.End();    // DoClipping
                        ProfilerShort.End();    // Update
                        return;
                    }

                    m_invalidated = 0;
                    m_notReady.Remove(this);
                    m_updateClippingFrustum = false;
                }
                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
        public static void OnGlobalSpawnEvent(object senderEvent)
        {
            // Select a spawn group to spawn
            MySpawnGroupDefinition spawnGroup = PickRandomSpawnGroup();

            if (spawnGroup == null)
            {
                return;
            }

            spawnGroup.ReloadPrefabs();

            ProfilerShort.Begin("Generate position and direction");

            double   spawnDistance  = NEUTRAL_SHIP_SPAWN_DISTANCE;
            Vector3D playerPosition = Vector3D.Zero;
            bool     isWorldLimited = MyEntities.IsWorldLimited();
            int      numPlayers     = 0;

            if (isWorldLimited)
            {
                spawnDistance = Math.Min(spawnDistance, MyEntities.WorldSafeHalfExtent() - spawnGroup.SpawnRadius);
            }
            else
            {
                // In infinite worlds players can be thousands of kilometers away, so spawn ship around random player
                // so cargo ships will be spawned around every player at some time
                var players = MySession.Static.Players.GetOnlinePlayers();
                // In DS there can be no players connected
                numPlayers = Math.Max(0, players.Count - 1);
                int randomPlayerPosition = MyUtils.GetRandomInt(0, numPlayers);
                int i = 0;
                foreach (var player in players)
                {
                    if (i == randomPlayerPosition)
                    {
                        if (player.Character != null)
                        {
                            playerPosition = player.GetPosition();
                        }
                        break;
                    }
                    i++;
                }
            }
            if (spawnDistance < 0.0f)
            {
                MySandboxGame.Log.WriteLine("Not enough space in the world to spawn such a huge spawn group!");
                return;
            }

            double       forbiddenRadius = NEUTRAL_SHIP_FORBIDDEN_RADIUS;
            BoundingBoxD spawnBox;

            if (isWorldLimited)
            {
                spawnBox = new BoundingBoxD(new Vector3D(playerPosition - spawnDistance), new Vector3D(playerPosition + spawnDistance));
            }
            else
            {
                // We need to extend bouding box so cargo ships aren't spawned near other players
                GetSafeBoundingBoxForPlayers(playerPosition, spawnDistance, out spawnBox);
                // Forbidden radius is sphere around all players in box.
                // Bounding box is generated from players positions so their distance to center shall be same for all players
                forbiddenRadius += spawnBox.HalfExtents.Max() - NEUTRAL_SHIP_FORBIDDEN_RADIUS;
            }

            // Get the direction to the center and deviate it randomly
            Vector3D?origin = MyUtils.GetRandomBorderPosition(ref spawnBox);

            origin = MyEntities.FindFreePlace(origin.Value, spawnGroup.SpawnRadius);
            if (!origin.HasValue)
            {
                MySandboxGame.Log.WriteLine("Could not spawn neutral ships - no free place found");
                MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                ProfilerShort.End();
                return;
            }

            // Radius in arc units of the forbidden sphere in the center, when viewed from origin
            float centerArcRadius = (float)Math.Atan(forbiddenRadius / (origin.Value - spawnBox.Center).Length());

            // Generate direction with elevation from centerArcRadius radians to (cAR + N_S_D_S) radians
            Vector3D direction = -Vector3D.Normalize(origin.Value);
            float    theta     = MyUtils.GetRandomFloat(centerArcRadius, centerArcRadius + NEUTRAL_SHIP_DIRECTION_SPREAD);
            float    phi       = MyUtils.GetRandomRadian();
            Vector3D cosVec    = Vector3D.CalculatePerpendicularVector(direction);
            Vector3D sinVec    = Vector3D.Cross(direction, cosVec);

            cosVec   *= (Math.Sin(theta) * Math.Cos(phi));
            sinVec   *= (Math.Sin(theta) * Math.Sin(phi));
            direction = direction * Math.Cos(theta) + cosVec + sinVec;

            Vector3D destination  = Vector3D.Zero;
            RayD     ray          = new RayD(origin.Value, direction);
            double?  intersection = ray.Intersects(spawnBox);
            Vector3D directionMult;

            if (!intersection.HasValue || intersection.Value < NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH)
            {
                directionMult = direction * NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH;
            }
            else
            {
                directionMult = direction * intersection.Value;
            }
            destination = origin.Value + directionMult;

            Vector3D upVector     = Vector3D.CalculatePerpendicularVector(direction);
            Vector3D rightVector  = Vector3D.Cross(direction, upVector);
            MatrixD  originMatrix = MatrixD.CreateWorld(origin.Value, direction, upVector);

            ProfilerShort.End();

            ProfilerShort.Begin("Check free space");

            // CH:TODO: Convex cast to detect collision
            // Check ships' path to avoid possible collisions. (TODO: But only if it is said in the definitions)
            m_raycastHits.Clear();
            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                var prefabDef = MyDefinitionManager.Static.GetPrefabDefinition(shipPrefab.SubtypeId);
                Debug.Assert(prefabDef != null);

                Vector3D shipPosition    = Vector3.Transform(shipPrefab.Position, originMatrix);
                Vector3D shipDestination = shipPosition + directionMult;
                float    radius          = prefabDef == null ? 10.0f : prefabDef.BoundingSphere.Radius;

                MyPhysics.CastRay(shipPosition, shipDestination, m_raycastHits, MyPhysics.ObjectDetectionCollisionLayer);
                if (m_raycastHits.Count() > 0)
                {
                    MySandboxGame.Log.WriteLine("Could not spawn neutral ships due to collision");
                    MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                    ProfilerShort.End();
                    return;
                }

                for (int i = 0; i < 4; ++i)
                {
                    Vector3D shiftVector = upVector * m_upVecMultipliers[i] * radius + rightVector * m_rightVecMultipliers[i] * radius;
                    MyPhysics.CastRay(shipPosition + shiftVector, shipDestination + shiftVector, m_raycastHits, MyPhysics.ObjectDetectionCollisionLayer);

                    if (m_raycastHits.Count() > 0)
                    {
                        MySandboxGame.Log.WriteLine("Could not spawn neutral ships due to collision");
                        MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                        ProfilerShort.End();
                        return;
                    }
                }
            }

            ProfilerShort.End();

            ProfilerShort.Begin("Spawn ships");

            //This is not an NPC so that it doesn't show up in assign ownership drop down menu
            MyIdentity spawnGroupIdentity = Sync.Players.CreateNewIdentity("Neutral NPC");
            long       spawnGroupId       = spawnGroupIdentity.IdentityId;

            // The ships were collision-free. Now spawn them
            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                ProfilerShort.Begin(shipPrefab.BeaconText);

                // Yes, this could have been saved in the previous loop, but compared to (e.g.) raycasts, this does not take too much time to recalculate
                Vector3D shipPosition    = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);
                Vector3D shipDestination = shipPosition + directionMult;
                Vector3D up = Vector3D.CalculatePerpendicularVector(-direction);

                m_tmpGridList.Clear();

                // Deploy ship
                ProfilerShort.Begin("Spawn cargo ship");
                MyPrefabManager.Static.SpawnPrefab(
                    resultList: m_tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: up,
                    initialLinearVelocity: shipPrefab.Speed * direction,
                    beaconName: shipPrefab.BeaconText,
                    spawningOptions: Sandbox.ModAPI.SpawningOptions.RotateFirstCockpitTowardsDirection |
                    Sandbox.ModAPI.SpawningOptions.SpawnRandomCargo |
                    Sandbox.ModAPI.SpawningOptions.DisableDampeners,
                    updateSync: true);
                ProfilerShort.End();

                foreach (var grid in m_tmpGridList)
                {
                    grid.ChangeGridOwnership(spawnGroupId, MyOwnershipShareModeEnum.None);

                    var cockpit = grid.GetFirstBlockOfType <MyCockpit>();
                    if (cockpit != null)
                    {
                        MySimpleAutopilot ai = new MySimpleAutopilot(shipDestination, (Vector3)direction);
                        cockpit.AttachAutopilot(ai);
                        break;
                    }
                }

                m_tmpGridList.Clear();

                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
示例#26
0
        //  Sends input (keyboard/mouse) to screen which has focus (top-most)
        public void HandleInput()
        {
            ProfilerShort.Begin("MyGuiManager.HandleInput");
            try
            {
                if (MyInput.Static.IsAnyAltKeyPressed() && MyInput.Static.IsNewKeyPressed(MyKeys.F4))
                {
                    MyAnalyticsTracker.SendGameEnd("Alt+F4", MySandboxGame.TotalTimeInMilliseconds / 1000);

                    //  Exit application
                    MySandboxGame.ExitThreadSafe();
                    return;
                }

                //  Screenshot(s)
                if (MyInput.Static.IsNewGameControlPressed(MyControlsSpace.SCREENSHOT))
                {
                    MyGuiAudio.PlaySound(MyGuiSounds.HudMouseClick);
                    TakeScreenshot();
                }

                bool newPressf12 = MyInput.Static.IsNewKeyPressed(MyKeys.F12);
                bool newPressf2  = MyInput.Static.IsNewKeyPressed(MyKeys.F2);
                if ((newPressf2 || newPressf12) && MyInput.Static.IsAnyShiftKeyPressed() && MyInput.Static.IsAnyAltKeyPressed())
                {
                    if (MySession.Static != null && MySession.Static.CreativeMode)
                    {
                        if (newPressf12)
                        {
                            MyDebugDrawSettings.DEBUG_DRAW_PHYSICS = !MyDebugDrawSettings.DEBUG_DRAW_PHYSICS;
                            if (!m_shapeRenderingMessageBoxShown)
                            {
                                m_shapeRenderingMessageBoxShown = true;
                                AddScreen(MyGuiSandbox.CreateMessageBox(
                                              messageCaption: new StringBuilder("PHYSICS SHAPES"),
                                              messageText: new StringBuilder("Enabled physics shapes rendering. This feature is for modders only and is not part of the gameplay.")));
                            }
                        }
                    }
                    else
                    {
                        AddScreen(MyGuiSandbox.CreateMessageBox(
                                      messageCaption: new StringBuilder("MODDING HELPER KEYS"),
                                      messageText: new StringBuilder("Use of helper key combinations for modders is only allowed in creative mode.")));
                    }
                    return;
                }

                if (MyInput.Static.IsNewKeyPressed(MyKeys.H) && MyInput.Static.IsAnyCtrlKeyPressed())
                {
                    if (MyFakes.ENABLE_NETGRAPH)
                    {
                        MyHud.IsNetgraphVisible = !MyHud.IsNetgraphVisible;
                    }
                }

                if (MyInput.Static.IsNewKeyPressed(MyKeys.F11))
                {
                    if (MyInput.Static.IsAnyShiftKeyPressed() && !MyInput.Static.IsAnyCtrlKeyPressed())
                    {
                        SwitchTimingScreen();
                    }
                }

                if (MyFakes.ENABLE_MISSION_SCREEN && MyInput.Static.IsNewKeyPressed(MyKeys.U))
                {
                    MyScreenManager.AddScreen(new MyGuiScreenMission());
                }

                if (!MyInput.Static.ENABLE_DEVELOPER_KEYS && Sync.MultiplayerActive && m_currentDebugScreen is MyGuiScreenDebugOfficial)
                {
                    RemoveScreen(m_currentDebugScreen);
                    m_currentDebugScreen = null;
                }

                bool inputHandled = false;

                if (MySession.Static != null && MySession.Static.CreativeMode ||
                    MyInput.Static.ENABLE_DEVELOPER_KEYS)
                {
                    F12Handling();
                }

                if (MyInput.Static.ENABLE_DEVELOPER_KEYS)
                {
                    //  Statistics screen
                    if (MyInput.Static.IsNewKeyPressed(MyKeys.F11) && !MyInput.Static.IsAnyShiftKeyPressed() && MyInput.Static.IsAnyCtrlKeyPressed())
                    {
                        SwitchStatisticsScreen();
                    }

                    if (MyInput.Static.IsAnyShiftKeyPressed() && MyInput.Static.IsAnyAltKeyPressed() && MyInput.Static.IsAnyCtrlKeyPressed() &&
                        MyInput.Static.IsNewKeyPressed(MyKeys.Home))
                    {
                        throw new InvalidOperationException("Controlled crash");
                    }

                    // Forge GC to run
                    if (MyInput.Static.IsNewKeyPressed(MyKeys.Pause) && MyInput.Static.IsAnyShiftKeyPressed())
                    {
                        GC.Collect(GC.MaxGeneration);
                    }

                    if (MyInput.Static.IsAnyCtrlKeyPressed() && MyInput.Static.IsNewKeyPressed(MyKeys.F2))
                    {
                        //Reload textures
                        if (MyInput.Static.IsKeyPress(MyKeys.LeftShift))
                        {
                            MyDefinitionManager.Static.ReloadDecalMaterials();
                            VRageRender.MyRenderProxy.ReloadTextures();
                        }
                        else
                        if (MyInput.Static.IsKeyPress(MyKeys.LeftAlt))
                        {
                            VRageRender.MyRenderProxy.ReloadModels();
                        }
                        else
                        {
                            VRageRender.MyRenderProxy.ReloadEffects();
                        }
                    }

                    //WS size
                    if (MyInput.Static.IsNewKeyPressed(MyKeys.F3) && MyInput.Static.IsKeyPress(MyKeys.LeftShift))
                    {
#if !XB1
                        WinApi.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
#endif // !XB1
                    }

                    inputHandled = HandleDebugInput();
                }

                if (!inputHandled)
                {
                    MyScreenManager.HandleInput();
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
        public static List <MyCubeBlockDefinition.MountPoint> AutogenerateMountpoints(HkShape[] shapes, float gridSize)
        {
            ProfilerShort.Begin("AutogenerateMountpoints");
            HkShapeCutterUtil cutter = new HkShapeCutterUtil();

            List <BoundingBox>[] aabbsPerDirection = new List <BoundingBox> [Base6Directions.EnumDirections.Length];

            var newMountPoints = new List <MyCubeBlockDefinition.MountPoint>();

            foreach (var directionEnum in Base6Directions.EnumDirections)
            {
                int dirEnum = (int)directionEnum;
                //int dirEnum = 2;
                Vector3 direction = Base6Directions.Directions[dirEnum];

                foreach (var shape in shapes)
                {
                    if (shape.ShapeType == HkShapeType.List)
                    {
                        var listShape = (HkListShape)shape;
                        var iterator  = listShape.GetIterator();
                        while (iterator.IsValid)
                        {
                            HkShape childShape = iterator.CurrentValue;

                            if (childShape.ShapeType == HkShapeType.ConvexTransform)
                            {
                                HkConvexTransformShape transformShape = (HkConvexTransformShape)childShape;

                                FindMountPoint(cutter, transformShape.Base, direction, gridSize, newMountPoints);
                            }
                            else
                            if (childShape.ShapeType == HkShapeType.ConvexTranslate)
                            {
                                HkConvexTranslateShape translateShape = (HkConvexTranslateShape)childShape;

                                FindMountPoint(cutter, translateShape.Base, direction, gridSize, newMountPoints);
                            }
                            else
                            {
                                FindMountPoint(cutter, childShape, direction, gridSize, newMountPoints);
                            }

                            iterator.Next();
                        }
                        break;
                    }
                    else
                    if (shape.ShapeType == HkShapeType.Mopp)
                    {
                        var compoundShape = (HkMoppBvTreeShape)shape;
                        for (int s = 0; s < compoundShape.ShapeCollection.ShapeCount; s++)
                        {
                            HkShape childShape = compoundShape.ShapeCollection.GetShape((uint)s, null);

                            if (childShape.ShapeType == HkShapeType.ConvexTranslate)
                            {
                                HkConvexTranslateShape translateShape = (HkConvexTranslateShape)childShape;

                                FindMountPoint(cutter, translateShape.Base, direction, gridSize, newMountPoints);
                            }
                        }
                        break;
                    }
                    else
                    {
                        FindMountPoint(cutter, shape, direction, gridSize, newMountPoints);
                    }
                }
            }
            ProfilerShort.End();
            return(newMountPoints);
        }
示例#28
0
        //  Draw all screens
        public void Draw()
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyGuiSandbox::Draw");

            ProfilerShort.Begin("ScreenManager.Draw");
            MyScreenManager.Draw();
            ProfilerShort.End();

            m_debugText.Clear();

            if (MyInput.Static.ENABLE_DEVELOPER_KEYS && MySandboxGame.Config.DebugComponentsInfo != MyDebugComponent.MyDebugComponentInfoState.NoInfo)
            {
                var  h = 0f;
                var  i = 0;
                bool drawBackground = false;

                MyDebugComponent.ResetFrame();

                foreach (var userInputComponent in UserDebugInputComponents)
                {
                    if (userInputComponent.Enabled)
                    {
                        if (h == 0)
                        {
                            m_debugText.AppendLine("Debug input:");
                            m_debugText.AppendLine();
                            h += 0.0630f;
                        }
                        m_debugText.ConcatFormat("{0} (Ctrl + numPad{1})", UserDebugInputComponents[i].GetName(), i);
                        m_debugText.AppendLine();
                        h += 0.0265f;
                        if (MySession.Static != null)
                        {
                            userInputComponent.DispatchUpdate();
                        }
                        userInputComponent.Draw();
                        drawBackground = true;
                    }
                    ++i;
                }

                if (drawBackground)
                {
                    MyGuiManager.DrawSpriteBatch(@"Textures\GUI\Controls\rectangle_dark_center.dds",
                                                 new Vector2(MyGuiManager.GetMaxMouseCoord().X, 0f),
                                                 new Vector2(MyGuiManager.MeasureString(MyFontEnum.White, m_debugText, 1f).X + 0.012f, h),
                                                 new Color(0, 0, 0, 130),
                                                 MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_TOP);
                    MyGuiManager.DrawString(MyFontEnum.White, m_debugText, new Vector2(MyGuiManager.GetMaxMouseCoord().X - 0.01f, 0f), 1f, Color.White, MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_TOP);
                }
            }

            bool hwCursor = MyVideoSettingsManager.IsHardwareCursorUsed();

            var screenWithFocus = MyScreenManager.GetScreenWithFocus();

            if (((screenWithFocus != null) && (screenWithFocus.GetDrawMouseCursor() == true)) || (MyScreenManager.InputToNonFocusedScreens && MyScreenManager.GetScreensCount() > 1))
            {
#if XB1
                SetMouseCursorVisibility(false, false);
                DrawMouseCursor(GetMouseOverTexture(screenWithFocus));
#else
                SetMouseCursorVisibility(hwCursor, false);

                if (!hwCursor || MyFakes.FORCE_SOFTWARE_MOUSE_DRAW)
                {
                    DrawMouseCursor(GetMouseOverTexture(screenWithFocus));
                }
#endif
            }
            else
            {
                if (hwCursor)
                {
                    if (screenWithFocus != null)
                    {
                        SetMouseCursorVisibility(screenWithFocus.GetDrawMouseCursor());
                    }
                }
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
示例#29
0
        public static void UpdateBeforeSimulation()
        {
            if (MySandboxGame.IsGameReady == false)
            {
                return;
            }

            ProfilerShort.Begin("MyEntities.UpdateBeforeSimulation");
            System.Diagnostics.Debug.Assert(MyEntities.UpdateInProgress == false);
            MyEntities.UpdateInProgress = true;

            {
                ProfilerShort.Begin("Before first frame");
                MyEntities.UpdateOnceBeforeFrame();

                ProfilerShort.BeginNextBlock("Each update");
                m_entitiesForUpdate.List.ApplyChanges();
                m_entitiesForUpdate.Update();
                MySimpleProfiler.Begin("Blocks");
                m_entitiesForUpdate.Iterate((x) =>
                {
                    ProfilerShort.Begin(x.GetType().Name);
                    if (x.MarkedForClose == false)
                    {
                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.Begin(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.Begin("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.Begin("&&GRID&&" + grid.DisplayName);
                            }
                        }

                        x.UpdateBeforeSimulation();

                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.End(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.End("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.End("&&GRID&&" + grid.DisplayName);
                            }
                        }
                    }
                    ProfilerShort.End();
                });

                ProfilerShort.BeginNextBlock("10th update");
                m_entitiesForUpdate10.List.ApplyChanges();
                m_entitiesForUpdate10.Update();
                m_entitiesForUpdate10.Iterate((x) =>
                {
                    ProfilerShort.Begin(x.GetType().Name);
                    if (x.MarkedForClose == false)
                    {
                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.Begin(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.Begin("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.Begin("&&GRID&&" + grid.DisplayName);
                            }
                        }

                        x.UpdateBeforeSimulation10();

                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.End(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.End("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.End("&&GRID&&" + grid.DisplayName);
                            }
                        }
                    }
                    ProfilerShort.End();
                });


                ProfilerShort.BeginNextBlock("100th update");
                m_entitiesForUpdate100.List.ApplyChanges();
                m_entitiesForUpdate100.Update();
                m_entitiesForUpdate100.Iterate((x) =>
                {
                    ProfilerShort.Begin(x.GetType().Name);
                    if (x.MarkedForClose == false)
                    {
                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.Begin(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.Begin("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.Begin("&&GRID&&" + grid.DisplayName);
                            }
                        }

                        x.UpdateBeforeSimulation100();

                        if (ProfilePerBlock)
                        {
                            MyCubeBlock block = x as MyCubeBlock;
                            if (block != null)
                            {
                                MySimpleProfiler.End(block.DefinitionDisplayNameText + (ProfilePerGrid ? $" - {block.CubeGrid.DisplayName}" : string.Empty));
                                if (ProfilePerGrid)
                                {
                                    MySimpleProfiler.End("&&GRID&&" + block.CubeGrid.DisplayName);
                                }
                            }
                        }
                        if (ProfilePerGrid)
                        {
                            MyCubeGrid grid = x as MyCubeGrid;
                            if (grid != null)
                            {
                                MySimpleProfiler.Begin("&&GRID&&" + grid.DisplayName);
                            }
                        }
                    }
                    ProfilerShort.End();
                });

                ProfilerShort.End();
            }
            MySimpleProfiler.End("Blocks");

            MyEntities.UpdateInProgress = false;

            ProfilerShort.End();
        }
        public MyIsoMesh Precalc(IMyStorage storage, int lod, Vector3I voxelStart, Vector3I voxelEnd, bool generateMaterials)
        {
            // change range so normal can be computed at edges (expand by 1 in all directions)
            voxelStart -= 1;
            voxelEnd   += 1;
            m_cache.Resize(voxelStart, voxelEnd);
            storage.ReadRange(m_cache, MyStorageDataTypeFlags.Content, lod, ref voxelStart, ref voxelEnd);
            if (!m_cache.ContainsIsoSurface())
            {
                return(null);
            }

            if (generateMaterials)
            {
                storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, lod, ref voxelStart, ref voxelEnd);
            }
            else
            {
                m_cache.ClearMaterials(0);
            }
            var voxelSize = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << lod);

            ProfilerShort.Begin("Dual Contouring");
            unsafe
            {
                fixed(byte *voxels = m_cache.Data)
                {
                    var size3d = m_cache.Size3D;

                    Debug.Assert(size3d.X == size3d.Y && size3d.Y == size3d.Z);
                    IsoMesher.Calculate(size3d.X, (VoxelData *)voxels, m_buffer);
                }
            }
            ProfilerShort.End();

            if (m_buffer.VerticesCount == 0 && m_buffer.Triangles.Count == 0)
            {
                return(null);
            }

            ProfilerShort.Begin("Geometry post-processing");
            {
                var vertexCellOffset = voxelStart - AffectedRangeOffset;
                var positions        = m_buffer.Positions.GetInternalArray();
                var vertexCells      = m_buffer.Cells.GetInternalArray();
                for (int i = 0; i < m_buffer.VerticesCount; i++)
                {
                    var min = -Vector3.One;
                    var max = Vector3.One;
                    //   Debug.Assert(positions[i].IsInsideInclusive(ref min, ref max));
                    vertexCells[i] += vertexCellOffset;
                }

                float numCellsHalf = 0.5f * (m_cache.Size3D.X - 3);
                m_buffer.PositionOffset = (vertexCellOffset + numCellsHalf) * voxelSize;
                m_buffer.PositionScale  = new Vector3(numCellsHalf * voxelSize);
            }
            ProfilerShort.End();

            // Replace filled mesh with new one.
            // This way prevents allocation of meshes which then end up empty.
            var buffer = m_buffer;

            m_buffer = new MyIsoMesh();
            return(buffer);
        }