private void QueryTrigger() { m_queryResult.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref m_triggerAABB, m_queryResult); for (int i = m_queryResult.Count - 1; i >= 0; i--) { var e = m_queryResult[i]; if (e.Physics == null || e.Physics.IsStatic) { m_queryResult.RemoveAtFast(i); continue; } if (e is MyFloatingObject || e is MyDebrisBase) { m_queryResult.RemoveAtFast(i); continue; } if (e == Entity.GetTopMostParent()) { m_queryResult.RemoveAtFast(i); continue; } //if (e.Physics.RigidBody != null && e.Physics.RigidBody.IsActive) // activeCounter++; //e.Physics.RigidBody.Activated += RBActivated; //e.Physics.RigidBody.Deactivated += RBDeactivated; } }
private List <MyEntity> EntitiesInLargeAABB(BoundingBoxD start, BoundingBoxD end) { Vector3D[] pathPoints = new Vector3D[4]; pathPoints[0] = start.Min; pathPoints[1] = start.Max; pathPoints[2] = end.Min; pathPoints[3] = end.Max; BoundingBoxD PathAABB = BoundingBoxD.CreateFromPoints(pathPoints); //m_logger.debugLog("Path AABB = " + PathAABB, "EntitiesInLargeAABB()"); m_offenders.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref PathAABB, m_offenders); m_offRemove.Clear(); for (int i = 0; i < m_offenders.Count; i++) { if (!collect_Entity(m_grid, m_offenders[i]) || (m_ignoreEntity != null && m_ignoreEntity == m_offenders[i])) { //m_logger.debugLog("discarding: " + m_offenders[i].getBestName(), "EntitiesInLargeAABB()"); m_offRemove.Add(m_offenders[i]); } } for (int i = 0; i < m_offRemove.Count; i++) { m_offenders.Remove(m_offRemove[i]); } return(m_offenders); }
public override void UpdateAfterSimulation() { if (Tick % 5 == 0) { if (Camera == null) { return; } rainImpactEntities.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref frustumBBox, rainImpactEntities); //MyAPIGateway.Parallel.Start(CalculateLines); CalculateLines(); } if (Tick % 60 == 0 && closestPlanet != null) { cameraDistanceFromSurface = closestPlanet.GetClosestSurfacePointGlobal(Camera.Position); cameraAltitude = (Camera.Position - cameraDistanceFromSurface).Length(); } if (Tick % 301 == 0) { closestPlanet = MyGamePruningStructure.GetClosestPlanet(Camera.Position); if (closestPlanet != null) { planetCentre = closestPlanet.PositionComp.WorldAABB.Center; } } lines.Clear(); }
public override IMyReplicable GetDependency() { if (m_physicsSync == null || Grid.IsStatic) { return(null); } MyCubeGrid master = MyGridPhysicsStateGroup.GetMasterGrid(Grid); if (master != Grid) { return(MyExternalReplicable.FindByObject(master)); } BoundingBoxD box = Grid.PositionComp.WorldAABB; var group = MyCubeGridGroups.Static.PhysicalDynamic.GetGroup(Grid); if (group != null) { foreach (var node in group.Nodes) { box.Include(node.NodeData.PositionComp.WorldAABB); } } if (m_foundEntities == null) { m_foundEntities = new List <MyEntity>(); } m_foundEntities.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, m_foundEntities); float maxRadius = 0; MyCubeGrid biggestGrid = null; foreach (var entity in m_foundEntities) { MyCubeGrid grid = entity as MyCubeGrid; if (grid != null) { var rad = grid.PositionComp.LocalVolume.Radius; if (rad > maxRadius || (rad == maxRadius && (biggestGrid == null || grid.EntityId > biggestGrid.EntityId))) { maxRadius = rad; biggestGrid = grid; } } } if (biggestGrid != null && biggestGrid != Grid) { return(MyExternalReplicable.FindByObject(biggestGrid)); } return(null); }
protected virtual void UpdateInternal() { if (this.DoQuery) { this.m_queryResult.Clear(); TriggerType triggerType = this.m_triggerType; if (triggerType == TriggerType.AABB) { MyGamePruningStructure.GetTopMostEntitiesInBox(ref this.m_AABB, this.m_queryResult, MyEntityQueryType.Both); } else { if (triggerType != TriggerType.Sphere) { throw new ArgumentOutOfRangeException(); } MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref this.m_boundingSphere, this.m_queryResult, MyEntityQueryType.Both); } int index = 0; while (index < this.m_queryResult.Count) { MyEntity entity = this.m_queryResult[index]; if (!this.QueryEvaluator(entity)) { this.m_queryResult.RemoveAtFast <MyEntity>(index); continue; } triggerType = this.m_triggerType; if (triggerType == TriggerType.AABB) { if (!this.m_AABB.Intersects(this.m_queryResult[index].PositionComp.WorldAABB)) { this.m_queryResult.RemoveAtFast <MyEntity>(index); continue; } index++; continue; } if (triggerType != TriggerType.Sphere) { index++; continue; } if (!this.m_boundingSphere.Intersects(this.m_queryResult[index].PositionComp.WorldAABB)) { this.m_queryResult.RemoveAtFast <MyEntity>(index); continue; } index++; } } }
// For backwards compatbility we store areas that need to be cleared public void InitClearAreasManagement() { m_obstructorsPerSector = new Dictionary <long, List <MyOrientedBoundingBoxD> >(); var interestArea = Planet.PositionComp.WorldAABB; List <MyEntity> entities = new List <MyEntity>(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref interestArea, entities); foreach (var entity in entities) { RasterSectorsForCollision(entity); } CollisionCheckEnabled = true; }
private static bool Conflicts(MyObjectBuilder_CubeGrid grid) { // Credits for this to KSH GitHub. var gridSize = MyDefinitionManager.Static.GetCubeSize(grid.GridSizeEnum); var localBb = new BoundingBox(Vector3.MaxValue, Vector3.MinValue); foreach (var block in grid.CubeBlocks) { MyCubeBlockDefinition definition; if (!MyDefinitionManager.Static.TryGetCubeBlockDefinition(block.GetId(), out definition)) { continue; } MyBlockOrientation ori = block.BlockOrientation; var blockSize = Vector3.TransformNormal(new Vector3(definition.Size) * gridSize, ori); blockSize = Vector3.Abs(blockSize); var minCorner = new Vector3(block.Min) * gridSize - new Vector3(gridSize / 2); var maxCorner = minCorner + blockSize; localBb.Include(minCorner); localBb.Include(maxCorner); } var worldAABB = ((BoundingBoxD)localBb).TransformFast(grid.PositionAndOrientation?.GetMatrix() ?? MatrixD.Identity); var list = m_entityListPool.Get(); list.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref worldAABB, list); foreach (var k in list) { var g = k as IMyCubeGrid; var voxel = (k as IMyVoxelBase)?.PositionComp; if (g != null && g.WorldAABB.Intersects(worldAABB)) { return(true); } if (voxel != null && voxel.WorldVolume.Intersects(worldAABB)) { return(true); } } list.Clear(); return(false); }
public void UpdateAttachedGrids() { AttachedGrids.Clear(); var box = Entity.WorldAABB; var entities = new List <MyEntity>(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, entities, MyEntityQueryType.Static); foreach (var entity in entities.Where(e => e is IMyCubeGrid)) { var gridModel = Tree.Grids.FirstOrDefault(g => g.Entity.EntityId == entity.EntityId); if (gridModel == null) { gridModel = new GridViewModel((MyCubeGrid)entity, Tree); Tree.Grids.Add(gridModel); } AttachedGrids.Add(gridModel); } }
public void DoWork(WorkData workData = null) { if (!_ref.TryGetTarget(out MyCubeGrid ent)) { return; } BalanceTick(ent); var aabb = ent.PositionComp.WorldAABB.Inflate(NextQueryDistance); _entityListPool.AllocateOrCreate(out var list); if (list == null) { list = new List <MyEntity>(); } try { list.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref aabb, list, MyEntityQueryType.Static); var dt = (DateTime.Now - LastNearbyUpdate).TotalSeconds; aabb = aabb.Inflate(Math.Min(dt * 30, NextQueryDistance)); MyGamePruningStructure.GetTopMostEntitiesInBox(ref aabb, list, MyEntityQueryType.Dynamic); using (Lock.WriteUsing()) { foreach (var k in NearbyEntities) { k.Free(); } NearbyEntities.Clear(); foreach (var e in list) { NearbyEntities.Add(GCHandle.Alloc(e, GCHandleType.Weak)); } } } finally { _entityListPool.Deallocate(list); } LastNearbyUpdate = DateTime.Now; }
private Vector3D?FindSuitableJumpLocation(Vector3D desiredLocation) { BoundingBoxD shipBBox = GetAggregateBBox(); // 1 Km distante to other objects to prevent spawning in bases shipBBox.Inflate(1000f); BoundingBoxD regionBBox = shipBBox.GetInflated(shipBBox.HalfExtents * 10); regionBBox.Translate(desiredLocation - regionBBox.Center); MyProceduralWorldGenerator.Static.OverlapAllPlanetSeedsInSphere(new BoundingSphereD(regionBBox.Center, regionBBox.HalfExtents.AbsMax()), m_objectsInRange); Vector3D currentSearchPosition = desiredLocation; foreach (var planet in m_objectsInRange) { if (planet.BoundingVolume.Contains(currentSearchPosition) != ContainmentType.Disjoint) { Vector3D v = currentSearchPosition - planet.BoundingVolume.Center; v.Normalize(); v *= planet.BoundingVolume.HalfExtents * 1.5; currentSearchPosition = planet.BoundingVolume.Center + v; break; } } m_objectsInRange.Clear(); MyProceduralWorldGenerator.Static.OverlapAllAsteroidSeedsInSphere(new BoundingSphereD(regionBBox.Center, regionBBox.HalfExtents.AbsMax()), m_objectsInRange); foreach (var asteroid in m_objectsInRange) { m_obstaclesInRange.Add(asteroid.BoundingVolume); } m_objectsInRange.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref regionBBox, m_entitiesInRange); // Inflate the obstacles so we only need to check the center of the ship for collisions foreach (var entity in m_entitiesInRange) { if (!(entity is MyPlanet)) { m_obstaclesInRange.Add(entity.PositionComp.WorldAABB.GetInflated(shipBBox.HalfExtents)); } } int maxStepCount = 10; int stepCount = 0; // When we collide with an obsticle, we add it here BoundingBoxD?aggregateCollidedObstacles = null; bool obstructed = false; bool found = false; while (stepCount < maxStepCount) { stepCount++; obstructed = false; foreach (var obstacle in m_obstaclesInRange) { var contains = obstacle.Contains(currentSearchPosition); if (contains == ContainmentType.Contains || contains == ContainmentType.Intersects) { if (!aggregateCollidedObstacles.HasValue) { aggregateCollidedObstacles = obstacle; } aggregateCollidedObstacles = aggregateCollidedObstacles.Value.Include(obstacle); aggregateCollidedObstacles = aggregateCollidedObstacles.Value.Inflate(1.0); currentSearchPosition = ClosestPointOnBounds(aggregateCollidedObstacles.Value, currentSearchPosition); obstructed = true; break; } } if (!obstructed) { // No obstacle found, return current search position found = true; break; } } m_obstaclesInRange.Clear(); m_entitiesInRange.Clear(); m_objectsInRange.Clear(); if (found) { return(currentSearchPosition); } else { return(null); } }
/// <summary> /// Override this function to set custom update behaviour. /// Call base at first because it queries objects if DoQuery is set. /// </summary> protected virtual void UpdateInternal() { if (DoQuery) { m_queryResult.Clear(); switch (m_triggerType) { case TriggerType.AABB: MyGamePruningStructure.GetTopMostEntitiesInBox(ref m_AABB, m_queryResult); break; case TriggerType.Sphere: MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref m_boundingSphere, m_queryResult); break; default: throw new ArgumentOutOfRangeException(); } for (int index = 0; index < m_queryResult.Count;) { var result = m_queryResult[index]; if (!QueryEvaluator(result)) { m_queryResult.RemoveAtFast(index); } else { switch (m_triggerType) { case TriggerType.AABB: if (!m_AABB.Intersects(m_queryResult[index].PositionComp.WorldAABB)) { m_queryResult.RemoveAtFast(index); } else { index++; } break; case TriggerType.Sphere: if (!m_boundingSphere.Intersects(m_queryResult[index].PositionComp.WorldAABB)) { m_queryResult.RemoveAtFast(index); } else { index++; } break; default: index++; break; } } } } }
internal void MonitorRefreshTasks(int x, ref List <MyEntity> monitorList, bool reInforce, ref bool newSub) { var s = _workData.ShieldList[x]; if (reInforce) { var newMode = !s.ReInforcedShield; if (!newMode) { return; } HashSet <MyCubeGrid> subs; lock (s.SubLock) { subs = SetMyCubeGridPool.Get(); subs.UnionWith(s.ShieldComp.SubGrids); } foreach (var sub in subs) { if (!_globalEntTmp.ContainsKey(sub)) { newSub = true; } _entRefreshQueue.Enqueue(sub); if (!s.WasPaused) { _globalEntTmp[sub] = _workData.Tick; } } subs.Clear(); SetMyCubeGridPool.Return(subs); s.ReInforcedShield = true; s.TicksWithNoActivity = 0; s.LastWokenTick = _workData.Tick; s.Asleep = false; } else { var newMode = false; if (s.ReInforcedShield) { HashSet <MyCubeGrid> subs; lock (s.SubLock) { subs = SetMyCubeGridPool.Get(); subs.UnionWith(s.ShieldComp.SubGrids); } foreach (var sub in subs) { _entRefreshQueue.Enqueue(sub); if (!s.WasPaused) { _globalEntTmp[sub] = _workData.Tick; } } subs.Clear(); SetMyCubeGridPool.Return(subs); //if (Enforced.Debug >= 2) Log.Line($"found Reinforce"); s.ReInforcedShield = false; s.TicksWithNoActivity = 0; s.LastWokenTick = _workData.Tick; s.Asleep = false; newMode = true; } if (!newMode) { var foundNewEnt = false; var disableVoxels = Enforced.DisableVoxelSupport == 1 || s.ShieldComp.Modulator == null || s.ShieldComp.Modulator.ModSet.Settings.ModulateVoxels; MyGamePruningStructure.GetTopmostEntitiesInBox(ref s.WebBox, monitorList); if (!s.WasPaused) { foreach (var ent in monitorList) { var voxel = ent as MyVoxelBase; if (ent == null || ent.MarkedForClose || (voxel == null && (ent.Physics == null || ent.Physics.IsPhantom || ent.DefinitionId == null)) || (!s.GridIsMobile && voxel != null) || (disableVoxels && voxel != null) || (voxel != null && voxel != voxel.RootVoxel)) { continue; } if (ent is IMyFloatingObject || ent is IMyEngineerToolBase || !s.WebSphere.Intersects(ent.PositionComp.WorldVolume)) { continue; } if (CustomCollision.NewObbPointsInShield(ent, s.DetectMatrixOutsideInv) > 0) { if (!_globalEntTmp.ContainsKey(ent)) { foundNewEnt = true; s.Asleep = false; } _globalEntTmp[ent] = _workData.Tick; } s.NewEntByShield = foundNewEnt; } } else { s.NewEntByShield = false; } if (!s.NewEntByShield) { var foundPlayer = false; foreach (var player in Players.Values) { var character = player.Character; if (character == null) { continue; } if (Vector3D.DistanceSquared(character.PositionComp.WorldMatrixRef.Translation, s.DetectionCenter) < SyncDistSqr) { foundPlayer = true; break; } } s.PlayerByShield = foundPlayer; } if (!s.PlayerByShield) { s.MoverByShield = false; var newMover = false; var moverList = ListMyEntityPool.Get(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref s.ShieldBox3K, moverList, MyEntityQueryType.Dynamic); for (int i = 0; i < moverList.Count; i++) { var ent = moverList[i]; var meteor = ent as IMyMeteor; if (meteor != null) { if (CustomCollision.FutureIntersect(s, ent, s.DetectMatrixOutside, s.DetectMatrixOutsideInv)) { if (Enforced.Debug >= 2) { Log.Line($"[Future Intersecting Meteor] distance from shieldCenter: {Vector3D.Distance(s.DetectionCenter, ent.WorldMatrix.Translation)} - waking:"); } newMover = true; break; } continue; } if (!(ent.Physics == null || ent.Physics.IsPhantom || ent is MyCubeGrid || ent is IMyCharacter)) { continue; } var entPos = ent.PositionComp.WorldAABB.Center; var keyFound = s.EntsByMe.ContainsKey(ent); if (keyFound) { if (!s.EntsByMe[ent].Pos.Equals(entPos, 1e-3)) { MoverInfo moverInfo; s.EntsByMe.TryRemove(ent, out moverInfo); s.EntsByMe.TryAdd(ent, new MoverInfo(entPos, _workData.Tick)); if (moverInfo.CreationTick == _workData.Tick - 1) { if (Enforced.Debug >= 3 && s.WasPaused) { Log.Line($"[Moved] Ent:{ent.DebugName} - howMuch:{Vector3D.Distance(entPos, s.EntsByMe[ent].Pos)} - ShieldId [{s.Shield.EntityId}]"); } newMover = true; } break; } } else { if (Enforced.Debug >= 3) { Log.Line($"[NewMover] Ent:{ent.DebugName} - ShieldId [{s.Shield.EntityId}]"); } s.EntsByMe.TryAdd(ent, new MoverInfo(entPos, _workData.Tick)); } } moverList.Clear(); ListMyEntityPool.Return(moverList); s.MoverByShield = newMover; } if (_workData.Tick < s.LastWokenTick + 400) { s.Asleep = false; return; } } if (s.EntCleanUpTime) { s.EntCleanUpTime = false; if (!s.EntsByMe.IsEmpty) { var entsByMeTmp = new List <KeyValuePair <MyEntity, MoverInfo> >(); entsByMeTmp.AddRange(s.EntsByMe.Where(info => !info.Key.InScene || _workData.Tick - info.Value.CreationTick > EntMaxTickAge)); for (int i = 0; i < entsByMeTmp.Count; i++) { MoverInfo mInfo; s.EntsByMe.TryRemove(entsByMeTmp[i].Key, out mInfo); } } } } }
public void WebEntities() { PruneList.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref WebBox, PruneList); if (Missiles.Count > 0) { var missileBox = WebBox; foreach (var missile in Missiles) { if (missile.InScene && !missile.MarkedForClose && missileBox.Intersects(missile.PositionComp.WorldAABB)) { PruneList.Add(missile); } } } var shieldsStartIndex = PruneList.Count; foreach (var eShield in EnemyShields) { PruneList.Add(eShield); } var disableVoxels = Session.Enforced.DisableVoxelSupport == 1 || ShieldComp.Modulator == null || ShieldComp.Modulator.ModSet.Settings.ModulateVoxels; var voxelFound = false; var shieldFound = false; var entChanged = false; var iMoving = ShieldComp.GridIsMoving; var tick = Session.Instance.Tick; _enablePhysics = false; for (int i = 0; i < PruneList.Count; i++) { var ent = PruneList[i]; var entPhysics = ent.Physics; if (i < shieldsStartIndex) { var voxel = ent as MyVoxelBase; if (ent == null || (voxel == null && (entPhysics == null || entPhysics.IsPhantom || ent.DefinitionId == null)) || (voxel != null && (!iMoving || !GridIsMobile || disableVoxels || voxel != voxel.RootVoxel))) { continue; } bool quickReject; if (_isServer) { quickReject = ent is IMyEngineerToolBase || IgnoreCache.Contains(ent) || EnemyShields.Contains(ent) || FriendlyMissileCache.Contains(ent) || AuthenticatedCache.Contains(ent); } else { quickReject = (!(ent is MyCubeGrid) && voxel == null && !(ent is IMyCharacter)) || IgnoreCache.Contains(ent) || EnemyShields.Contains(ent) || AuthenticatedCache.Contains(ent); } var floater = ent as IMyFloatingObject; if (quickReject || floater != null && (!iMoving && Vector3.IsZero(entPhysics.LinearVelocity, 1e-2f)) || !WebSphere.Intersects(ent.PositionComp.WorldVolume)) { continue; } if (voxel != null) { if (VoxelsToIntersect.ContainsKey(voxel)) { VoxelsToIntersect[voxel]++; } else { VoxelsToIntersect[voxel] = 1; } voxelFound = true; entChanged = true; _enablePhysics = true; continue; } } Ent relation; ProtectCache protectedEnt; EntIntersectInfo entInfo = null; ProtectedEntCache.TryGetValue(ent, out protectedEnt); var refreshInfo = false; if (protectedEnt == null) { WebEnts.TryGetValue(ent, out entInfo); if (entInfo != null) { var last = entInfo.LastTick; var refresh = entInfo.RefreshTick; var refreshTick = tick - last > 180 || (tick - last == 180 && tick - refresh >= 3600) || (tick - last == 1 && tick - refresh >= 60); refreshInfo = refreshTick; if (refreshInfo || entInfo.RefreshNow) { entInfo.RefreshTick = tick; entInfo.Relation = EntType(ent); } relation = entInfo.Relation; entInfo.LastTick = tick; } else { relation = EntType(ent); } } else { var last = protectedEnt.LastTick; var refresh = protectedEnt.RefreshTick; var refreshTick = tick - last > 180 || (tick - last == 180 && tick - refresh >= 3600) || (tick - last == 1 && tick - refresh >= 60); refreshInfo = refreshTick; if (refreshInfo) { protectedEnt.RefreshTick = tick; protectedEnt.PreviousRelation = protectedEnt.Relation; protectedEnt.Relation = EntType(ent); } relation = protectedEnt.Relation; protectedEnt.LastTick = tick; } switch (relation) { case Ent.Authenticated: continue; case Ent.Ignore: case Ent.Friendly: case Ent.Protected: if (relation == Ent.Protected) { if (protectedEnt == null) { ProtectedEntCache[ent] = new ProtectCache(tick, tick, tick, relation, relation); } MyProtectors protectors; Session.Instance.GlobalProtect.TryGetValue(ent, out protectors); if (protectors == null) { protectors = Session.Instance.GlobalProtect[ent] = Session.ProtSets.Get(); protectors.Init(LogicSlot, tick); } if (protectors.Shields.Contains(this)) { continue; } protectors.Shields.Add(this); protectors.Shields.ApplyAdditions(); continue; } IgnoreCache.Add(ent); continue; } if (relation == Ent.Shielded) { shieldFound = true; } try { if (entInfo != null) { var interestingEnts = relation == Ent.Floater || relation == Ent.EnemyGrid || relation == Ent.NobodyGrid || relation == Ent.Shielded; if (entPhysics != null && entPhysics.IsMoving) { entChanged = true; } else if (entInfo.Touched || (refreshInfo && interestingEnts && !ent.PositionComp.LocalAABB.Equals(entInfo.Box))) { entInfo.RefreshTick = tick; entInfo.Box = ent.PositionComp.LocalAABB; entChanged = true; } _enablePhysics = true; if (refreshInfo) { if ((relation == Ent.EnemyGrid || relation == Ent.NobodyGrid) && entInfo.CacheBlockList.Count != (ent as MyCubeGrid).BlocksCount) { entInfo.RefreshNow = true; } } } else { if (relation == Ent.Other) { var entPast = -Vector3D.Normalize(entPhysics.LinearVelocity) * 6; var entTestLoc = ent.PositionComp.WorldVolume.Center + entPast; var centerStep = -Vector3D.Normalize(entTestLoc - DetectionCenter) * 2f; var counterDrift = centerStep + entTestLoc; if (CustomCollision.PointInShield(counterDrift, DetectMatrixOutsideInv)) { FriendlyMissileCache.Add(ent); continue; } } entChanged = true; _enablePhysics = true; ProtectedEntCache.Remove(ent); WebEnts.TryAdd(ent, new EntIntersectInfo(false, ent.PositionComp.LocalAABB, tick, tick, tick, relation)); } } catch (Exception ex) { Log.Line($"Exception in WebEntities entInfo: {ex}"); } } if (!_enablePhysics) { return; } ShieldMatrix = ShieldEnt.PositionComp.WorldMatrix; if ((_needPhysics && shieldFound) || !ShieldMatrix.EqualsFast(ref OldShieldMatrix)) { OldShieldMatrix = ShieldMatrix; if (shieldFound) { _needPhysics = false; Icosphere.ReturnPhysicsVerts(DetectMatrixOutside, ShieldComp.PhysicsOutside); } else { _needPhysics = true; } if (voxelFound) { Icosphere.ReturnPhysicsVerts(DetectMatrixOutside, ShieldComp.PhysicsOutsideLow); } } if (iMoving || entChanged) { Asleep = false; LastWokenTick = tick; Session.Instance.WebWrapper.Enqueue(this); Session.Instance.WebWrapperOn = true; } }
private void UpdateOxygen() { MyOxygenRoom room; List <MyEntity> result = new List <MyEntity>(); BoundingBoxD worldAABB = base.Character.PositionComp.WorldAABB; bool enableOxygen = MySession.Static.Settings.EnableOxygen; bool noOxygenDamage = MySession.Static.Settings.EnableOxygen; bool isInEnvironment = true; bool flag4 = false; if (!Sync.IsServer) { goto TR_000A; } else { base.Character.EnvironmentOxygenLevelSync.Value = MyOxygenProviderSystem.GetOxygenInPoint(base.Character.PositionComp.GetPosition()); base.Character.OxygenLevelAtCharacterLocation.Value = base.Character.EnvironmentOxygenLevel; room = null; if (!MySession.Static.Settings.EnableOxygen) { goto TR_000C; } else { GasData data; if (this.TryGetGasData(OxygenId, out data)) { float num = (MySession.Static.GameplayFrameCounter - data.LastOutputTime) * 0.01666667f; flag4 = (this.CharacterGasSink.CurrentInputByType(OxygenId) * num) > this.Definition.OxygenConsumption; if (flag4) { noOxygenDamage = false; enableOxygen = false; } } MyCockpit parent = base.Character.Parent as MyCockpit; bool flag5 = false; if ((parent != null) && parent.BlockDefinition.IsPressurized) { if ((!this.HelmetEnabled && (MySession.Static.SurvivalMode && !flag4)) && (parent.OxygenAmount >= (this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier))) { parent.OxygenAmount -= this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier; noOxygenDamage = false; enableOxygen = false; } base.Character.EnvironmentOxygenLevelSync.Value = parent.OxygenFillLevel; isInEnvironment = false; flag5 = true; } if (!flag5 || (MyFakes.ENABLE_NEW_SOUNDS && MySession.Static.Settings.RealisticSound)) { base.Character.OxygenSourceGridEntityId.Value = 0L; Vector3D center = base.Character.PositionComp.WorldAABB.Center; MyGamePruningStructure.GetTopMostEntitiesInBox(ref worldAABB, result, MyEntityQueryType.Both); using (List <MyEntity> .Enumerator enumerator = result.GetEnumerator()) { while (true) { while (true) { if (enumerator.MoveNext()) { MyCubeGrid current = enumerator.Current as MyCubeGrid; if (current == null) { continue; } if (current.GridSystems.GasSystem == null) { continue; } MyOxygenBlock safeOxygenBlock = current.GridSystems.GasSystem.GetSafeOxygenBlock(center); if (safeOxygenBlock == null) { continue; } if (safeOxygenBlock.Room == null) { continue; } room = safeOxygenBlock.Room; if ((room.OxygenLevel(current.GridSize) > this.Definition.PressureLevelForLowDamage) && !this.HelmetEnabled) { enableOxygen = false; } if (!room.IsAirtight) { float environmentOxygen = room.EnvironmentOxygen; base.Character.OxygenLevelAtCharacterLocation.Value = environmentOxygen; if (flag5) { break; } base.Character.EnvironmentOxygenLevelSync.Value = environmentOxygen; if (this.HelmetEnabled) { break; } if (base.Character.EnvironmentOxygenLevelSync.Value <= (this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier)) { break; } noOxygenDamage = false; } else { float num2 = room.OxygenLevel(current.GridSize); if (!flag5) { base.Character.EnvironmentOxygenLevelSync.Value = num2; } base.Character.OxygenLevelAtCharacterLocation.Value = num2; base.Character.OxygenSourceGridEntityId.Value = current.EntityId; if (room.OxygenAmount <= (this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier)) { break; } if (!this.HelmetEnabled) { noOxygenDamage = false; safeOxygenBlock.PreviousOxygenAmount = safeOxygenBlock.OxygenAmount() - (this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier); safeOxygenBlock.OxygenChangeTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; if (!flag4) { room.OxygenAmount -= this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier; } } } goto TR_000D; } else { goto TR_000D; } break; } isInEnvironment = false; } } } } } goto TR_000D; TR_000A: this.CharacterGasSink.Update(); if (Sync.IsServer && !MySession.Static.CreativeMode) { this.RefillSuitGassesFromBottles(); if (MySession.Static.Settings.EnableOxygen) { this.UpdateSuitOxygen(enableOxygen, noOxygenDamage, isInEnvironment); } foreach (GasData data2 in this.m_storedGases) { base.Character.UpdateStoredGas(data2.Id, data2.FillLevel); } } return; TR_000C: this.UpdateGassesFillLevelsAndAmounts(room); goto TR_000A; TR_000D: this.m_oldSuitOxygenLevel = this.SuitOxygenLevel; goto TR_000C; }
internal void MonitorRefreshTasks(int x, ref List <MyEntity> monitorList, bool reInforce, ref bool newSub) { var s = _workData.ShieldList[x]; if (reInforce) { HashSet <MyCubeGrid> subs; lock (s.GetCubesLock) subs = new HashSet <MyCubeGrid>(s.ShieldComp.GetSubGrids); var newMode = !s.ReInforcedShield; if (!newMode) { return; } foreach (var sub in subs) { //if (Enforced.Debug >= 2) Log.Line("Server queuing entFresh for reinforced shield"); if (!_globalEntTmp.ContainsKey(sub)) { newSub = true; } _entRefreshQueue.Enqueue(sub); if (!s.WasPaused) { _globalEntTmp[sub] = _workData.Tick; } } s.ReInforcedShield = true; s.TicksWithNoActivity = 0; s.LastWokenTick = _workData.Tick; s.Asleep = false; } else { var newMode = false; if (s.ReInforcedShield) { HashSet <MyCubeGrid> subs; lock (s.GetCubesLock) subs = new HashSet <MyCubeGrid>(s.ShieldComp.GetSubGrids); foreach (var sub in subs) { _entRefreshQueue.Enqueue(sub); if (!s.WasPaused) { _globalEntTmp[sub] = _workData.Tick; } } //if (Enforced.Debug >= 2) Log.Line($"found Reinforce"); s.ReInforcedShield = false; s.TicksWithNoActivity = 0; s.LastWokenTick = _workData.Tick; s.Asleep = false; newMode = true; } if (!newMode) { // var testMat = s.DetectMatrixOutside; // var shape1 = new Sphere(Vector3D.Zero, 1.0).Transformed(testMat); var foundNewEnt = false; var disableVoxels = Enforced.DisableVoxelSupport == 1 || s.ShieldComp.Modulator == null || s.ShieldComp.Modulator.ModSet.Settings.ModulateVoxels; MyGamePruningStructure.GetTopmostEntitiesInBox(ref s.WebBox, monitorList); foreach (var ent in monitorList) { var voxel = ent as MyVoxelBase; if (ent == null || ent.MarkedForClose || (voxel == null && (ent.Physics == null || ent.DefinitionId == null)) || (!s.GridIsMobile && voxel != null) || (disableVoxels && voxel != null) || (voxel != null && voxel != voxel.RootVoxel)) { continue; } if (ent is IMyFloatingObject || ent is IMyEngineerToolBase || !s.WebSphere.Intersects(ent.PositionComp.WorldVolume)) { continue; } // var halfExtents = ent.PositionComp.LocalAABB.HalfExtents; // if (halfExtents.X < 1) halfExtents.X = 10; // if (halfExtents.Y < 1) halfExtents.Y = 10; // if (halfExtents.Z < 1) halfExtents.Z = 10; // var shape2 = new Box(-halfExtents, halfExtents).Transformed(ent.WorldMatrix); // var test = Gjk.Intersects(ref shape1, ref shape2); // Log.Line($"{ent.DebugName} - {test}"); if (CustomCollision.NewObbPointsInShield(ent, s.DetectMatrixOutsideInv) > 0) { if (!s.WasPaused && !_globalEntTmp.ContainsKey(ent)) { foundNewEnt = true; s.Asleep = false; //if (Enforced.Debug >= 2) Log.Line($"New entity"); } if (!s.WasPaused) { _globalEntTmp[ent] = _workData.Tick; } } s.NewEntByShield = foundNewEnt; } if (!s.NewEntByShield) { var foundPlayer = false; foreach (var player in Players.Values) { var character = player.Character; if (character == null) { continue; } if (Vector3D.DistanceSquared(character.PositionComp.WorldMatrix.Translation, s.DetectionCenter) < SyncDistSqr) { foundPlayer = true; break; } } s.PlayerByShield = foundPlayer; } if (!s.PlayerByShield) { s.MoverByShield = false; var newMover = false; var moverList = new List <MyEntity>(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref s.ShieldBox3K, moverList, MyEntityQueryType.Dynamic); for (int i = 0; i < moverList.Count; i++) { var ent = moverList[i]; if (!(ent.Physics == null || ent is MyCubeGrid || ent is IMyCharacter || ent is IMyMeteor)) { continue; } var entPos = ent.PositionComp.WorldMatrix.Translation; var keyFound = s.EntsByMe.ContainsKey(ent); if (keyFound) { if (!s.EntsByMe[ent].Pos.Equals(entPos, 1e-3)) { //if (Enforced.Debug >= 2) Log.Line($"[Moved] Ent:{ent.DebugName}"); MoverInfo moverInfo; s.EntsByMe.TryRemove(ent, out moverInfo); s.EntsByMe.TryAdd(ent, new MoverInfo(entPos, _workData.Tick)); newMover = true; break; } } else { s.EntsByMe.TryAdd(ent, new MoverInfo(entPos, _workData.Tick)); } } s.MoverByShield = newMover; } if (_workData.Tick < s.LastWokenTick + 400) { s.Asleep = false; return; } } if (s.EntCleanUpTime) { s.EntCleanUpTime = false; if (!s.EntsByMe.IsEmpty) { var entsByMeTmp = new List <KeyValuePair <MyEntity, MoverInfo> >(); entsByMeTmp.AddRange(s.EntsByMe.Where(info => !info.Key.InScene || _workData.Tick - info.Value.CreationTick > EntMaxTickAge)); for (int i = 0; i < entsByMeTmp.Count; i++) { MoverInfo mInfo; s.EntsByMe.TryRemove(entsByMeTmp[i].Key, out mInfo); } } } } }
private void UpdateOxygen() { // Try to find grids that might contain oxygen var entities = new List <MyEntity>(); var aabb = Character.PositionComp.WorldAABB; bool lowOxygenDamage = MySession.Static.Settings.EnableOxygen; bool noOxygenDamage = MySession.Static.Settings.EnableOxygen; bool isInEnvironment = true; bool oxygenReplenished = false; EnvironmentOxygenLevel = MyOxygenProviderSystem.GetOxygenInPoint(Character.PositionComp.GetPosition()); OxygenLevelAtCharacterLocation = EnvironmentOxygenLevel; if (Sync.IsServer) { // Check for possibility that we are replenishing oxygen if (MySession.Static.Settings.EnableOxygen) { GasData oxygenData; if (TryGetGasData(OxygenId, out oxygenData)) { float timeSinceLastUpdateSeconds = (MySession.Static.GameplayFrameCounter - oxygenData.LastOutputTime) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; oxygenReplenished = CharacterGasSink.CurrentInputByType(OxygenId) * timeSinceLastUpdateSeconds > Definition.OxygenConsumption; if (oxygenReplenished) { noOxygenDamage = false; lowOxygenDamage = false; } } } // Update Gases fill levels and capacity amounts foreach (GasData gasInfo in m_storedGases) { var timeSinceLastOutputSeconds = (MySession.Static.GameplayFrameCounter - gasInfo.LastOutputTime) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; var timeSinceLastInputSeconds = (MySession.Static.GameplayFrameCounter - gasInfo.LastInputTime) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; gasInfo.LastOutputTime = MySession.Static.GameplayFrameCounter; gasInfo.LastInputTime = MySession.Static.GameplayFrameCounter; float gasOutputAmount = CharacterGasSource.CurrentOutputByType(gasInfo.Id) * timeSinceLastOutputSeconds; float gasInputAmount = CharacterGasSink.CurrentInputByType(gasInfo.Id) * timeSinceLastInputSeconds; // Values that are not in distribution system yet and happend to inc/dec between updates float outTransfer = -MathHelper.Clamp(gasInfo.NextGasTransfer, float.NegativeInfinity, 0f); float inTransfer = MathHelper.Clamp(gasInfo.NextGasTransfer, 0f, float.PositiveInfinity); gasInfo.NextGasTransfer = 0f; TransferSuitGas(ref gasInfo.Id, gasInputAmount + inTransfer, gasOutputAmount + outTransfer); } } if (MySession.Static.Settings.EnableOxygen) { var cockpit = Character.Parent as MyCockpit; bool OxygenFromCockpit = false; if (cockpit != null && cockpit.BlockDefinition.IsPressurized) { if (Sync.IsServer && MySession.Static.SurvivalMode && !oxygenReplenished) { // Character is in pressurized room if (!HelmetEnabled) { if (cockpit.OxygenFillLevel > 0f) { if (cockpit.OxygenAmount >= Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier) { cockpit.OxygenAmount -= Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier; noOxygenDamage = false; lowOxygenDamage = false; } } } } EnvironmentOxygenLevel = cockpit.OxygenFillLevel; isInEnvironment = false; OxygenFromCockpit = true; } if (OxygenFromCockpit == false || (MyFakes.ENABLE_NEW_SOUNDS && MySession.Static.Settings.RealisticSound)) { OxygenSourceGrid = null; Vector3D pos = Character.GetHeadMatrix(true, true, false, true).Translation; MyGamePruningStructure.GetTopMostEntitiesInBox(ref aabb, entities); foreach (var entity in entities) { var grid = entity as MyCubeGrid; // Oxygen can be present on small grids as well because of mods if (grid != null && grid.GridSystems.GasSystem != null) { var oxygenBlock = grid.GridSystems.GasSystem.GetSafeOxygenBlock(pos); if (oxygenBlock.Room != null) { if (oxygenBlock.Room.OxygenLevel(grid.GridSize) > Definition.PressureLevelForLowDamage) { if (!HelmetEnabled) { lowOxygenDamage = false; } } if (oxygenBlock.Room.IsPressurized) { float oxygen = oxygenBlock.Room.OxygenLevel(grid.GridSize); if (!OxygenFromCockpit) { EnvironmentOxygenLevel = oxygen; } OxygenLevelAtCharacterLocation = oxygen; OxygenSourceGrid = grid; if (oxygenBlock.Room.OxygenAmount > Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier) { if (!HelmetEnabled) { noOxygenDamage = false; oxygenBlock.PreviousOxygenAmount = oxygenBlock.OxygenAmount() - Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier; oxygenBlock.OxygenChangeTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; if (!oxygenReplenished) { oxygenBlock.Room.OxygenAmount -= Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier; } } break; } } else { float oxygen = oxygenBlock.Room.EnvironmentOxygen; OxygenLevelAtCharacterLocation = oxygen; if (!OxygenFromCockpit) { EnvironmentOxygenLevel = oxygen; if (!HelmetEnabled && EnvironmentOxygenLevel > Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier) { noOxygenDamage = false; break; } } } isInEnvironment = false; } } } } if (MySession.Static.LocalCharacter == Character) { if (m_oldSuitOxygenLevel >= 0.25f && SuitOxygenLevel < 0.25f) { MyHud.Notifications.Add(m_lowOxygenNotification); } else if (m_oldSuitOxygenLevel >= 0.05f && SuitOxygenLevel < 0.05f) { MyHud.Notifications.Add(m_criticalOxygenNotification); } } m_oldSuitOxygenLevel = SuitOxygenLevel; } CharacterGasSink.Update(); // Cannot early exit before calculations because of UI if (!Sync.IsServer || MySession.Static.CreativeMode || !MySession.Static.Settings.EnableOxygen) { return; } foreach (var gasInfo in m_storedGases) { if (gasInfo.FillLevel < GAS_REFILL_RATION) // Get rid of the specific oxygen version of this { if (gasInfo.NextGasRefill == -1) { gasInfo.NextGasRefill = MySandboxGame.TotalGamePlayTimeInMilliseconds + m_gasRefillInterval * 1000; } if (MySandboxGame.TotalGamePlayTimeInMilliseconds < gasInfo.NextGasRefill) { continue; } gasInfo.NextGasRefill = -1; var items = Character.GetInventory().GetItems(); bool bottlesUsed = false; foreach (var item in items) { var gasContainer = item.Content as MyObjectBuilder_GasContainerObject; if (gasContainer != null) { if (gasContainer.GasLevel == 0f) { continue; } var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(gasContainer) as MyOxygenContainerDefinition; if (physicalItem.StoredGasId != gasInfo.Id) { continue; } float gasAmount = gasContainer.GasLevel * physicalItem.Capacity; float transferredAmount = Math.Min(gasAmount, (1f - gasInfo.FillLevel) * gasInfo.MaxCapacity); gasContainer.GasLevel = Math.Max((gasAmount - transferredAmount) / physicalItem.Capacity, 0f); if (gasContainer.GasLevel > 1f) { Debug.Fail("Incorrect value"); } Character.GetInventory().UpdateGasAmount(); bottlesUsed = true; TransferSuitGas(ref gasInfo.Id, transferredAmount, 0); if (gasInfo.FillLevel == 1f) { break; } } } if (bottlesUsed) { if (MySession.Static.LocalCharacter == Character) { ShowRefillFromBottleNotification(gasInfo.Id); } else { Character.SendRefillFromBottle(gasInfo.Id); } } var jetpack = Character.JetpackComp; if (jetpack != null && jetpack.TurnedOn && jetpack.FuelDefinition != null && jetpack.FuelDefinition.Id == gasInfo.Id && gasInfo.FillLevel <= 0 && (Character.ControllerInfo.Controller != null && MySession.Static.IsAdminModeEnabled(Character.ControllerInfo.Controller.Player.Id.SteamId) == false || (MySession.Static.LocalCharacter != Character && Sync.IsServer == false))) { jetpack.SwitchThrusts(); } } else { gasInfo.NextGasRefill = -1; } } // No oxygen or low oxygen found in room, try to get it from suit if (MySession.Static.Settings.EnableOxygen) { if (noOxygenDamage || lowOxygenDamage) { if (HelmetEnabled && SuitOxygenAmount > Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier) { noOxygenDamage = false; lowOxygenDamage = false; } if (isInEnvironment && !HelmetEnabled) { if (EnvironmentOxygenLevel > Definition.PressureLevelForLowDamage) { lowOxygenDamage = false; } if (EnvironmentOxygenLevel > 0f) { noOxygenDamage = false; } } } m_oldSuitOxygenLevel = SuitOxygenLevel; if (noOxygenDamage) { Character.DoDamage(Definition.DamageAmountAtZeroPressure, MyDamageType.LowPressure, true); } else if (lowOxygenDamage) { Character.DoDamage(1f, MyDamageType.Asphyxia, true); } } Character.UpdateOxygen(SuitOxygenAmount); foreach (var gasInfo in m_storedGases) { Character.UpdateStoredGas(gasInfo.Id, gasInfo.FillLevel); } }
public override void UpdateAfterSimulation10() { base.UpdateAfterSimulation10(); if (!Sync.IsServer || !IsWorking) { return; } if (!ResourceSink.IsPowered) { if (ResourceSink.IsPowerAvailable(MyResourceDistributorComponent.ElectricityId, BlockDefinition.RequiredPowerInput)) { float origInput = ResourceSink.RequiredInput; ResourceSink.SetRequiredInputByType(MyResourceDistributorComponent.ElectricityId, 0); ResourceSink.SetRequiredInputByType(MyResourceDistributorComponent.ElectricityId, origInput); } else { return; } } var rotation1 = Quaternion.CreateFromForwardUp(WorldMatrix.Forward, WorldMatrix.Up); var position1 = PositionComp.GetPosition() + Vector3D.Transform(PositionComp.LocalVolume.Center + (m_fieldMax.Value + m_fieldMin.Value) * 0.5f, rotation1); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Recreate Field"); if (m_recreateField) { m_recreateField = false; m_fieldShape.RemoveReference(); m_fieldShape = GetHkShape(); ResourceSink.Update(); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); var boundingBox = new BoundingBoxD(m_fieldMin.Value, m_fieldMax.Value).Translate(PositionComp.LocalVolume.Center).TransformFast(WorldMatrix.GetOrientation()).Translate(PositionComp.GetPosition()); m_potentialPenetrations.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref boundingBox, m_potentialPenetrations); m_potentialVoxelPenetrations.Clear(); MyGamePruningStructure.GetAllVoxelMapsInBox(ref boundingBox, m_potentialVoxelPenetrations);//disabled until heightmap queries are finished VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Sensor Physics"); LastDetectedEntity = null; bool empty = true; foreach (var entity in m_potentialPenetrations) { if (entity is MyVoxelBase) { //voxels are handled in different loop (becaose of planets) continue; } if (ShouldDetect(entity)) { Quaternion rotation2; Vector3 posDiff; HkShape? shape2; if (GetPropertiesFromEntity(entity, ref position1, out rotation2, out posDiff, out shape2)) { if (entity.GetPhysicsBody().HavokWorld.IsPenetratingShapeShape(m_fieldShape, ref Vector3.Zero, ref rotation1, shape2.Value, ref posDiff, ref rotation2)) { LastDetectedEntity = entity; empty = false; break; } } } } if (DetectAsteroids) { foreach (var entity in m_potentialVoxelPenetrations) { var voxel = entity as MyVoxelPhysics; if (voxel != null) { Vector3D localPositionMin, localPositionMax; MyVoxelCoordSystems.WorldPositionToLocalPosition(boundingBox.Min, voxel.PositionComp.WorldMatrix, voxel.PositionComp.WorldMatrixInvScaled, voxel.SizeInMetresHalf, out localPositionMin); MyVoxelCoordSystems.WorldPositionToLocalPosition(boundingBox.Max, voxel.PositionComp.WorldMatrix, voxel.PositionComp.WorldMatrixInvScaled, voxel.SizeInMetresHalf, out localPositionMax); var aabb = new BoundingBox(localPositionMin, localPositionMax); aabb.Translate(voxel.StorageMin); if (voxel.Storage.Intersect(ref aabb) != ContainmentType.Disjoint) { LastDetectedEntity = voxel; empty = false; break; } } else { Quaternion rotation2; Vector3 posDiff; HkShape? shape2; if (GetPropertiesFromEntity(entity, ref position1, out rotation2, out posDiff, out shape2)) { if (entity.GetPhysicsBody().HavokWorld.IsPenetratingShapeShape(m_fieldShape, ref Vector3.Zero, ref rotation1, shape2.Value, ref posDiff, ref rotation2)) { LastDetectedEntity = entity; empty = false; break; } } } } } IsActive = !empty; m_potentialPenetrations.Clear(); m_potentialVoxelPenetrations.Clear(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }