Beispiel #1
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();
        }
Beispiel #2
0
        public virtual void OnRemovedFromGroup(MyGridLogicalGroupData group)
        {
            if (m_blocksRegistered)
            {
                ProfilerShort.Begin("Removing block groups from grid group");
                TerminalSystem.GroupAdded   -= m_terminalSystem_GroupAdded;
                TerminalSystem.GroupRemoved -= m_terminalSystem_GroupRemoved;
                foreach (var g in m_cubeGrid.BlockGroups)
                {
                    TerminalSystem.RemoveGroup(g);
                }
                ProfilerShort.End();

                foreach (var block in m_cubeGrid.GetBlocks())
                {
                    if (block.FatBlock == null)
                    {
                        continue;
                    }

                    var functionalBlock = block.FatBlock as MyTerminalBlock;
                    if (functionalBlock != null)
                    {
                        TerminalSystem.Remove(functionalBlock);
                    }

                    var producer = block.FatBlock.Components.Get <MyResourceSourceComponent>();
                    if (producer != null)
                    {
                        ResourceDistributor.RemoveSource(producer);
                    }

                    var consumer = block.FatBlock.Components.Get <MyResourceSinkComponent>();
                    if (consumer != null)
                    {
                        ResourceDistributor.RemoveSink(consumer, resetSinkInput: false, markedForClose: block.FatBlock.MarkedForClose);
                    }

                    var socketOwner = block.FatBlock as IMyRechargeSocketOwner;
                    if (socketOwner != null)
                    {
                        socketOwner.RechargeSocket.ResourceDistributor = null;
                    }

                    var weapon = block.FatBlock as IMyGunObject <MyDeviceBase>;
                    if (weapon != null)
                    {
                        WeaponSystem.Unregister(weapon);
                    }
                }
            }

            group.ResourceDistributor.RemoveSink(ConveyorSystem.ResourceSink, resetSinkInput: false);
            group.ResourceDistributor.RemoveSink(GyroSystem.ResourceSink, resetSinkInput: false);

            var gridThrustComponent = CubeGrid.Components.Get <MyEntityThrustComponent>();

            if (gridThrustComponent != null)
            {
                group.ResourceDistributor.RemoveSink(gridThrustComponent.ResourceSink);
            }

            m_cubeGrid.OnBlockAdded   -= ResourceDistributor.CubeGrid_OnBlockAddedOrRemoved;
            m_cubeGrid.OnBlockRemoved -= ResourceDistributor.CubeGrid_OnBlockAddedOrRemoved;

            ResourceDistributor = null;
            TerminalSystem      = null;
            WeaponSystem        = null;
        }
        private void GenerateObject(MyProceduralCell cell, MyObjectSeed objectSeed, ref int index, MyRandom random, IMyModule densityFunctionFilled, IMyModule densityFunctionRemoved)
        {
            cell.AddObject(objectSeed);

            IMyAsteroidFieldDensityFunction func = objectSeed.UserData as IMyAsteroidFieldDensityFunction;

            if (func != null)
            {
                ChildrenAddDensityFunctionRemoved(func);
            }

            switch (objectSeed.Type)
            {
            case MyObjectSeedType.Moon:
                break;

            case MyObjectSeedType.Planet:
                m_tmpClusterBoxes.Add(objectSeed.BoundingVolume);

                for (int i = 0; i < MOONS_MAX; ++i)
                {
                    var direction = MyProceduralWorldGenerator.GetRandomDirection(random);
                    var size      = MathHelper.Lerp(MOON_SIZE_MIN, MOON_SIZE_MAX, random.NextDouble());
                    var distance  = MathHelper.Lerp(MOON_DISTANCE_MIN, MOON_DISTANCE_MAX, random.NextDouble());
                    var position  = objectSeed.BoundingVolume.Center + direction * (size + objectSeed.BoundingVolume.HalfExtents.Length() * 2 + distance);

                    ProfilerShort.Begin("GetValue");
                    var value = densityFunctionFilled.GetValue(position.X, position.Y, position.Z);
                    ProfilerShort.End();

                    if (value < MOON_DENSITY)     // -1..+1
                    {
                        var clusterObjectSeed = new MyObjectSeed(cell, position, size);
                        clusterObjectSeed.Seed     = random.Next();
                        clusterObjectSeed.Type     = MyObjectSeedType.Moon;
                        clusterObjectSeed.Index    = index++;
                        clusterObjectSeed.UserData = new MySphereDensityFunction(position, OBJECT_SEED_RADIUS, OBJECT_SEED_RADIUS);

                        bool overlaps = false;
                        foreach (var box in m_tmpClusterBoxes)
                        {
                            if (overlaps |= clusterObjectSeed.BoundingVolume.Intersects(box))
                            {
                                break;
                            }
                        }

                        if (!overlaps)
                        {
                            m_tmpClusterBoxes.Add(clusterObjectSeed.BoundingVolume);
                            GenerateObject(cell, clusterObjectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved);
                        }
                    }
                }
                m_tmpClusterBoxes.Clear();
                break;

            case MyObjectSeedType.Empty:
                break;

            default:
                throw new InvalidBranchException();
                break;
            }
        }
Beispiel #4
0
        private unsafe void BuildShape()
        {
            ProfilerShort.Begin("BuildPhysicsShape()");
            FetchData(0);

            ProfilerShort.Begin("CollectInstances");

            var shape = new CompoundInstancedShape();

            if (m_modelsToShapes == null)
            {
                m_modelsToShapes = new Dictionary <int, HkShape>();
            }

            int totalItems = DataView.Items.Count;

            fixed(ItemInfo *items = DataView.Items.GetInternalArray())
            {
                for (int i = 0; i < totalItems; ++i)
                {
                    var model = items[i].ModelIndex;
                    if (model < 0)
                    {
                        continue;
                    }

                    HkShape modelShape;

                    if (!m_modelsToShapes.TryGetValue(model, out modelShape))
                    {
                        var modelData = MyModels.GetModelOnlyData(Owner.GetModelForId(model).Model);

                        var shapes = modelData.HavokCollisionShapes;
                        if (shapes != null)
                        {
                            if (shapes.Length == 0)
                            {
                                MyLog.Default.Warning("Model {0} has an empty list of shapes, something wrong with export?", modelData.AssetName);
                            }
                            else
                            {
                                if (shapes.Length > 1)
                                {
                                    MyLog.Default.Warning("Model {0} has multiple shapes, only the first will be used.", modelData.AssetName);
                                }

                                modelShape = shapes[0];
                            }
                        }
                        m_modelsToShapes[model] = modelShape;
                    }

                    shape.AddInstance(i, ref items[i], modelShape);
                }
            }

            ProfilerShort.BeginNextBlock("Bake()");
            shape.Bake();
            ProfilerShort.End();

            m_newShape = shape;

            ProfilerShort.End();
        }
        /// <summary>
        /// Returns the best path from managers according to both initial and target positions
        /// </summary>
        /// <param name="planet"></param>
        /// <param name="initialPosition"></param>
        /// <param name="targetPosition"></param>
        /// <returns></returns>
        private List <Vector3D> GetBestPathFromManagers(MyPlanet planet, Vector3D initialPosition, Vector3D targetPosition)
        {
            bool            noTilesToGenerated, pathContainsTarget;
            List <Vector3D> pathPoints;

            var managersContainingInitialPosition = m_planetManagers[planet].Where(m => m.ContainsPosition(initialPosition)).ToList();

            if (managersContainingInitialPosition.Count > 0)
            {
                //TODO: Check if a manager has both positions
                // In that case, if the returned path is final, check if the last position is reached
                foreach (var manager in managersContainingInitialPosition)
                {
                    if (manager.ContainsPosition(targetPosition))
                    {
                        pathContainsTarget = manager.GetPathPoints(initialPosition, targetPosition, out pathPoints, out noTilesToGenerated);
                        //TODO: if there is path to target
                        if (pathContainsTarget || !noTilesToGenerated)
                        {
                            return(pathPoints);
                        }
                    }
                }

                // Choose the manager that is closer to the initial position
                MyNavmeshManager closestManager   = null;
                double           smallestDistance = double.MaxValue;
                foreach (var manager in managersContainingInitialPosition)
                {
                    double distanceToInitialPosition = (manager.Center - initialPosition).LengthSquared();
                    if (smallestDistance > distanceToInitialPosition)
                    {
                        smallestDistance = distanceToInitialPosition;
                        closestManager   = manager;
                    }
                }

                pathContainsTarget = closestManager.GetPathPoints(initialPosition, targetPosition, out pathPoints, out noTilesToGenerated);
                //if (!finalPath || pathPoints.Count >= 2)
                //   return pathPoints;

                // It's the final path (all needed tiles generated)
                if (!pathContainsTarget && noTilesToGenerated && pathPoints.Count <= 2 && smallestDistance > MIN_NAVMESH_MANAGER_SQUARED_DISTANCE)
                {
                    var currentPositionDistanceToTarget = (initialPosition - targetPosition).LengthSquared();
                    var currentManagerDistanceToTarget  = (closestManager.Center - targetPosition).LengthSquared();
                    // Generates new manager if the one available is far enough
                    if (currentManagerDistanceToTarget - currentPositionDistanceToTarget > MIN_NAVMESH_MANAGER_SQUARED_DISTANCE)
                    {
                        ProfilerShort.Begin("MyRDPathfinding.CreateManager2");
                        var manager = CreateManager(initialPosition);
                        manager.TilesToGenerate(initialPosition, targetPosition);
                        ProfilerShort.End();
                    }
                }

                return(pathPoints);
            }
            else
            // No manager contains the initial position, bummer....
            {
                ProfilerShort.Begin("MyRDPathfinding.CreateManager1");
                var manager = CreateManager(initialPosition);
                manager.TilesToGenerate(initialPosition, targetPosition);
                ProfilerShort.End();

                return(new List <Vector3D>());
            }
        }
Beispiel #6
0
        internal void InitFromBreakableBody(HkdBreakableBody b, MatrixD worldMatrix, MyCubeBlock block)
        {
            ProfilerShort.Begin("RemoveGen&SetFixed");

            OriginalBlocks.Clear();
            if (block != null)
            {
                if (block is MyCompoundCubeBlock)
                {
                    foreach (var block2 in (block as MyCompoundCubeBlock).GetBlocks())
                    {
                        OriginalBlocks.Add(block2.BlockDefinition.Id);
                    }
                }
                else if (block is MyFracturedBlock)
                {
                    OriginalBlocks.AddRange((block as MyFracturedBlock).OriginalBlocks);
                }
                else
                {
                    OriginalBlocks.Add(block.BlockDefinition.Id);
                }
            }

            var  rigidBody = b.GetRigidBody();
            bool isFixed   = MyDestructionHelper.IsFixed(b.BreakableShape);

            if (isFixed)
            {
                rigidBody.UpdateMotionType(HkMotionType.Fixed);
                rigidBody.LinearVelocity  = Vector3.Zero;
                rigidBody.AngularVelocity = Vector3.Zero;
            }

            ProfilerShort.Begin("Sync");
            if (SyncFlag)
            {
                CreateSync();
            }
            ProfilerShort.End();

            PositionComp.WorldMatrix = worldMatrix;
            Physics.Flags            = isFixed ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS;
            Physics.BreakableBody    = b;
            rigidBody.UserObject     = Physics;
            if (!isFixed)
            {
                rigidBody.Motion.SetDeactivationClass(HkSolverDeactivation.High);
                rigidBody.EnableDeactivation = true;
                if (MyFakes.REDUCE_FRACTURES_COUNT)
                {
                    if (b.BreakableShape.Volume < 1 && MyRandom.Instance.Next(6) > 1)
                    {
                        rigidBody.Layer = MyFracturedPiecesManager.FakePieceLayer;
                    }
                    else
                    {
                        rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer;
                    }
                }
                else
                {
                    rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer;
                }
            }
            else
            {
                rigidBody.Layer = MyPhysics.CollisionLayers.StaticCollisionLayer;
            }
            Physics.BreakableBody.AfterReplaceBody += Physics.FracturedBody_AfterReplaceBody;

            if (OriginalBlocks.Count > 0)
            {
                MyPhysicalModelDefinition def;
                if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(OriginalBlocks[0], out def))
                {
                    Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId;
                }
            }

            ProfilerShort.BeginNextBlock("Enable");
            Physics.Enabled = true;
            MyDestructionHelper.FixPosition(this);
            SetDataFromHavok(b.BreakableShape);
            var coml = b.GetRigidBody().CenterOfMassLocal;
            var comw = b.GetRigidBody().CenterOfMassWorld;
            var com  = b.BreakableShape.CoM;

            b.GetRigidBody().CenterOfMassLocal = com;
            b.BreakableShape.RemoveReference();
            ProfilerShort.End();
        }
Beispiel #7
0
        public bool DoSerialWork()
        {
            if (Closed)
            {
                return(false);
            }
            if (HasParallelWorkPending)
            {
                return(false);
            }

            bool work = false;

            ProfilerShort.Begin("Update Modules");
            if (m_togglePhysics || m_lodSwitchedFrom != m_lodToSwitch)
            {
                foreach (var module in m_modules)
                {
                    ProfilerShort.Begin(module.Key.Name);
                    if (m_lodSwitchedFrom != m_lodToSwitch)
                    {
                        module.Value.Proxy.CommitLodChange(m_lodSwitchedFrom, m_lodToSwitch);
                    }
                    if (m_togglePhysics)
                    {
                        module.Value.Proxy.CommitPhysicsChange(!HasPhysics);
                    }
                    ProfilerShort.End();
                }
                work = true;
            }
            ProfilerShort.End();

            m_currentLod = m_lodToSwitch;

            ProfilerShort.Begin("Event Callbacks");
            if (m_lodSwitchedFrom != m_currentLod && m_lodToSwitch == m_currentLod)
            {
                RaiseOnLodCommitEvent(m_currentLod);
            }
            if (m_togglePhysics)
            {
                RaiseOnPhysicsCommitEvent(HasPhysics);
            }
            ProfilerShort.End();

            ProfilerShort.Begin("Update Renderer");
            if (m_render != null && m_render.HasChanges() && m_lodToSwitch == m_currentLod)
            {
                m_render.CommitChangesToRenderer();
                work = true;
                m_lodSwitchedFrom = m_currentLod;
            }
            ProfilerShort.End();

            ProfilerShort.Begin("Prepare Rigid Body");
            if (m_togglePhysics)
            {
                if (HasPhysics)
                {
                    Physics.Enabled = false;
                    HasPhysics      = false;
                    m_togglePhysics = false;
                }
                else if (m_newShape != null)
                {
                    PreparePhysicsBody();
                    work            = true;
                    HasPhysics      = true;
                    m_togglePhysics = false;
                }
            }
            if (m_recalculateShape)
            {
                m_recalculateShape = false;
                if (HasPhysics && m_newShape != null)
                {
                    PreparePhysicsBody();
                }
            }

            ProfilerShort.End();

            HasSerialWorkPending = false;

            return(work);
        }
        /// <param name="minVoxelChanged">Inclusive min.</param>
        /// <param name="maxVoxelChanged">Inclusive max.</param>
        internal void InvalidateRange(Vector3I minVoxelChanged, Vector3I maxVoxelChanged)
        {
            MyPrecalcComponent.AssertUpdateThread();
            ProfilerShort.Begin("MyVoxelPhysicsBody.InvalidateRange");

            minVoxelChanged -= MyPrecalcComponent.InvalidatedRangeInflate;
            maxVoxelChanged += MyPrecalcComponent.InvalidatedRangeInflate;
            m_voxelMap.Storage.ClampVoxelCoord(ref minVoxelChanged);
            m_voxelMap.Storage.ClampVoxelCoord(ref maxVoxelChanged);

            Vector3I minCellChanged, maxCellChanged;

            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref minVoxelChanged, out minCellChanged);
            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxVoxelChanged, out maxCellChanged);

            Vector3I minCellChangedVoxelMap, maxCellChangedVoxelMap;

            minCellChangedVoxelMap = minCellChanged - m_cellsOffset;
            maxCellChangedVoxelMap = maxCellChanged - m_cellsOffset;
            var maxCell = m_voxelMap.Size - 1;

            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxCell, out maxCell);
            Vector3I.Min(ref maxCellChangedVoxelMap, ref maxCell, out maxCellChangedVoxelMap);

            Debug.Assert(RigidBody != null, "RigidBody in voxel physics is null! This must not happen.");
            if (RigidBody != null)
            {
                var shape = (HkUniformGridShape)GetShape();//RigidBody.GetShape();
                Debug.Assert(shape.Base.IsValid);
                var tmpBuffer    = m_cellsToGenerateBuffer;
                int invalidCount = shape.InvalidateRange(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap, tmpBuffer);
                if (invalidCount > tmpBuffer.Length)
                {
                    // Not storing this new buffer in static variable since this is just temporary and potentially large.
                    // Static variable could be potentially the same as leak.
                    tmpBuffer = new Vector3I[invalidCount];
                    int invalidCount2 = shape.InvalidateRange(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap, tmpBuffer);
                    Debug.Assert(invalidCount == invalidCount2);
                    invalidCount = invalidCount2;
                }

                Debug.Assert(invalidCount <= tmpBuffer.Length);
                for (int i = 0; i < invalidCount; i++)
                {
                    InvalidCells.Add(tmpBuffer[i]);
                }
                if (RunningBatchTask == null && InvalidCells.Count != 0)
                {
                    MyPrecalcComponent.PhysicsWithInvalidCells.Add(this);
                }
            }

            if (minCellChangedVoxelMap == Vector3I.Zero && maxCellChangedVoxelMap == maxCell)
            {
                m_workTracker.CancelAll();
            }
            else
            {
                var cell = minCellChanged;
                for (var it = new Vector3I.RangeIterator(ref minCellChanged, ref maxCellChanged);
                     it.IsValid(); it.GetNext(out cell))
                {
                    m_workTracker.Cancel(cell);
                }
            }

            m_needsShapeUpdate = true;

            ProfilerShort.End();

            m_voxelMap.RaisePhysicsChanged();
        }
Beispiel #9
0
        private void UpdatePosition(bool forceUpdate = false)
        {
            if (SafeConstraint == null)
            {
                return;
            }
            if (!IsWorking && !forceUpdate)
            {
                return;
            }
            //if (!forceUpdate && !CubeGrid.SyncObject.ResponsibleForUpdate(Sync.Clients.LocalClient))
            //return;

            bool changed = false;

            float compensatedDelta = Velocity / 60 * Sync.RelativeSimulationRatio;

            ProfilerShort.Begin("PosAndHandlers");
            if (!forceUpdate)
            {
                if (compensatedDelta < 0)
                {
                    if (m_currentPos > MinLimit)
                    {
                        m_currentPos += compensatedDelta;
                        m_currentPos  = Math.Max(m_currentPos, MinLimit);
                        changed       = true;
                        if (m_currentPos == MinLimit)
                        {
                            var handle = LimitReached;
                            if (handle != null)
                            {
                                handle(false);
                            }
                        }
                    }
                }
                else if (m_currentPos < MaxLimit)
                {
                    m_currentPos += compensatedDelta;
                    m_currentPos  = Math.Min(m_currentPos, MaxLimit);
                    changed       = true;
                    if (m_currentPos == MaxLimit)
                    {
                        var handle = LimitReached;
                        if (handle != null)
                        {
                            handle(true);
                        }
                    }
                }
            }
            ProfilerShort.End();

            if (changed || forceUpdate)
            {
                ProfilerShort.Begin("UpdateText");
                UpdateText();
                ProfilerShort.End();

                ProfilerShort.Begin("UpdateAnimation");
                UpdateAnimation();
                ProfilerShort.End();

                ProfilerShort.Begin("Calculations");
                m_posChanged = true;
                if (CubeGrid == null)
                {
                    MySandboxGame.Log.WriteLine("CubeGrid is null");
                }
                if (m_topGrid == null)
                {
                    MySandboxGame.Log.WriteLine("TopGrid is null");
                }
                if (Subpart3 == null)
                {
                    MySandboxGame.Log.WriteLine("Subpart is null");
                }
                if (CubeGrid.Physics != null)
                {
                    CubeGrid.Physics.RigidBody.Activate();
                }
                if (m_topGrid != null && m_topGrid.Physics != null)
                {
                    m_topGrid.Physics.RigidBody.Activate();
                }
                var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up);
                var matA  = (Matrix)matAD;
                var matB  = Matrix.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize /*- m_topBlock.LocalMatrix.Up * m_currentPos*/, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up);
                ProfilerShort.End();

                ProfilerShort.Begin("SetInBodySpace");
                ConstraintData.SetInBodySpace(ref matA, ref matB);
                ProfilerShort.End();

                ProfilerShort.Begin("UpdateSubpartFixedData");
                UpdateSubpartFixedData();
                ProfilerShort.End();
            }
        }
Beispiel #10
0
        private void GenerateObject(MyProceduralCell cell, MyObjectSeed objectSeed, ref int index, MyRandom random, IMyModule densityFunctionFilled, IMyModule densityFunctionRemoved)
        {
            cell.AddObject(objectSeed);
            switch (objectSeed.Params.Type)
            {
            case MyObjectSeedType.Asteroid:
                break;

            case MyObjectSeedType.AsteroidCluster:
                objectSeed.Params.Type = MyObjectSeedType.Asteroid;

                m_tmpClusterBoxes.Add(objectSeed.BoundingVolume);

                for (int i = 0; i < OBJECT_MAX_IN_CLUSTER; ++i)
                {
                    var direction             = MyProceduralWorldGenerator.GetRandomDirection(random);
                    var size                  = GetClusterObjectSize(random.NextDouble());
                    var distance              = MathHelper.Lerp(OBJECT_MIN_DISTANCE_CLUSTER, OBJECT_MAX_DISTANCE_CLUSTER, random.NextDouble());
                    var clusterObjectPosition = objectSeed.BoundingVolume.Center + direction * (size + objectSeed.BoundingVolume.HalfExtents.Length() * 2 + distance);

                    ProfilerShort.Begin("Density functions");
                    double valueRemoved = -1;
                    if (densityFunctionRemoved != null)
                    {
                        valueRemoved = densityFunctionRemoved.GetValue(clusterObjectPosition.X, clusterObjectPosition.Y, clusterObjectPosition.Z);

                        if (valueRemoved <= -1)
                        {
                            ProfilerShort.End();
                            continue;
                        }
                    }

                    var valueFilled = densityFunctionFilled.GetValue(clusterObjectPosition.X, clusterObjectPosition.Y, clusterObjectPosition.Z);

                    if (densityFunctionRemoved != null)
                    {
                        if (valueRemoved < valueFilled)
                        {
                            ProfilerShort.End();
                            continue;
                        }
                    }
                    ProfilerShort.End();

                    if (valueFilled < OBJECT_DENSITY_CLUSTER)     // -1..+1
                    {
                        var clusterObjectSeed = new MyObjectSeed(cell, clusterObjectPosition, size);
                        clusterObjectSeed.Params.Seed  = random.Next();
                        clusterObjectSeed.Params.Index = index++;
                        clusterObjectSeed.Params.Type  = GetClusterSeedType(random.NextDouble());

                        bool overlaps = false;
                        foreach (var box in m_tmpClusterBoxes)
                        {
                            if (overlaps |= clusterObjectSeed.BoundingVolume.Intersects(box))
                            {
                                break;
                            }
                        }

                        if (!overlaps)
                        {
                            m_tmpClusterBoxes.Add(clusterObjectSeed.BoundingVolume);
                            GenerateObject(cell, clusterObjectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved);
                        }
                    }
                }
                m_tmpClusterBoxes.Clear();
                break;

            case MyObjectSeedType.EncounterAlone:
            case MyObjectSeedType.EncounterSingle:
            case MyObjectSeedType.EncounterMulti:
                break;

            default:
                throw new InvalidBranchException();
                break;
            }
        }
Beispiel #11
0
        protected override MyProceduralCell GenerateProceduralCell(ref VRageMath.Vector3I cellId)
        {
            MyProceduralCell cell = new MyProceduralCell(cellId, this.CELL_SIZE);

            ProfilerShort.Begin("GenerateObjectSeedsCell");

            IMyModule densityFunctionFilled = GetCellDensityFunctionFilled(cell.BoundingVolume);

            if (densityFunctionFilled == null)
            {
                ProfilerShort.End();
                return(null);
            }
            IMyModule densityFunctionRemoved = GetCellDensityFunctionRemoved(cell.BoundingVolume);

            int cellSeed = GetCellSeed(ref cellId);
            var random   = MyRandom.Instance;

            using (random.PushSeed(cellSeed))
            {
                int      index     = 0;
                Vector3I subCellId = Vector3I.Zero;
                Vector3I max       = new Vector3I(SUBCELLS - 1);
                for (var iter = new Vector3I_RangeIterator(ref Vector3I.Zero, ref max); iter.IsValid(); iter.GetNext(out subCellId))
                {
                    // there is a bug in the position calculation which can very rarely cause overlaping objects but backwards compatibility so meh
                    Vector3D position = new Vector3D(random.NextDouble(), random.NextDouble(), random.NextDouble());
                    position += (Vector3D)subCellId / SUBCELL_SIZE;
                    position += cellId;
                    position *= CELL_SIZE;

                    if (!MyEntities.IsInsideWorld(position))
                    {
                        continue;
                    }

                    ProfilerShort.Begin("Density functions");
                    double valueRemoved = -1;
                    if (densityFunctionRemoved != null)
                    {
                        valueRemoved = densityFunctionRemoved.GetValue(position.X, position.Y, position.Z);

                        if (valueRemoved <= -1)
                        {
                            ProfilerShort.End();
                            continue;
                        }
                    }

                    var valueFilled = densityFunctionFilled.GetValue(position.X, position.Y, position.Z);

                    if (densityFunctionRemoved != null)
                    {
                        if (valueRemoved < valueFilled)
                        {
                            ProfilerShort.End();
                            continue;
                        }
                    }
                    ProfilerShort.End();

                    if (valueFilled < m_objectDensity) // -1..+1
                    {
                        var objectSeed = new MyObjectSeed(cell, position, GetObjectSize(random.NextDouble()));
                        objectSeed.Params.Type  = GetSeedType(random.NextDouble());
                        objectSeed.Params.Seed  = random.Next();
                        objectSeed.Params.Index = index++;

                        GenerateObject(cell, objectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved);
                    }
                }
            }

            ProfilerShort.End();
            return(cell);
        }
Beispiel #12
0
        public override void GenerateObjects(List <MyObjectSeed> objectsList, HashSet <MyObjectSeedParams> existingObjectsSeeds)
        {
            ProfilerShort.Begin("GenerateObjects");
            foreach (var objectSeed in objectsList)
            {
                if (objectSeed.Params.Generated || existingObjectsSeeds.Contains(objectSeed.Params))
                {
                    continue;
                }

                objectSeed.Params.Generated = true;

                using (MyRandom.Instance.PushSeed(GetObjectIdSeed(objectSeed)))
                {
                    switch (objectSeed.Params.Type)
                    {
                    case MyObjectSeedType.Asteroid:
                        ProfilerShort.Begin("Asteroid");

                        var bbox = objectSeed.BoundingVolume;
                        MyGamePruningStructure.GetAllVoxelMapsInBox(ref bbox, m_tmpVoxelMapsList);

                        String storageName = string.Format("Asteroid_{0}_{1}_{2}_{3}_{4}", objectSeed.CellId.X, objectSeed.CellId.Y, objectSeed.CellId.Z, objectSeed.Params.Index, objectSeed.Params.Seed);

                        bool exists = false;
                        foreach (var voxelMap in m_tmpVoxelMapsList)
                        {
                            if (voxelMap.StorageName == storageName)
                            {
                                existingObjectsSeeds.Add(objectSeed.Params);
                                exists = true;
                                break;
                            }
                        }

                        if (!exists)
                        {
                            var           provider = MyCompositeShapeProvider.CreateAsteroidShape(objectSeed.Params.Seed, objectSeed.Size, MySession.Static.Settings.VoxelGeneratorVersion);
                            MyStorageBase storage  = new MyOctreeStorage(provider, GetAsteroidVoxelSize(objectSeed.Size));
                            var           voxelMap = MyWorldGenerator.AddVoxelMap(storageName, storage, objectSeed.BoundingVolume.Center - VRageMath.MathHelper.GetNearestBiggerPowerOfTwo(objectSeed.Size) / 2, GetAsteroidEntityId(storageName));

                            if (voxelMap != null)
                            {
                                voxelMap.Save = false;
                                MyVoxelBase.StorageChanged OnStorageRangeChanged = null;
                                OnStorageRangeChanged = delegate(MyVoxelBase voxel, Vector3I minVoxelChanged, Vector3I maxVoxelChanged, MyStorageDataTypeFlags changedData)
                                {
                                    voxelMap.Save          = true;
                                    voxelMap.RangeChanged -= OnStorageRangeChanged;
                                };
                                voxelMap.RangeChanged += OnStorageRangeChanged;
                            }
                        }
                        m_tmpVoxelMapsList.Clear();
                        ProfilerShort.End();
                        break;

                    case MyObjectSeedType.EncounterAlone:
                    case MyObjectSeedType.EncounterSingle:
                    case MyObjectSeedType.EncounterMulti:
                        ProfilerShort.Begin("Encounter");
                        bool doSpawn = true;
                        foreach (var start in MySession.Static.Scenario.PossiblePlayerStarts)
                        {
                            Vector3D?startPos = start.GetStartingLocation();
                            if (!startPos.HasValue)
                            {
                                startPos = Vector3D.Zero;
                            }
                            if ((startPos.Value - objectSeed.BoundingVolume.Center).LengthSquared() < (15000 * 15000))
                            {
                                doSpawn = false;
                            }
                        }
                        if (doSpawn)
                        {
                            MyEncounterGenerator.PlaceEncounterToWorld(objectSeed.BoundingVolume, objectSeed.Params.Seed, objectSeed.Params.Type);
                        }
                        ProfilerShort.End();
                        break;

                    default:
                        throw new InvalidBranchException();
                        break;
                    }
                }
            }
            ProfilerShort.End();
        }
Beispiel #13
0
        protected override void Draw(MyRenderContext RC, List <MyInstanceComponent> visibleInstances)
        {
            int maxLodId = MyManagers.IDGenerator.DepthLods.GetHighestID();

            if (IsProfilingDoable())
            {
                ProfilerShort.Begin("Preparation");
            }
            m_drawableGroupDepthStrategy.Prepare(m_vbInstances);
            m_drawableGroupFactory.Compute(m_drawableGroupDepthStrategy, visibleInstances, PassId, maxLodId);
            bool isEmpty = !m_drawableGroupDepthStrategy.Finalize(RC, out m_vbInstances);

            if (!isEmpty)
            {
                FillConstantBuffer(RC, MyCommon.ProjectionConstants, Matrix.Transpose(m_viewProjMatrix));

                RC.SetPrimitiveTopology(PrimitiveTopology.TriangleList);

                RC.SetViewport(m_viewport.OffsetX, m_viewport.OffsetY, m_viewport.Width, m_viewport.Height);
                RC.SetRtv(m_dsv, null);

                FillConstantBuffer(RC, MyCommon.ProjectionConstants, Matrix.Transpose(m_viewProjMatrix));

                RC.VertexShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants);
                RC.VertexShader.SetConstantBuffer(MyCommon.PROJECTION_SLOT, MyCommon.ProjectionConstants);

                RC.PixelShader.SetSamplers(0, MySamplerStateManager.StandardSamplers);
                RC.PixelShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants);
                RC.PixelShader.SetSrv(MyCommon.DITHER_8X8_SLOT, MyGeneratedTextureManager.Dithering8x8Tex);

                // Just some placeholder:
                IConstantBuffer cbObjectData = GetPlaceholderObjectCB(RC, 0);
                RC.VertexShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData);
                RC.PixelShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData);

                if (IsProfilingDoable())
                {
                    ProfilerShort.BeginNextBlock("Recording commands");
                }

                foreach (var itGroup in m_drawableGroupFactory.GetRawDrawableGroups())
                {
                    MyRenderProxy.Assert(itGroup.InstancesCount != 0);
                    MyRenderProxy.Assert(itGroup.InstancesCount == itGroup.InstancesIncrement);
                    foreach (var part in itGroup.Lod.Parts)
                    {
                        RC.SetVertexBuffer(0, part.Parent.VB0);
                        RC.SetVertexBuffer(2, m_vbInstances);
                        RC.SetIndexBuffer(part.Parent.IB);

                        RC.SetDepthStencilState(null);
                        RC.SetRasterizerState(GetRasterizerState(m_isCascade));
                        RC.SetBlendState(null);

                        MyShaderBundle shaderBundle = part.GetShaderBundle(itGroup.State);
                        RC.SetInputLayout(shaderBundle.InputLayout);
                        RC.VertexShader.Set(shaderBundle.VertexShader);
                        RC.PixelShader.Set(shaderBundle.PixelShader);

                        int numInstances = itGroup.InstancesCount;
                        int ibOffset     = itGroup.OffsetInInstanceBuffer + (part.InstanceMaterialOffsetInLod + 1) * itGroup.InstancesCount;
                        RC.DrawIndexedInstanced(part.IndicesCount, numInstances, part.StartIndex,
                                                part.StartVertex, ibOffset);

                        Stats.Triangles += (part.IndicesCount / 3) * numInstances;
                        Stats.Instances += numInstances;
                        Stats.Draws++;
                    }
                }
            }

            if (IsProfilingDoable())
            {
                ProfilerShort.End();
            }
        }
Beispiel #14
0
        protected override void Draw(MyRenderContext RC, List <MyInstanceComponent> visibleInstances)
        {
            int maxLodId = MyManagers.IDGenerator.GBufferLods.GetHighestID();

            ProfilerShort.Begin("Preparation");
            m_drawableGroupGBufferStrategy.Prepare(m_vbInstances);
            m_drawableGroupFactory.Compute(m_drawableGroupGBufferStrategy, visibleInstances, 0, maxLodId);
            bool isEmpty = !m_drawableGroupGBufferStrategy.Finalize(RC, out m_vbInstances);

            if (!isEmpty)
            {
                RC.SetPrimitiveTopology(PrimitiveTopology.TriangleList);

                RC.SetViewport(m_viewport.OffsetX, m_viewport.OffsetY, m_viewport.Width, m_viewport.Height);
                RC.SetRtvs(m_gbuffer, MyDepthStencilAccess.ReadWrite);

                FillConstantBuffer(RC, MyCommon.ProjectionConstants, Matrix.Transpose(m_viewProjMatrix));

                RC.VertexShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants);
                RC.VertexShader.SetConstantBuffer(MyCommon.PROJECTION_SLOT, MyCommon.ProjectionConstants);

                RC.PixelShader.SetSamplers(0, MySamplerStateManager.StandardSamplers);
                RC.PixelShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants);
                RC.PixelShader.SetSrv(MyCommon.DITHER_8X8_SLOT, MyGeneratedTextureManager.Dithering8x8Tex);

                // Ugly hotfix to enable rendering. If shaders will be modified, it will be good to remove this completly
                if (!MyRender11.Settings.DisplayGbufferLOD)
                {
                    IConstantBuffer cbObjectData = GetPlaceholderObjectCB(RC, 0); // <- the lod value does not matter in this case
                    RC.VertexShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData);
                    RC.PixelShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData);
                }

                ProfilerShort.BeginNextBlock("Recording commands");

                foreach (var itGroup in m_drawableGroupFactory.GetRawDrawableGroups())
                {
                    MyRenderProxy.Assert(itGroup.InstancesCount != 0);
                    MyRenderProxy.Assert(itGroup.InstancesCount == itGroup.InstancesIncrement);
                    foreach (var part in itGroup.Lod.Parts)
                    {
                        // Ugly hotfix to enable displaying lods. If there will be proper solution for displaying lods, this part can be removed completly
                        if (MyRender11.Settings.DisplayGbufferLOD)
                        {
                            IConstantBuffer cbObjectData = GetPlaceholderObjectCB(RC, (uint)part.Parent.LodNum);
                            RC.VertexShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData);
                            RC.PixelShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData);
                        }
                        // End of temporary solution

                        IMaterial material = part.Material;
                        RC.SetVertexBuffer(0, part.Parent.VB0);
                        RC.SetVertexBuffer(1, part.Parent.VB1);
                        RC.SetVertexBuffer(2, m_vbInstances);
                        RC.SetIndexBuffer(part.Parent.IB);
                        if (MyRender11.Settings.Wireframe)
                        {
                            RC.SetDepthStencilState(MyDepthStencilStateManager.DepthTestWrite);
                            RC.SetBlendState(null);
                            RC.SetRasterizerState(MyRasterizerStateManager.NocullWireframeRasterizerState);
                        }
                        else
                        {
                            RC.SetDepthStencilState(part.Material.DepthStencilState);
                            RC.SetRasterizerState(material.RasterizerState);
                            RC.SetBlendState(part.Material.BlendState);
                        }

                        MyShaderBundle shaderBundle = part.GetShaderBundle(itGroup.State);
                        RC.SetInputLayout(shaderBundle.InputLayout);
                        RC.VertexShader.Set(shaderBundle.VertexShader);
                        RC.PixelShader.Set(shaderBundle.PixelShader);
                        RC.PixelShader.SetSrvs(0, part.Material.Srvs);

                        int numInstances = itGroup.InstancesCount;
                        int ibOffset     = itGroup.OffsetInInstanceBuffer + (part.InstanceMaterialOffsetInLod + 1) * itGroup.InstancesCount;
                        RC.DrawIndexedInstanced(part.IndicesCount, numInstances, part.StartIndex,
                                                part.StartVertex, ibOffset);

                        Stats.Triangles += (part.IndicesCount / 3) * numInstances;
                        Stats.Instances += numInstances;
                        Stats.Draws++;
                    }
                }
            }

            ProfilerShort.End();
        }
        public bool Drill(bool collectOre = true, bool performCutout = true, bool assignDamagedMaterial = false, float speedMultiplier = 1f)
        {
            ProfilerShort.Begin("MyDrillBase::Drill()");

            bool drillingSuccess = false;

            MySoundPair sound = null;

            if ((m_drillEntity.Parent != null) && (m_drillEntity.Parent.Physics != null) && !m_drillEntity.Parent.Physics.Enabled)
            {
                return(false);
            }

            if (performCutout)
            {
                StopSparkParticles();
                StopDustParticles();
                var          entitiesInRange = m_sensor.EntitiesInRange;
                MyStringHash targetMaterial  = MyStringHash.NullOrEmpty;
                MyStringHash bestMaterial    = MyStringHash.NullOrEmpty;
                float        distanceBest    = float.MaxValue;
                bool         targetIsBlock   = false;
                foreach (var entry in entitiesInRange)
                {
                    drillingSuccess = false;
                    var entity = entry.Value.Entity;
                    if (entity.MarkedForClose)
                    {
                        continue;
                    }
                    if (entity is MyCubeGrid)
                    {
                        var grid = entity as MyCubeGrid;
                        if (grid.Physics != null && grid.Physics.Enabled)
                        {
                            drillingSuccess = TryDrillBlocks(grid, entry.Value.DetectionPoint, !Sync.IsServer, out targetMaterial);
                            targetIsBlock   = true;
                        }
                        if (drillingSuccess)
                        {
                            m_initialHeatup = false;
                            CreateParticles(entry.Value.DetectionPoint, false, true, false);
                        }
                    }
                    else if (entity is MyVoxelBase)
                    {
                        ProfilerShort.Begin("Drill voxel map");
                        var voxels = entity as MyVoxelBase;
                        drillingSuccess = TryDrillVoxels(voxels, entry.Value.DetectionPoint, collectOre, !Sync.IsServer, assignDamagedMaterial);
                        ProfilerShort.BeginNextBlock("Create particles");
                        if (drillingSuccess)
                        {
                            Vector3D drillHitPoint = entry.Value.DetectionPoint;
                            if (targetMaterial == MyStringHash.NullOrEmpty)
                            {
                                var voxelMaterial = voxels.GetMaterialAt(ref drillHitPoint);
                                if (voxelMaterial != null)
                                {
                                    targetMaterial = MyStringHash.GetOrCompute(voxelMaterial.MaterialTypeName);
                                }
                            }
                            CreateParticles(entry.Value.DetectionPoint, true, false, true);
                        }
                        ProfilerShort.End();
                    }
                    else if (entity is MyFloatingObject)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= 1.33f;
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            MyFloatingObject flObj = entity as MyFloatingObject;
                            if (Sync.IsServer)
                            {
                                if (flObj.Item.Content.TypeId == typeof(MyObjectBuilder_Ore))
                                {
                                    var invOwn = (m_drillEntity != null && m_drillEntity.HasInventory) ? m_drillEntity : null;
                                    if (invOwn == null)
                                    {
                                        invOwn = (m_drillEntity as MyHandDrill).Owner;
                                    }

                                    System.Diagnostics.Debug.Assert((invOwn.GetInventory(0) as MyInventory) != null, "Null or unexpected inventory type!");
                                    (invOwn.GetInventory(0) as MyInventory).TakeFloatingObject(flObj);
                                }
                                else
                                {
                                    (entity as MyFloatingObject).DoDamage(70, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                                }
                            }
                            drillingSuccess = true;
                        }
                    }
                    else if (entity is MyCharacter)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= 0.8f;
                        var character = entity as MyCharacter;
                        if (targetMaterial == MyStringHash.NullOrEmpty)
                        {
                            targetMaterial = MyStringHash.GetOrCompute((entity as MyCharacter).Definition.PhysicalMaterial);
                        }
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);

                            //damage tracking
                            if ((m_drillEntity is MyHandDrill) && (m_drillEntity as MyHandDrill).Owner == MySession.Static.LocalCharacter && character != MySession.Static.LocalCharacter && character.IsDead == false)
                            {
                                MySession.Static.TotalDamageDealt += 20;
                            }

                            if (Sync.IsServer)
                            {
                                character.DoDamage(20, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                            }
                            drillingSuccess = true;
                        }
                        else
                        {
                            BoundingSphereD headSphere = new BoundingSphereD(character.PositionComp.WorldMatrix.Translation + character.WorldMatrix.Up * 1.25f, 0.6f);
                            //MyRenderProxy.DebugDrawSphere(headSphere.Center, headSphere.Radius, Color.Red.ToVector3(), 1, false);
                            if (headSphere.Intersects(sphere))
                            {
                                //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);

                                //damage tracking
                                if ((m_drillEntity is MyHandDrill) && (m_drillEntity as MyHandDrill).Owner == MySession.Static.LocalCharacter && character != MySession.Static.LocalCharacter && character.IsDead == false)
                                {
                                    MySession.Static.TotalDamageDealt += 20;
                                }

                                if (Sync.IsServer)
                                {
                                    character.DoDamage(20, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                                }
                                drillingSuccess = true;
                            }
                        }
                    }
                    else if (entity is MyEnvironmentSector)
                    {
                        if (m_lastItemId != entry.Value.ItemId)
                        {
                            m_lastItemId      = entry.Value.ItemId;
                            m_lastContactTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
                        }
                        if (MySandboxGame.TotalGamePlayTimeInMilliseconds - m_lastContactTime > MyDebrisConstants.CUT_TREE_IN_MILISECONDS * speedMultiplier)
                        {
                            var sectorProxy = (entity as MyEnvironmentSector).GetModule <MyBreakableEnvironmentProxy>();
                            sectorProxy.BreakAt(entry.Value.ItemId, entry.Value.DetectionPoint, Vector3D.Zero, 0);
                            drillingSuccess = true;
                            m_lastItemId    = 0;
                        }
                    }
                    if (drillingSuccess)
                    {
                        m_lastContactTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
                        float dist = Vector3.DistanceSquared(entry.Value.DetectionPoint, Sensor.Center);
                        if (targetMaterial != null && targetMaterial != MyStringHash.NullOrEmpty && dist < distanceBest)
                        {
                            bestMaterial = targetMaterial;
                            distanceBest = dist;
                        }
                    }
                }

                if (bestMaterial != null && bestMaterial != MyStringHash.NullOrEmpty)
                {
                    sound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_drillMaterial, bestMaterial);
                    if (sound == null || sound == MySoundPair.Empty)//target material was not set in definition - using metal/rock sound
                    {
                        if (targetIsBlock)
                        {
                            bestMaterial = m_metalMaterial;
                        }
                        else
                        {
                            bestMaterial = m_rockMaterial;
                        }
                    }
                    sound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_drillMaterial, bestMaterial);
                }
            }

            if (sound != null && sound != MySoundPair.Empty)
            {
                StartLoopSound(sound);
            }
            else
            {
                StartIdleSound(m_idleSoundLoop);
            }

            if (!IsDrilling)
            {
                IsDrilling = true;
                m_animationLastUpdateTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
            }

            ProfilerShort.End();
            return(drillingSuccess);
        }
Beispiel #16
0
        private void RenderCallback()
        {
            if (m_messageProcessingStart != MyTimeSpan.Zero)
            {
                MyTimeSpan messageQueueDuration = m_timer.Elapsed - m_messageProcessingStart;
                ProfilerShort.CustomValue("MessageQueue", 0, messageQueueDuration);
            }
            ProfilerShort.Begin("Wait");
            m_waiter.Wait();
            ProfilerShort.End();

            m_frameStart = m_timer.Elapsed;

            ProfilerShort.Begin("PrepareDraw");

            ProfilerShort.Begin("ProcessInvoke");
            Action action;

            while (m_invokeQueue.TryDequeue(out action))
            {
                action();
            }
            ProfilerShort.End();

            ProfilerShort.Begin("ApplyModeChanges");
            ApplySettingsChanges();
            ProfilerShort.End();

            ProfilerShort.Begin("BeforeRender");
            MyRenderStats.Generic.WriteFormat("Available GPU memory: {0} MB", (float)MyRenderProxy.GetAvailableTextureMemory() / 1024 / 1024, MyStatTypeEnum.CurrentValue, 300, 2);
            MyRenderProxy.BeforeRender(m_frameStart);
            ProfilerShort.End();

            ProfilerShort.Begin("RenderWindow.BeforeDraw");
            m_renderWindow.BeforeDraw();
            ProfilerShort.End();

            ProfilerShort.Begin("BeforeDraw(event)");
            if (BeforeDraw != null)
            {
                BeforeDraw();
            }
            ProfilerShort.End();

            ProfilerShort.End();

            ProfilerShort.Begin("Draw");

            ProfilerShort.Begin("TestCooperativeLevel");
            var deviceResult = MyRenderProxy.TestDeviceCooperativeLevel();

            ProfilerShort.End();

            if (!m_renderWindow.DrawEnabled)
            {
                ProfilerShort.Begin("ProcessMessages");
                MyRenderProxy.ProcessMessages();
                ProfilerShort.End();
            }
            else if (deviceResult == MyRenderDeviceCooperativeLevel.Ok)
            {
                Draw();
            }
            else
            {
                ProfilerShort.Begin("WaitForReset");

                ProfilerShort.Begin("ProcessMessages");
                MyRenderProxy.ProcessMessages();
                ProfilerShort.End();

                if (deviceResult == MyRenderDeviceCooperativeLevel.Lost)
                {
                    ProfilerShort.Begin("DeviceLost");
                    Thread.Sleep(20);
                    ProfilerShort.End();
                }
                else if (deviceResult == MyRenderDeviceCooperativeLevel.NotReset)
                {
                    ProfilerShort.Begin("DeviceReset");
                    Thread.Sleep(20);
                    DeviceReset();
                    ProfilerShort.End();
                }
                else
                {
                    // TODO: OP! Log error code
                }
                ProfilerShort.End();
            }
            ProfilerShort.End();

            ProfilerShort.Begin("AfterRender");
            MyRenderProxy.AfterRender();
            ProfilerShort.End();

            ProfilerShort.Begin("Present");
            if (deviceResult == MyRenderDeviceCooperativeLevel.Ok && m_renderWindow.DrawEnabled)
            {
                this.DoBeforePresent();
                try
                {
                    MyRenderProxy.Present();
                }
                catch (MyDeviceErrorException e)
                {
                    // Present() ended up with an error -- don't try to recover
                    MyRenderProxy.Error(e.Message, shouldTerminate: true);
                    Exit();
                }
                this.DoAfterPresent();
            }
            ProfilerShort.End();

            if (m_separateThread)
            {
                MyRenderProxy.GetRenderProfiler().Commit();
            }

            m_messageProcessingStart = m_timer.Elapsed;

            if (MyRenderProxy.Settings.ForceSlowCPU)
            {
                Thread.Sleep(200);
            }
        }
Beispiel #17
0
        private void ActivateCommon()
        {
            BoundingSphereD globalSphere = new BoundingSphereD(Vector3D.Transform(m_detectorSphere.Center, CubeGrid.WorldMatrix), m_detectorSphere.Radius);

            if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW)
            {
                MyRenderProxy.DebugDrawSphere(globalSphere.Center, (float)globalSphere.Radius, Color.Red.ToVector3(), 1.0f, false);
            }

            m_isActivatedOnSomething = false;
            ProfilerShort.Begin("Query");
            var res = MyEntities.GetTopMostEntitiesInSphere(ref globalSphere);

            m_entitiesInContact.Clear();
            foreach (MyEntity entity in res)
            {
                var rootEntity = entity.GetTopMostParent();
                if (CanInteractWith(rootEntity))
                {
                    m_entitiesInContact.Add(rootEntity);
                }
            }
            res.Clear();
            ProfilerShort.End();

            //TODO:cache blocks on this grid
            foreach (var entry in m_entitiesInContact)
            {
                MyCubeGrid  grid      = entry as MyCubeGrid;
                MyCharacter character = entry as MyCharacter;

                if (grid != null)
                {
                    m_tempBlocksBuffer.Clear();
                    grid.GetBlocksInsideSphere(ref globalSphere, m_tempBlocksBuffer);
                    m_blocksToActivateOn.UnionWith(m_tempBlocksBuffer);
                }
                if (character != null && Sync.IsServer)
                {
                    MyStringHash damageType = MyDamageType.Drill;
                    if (this is IMyShipGrinder)
                    {
                        damageType = MyDamageType.Grind;
                    }
                    else if (this is IMyShipWelder)
                    {
                        damageType = MyDamageType.Weld;
                    }

                    character.DoDamage(20, damageType, true, attackerId: EntityId);
                }
            }

            m_isActivatedOnSomething |= Activate(m_blocksToActivateOn);

            m_activateCounter++;
            m_lastTimeActivate = MySandboxGame.TotalGamePlayTimeInMilliseconds;

            PlayLoopSound(m_isActivatedOnSomething);

            m_blocksToActivateOn.Clear();
        }
Beispiel #18
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();
            }
        }
        private bool AddCell(Vector3I cellPos)
        {
            MyCellCoord coord = new MyCellCoord(NAVMESH_LOD, cellPos);

            var geometry = m_voxelMap.Storage.Geometry;

            MyVoxelGeometry.CellData data = geometry.GetCell(ref coord);
            if (data == null)
            {
                m_processedCells.Add(ref cellPos);
                m_higherLevelHelper.AddExplored(ref cellPos);
                return(false);
            }

            ulong packedCoord = coord.PackId64();

            List <DebugDrawEdge> debugEdgesList = new List <DebugDrawEdge>();

            m_debugCellEdges[packedCoord] = debugEdgesList;

            MyVoxelPathfinding.CellId cellId = new MyVoxelPathfinding.CellId()
            {
                VoxelMap = m_voxelMap, Pos = cellPos
            };

            MyTrace.Send(TraceWindow.Ai, "Adding cell " + cellPos);

            m_connectionHelper.ClearCell();
            m_vertexMapping.Init(data.VoxelVerticesCount);

            // Prepare list of possibly intersecting cube grids for voxel-grid navmesh intersection testing
            Vector3D     bbMin  = m_voxelMap.PositionLeftBottomCorner + (m_cellSize * (new Vector3D(-0.125) + cellPos));
            Vector3D     bbMax  = m_voxelMap.PositionLeftBottomCorner + (m_cellSize * (Vector3D.One + cellPos));
            BoundingBoxD cellBB = new BoundingBoxD(bbMin, bbMax);

            m_tmpGridList.Clear();
            m_navmeshCoordinator.PrepareVoxelTriangleTests(cellBB, m_tmpGridList);

            Vector3D voxelMapCenter     = m_voxelMap.PositionComp.GetPosition();
            Vector3  centerDisplacement = voxelMapCenter - m_voxelMap.PositionLeftBottomCorner;

            // This is needed for correct edge classification - to tell, whether the edges are inner or outer edges of the cell
            ProfilerShort.Begin("Triangle preprocessing");
            for (int i = 0; i < data.VoxelTrianglesCount; i++)
            {
                short a = data.VoxelTriangles[i].VertexIndex0;
                short b = data.VoxelTriangles[i].VertexIndex1;
                short c = data.VoxelTriangles[i].VertexIndex2;

                Vector3 aPos, bPos, cPos;
                Vector3 vert;
                data.GetUnpackedPosition(a, out vert);
                aPos = vert - centerDisplacement;
                data.GetUnpackedPosition(b, out vert);
                bPos = vert - centerDisplacement;
                data.GetUnpackedPosition(c, out vert);
                cPos = vert - centerDisplacement;

                bool invalidTriangle = false;
                if ((bPos - aPos).LengthSquared() <= MyVoxelConnectionHelper.OUTER_EDGE_EPSILON_SQ)
                {
                    m_vertexMapping.Union(a, b);
                    invalidTriangle = true;
                }
                if ((cPos - aPos).LengthSquared() <= MyVoxelConnectionHelper.OUTER_EDGE_EPSILON_SQ)
                {
                    m_vertexMapping.Union(a, c);
                    invalidTriangle = true;
                }
                if ((cPos - bPos).LengthSquared() <= MyVoxelConnectionHelper.OUTER_EDGE_EPSILON_SQ)
                {
                    m_vertexMapping.Union(b, c);
                    invalidTriangle = true;
                }

                if (invalidTriangle)
                {
                    continue;
                }

                m_connectionHelper.PreprocessInnerEdge(a, b);
                m_connectionHelper.PreprocessInnerEdge(b, c);
                m_connectionHelper.PreprocessInnerEdge(c, a);
            }
            ProfilerShort.End();

            ProfilerShort.Begin("Free face sorting");
            // Ensure that the faces have increasing index numbers
            Mesh.SortFreeFaces();
            ProfilerShort.End();

            m_higherLevelHelper.OpenNewCell(coord);

            ProfilerShort.Begin("Adding triangles");
            for (int i = 0; i < data.VoxelTrianglesCount; i++)
            {
                short a    = data.VoxelTriangles[i].VertexIndex0;
                short b    = data.VoxelTriangles[i].VertexIndex1;
                short c    = data.VoxelTriangles[i].VertexIndex2;
                short setA = (short)m_vertexMapping.Find(a);
                short setB = (short)m_vertexMapping.Find(b);
                short setC = (short)m_vertexMapping.Find(c);

                if (setA == setB || setB == setC || setA == setC)
                {
                    continue;
                }

                Vector3 aPos, bPos, cPos;
                Vector3 vert;
                data.GetUnpackedPosition(setA, out vert);
                aPos = vert - centerDisplacement;
                data.GetUnpackedPosition(setB, out vert);
                bPos = vert - centerDisplacement;
                data.GetUnpackedPosition(setC, out vert);
                cPos = vert - centerDisplacement;

                if (MyFakes.NAVMESH_PRESUMES_DOWNWARD_GRAVITY)
                {
                    Vector3 normal = (cPos - aPos).Cross(bPos - aPos);
                    normal.Normalize();
                    if (normal.Dot(ref Vector3.Up) <= 0.4f)
                    {
                        continue;
                    }
                }

                Vector3D aTformed = aPos + voxelMapCenter;
                Vector3D bTformed = bPos + voxelMapCenter;
                Vector3D cTformed = cPos + voxelMapCenter;

                bool intersecting = false;
                m_tmpLinkCandidates.Clear();
                m_navmeshCoordinator.TestVoxelNavmeshTriangle(ref aTformed, ref bTformed, ref cTformed, m_tmpGridList, m_tmpLinkCandidates, out intersecting);
                if (intersecting)
                {
                    m_tmpLinkCandidates.Clear();
                    continue;
                }

                if (!m_connectionHelper.IsInnerEdge(a, b))
                {
                    debugEdgesList.Add(new DebugDrawEdge(aTformed, bTformed));
                }
                if (!m_connectionHelper.IsInnerEdge(b, c))
                {
                    debugEdgesList.Add(new DebugDrawEdge(bTformed, cTformed));
                }
                if (!m_connectionHelper.IsInnerEdge(c, a))
                {
                    debugEdgesList.Add(new DebugDrawEdge(cTformed, aTformed));
                }

                int edgeAB   = m_connectionHelper.TryGetAndRemoveEdgeIndex(b, a, ref bPos, ref aPos);
                int edgeBC   = m_connectionHelper.TryGetAndRemoveEdgeIndex(c, b, ref cPos, ref bPos);
                int edgeCA   = m_connectionHelper.TryGetAndRemoveEdgeIndex(a, c, ref aPos, ref cPos);
                int formerAB = edgeAB;
                int formerBC = edgeBC;
                int formerCA = edgeCA;

                ProfilerShort.Begin("AddTriangle");
                var tri = AddTriangle(ref aPos, ref bPos, ref cPos, ref edgeAB, ref edgeBC, ref edgeCA);
                ProfilerShort.End();

                CheckMeshConsistency();

                m_higherLevelHelper.AddTriangle(tri.Index);

                if (formerAB == -1)
                {
                    m_connectionHelper.AddEdgeIndex(a, b, ref aPos, ref bPos, edgeAB);
                }
                if (formerBC == -1)
                {
                    m_connectionHelper.AddEdgeIndex(b, c, ref bPos, ref cPos, edgeBC);
                }
                if (formerCA == -1)
                {
                    m_connectionHelper.AddEdgeIndex(c, a, ref cPos, ref aPos, edgeCA);
                }

                // TODO: Instead of this, just add the tri into a list of tris that want to connect with the link candidates
                //m_navmeshCoordinator.TryAddVoxelNavmeshLinks(tri, cellId, m_tmpLinkCandidates);
                foreach (var candidate in m_tmpLinkCandidates)
                {
                    List <MyNavigationPrimitive> primitives = null;
                    if (!m_tmpCubeLinkCandidates.TryGetValue(candidate, out primitives))
                    {
                        primitives = m_primitiveListPool.Allocate();
                        m_tmpCubeLinkCandidates.Add(candidate, primitives);
                    }

                    primitives.Add(tri);
                }
                m_tmpLinkCandidates.Clear();
            }
            ProfilerShort.End();

            m_tmpGridList.Clear();
            m_connectionHelper.ClearCell();
            m_vertexMapping.Clear();

            Debug.Assert(!m_processedCells.Contains(ref cellPos));
            m_processedCells.Add(ref cellPos);
            m_higherLevelHelper.AddExplored(ref cellPos);

            // Find connected components in the current cell's subgraph of the navigation mesh
            m_higherLevelHelper.ProcessCellComponents();
            m_higherLevelHelper.CloseCell();

            // Create navmesh links using the navmesh coordinator, taking into consideration the high level components
            m_navmeshCoordinator.TryAddVoxelNavmeshLinks2(cellId, m_tmpCubeLinkCandidates);
            m_navmeshCoordinator.UpdateVoxelNavmeshCellHighLevelLinks(cellId);

            foreach (var candidate in m_tmpCubeLinkCandidates)
            {
                candidate.Value.Clear();
                m_primitiveListPool.Deallocate(candidate.Value);
            }
            m_tmpCubeLinkCandidates.Clear();

            return(true);
        }
Beispiel #20
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();
        }
Beispiel #21
0
        private unsafe void FetchData(int lodToSwitch)
        {
            ProfilerShort.Begin(string.Format("FetchData({0})", lodToSwitch));
            var oldData = DataView;

            if (oldData != null && oldData.Lod == lodToSwitch)
            {
                ProfilerShort.End();
                return;
            }

            DataView = m_provider.GetItemView(lodToSwitch, ref m_dataRange.Min, ref m_dataRange.Max, ref m_sectorCenter);

            DataView.Listener = this;

            if (oldData != null)
            {
                oldData.Close();
            }

            foreach (var module in m_modules.Values)
            {
                module.Proxy.Close();
            }

            m_modules.Clear();

            int totalItems = DataView.Items.Count;

            fixed(ItemInfo *items = DataView.Items.GetInternalArray())
            for (int i = 0; i < totalItems; ++i)
            {
                if (items[i].DefinitionIndex == -1)
                {
                    continue;
                }

                var def = m_environment.Items[items[i].DefinitionIndex];

                var proxies = def.Type.ProxyModules;

                if (proxies != null)
                {
                    foreach (var proxy in proxies)
                    {
                        Module mod;
                        if (!m_modules.TryGetValue(proxy.Type, out mod))
                        {
                            mod                   = new Module((IMyEnvironmentModuleProxy)Activator.CreateInstance(proxy.Type));
                            mod.Definition        = proxy.Definition;
                            m_modules[proxy.Type] = mod;
                        }

                        mod.Items.Add(i);
                    }
                }
            }

            ProfilerShort.End();

            ProfilerShort.Begin("InitModuleProxies()");
            foreach (var module in m_modules)
            {
                ProfilerShort.Begin(module.Key.Name);
                module.Value.Proxy.Init(this, module.Value.Items);
                module.Value.Items = null;
                ProfilerShort.End();
            }
            ProfilerShort.End();
        }
        //collisions
        //sphere vs voxel volumetric test
        // mk:TODO Remove. This is not very accurate.
        public override bool DoOverlapSphereTest(float sphereRadius, Vector3D spherePos)
        {
            if (Storage.Closed)
            {
                return(false);
            }

            ProfilerShort.Begin("MyVoxelMap.DoOverlapSphereTest");
            Vector3D        body0Pos = spherePos; // sphere pos
            BoundingSphereD newSphere;

            newSphere.Center = body0Pos;
            newSphere.Radius = sphereRadius;

            //  We will iterate only voxels contained in the bounding box of new sphere, so here we get min/max corned in voxel units
            Vector3I minCorner, maxCorner;

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

            minCorner += StorageMin;
            maxCorner += StorageMin;

            Storage.ClampVoxelCoord(ref minCorner);
            Storage.ClampVoxelCoord(ref maxCorner);
            m_tempStorage.Resize(minCorner, maxCorner);
            Storage.ReadRange(m_tempStorage, MyStorageDataTypeFlags.Content, 0, ref minCorner, ref maxCorner);

            Vector3I tempVoxelCoord, cache;

            for (tempVoxelCoord.Z = minCorner.Z, cache.Z = 0; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++, cache.Z++)
            {
                for (tempVoxelCoord.Y = minCorner.Y, cache.Y = 0; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++, cache.Y++)
                {
                    for (tempVoxelCoord.X = minCorner.X, cache.X = 0; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++, cache.X++)
                    {
                        byte voxelContent = m_tempStorage.Content(ref cache);

                        //  Ignore voxels bellow the ISO value (empty, partialy empty...)
                        if (voxelContent < MyVoxelConstants.VOXEL_ISO_LEVEL)
                        {
                            continue;
                        }

                        Vector3D voxelPosition;
                        MyVoxelCoordSystems.VoxelCoordToWorldPosition(PositionLeftBottomCorner - StorageMin * MyVoxelConstants.VOXEL_SIZE_IN_METRES, ref tempVoxelCoord, out voxelPosition);

                        float voxelSize = (voxelContent / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT) * MyVoxelConstants.VOXEL_RADIUS;

                        //  If distance to voxel border is less than sphere radius, we have a collision
                        //  So now we calculate normal vector and penetration depth but on OLD sphere
                        float newDistanceToVoxel = Vector3.Distance(voxelPosition, newSphere.Center) - voxelSize;
                        if (newDistanceToVoxel < (newSphere.Radius))
                        {
                            ProfilerShort.End();
                            return(true);
                        }
                    }
                }
            }
            ProfilerShort.End();
            return(false);
        }
Beispiel #23
0
        public void RemoveUnusedBones(MyCubeGrid grid)
        {
            ProfilerShort.Begin("RemoveUnusedBones");
            if (m_tmpRemovedCubes.Count != 0)
            {
                Debug.Assert(m_testedCubes.Count == 0);
                Debug.Assert(m_usedBones.Count == 0);

                foreach (var cube in m_tmpRemovedCubes)
                {
                    if (grid.CubeExists(cube))
                    {
                        if (!m_testedCubes.Contains(cube))
                        {
                            m_testedCubes.Add(cube);
                            AddUsedBones(cube);
                        }
                        continue;
                    }

                    Vector3I centerBonePos = cube * BoneDensity + Vector3I.One;
                    Vector3I dir, neighbor;

                    // Iterate over all the neighbors of the cube and check whether they are present in the grid
                    for (int x = -1; x <= 1; ++x)
                    {
                        for (int y = -1; y <= 1; ++y)
                        {
                            for (int z = -1; z <= 1; ++z)
                            {
                                dir.X    = x;
                                dir.Y    = y;
                                dir.Z    = z;
                                neighbor = cube + dir;

                                if (grid.CubeExists(neighbor) && !m_testedCubes.Contains(neighbor))
                                {
                                    m_testedCubes.Add(neighbor);
                                    AddUsedBones(neighbor);
                                }
                            }
                        }
                    }
                }

                foreach (var cube in m_tmpRemovedCubes)
                {
                    Vector3I pos = cube * BoneDensity;
                    for (int x = 0; x <= BoneDensity; ++x)
                    {
                        for (int y = 0; y <= BoneDensity; ++y)
                        {
                            for (int z = 0; z <= BoneDensity; ++z)
                            {
                                if (!m_usedBones.Contains(pos))
                                {
                                    ClearBone(ref pos);
                                }

                                pos.Z++;
                            }
                            pos.Y++;
                            pos.Z -= BoneDensity + 1;
                        }
                        pos.X++;
                        pos.Y -= BoneDensity + 1;
                    }
                }

                m_testedCubes.Clear();
                m_usedBones.Clear();
                m_tmpRemovedCubes.Clear();
            }
            ProfilerShort.End();
        }
Beispiel #24
0
        //  Update position, check collisions, etc.
        //  Return false if projectile dies/timeouts in this tick.
        public bool Update()
        {
            //  Projectile was killed , but still not last time drawn, so we don't need to do update (we are waiting for last draw)
            if (m_state == MyProjectileStateEnum.KILLED)
            {
                return(true);
            }
            //  Projectile was killed and last time drawn, so we can finally remove it from buffer
            if (m_state == MyProjectileStateEnum.KILLED_AND_DRAWN)
            {
                StopEffect();
                return(false);
            }

            Vector3D position = m_position;

            m_position += m_velocity * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;

            //  Distance timeout
            Vector3 positionDelta = m_position - m_origin;

            if (Vector3.Dot(positionDelta, positionDelta) >= m_maxTrajectory * m_maxTrajectory)
            {
                StopEffect();
                m_state = MyProjectileStateEnum.KILLED;
                return(true);
            }

            m_checkIntersectionIndex = ++m_checkIntersectionIndex % CHECK_INTERSECTION_INTERVAL;
            if (m_checkIntersectionIndex != 0 && m_positionChecked) //check only each n-th intersection
            {
                return(true);
            }

            //  Calculate hit point, create decal and throw debris particles
            Vector3D lineEndPosition = position + CHECK_INTERSECTION_INTERVAL * (m_velocity * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS);

            LineD line = new LineD(m_positionChecked ? position : m_origin, lineEndPosition);

            m_positionChecked = true;

            IMyEntity entity;
            Vector3D  hitPosition;
            Vector3   hitNormal;
            bool      headShot;

            GetHitEntityAndPosition(line, out entity, out hitPosition, out hitNormal, out headShot);
            if (entity == null || entity == m_ignoreEntity || entity.Physics == null)
            {
                return(true);
            }
            ProfilerShort.Begin("Projectile.Update");
            m_position = hitPosition;

            bool isProjectileGroupKilled = false;

            if (!isProjectileGroupKilled)
            {
                MySurfaceImpactEnum surfaceImpact;
                MyStringHash        materialType;
                GetSurfaceAndMaterial(entity, out surfaceImpact, out materialType);

                PlayHitSound(materialType, entity, hitPosition);
                DoDamage(headShot ? m_projectileAmmoDefinition.ProjectileHeadShotDamage : m_projectileAmmoDefinition.ProjectileMassDamage, hitPosition, entity);
                //  Create smoke and debris particle at the place of voxel/model hit

                if (surfaceImpact != MySurfaceImpactEnum.CHARACTER)
                {
                    m_projectileAmmoDefinition.ProjectileOnHitParticles(ref hitPosition, ref hitNormal, ref line.Direction, entity, m_weapon, 1, OwnerEntity);
                }
                m_projectileAmmoDefinition.ProjectileOnHitMaterialParticles(ref hitPosition, ref hitNormal, ref line.Direction, entity, surfaceImpact, m_weapon, 1);

                CreateDecal(materialType);

                if (m_weapon == null || (entity.GetTopMostParent() != m_weapon.GetTopMostParent()))
                {
                    ApplyProjectileForce(entity, hitPosition, m_directionNormalized, false, m_projectileAmmoDefinition.ProjectileHitImpulse * m_impulseMultiplier);
                }

                StopEffect();
                m_state = MyProjectileStateEnum.KILLED;
            }
            ProfilerShort.End();
            return(true);
        }
Beispiel #25
0
        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();
        }
        private void UpdatePosition(bool forceUpdate = false)
        {
            if (m_subpart1 == null) //GK: forceUpdate happens on Init before loading subparts when setting m_currentPos (value changed). So make sure one subpart exists
            {
                return;
            }
            if (!IsWorking && !forceUpdate)
            {
                return;
            }
            //if (!forceUpdate && !CubeGrid.SyncObject.ResponsibleForUpdate(Sync.Clients.LocalClient))
            //return;

            bool changed = false;

            float compensatedDelta = Velocity / 60;

            ProfilerShort.Begin("PosAndHandlers");
            if (!forceUpdate)
            {
                if (compensatedDelta < 0)
                {
                    if (m_currentPos > MinLimit)
                    {
                        m_currentPos.Value = Math.Max(m_currentPos.Value + compensatedDelta, MinLimit);
                        changed            = true;
                        if (m_currentPos.Value <= MinLimit)
                        {
                            var handle = LimitReached;
                            if (handle != null)
                            {
                                handle(false);
                            }
                        }
                    }
                }
                else if (m_currentPos < MaxLimit)
                {
                    m_currentPos.Value = Math.Min(m_currentPos.Value + compensatedDelta, MaxLimit);
                    changed            = true;
                    if (m_currentPos.Value >= MaxLimit)
                    {
                        var handle = LimitReached;
                        if (handle != null)
                        {
                            handle(true);
                        }
                    }
                }
            }
            ProfilerShort.End();

            if (changed || forceUpdate)
            {
                ProfilerShort.Begin("UpdateText");
                UpdateText();
                ProfilerShort.End();

                ProfilerShort.Begin("UpdateAnimation");
                UpdateAnimation();
                ProfilerShort.End();

                ProfilerShort.Begin("Calculations");
                m_posChanged = true;
                if (CubeGrid == null)
                {
                    MySandboxGame.Log.WriteLine("CubeGrid is null");
                }
                if (Subpart3 == null)
                {
                    MySandboxGame.Log.WriteLine("Subpart is null");
                }
                if (CubeGrid.Physics != null)
                {
                    CubeGrid.Physics.RigidBody.Activate();
                }
                if (TopGrid != null && TopGrid.Physics != null)
                {
                    TopGrid.Physics.RigidBody.Activate();
                }
                Matrix matA;
                GetTopMatrix(out matA);
                Matrix matB = Matrix.Identity;
                if (TopGrid != null)
                {
                    matB = Matrix.CreateWorld(TopBlock.Position * TopBlock.CubeGrid.GridSize /*- TopBlock.LocalMatrix.Up * m_currentPos*/, Subpart3.PositionComp.LocalMatrix.Forward, TopBlock.PositionComp.LocalMatrix.Up);
                }
                ProfilerShort.End();

                ProfilerShort.Begin("SetInBodySpace");
                if (m_fixedData != null)
                {
                    m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, TopGrid.Physics);
                }
                ProfilerShort.End();

                ProfilerShort.Begin("UpdateSubpartFixedData");
                UpdateSubpartFixedData();
                ProfilerShort.End();
            }
        }
Beispiel #27
0
        public virtual void UnregisterFromSystems(MyCubeBlock block)
        {
            // Note: ResourceDistributor, WeaponSystem and TemrminalSystem can be null on closing (they are not in the ship but in the logical group). That's why they are null-checked
            if (ResourceDistributor != null)
            {
                ProfilerShort.Begin("Unregister Power producer");
                var powerProducer = block.Components.Get <MyResourceSourceComponent>();
                if (powerProducer != null)
                {
                    ResourceDistributor.RemoveSource(powerProducer);
                }

                ProfilerShort.BeginNextBlock("Unregister Power consumer");
                var powerConsumer = block.Components.Get <MyResourceSinkComponent>();
                if (powerConsumer != null)
                {
                    ResourceDistributor.RemoveSink(powerConsumer);
                }
                ProfilerShort.End();

                var socketOwner = block as IMyRechargeSocketOwner;
                if (socketOwner != null)
                {
                    socketOwner.RechargeSocket.ResourceDistributor = null;
                }
            }

            ProfilerShort.Begin("Unregister gun object");
            if (WeaponSystem != null)
            {
                var weapon = block as IMyGunObject <MyDeviceBase>;
                if (weapon != null)
                {
                    WeaponSystem.Unregister(weapon);
                }
            }

            ProfilerShort.BeginNextBlock("Unregister functional block");
            if (TerminalSystem != null)
            {
                var functionalBlock = block as MyTerminalBlock;
                if (functionalBlock != null)
                {
                    TerminalSystem.Remove(functionalBlock);
                }
            }

            // CH: We probably don't need to unregister controller blocks here. It's done in ShipController's OnUnregisteredFromGridSystems

            /*ProfilerShort.BeginNextBlock("Unregister controller block");
             * if (ControlSystem != null)
             * {
             *  var controllableBlock = block as MyShipController;
             *  if (controllableBlock != null && controllableBlock.ControllerInfo.Controller != null)
             *      ControlSystem.RemoveControllerBlock(controllableBlock);
             * }*/

            ProfilerShort.BeginNextBlock("Unregister inventory block");
            var inventoryBlock = block as IMyInventoryOwner;

            if (inventoryBlock != null)
            {
                ConveyorSystem.Remove(inventoryBlock);
            }

            ProfilerShort.BeginNextBlock("Unregister conveyor block");
            var conveyorBlock = block as IMyConveyorEndpointBlock;

            if (conveyorBlock != null)
            {
                ConveyorSystem.RemoveConveyorBlock(conveyorBlock);
            }

            ProfilerShort.BeginNextBlock("Unregister segment block");
            var segmentBlock = block as IMyConveyorSegmentBlock;

            if (segmentBlock != null)
            {
                ConveyorSystem.RemoveSegmentBlock(segmentBlock);
            }

            ProfilerShort.BeginNextBlock("Unregister Reflector light");
            var reflectorLight = block as MyReflectorLight;

            if (reflectorLight != null)
            {
                ReflectorLightSystem.Unregister(reflectorLight);
            }

            if (MyFakes.ENABLE_WHEEL_CONTROLS_IN_COCKPIT)
            {
                ProfilerShort.BeginNextBlock("Unregister wheel");
                var wheel = block as MyMotorSuspension;
                if (wheel != null)
                {
                    WheelSystem.Unregister(wheel);
                }
            }

            ProfilerShort.BeginNextBlock("Unregister landing gear");
            var gear = block as IMyLandingGear;

            if (gear != null)
            {
                LandingSystem.Unregister(gear);
            }

            ProfilerShort.BeginNextBlock("Unregister gyro");
            var gyro = block as MyGyro;

            if (gyro != null)
            {
                GyroSystem.Unregister(gyro);
            }

            ProfilerShort.BeginNextBlock("Unregister camera");
            var camera = block as MyCameraBlock;

            if (camera != null)
            {
                CameraSystem.Unregister(camera);
            }

            ProfilerShort.BeginNextBlock("block.OnUnregisteredFromGridSystems()");
            block.OnUnregisteredFromGridSystems();

            ProfilerShort.End();
        }
Beispiel #28
0
        public override void UpdateAfterSimulation()
        {
            base.UpdateAfterSimulation();

            if (!Sync.IsServer)
            {
                return;
            }

            if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_FAUNA_COMPONENT)
            {
                DebugDraw();
            }

            ProfilerShort.Begin("MySpaceFaunaComponent.UpdateAfter");

            m_waitForUpdate--;
            if (m_waitForUpdate > 0)
            {
                return;
            }
            m_waitForUpdate = UPDATE_DELAY;

            var players = Sync.Players.GetOnlinePlayers();

            m_tmpPlayerPositions.Capacity = Math.Max(m_tmpPlayerPositions.Capacity, players.Count);
            m_tmpPlayerPositions.Clear();

            // Reset bot numbers
            foreach (var planet in m_planets)
            {
                planet.Value.BotNumber = 0;
            }

            // Update bot numbers and save player positions
            foreach (var player in players)
            {
                // Human player
                if (player.Id.SerialId == 0)
                {
                    if (player.Controller.ControlledEntity == null)
                    {
                        continue;
                    }
                    var pos = player.GetPosition();
                    m_tmpPlayerPositions.Add(pos);
                }
                // Bot
                else
                {
                    if (player.Controller.ControlledEntity == null)
                    {
                        continue;
                    }
                    var pos    = player.GetPosition();
                    var planet = MyGravityProviderSystem.GetNearestPlanet(pos);
                    if (planet != null && planet.IsPositionInGravityWell(pos))
                    {
                        PlanetAIInfo planetInfo;
                        if (m_planets.TryGetValue(planet.EntityId, out planetInfo))
                        {
                            planetInfo.BotNumber++;
                        }
                    }
                }
            }

            int currentTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;

            // Spawn bots near players on planets, only if in survival/myfakes macro set
            if (MyFakes.SPAWN_SPACE_FAUNA_IN_CREATIVE)
            {
                foreach (var player in players)
                {
                    if (player.Controller.ControlledEntity == null)
                    {
                        continue;
                    }

                    var pos    = player.GetPosition();
                    var planet = MyGravityProviderSystem.GetNearestPlanet(pos);
                    if (planet == null || !planet.IsPositionInGravityWell(pos) || !PlanetHasFauna(planet))
                    {
                        continue;
                    }

                    PlanetAIInfo planetInfo = null;
                    if (!m_planets.TryGetValue(planet.EntityId, out planetInfo))
                    {
                        continue;
                    }

                    // Human player - spawn spiders
                    if (player.Id.SerialId == 0)
                    {
                        // Distance to surface check
                        Vector3D toSurface = planet.GetClosestSurfacePointGlobal(ref pos) - pos;
                        if (toSurface.LengthSquared() >= PROXIMITY_DIST * PROXIMITY_DIST && planetInfo.BotNumber >= MAX_BOTS_PER_PLANET)
                        {
                            continue;
                        }

                        int spawnPointCount = 0;
                        var pointEnum       = m_spawnInfoGrid.GetPointsCloserThan(ref pos, SPHERE_SPAWN_DIST);
                        while (pointEnum.MoveNext())
                        {
                            var spawnPoint = pointEnum.Current;
                            spawnPointCount++;
                            if (spawnPoint.SpawnDone)
                            {
                                continue; // Don't take not-yet cleaned spawn info into consideration
                            }
                            if (spawnPoint.ShouldSpawn(currentTime))
                            {
                                spawnPoint.SpawnDone = true;
                                var  timeouts       = m_timeoutInfoGrid.GetPointsCloserThan(ref pos, TIMEOUT_DIST);
                                bool timeoutPresent = false;
                                while (timeouts.MoveNext())
                                {
                                    if (timeouts.Current.IsTimedOut(currentTime))
                                    {
                                        continue;
                                    }
                                    timeoutPresent = true;
                                    break;
                                }
                                if (timeoutPresent)
                                {
                                    continue;
                                }

                                var animalSpawnInfo = MySpaceBotFactory.GetDayOrNightAnimalSpawnInfo(planet, spawnPoint.Position);
                                if (animalSpawnInfo == null)
                                {
                                    continue;
                                }

                                int numBots = MyUtils.GetRandomInt(animalSpawnInfo.WaveCountMin, animalSpawnInfo.WaveCountMax);
                                for (int i = 0; i < numBots; ++i)
                                {
                                    SpawnBot(spawnPoint, planet, animalSpawnInfo);
                                }
                            }
                            else
                            {
                                spawnPoint.UpdateAbandoned(currentTime);
                            }
                        }

                        if (spawnPointCount == 0) // we dont have any spawn points near human players position
                        {
                            var spawnInfo = new SpawnInfo(pos, currentTime, planet);
                            m_spawnInfoGrid.AddPoint(ref pos, spawnInfo);
                            m_allSpawnInfos.Add(spawnInfo);
                        }
                    }
                    // Despawn bots that are too far from all players
                    else //if (player.Id.SteamId == Sync.MyId)
                    {
                        double closestDistSq = double.MaxValue;
                        foreach (Vector3D playerPosition in m_tmpPlayerPositions)
                        {
                            closestDistSq = Math.Min(Vector3D.DistanceSquared(pos, playerPosition), closestDistSq);
                        }

                        if (closestDistSq > DESPAWN_DIST * DESPAWN_DIST)
                        {
                            MyAIComponent.Static.RemoveBot(player.Id.SerialId, removeCharacter: true);
                        }
                    }
                }
            }
            m_tmpPlayerPositions.Clear();

            m_waitForClean -= UPDATE_DELAY;

            if (m_waitForClean <= 0)
            {
                MyAIComponent.Static.CleanUnusedIdentities();
                m_waitForClean = CLEAN_DELAY;

                for (int i = 0; i < m_allSpawnInfos.Count; ++i)
                {
                    var spawnInfo = m_allSpawnInfos[i];
                    if (spawnInfo.IsAbandoned(currentTime) || spawnInfo.SpawnDone)
                    {
                        m_allSpawnInfos.RemoveAtFast(i);
                        Vector3D point = spawnInfo.Position;
                        m_spawnInfoGrid.RemovePoint(ref point);
                        --i;
                    }
                }

                for (int i = 0; i < m_allTimeoutInfos.Count; ++i)
                {
                    var timeoutInfo = m_allTimeoutInfos[i];
                    if (timeoutInfo.IsTimedOut(currentTime))
                    {
                        m_allTimeoutInfos.RemoveAtFast(i);
                        Vector3D point = timeoutInfo.Position;
                        m_timeoutInfoGrid.RemovePoint(ref point);
                        --i;
                    }
                }
            }

            ProfilerShort.End();
        }
        void IWork.DoWork(WorkData workData = null)
        {
            ProfilerShort.Begin("MyDepositQuery.DoWork");
            try
            {
                var cache = Cache;
                cache.Resize(new Vector3I(MyOreDetectorComponent.CELL_SIZE_IN_LOD_VOXELS));
                var min = m_args.Cell << MyOreDetectorComponent.CELL_SIZE_IN_VOXELS_BITS;
                var max = min + (MyOreDetectorComponent.CELL_SIZE_IN_LOD_VOXELS - 1);

                var storage = m_args.VoxelMap.Storage;
                if (storage == null || storage.Closed)
                {
                    return; // voxel map was probably closed in the meantime.
                }
                using (storage.Pin())
                {
                    storage.ReadRange(cache, MyStorageDataTypeFlags.Content, MyOreDetectorComponent.QUERY_LOD, ref min, ref max);
                    if (!cache.ContainsVoxelsAboveIsoLevel())
                    {
                        return;
                    }

                    storage.ReadRange(cache, MyStorageDataTypeFlags.Material, MyOreDetectorComponent.QUERY_LOD, ref min, ref max);
                }

                var      materialData = MaterialData;
                Vector3I c;
                for (c.Z = 0; c.Z < MyOreDetectorComponent.CELL_SIZE_IN_LOD_VOXELS; ++c.Z)
                {
                    for (c.Y = 0; c.Y < MyOreDetectorComponent.CELL_SIZE_IN_LOD_VOXELS; ++c.Y)
                    {
                        for (c.X = 0; c.X < MyOreDetectorComponent.CELL_SIZE_IN_LOD_VOXELS; ++c.X)
                        {
                            int i = cache.ComputeLinear(ref c);
                            if (cache.Content(i) > MyVoxelConstants.VOXEL_ISO_LEVEL)
                            {
                                const float VOXEL_SIZE      = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << MyOreDetectorComponent.QUERY_LOD);
                                const float VOXEL_SIZE_HALF = VOXEL_SIZE * 0.5f;
                                var         material        = cache.Material(i);
                                Vector3D    localPos        = (c + min) * VOXEL_SIZE + VOXEL_SIZE_HALF;
                                materialData[material].Sum   += localPos;
                                materialData[material].Count += 1;
                            }
                        }
                    }
                }

                for (int materialIdx = 0; materialIdx < materialData.Length; ++materialIdx)
                {
                    if (materialData[materialIdx].Count == 0)
                    {
                        continue;
                    }

                    var material = MyDefinitionManager.Static.GetVoxelMaterialDefinition((byte)materialIdx);
                    if (material.IsRare)
                    {
                        if (m_result == null)
                        {
                            m_result = new MyEntityOreDeposit(m_args.VoxelMap, m_args.Cell);
                        }

                        m_result.Materials.Add(new MyEntityOreDeposit.Data()
                        {
                            Material             = material,
                            AverageLocalPosition = Vector3D.Transform((materialData[materialIdx].Sum / materialData[materialIdx].Count - m_args.VoxelMap.SizeInMetresHalf), Quaternion.CreateFromRotationMatrix(m_args.VoxelMap.WorldMatrix)),
                        });
                    }
                }
                Array.Clear(materialData, 0, materialData.Length);
            }
            finally
            {
                ProfilerShort.End();
            }
        }
Beispiel #30
0
        private void UpdateProjection()
        {
            if (m_instantBuildingEnabled)
            {
                if (ProjectedGrid != null)
                {
                    foreach (var projectedBlock in ProjectedGrid.CubeBlocks)
                    {
                        ShowCube(projectedBlock, true);
                    }

                    m_clipboard.HasPreviewBBox = true;
                }
            }
            else
            {
                m_hiddenBlock = null;
                if (m_clipboard.PreviewGrids.Count == 0)
                {
                    return;
                }

                m_remainingBlocks = ProjectedGrid.CubeBlocks.Count;

                ProjectedGrid.Render.Transparency = 0f;

                m_buildableBlocksCount = 0;

                m_visibleBlocks.Clear();
                m_buildableBlocks.Clear();
                m_hiddenBlocks.Clear();

                ProfilerShort.Begin("Update cube visibility");
                foreach (var projectedBlock in ProjectedGrid.CubeBlocks)
                {
                    Vector3  worldPosition = ProjectedGrid.GridIntegerToWorld(projectedBlock.Position);
                    Vector3I realPosition  = CubeGrid.WorldToGridInteger(worldPosition);
                    var      realBlock     = CubeGrid.GetCubeBlock(realPosition);
                    if (realBlock != null && projectedBlock.BlockDefinition.Id == realBlock.BlockDefinition.Id)
                    {
                        m_hiddenBlocks.Add(projectedBlock);
                        m_remainingBlocks--;
                    }
                    else
                    {
                        bool canBuild = CanBuild(projectedBlock);
                        if (canBuild)
                        {
                            m_buildableBlocks.Add(projectedBlock);
                            m_buildableBlocksCount++;
                        }
                        else
                        {
                            if (m_showOnlyBuildable)
                            {
                                m_hiddenBlocks.Add(projectedBlock);
                            }
                            else
                            {
                                m_visibleBlocks.Add(projectedBlock);
                            }
                        }
                    }
                }

                foreach (var block in m_visibleBlocks)
                {
                    ShowCube(block, false);
                }
                foreach (var block in m_buildableBlocks)
                {
                    ShowCube(block, true);
                }
                foreach (var block in m_hiddenBlocks)
                {
                    HideCube(block);
                }
                ProfilerShort.End();


                if (m_remainingBlocks == 0 && !m_keepProjection)
                {
                    RemoveProjection(m_keepProjection);
                }
                else
                {
                    UpdateEmissivity();
                }

                m_statsDirty = true;
                if (m_shouldUpdateTexts)
                {
                    UpdateText();
                    m_shouldUpdateTexts = false;
                }

                m_clipboard.HasPreviewBBox = false;
            }
        }