protected void GenerateObjectSeeds(ref BoundingSphereD sphere) { ProfilerShort.Begin("GenerateObjectSeedsInBox"); BoundingBoxD box = BoundingBoxD.CreateFromSphere(sphere); Vector3I cellId = Vector3I.Floor(box.Min / CELL_SIZE); for (var iter = GetCellsIterator(sphere); iter.IsValid(); iter.GetNext(out cellId)) { if (m_cells.ContainsKey(cellId)) { continue; } var cellBox = new BoundingBoxD(cellId * CELL_SIZE, (cellId + 1) * CELL_SIZE); if (sphere.Contains(cellBox) == ContainmentType.Disjoint) { continue; } var cell = GenerateProceduralCell(ref cellId); if (cell != null) { m_cells.Add(cellId, cell); var cellBBox = cell.BoundingVolume; cell.proxyId = m_cellsTree.AddProxy(ref cellBBox, cell, 0); } } ProfilerShort.End(); }
public IEnumerable <OffenderProximityInfo> ScanProximity(IEnumerable <DefenderGridInfo> defenders) { var tmpNearEntities = new List <MyEntity>(); foreach (var defender in defenders) { var lookout = _config.MaxProximity * 10; var sphere = new BoundingSphereD(defender.Position, lookout); var bb = BoundingBoxD.CreateFromSphere(sphere); var obb = MyOrientedBoundingBoxD.CreateFromBoundingBox(bb); MyGamePruningStructure.GetAllEntitiesInOBB(ref obb, tmpNearEntities); foreach (var entity in tmpNearEntities) { Log.Trace($"near entity: \"{entity.DisplayName}\""); if (TryGetOffender(entity, defender, out var offender)) { yield return(offender); } } tmpNearEntities.Clear(); } }
/// <summary> /// Generates all Cells data that are within sphere, if they have not been generated. /// </summary> /// <param name="sphere">Bounding Sphere of the cells to generate</param> protected void GenerateObjectsData(ref BoundingSphereD sphere) { BoundingBoxD box = BoundingBoxD.CreateFromSphere(sphere); Vector3I cellId = Vector3I.Floor(box.Min / CELL_SIZE); for (var it = GetCellsIterator(sphere); it.IsValid(); it.GetNext(out cellId)) { if (m_cells.ContainsKey(cellId)) { continue; } BoundingBoxD cellBounds = new BoundingBoxD(cellId * CELL_SIZE, (cellId + 1) * CELL_SIZE); if (!(sphere.Contains(cellBounds) != ContainmentType.Disjoint)) { continue; } MyProceduralCell cell = GenerateCell(ref cellId); if (cell != null) { m_cells.Add(cellId, cell); BoundingBoxD aabb = cell.BoundingVolume; cell.proxyId = m_cellsTree.AddProxy(ref aabb, cell, 0u); } } }
public static void AddBroadcaster(MyRadioBroadcaster broadcaster) { if (broadcaster.RadioProxyID == MyConstants.PRUNING_PROXY_ID_UNITIALIZED) { BoundingBoxD box = BoundingBoxD.CreateFromSphere(new BoundingSphereD(broadcaster.BroadcastPosition, broadcaster.BroadcastRadius)); broadcaster.RadioProxyID = m_aabbTree.AddProxy(ref box, broadcaster, 0); } }
public static void MoveBroadcaster(MyRadioBroadcaster broadcaster) { if (broadcaster.RadioProxyID != MyConstants.PRUNING_PROXY_ID_UNITIALIZED) { BoundingBoxD box = BoundingBoxD.CreateFromSphere(new BoundingSphereD(broadcaster.BroadcastPosition, broadcaster.BroadcastRadius)); m_aabbTree.MoveProxy(broadcaster.RadioProxyID, ref box, Vector3.Zero); } }
internal void CheckForNearVoxel(uint steps) { var possiblePos = BoundingBoxD.CreateFromSphere(new BoundingSphereD(Position, ((MaxSpeed) * (steps + 1) * StepConst) + Info.ConsumableDef.Const.CollisionSize)); if (MyGamePruningStructure.AnyVoxelMapInBox(ref possiblePos)) { PruneQuery = MyEntityQueryType.Both; } }
protected virtual bool TryDrillBlocks(MyCubeGrid grid, Vector3 worldPoint, bool onlyCheck, out MyStringHash blockMaterial) { var invWorld = grid.PositionComp.WorldMatrixNormalizedInv; var gridLocalPosCenter = Vector3.Transform(m_sensor.Center, invWorld); var gridLocalPos = Vector3.Transform(m_sensor.FrontPoint, invWorld); var gridLocalTarget = Vector3.Transform(worldPoint, invWorld); var gridSpacePos = Vector3I.Round(gridLocalPos / grid.GridSize); var block = grid.GetCubeBlock(gridSpacePos); if (block != null) { if (block.BlockDefinition.PhysicalMaterial.Id.SubtypeId == MyStringHash.NullOrEmpty) { blockMaterial = m_metalMaterial; } else { blockMaterial = block.BlockDefinition.PhysicalMaterial.Id.SubtypeId; } } else { blockMaterial = MyStringHash.NullOrEmpty; } int createDebris = 0; if (!onlyCheck) { if (block != null && block is IMyDestroyableObject && block.CubeGrid.BlocksDestructionEnabled) { var destroyable = (block as IMyDestroyableObject); destroyable.DoDamage(60, MyDamageType.Drill, Sync.IsServer, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0); createDebris = grid.Physics.ApplyDeformation(0.25f, 1.5f, 2f, gridLocalTarget, Vector3.Normalize(gridLocalPos - gridLocalPosCenter), MyDamageType.Drill, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0); } } m_target = createDebris != 0 ? null : block; bool success = false; if (block != null) { if (createDebris != 0) { BoundingSphereD bsphere = m_cutOut.Sphere; BoundingBoxD aabb = BoundingBoxD.CreateFromSphere(bsphere); MyDebris.Static.CreateExplosionDebris(ref bsphere, block.CubeGrid, ref aabb, 0.3f); } success = true; } return(success); }
internal static void OnProjectileMoved(Projectile projectile, ref Vector3D velocity) { if (projectile.PruningProxyId == -1) { return; } BoundingSphereD sphere = new BoundingSphereD(projectile.Position, projectile.Info.AmmoDef.Const.AreaEffectSize); BoundingBoxD result; BoundingBoxD.CreateFromSphere(ref sphere, out result); projectile.Info.Ai.Session.ProjectileTree.MoveProxy(projectile.PruningProxyId, ref result, velocity); }
internal static void RegisterProjectile(Projectile projectile) { if (projectile.PruningProxyId != -1) { return; } BoundingSphereD sphere = new BoundingSphereD(projectile.Position, projectile.Info.AmmoDef.Const.AreaEffectSize); BoundingBoxD result; BoundingBoxD.CreateFromSphere(ref sphere, out result); projectile.PruningProxyId = projectile.Info.Ai.Session.ProjectileTree.AddProxy(ref result, projectile, 0U, true); }
public static void AddBroadcaster(MyRadioBroadcaster broadcaster) { if (broadcaster.Parent is MyCubeBlock) { MyCubeGrid grid = (broadcaster.Parent as MyCubeBlock).CubeGrid; Debug.Assert(grid.InScene, "adding broadcaster when grid is not in scene"); } if (broadcaster.RadioProxyID == MyConstants.PRUNING_PROXY_ID_UNITIALIZED) { BoundingBoxD box = BoundingBoxD.CreateFromSphere(new BoundingSphereD(broadcaster.BroadcastPosition, broadcaster.BroadcastRadius)); broadcaster.RadioProxyID = m_aabbTree.AddProxy(ref box, broadcaster, 0); } }
private void EnsureDetector(string researchKey, Ob_Trigger_Location trigger) { var key = new ResearchStatefulKey(researchKey, trigger.StateStorageKey); if (_detectors.ContainsKey(key)) { return; } var data = new DetectorData(key, trigger); _detectors.Add(key, data); var aabb = BoundingBoxD.CreateFromSphere(data.Detector); data.Handle = _detectorTree.AddProxy(ref aabb, data, 0); }
/// <summary> /// Gets all seeds within said bounds. /// If a cell inside the bounds is not loaded, it will generate the seed but wont load the cell. /// </summary> /// <param name="bounds">Bounds to get seeds from</param> /// <param name="list">List to put seeds into.</param> public void GetSeedsInBounds(BoundingSphereD bounds, List <MyObjectSeed> list) { BoundingBoxD box = BoundingBoxD.CreateFromSphere(bounds); Vector3I cellId = Vector3I.Floor(box.Min / m_cellSize); for (var it = GetCellsIterator(box); it.IsValid(); it.GetNext(out cellId)) { if (m_loadedCells.ContainsKey(cellId)) { m_loadedCells[cellId].GetAll(list, false); } else { MyProceduralCell cell = GenerateCellSeeds(cellId); cell.GetAll(list); } } }
protected virtual bool TryDrillBlocks(MyCubeGrid grid, Vector3 worldPoint, bool onlyCheck) { var invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); var gridLocalPosCenter = Vector3.Transform(m_sensor.Center, invWorld); var gridLocalPos = Vector3.Transform(m_sensor.FrontPoint, invWorld); var gridLocalTarget = Vector3.Transform(worldPoint, invWorld); var gridSpacePos = Vector3I.Round(gridLocalPos / grid.GridSize); var block = grid.GetCubeBlock(gridSpacePos); bool createDebris = false; if (!onlyCheck && MySession.Static.DestructibleBlocks) { if (block != null && block is IMyDestroyableObject) { var destroyable = (block as IMyDestroyableObject); destroyable.DoDamage(60, MyDamageType.Drill, Sync.IsServer); } createDebris = grid.Physics.ApplyDeformation(0.25f, 1.5f, 2f, gridLocalTarget, Vector3.Normalize(gridLocalPos - gridLocalPosCenter), MyDamageType.Drill); } m_target = createDebris ? null : block; bool success = false; if (block != null) { if (createDebris) { BoundingSphereD bsphere = m_cutOut.Sphere; BoundingBoxD aabb = BoundingBoxD.CreateFromSphere(bsphere); MyDebris.Static.CreateExplosionDebris(ref bsphere, block.CubeGrid, ref aabb, 0.3f); } success = true; } return(success); }
public static unsafe bool CutOutSphereFast(MyVoxelBase voxelMap, ref Vector3D center, float radius, out Vector3I cacheMin, out Vector3I cacheMax, bool notifyChanged) { Vector3I vectori; Vector3I vectori2; MatrixD worldMatrixInvScaled = voxelMap.PositionComp.WorldMatrixInvScaled; MatrixD *xdPtr1 = (MatrixD *)ref worldMatrixInvScaled; xdPtr1.Translation += voxelMap.SizeInMetresHalf; BoundingBoxD shapeAabb = BoundingBoxD.CreateFromSphere(new BoundingSphereD(center, (double)radius)).TransformFast(worldMatrixInvScaled); ComputeShapeBounds(voxelMap, ref shapeAabb, Vector3.Zero, voxelMap.Storage.Size, out vectori, out vectori2); cacheMin = vectori - 1; cacheMax = (Vector3I)(vectori2 + 1); voxelMap.Storage.ClampVoxelCoord(ref cacheMin, 1); voxelMap.Storage.ClampVoxelCoord(ref cacheMax, 1); CutOutSphere voxelOperator = new CutOutSphere { RadSq = radius * radius, Center = Vector3D.Transform(center, worldMatrixInvScaled) - (cacheMin - voxelMap.StorageMin) }; voxelMap.Storage.ExecuteOperationFast <CutOutSphere>(ref voxelOperator, MyStorageDataTypeFlags.Content, ref cacheMin, ref cacheMax, notifyChanged); return(voxelOperator.Changed); }
/// <summary> /// Marks cells to load or keep loaded inside the bounds /// </summary> /// <param name="bounds">Spherical bounds</param> public void MarkToLoadCellsInBounds(BoundingSphereD bounds) { BoundingBoxD box = BoundingBoxD.CreateFromSphere(bounds); Vector3I cellId = Vector3I.Floor(box.Min / m_cellSize); for (var it = GetCellsIterator(box); it.IsValid(); it.GetNext(out cellId)) { if (m_toLoadCells.Contains(cellId)) { continue; } BoundingBoxD cellBounds = new BoundingBoxD(cellId * m_cellSize, (cellId + 1) * m_cellSize); if (bounds.Contains(cellBounds) == ContainmentType.Disjoint) { continue; } m_toLoadCells.Add(cellId); } m_toLoadCells.ApplyAdditions(); }
public override void UpdateWorldAABB() { m_localAABB = new BoundingBoxD(new Vector3D(-0.5), new Vector3D(0.5)); if (IsTypeSpot) { if (m_spotParamsDirty) { UpdateSpotParams(); } m_localAABB = m_spotBoundingBox; m_aabb = m_spotBoundingBox; } else if (IsTypePoint || IsTypeHemisphere) { m_localAABB = BoundingBoxD.CreateFromSphere(m_pointBoundingSphere); m_aabb = m_localAABB; } base.UpdateWorldAABB(); }
private void UpdateState(int end = 0) { for (int i = ActiveProjetiles.Count - 1; i >= end; i--) { var p = ActiveProjetiles[i]; ++p.Info.Age; ++p.Info.Ai.MyProjectiles; p.Info.Ai.ProjectileTicker = p.Info.System.Session.Tick; switch (p.State) { case ProjectileState.Destroy: p.DestroyProjectile(); continue; case ProjectileState.Dead: continue; case ProjectileState.OneAndDone: case ProjectileState.Depleted: case ProjectileState.Detonate: if (p.Info.Age == 0 && p.State == ProjectileState.OneAndDone) { break; } p.ProjectileClose(); ProjectilePool.Push(p); ActiveProjetiles.RemoveAtFast(i); continue; } if (p.Info.Target.IsProjectile) { if (p.Info.Target.Projectile.State != ProjectileState.Alive) { p.UnAssignProjectile(true); } } if (!p.AtMaxRange) { if (p.FeelsGravity) { var update = (p.Info.Age % 60 == 0 || (p.FakeGravityNear || p.EntitiesNear) && p.Info.Age % 10 == 0) && p.Info.Age > 0; if (update) { float interference; p.Gravity = Session.Physics.CalculateNaturalGravityAt(p.Position, out interference); if (!p.Info.InPlanetGravity && !MyUtils.IsZero(p.Gravity)) { p.FakeGravityNear = true; } else { p.FakeGravityNear = false; } p.EntitiesNear = false; } p.Velocity += (p.Gravity * p.Info.ConsumableDef.Trajectory.GravityMultiplier) * Projectile.StepConst; Vector3D.Normalize(ref p.Velocity, out p.Info.Direction); } if (p.DeltaVelocityPerTick > 0 && !p.Info.EwarAreaPulse) { if (p.SmartsOn) { p.RunSmart(); } else { var accel = true; Vector3D newVel; if (p.FieldTime > 0) { var distToMax = p.Info.MaxTrajectory - p.Info.DistanceTraveled; var stopDist = p.VelocityLengthSqr / 2 / (p.AccelInMetersPerSec); if (distToMax <= stopDist) { accel = false; } newVel = accel ? p.Velocity + p.AccelVelocity : p.Velocity - p.AccelVelocity; p.VelocityLengthSqr = newVel.LengthSquared(); if (accel && p.VelocityLengthSqr > p.MaxSpeedSqr) { newVel = p.Info.Direction * p.MaxSpeed; } else if (!accel && distToMax <= 0) { newVel = Vector3D.Zero; p.VelocityLengthSqr = 0; } } else { newVel = p.Velocity + p.AccelVelocity; p.VelocityLengthSqr = newVel.LengthSquared(); if (p.VelocityLengthSqr > p.MaxSpeedSqr) { newVel = p.Info.Direction * p.MaxSpeed; } } p.Velocity = newVel; } } if (p.State == ProjectileState.OneAndDone) { p.LastPosition = p.Position; var beamEnd = p.Position + (p.Info.Direction * p.Info.MaxTrajectory); p.TravelMagnitude = p.Position - beamEnd; p.Position = beamEnd; } else { if (p.ConstantSpeed || p.VelocityLengthSqr > 0) { p.LastPosition = p.Position; } p.TravelMagnitude = p.Info.Age != 0 ? p.Velocity * StepConst : p.InitalStep; p.Position += p.TravelMagnitude; } p.Info.PrevDistanceTraveled = p.Info.DistanceTraveled; double distChanged; Vector3D.Dot(ref p.Info.Direction, ref p.TravelMagnitude, out distChanged); p.Info.DistanceTraveled += Math.Abs(distChanged); if (p.Info.DistanceTraveled <= 500) { ++p.Info.Ai.ProInMinCacheRange; } if (p.DynamicGuidance) { if (p.PruningProxyId != -1) { var sphere = new BoundingSphereD(p.Position, p.Info.ConsumableDef.Const.AreaEffectSize); BoundingBoxD result; BoundingBoxD.CreateFromSphere(ref sphere, out result); Session.ProjectileTree.MoveProxy(p.PruningProxyId, ref result, p.Velocity); } } } if (p.ModelState == EntityState.Exists) { var up = MatrixD.Identity.Up; MatrixD matrix; MatrixD.CreateWorld(ref p.Position, ref p.Info.Direction, ref up, out matrix); if (p.Info.ConsumableDef.Const.PrimeModel) { p.Info.AvShot.PrimeMatrix = matrix; } if (p.Info.ConsumableDef.Const.TriggerModel && p.Info.TriggerGrowthSteps < p.Info.ConsumableDef.Const.AreaEffectSize) { p.Info.TriggerMatrix = matrix; } } if (p.State != ProjectileState.OneAndDone) { if (p.Info.Age > p.Info.ConsumableDef.Const.MaxLifeTime) { p.DistanceToTravelSqr = p.Info.DistanceTraveled * p.Info.DistanceTraveled; p.EarlyEnd = true; } if (p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr) { p.AtMaxRange = !p.MineSeeking; if (p.FieldTime > 0) { p.FieldTime--; if (p.Info.ConsumableDef.Const.IsMine && !p.MineSeeking && !p.MineActivated) { if (p.EnableAv) { p.Info.AvShot.Cloaked = p.Info.ConsumableDef.Trajectory.Mines.Cloak; } p.MineSeeking = true; } } } } else { p.AtMaxRange = true; } if (p.Info.ConsumableDef.Const.Ewar) { p.RunEwar(); } } }
internal void CreateShieldShape() { var width = DsSet.Settings.Width; var height = DsSet.Settings.Height; var depth = DsSet.Settings.Depth; var maxMulti = ShieldMode != ShieldType.SmallGrid ? 0.33333f : 1f; var xMax = GridIsMobile ? DsState.State.GridHalfExtents.X * maxMulti : float.MaxValue; var yMax = GridIsMobile ? DsState.State.GridHalfExtents.Y * maxMulti : float.MaxValue; var zMax = GridIsMobile ? DsState.State.GridHalfExtents.Z * maxMulti : float.MaxValue; var offsetMulti = ShieldMode != ShieldType.SmallGrid ? 1 : 0.2f; var wOffset = MathHelper.Clamp(DsSet.Settings.ShieldOffset.X * offsetMulti, -xMax, xMax); var hOffset = MathHelper.Clamp(DsSet.Settings.ShieldOffset.Y * offsetMulti, -yMax, yMax); var dOffset = MathHelper.Clamp(DsSet.Settings.ShieldOffset.Z * offsetMulti, -zMax, zMax); var localOffsetMeters = new Vector3D(wOffset, hOffset, dOffset) * MyGrid.GridSize; var gridMatrix = MyGrid.PositionComp.WorldMatrixRef; var worldOffset = Vector3D.TransformNormal(localOffsetMeters, gridMatrix); if (GridIsMobile) { DetectionCenter = MyGridCenter + worldOffset; _updateMobileShape = false; if (_shapeChanged) { CreateMobileShape(localOffsetMeters); } DetectionMatrix = ShieldShapeMatrix * gridMatrix; SQuaternion = Quaternion.CreateFromRotationMatrix(gridMatrix); ShieldSphere.Center = DetectionCenter; ShieldSphere.Radius = ShieldSize.AbsMax(); } else { IMyUpgradeModule emitter; if (_isServer) { emitter = ShieldComp.StationEmitter.Emitter; } else { emitter = (IMyUpgradeModule)MyEntities.GetEntityById(DsState.State.ActiveEmitterId, true); } if (emitter == null) { UpdateDimensions = true; return; } var blockGridPosMeters = new Vector3D(emitter.Position) * MyGrid.GridSize; var localOffsetPosMeters = localOffsetMeters + blockGridPosMeters; var emitterCenter = emitter.PositionComp.GetPosition(); var offsetLMatrix = Matrix.CreateWorld(localOffsetPosMeters, Vector3D.Forward, Vector3D.Up); var translationInWorldSpace = emitterCenter + worldOffset; OffsetEmitterWMatrix = MatrixD.CreateWorld(translationInWorldSpace, gridMatrix.Forward, gridMatrix.Up); DetectionCenter = OffsetEmitterWMatrix.Translation; var halfDistToCenter = 1000 - Vector3D.Distance(DetectionCenter, emitterCenter); var vectorScale = new Vector3D(MathHelper.Clamp(width, 30, halfDistToCenter), MathHelper.Clamp(height, 30, halfDistToCenter), MathHelper.Clamp(depth, 30, halfDistToCenter)); DetectionMatrix = MatrixD.Rescale(OffsetEmitterWMatrix, vectorScale); ShieldShapeMatrix = MatrixD.Rescale(offsetLMatrix, vectorScale); ShieldSize = DetectionMatrix.Scale; SQuaternion = Quaternion.CreateFromRotationMatrix(OffsetEmitterWMatrix); ShieldSphere.Center = DetectionCenter; ShieldSphere.Radius = ShieldSize.AbsMax(); } ShieldSphere3K.Center = DetectionCenter; WebSphere.Center = DetectionCenter; SOriBBoxD.Center = DetectionCenter; SOriBBoxD.Orientation = SQuaternion; if (_shapeChanged) { SOriBBoxD.HalfExtent = ShieldSize; ShieldAabbScaled.Min = -ShieldSize; ShieldAabbScaled.Max = ShieldSize; _ellipsoidSa.Update(DetectMatrixOutside.Scale.X, DetectMatrixOutside.Scale.Y, DetectMatrixOutside.Scale.Z); BoundingRange = ShieldSize.AbsMax(); ShieldSphere3K.Radius = BoundingRange + 3000; WebSphere.Radius = BoundingRange + (IsStatic ? 20 : 10); _ellipsoidSurfaceArea = _ellipsoidSa.Surface; var magicMod = DsState.State.Enhancer && ShieldMode == ShieldType.Station ? 100f : DsState.State.Enhancer && DsSet.Settings.FortifyShield ? 12f + Math.Sqrt(DsSet.Settings.Fit) : 1f; var ellipsoidMagic = _ellipsoidSurfaceArea / (MagicEllipsoidRatio * magicMod); var rawScaler = Math.Sqrt(ellipsoidMagic); _sizeScaler = (float)rawScaler; /// Large ship bonus var size = DsState.State.RealGridHalfExtents.Volume * 2; var scaleMod = size * (size * 0.00000012d); var scaleSqrt = Math.Sqrt(scaleMod) - 1d; var safeSqrt = scaleSqrt <= 0 ? 0.1d : scaleSqrt; var volumeModifier = Math.Log10(safeSqrt); if (ShieldMode != ShieldType.Station && DsState.State.BlockDensity >= 1 && volumeModifier >= 1) { _sizeScaler /= (float)volumeModifier; } /// if (_isServer) { ShieldChangeState(); ShieldComp.ShieldVolume = DetectMatrixOutside.Scale.Volume; } } if (_shapeChanged) { var zeroMatrix = Matrix.Zero; var shieldMatrix = (Matrix)ShieldShapeMatrix; if (!_isDedicated) { _shellPassive.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true); // Bug - Cannot just change X coord, so I reset first. ShellActive.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true); _shellPassive.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true); ShellActive.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true); } ShieldEnt.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true); ShieldEnt.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true); ShieldEnt.PositionComp.LocalAABB = BoundingBox.CreateFromHalfExtent(Vector3.Zero, (float)ShieldSize.AbsMax()); ShieldEnt.PositionComp.WorldMatrix *= MyGrid.PositionComp.WorldMatrix.GetOrientation(); ShapeChangeTick = _tick; } ShieldEnt.PositionComp.SetPosition(DetectionCenter); BoundingBoxD.CreateFromSphere(ref WebSphere, out WebBox); BoundingBoxD.CreateFromSphere(ref ShieldSphere3K, out ShieldBox3K); }
public static MyDetectedEntityInfo Create(MyEntity entity, long sensorOwner, Vector3D?hitPosition = new Vector3D?()) { MyDetectedEntityType type; MyRelationsBetweenPlayerAndBlock neutral; string displayName; if (entity == null) { return(new MyDetectedEntityInfo()); } MatrixD zero = MatrixD.Zero; Vector3 velocity = (Vector3)Vector3D.Zero; int totalGamePlayTimeInMilliseconds = MySandboxGame.TotalGamePlayTimeInMilliseconds; BoundingBoxD worldAABB = entity.PositionComp.WorldAABB; if (entity.Physics != null) { zero = entity.Physics.GetWorldMatrix().GetOrientation(); velocity = entity.Physics.LinearVelocity; } MyCubeGrid topMostParent = entity.GetTopMostParent(null) as MyCubeGrid; if (topMostParent != null) { type = (topMostParent.GridSizeEnum != MyCubeSize.Small) ? MyDetectedEntityType.LargeGrid : MyDetectedEntityType.SmallGrid; neutral = (topMostParent.BigOwners.Count != 0) ? MyIDModule.GetRelation(sensorOwner, topMostParent.BigOwners[0], MyOwnershipShareModeEnum.Faction, MyRelationsBetweenPlayerAndBlock.Enemies, MyRelationsBetweenFactions.Enemies, MyRelationsBetweenPlayerAndBlock.FactionShare) : MyRelationsBetweenPlayerAndBlock.NoOwnership; if ((neutral == MyRelationsBetweenPlayerAndBlock.Owner) || (neutral == MyRelationsBetweenPlayerAndBlock.FactionShare)) { displayName = topMostParent.DisplayName; } else { displayName = (topMostParent.GridSizeEnum != MyCubeSize.Small) ? MyTexts.GetString(MySpaceTexts.DetectedEntity_LargeGrid) : MyTexts.GetString(MySpaceTexts.DetectedEntity_SmallGrid); } zero = topMostParent.WorldMatrix.GetOrientation(); return(new MyDetectedEntityInfo(topMostParent.EntityId, displayName, type, hitPosition, zero, topMostParent.Physics.LinearVelocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds)); } MyCharacter character = entity as MyCharacter; if (character != null) { type = !character.IsPlayer ? MyDetectedEntityType.CharacterOther : MyDetectedEntityType.CharacterHuman; neutral = MyIDModule.GetRelation(sensorOwner, character.GetPlayerIdentityId(), MyOwnershipShareModeEnum.Faction, MyRelationsBetweenPlayerAndBlock.Enemies, MyRelationsBetweenFactions.Enemies, MyRelationsBetweenPlayerAndBlock.FactionShare); if ((neutral == MyRelationsBetweenPlayerAndBlock.Owner) || (neutral == MyRelationsBetweenPlayerAndBlock.FactionShare)) { displayName = character.DisplayNameText; } else { displayName = !character.IsPlayer ? MyTexts.GetString(MySpaceTexts.DetectedEntity_CharacterOther) : MyTexts.GetString(MySpaceTexts.DetectedEntity_CharacterHuman); } return(new MyDetectedEntityInfo(entity.EntityId, displayName, type, hitPosition, zero, velocity, neutral, character.Model.BoundingBox.Transform(character.WorldMatrix), (long)totalGamePlayTimeInMilliseconds)); } neutral = MyRelationsBetweenPlayerAndBlock.Neutral; MyFloatingObject obj2 = entity as MyFloatingObject; if (obj2 != null) { displayName = obj2.Item.Content.SubtypeName; return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.FloatingObject, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds)); } MyInventoryBagEntity entity2 = entity as MyInventoryBagEntity; if (entity2 != null) { displayName = entity2.DisplayName; return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.FloatingObject, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds)); } MyPlanet planet = entity as MyPlanet; if (planet != null) { displayName = MyTexts.GetString(MySpaceTexts.DetectedEntity_Planet); return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.Planet, hitPosition, zero, velocity, neutral, BoundingBoxD.CreateFromSphere(new BoundingSphereD(planet.PositionComp.GetPosition(), (double)planet.MaximumRadius)), (long)totalGamePlayTimeInMilliseconds)); } MyVoxelPhysics physics = entity as MyVoxelPhysics; if (physics != null) { displayName = MyTexts.GetString(MySpaceTexts.DetectedEntity_Planet); return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.Planet, hitPosition, zero, velocity, neutral, BoundingBoxD.CreateFromSphere(new BoundingSphereD(physics.Parent.PositionComp.GetPosition(), (double)physics.Parent.MaximumRadius)), (long)totalGamePlayTimeInMilliseconds)); } if (entity is MyVoxelMap) { displayName = MyTexts.GetString(MySpaceTexts.DetectedEntity_Asteroid); return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.Asteroid, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds)); } if (entity is MyMeteor) { displayName = MyTexts.GetString(MySpaceTexts.DetectedEntity_Meteor); return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.Meteor, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds)); } if (entity is MyMissile) { return(new MyDetectedEntityInfo(entity.EntityId, entity.DisplayName, MyDetectedEntityType.Missile, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds)); } Vector3D?nullable = null; MatrixD orientation = new MatrixD(); Vector3 vector2 = new Vector3(); return(new MyDetectedEntityInfo(0L, string.Empty, MyDetectedEntityType.Unknown, nullable, orientation, vector2, MyRelationsBetweenPlayerAndBlock.NoOwnership, new BoundingBoxD(), (long)MySandboxGame.TotalGamePlayTimeInMilliseconds)); }
public static MyDetectedEntityInfo Create(MyEntity entity, long sensorOwner, Vector3D?hitPosition = null) { if (entity == null) { return(new MyDetectedEntityInfo()); } MatrixD orientation = MatrixD.Zero; Vector3 velocity = Vector3D.Zero; int timeStamp = MySandboxGame.TotalGamePlayTimeInMilliseconds; MyDetectedEntityType type; BoundingBoxD boundingBox = entity.PositionComp.WorldAABB; MyRelationsBetweenPlayerAndBlock relationship; string name; if (entity.Physics != null) { orientation = entity.Physics.GetWorldMatrix().GetOrientation(); velocity = entity.Physics.LinearVelocity; } //using GetTopMostParent in case we are looking at a MyCubeBlock; we want the grid the block is on var grid = entity.GetTopMostParent() as MyCubeGrid; if (grid != null) { if (grid.GridSizeEnum == MyCubeSize.Small) { type = MyDetectedEntityType.SmallGrid; } else { type = MyDetectedEntityType.LargeGrid; } if (grid.BigOwners.Count == 0) { relationship = MyRelationsBetweenPlayerAndBlock.NoOwnership; } else { relationship = MyIDModule.GetRelation(sensorOwner, grid.BigOwners[0], MyOwnershipShareModeEnum.Faction); } if (relationship == MyRelationsBetweenPlayerAndBlock.Owner || relationship == MyRelationsBetweenPlayerAndBlock.FactionShare) { name = grid.DisplayName; } else { if (grid.GridSizeEnum == MyCubeSize.Small) { name = MyTexts.GetString(MySpaceTexts.DetectedEntity_SmallGrid); } else { name = MyTexts.GetString(MySpaceTexts.DetectedEntity_LargeGrid); } } return(new MyDetectedEntityInfo(grid.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp)); } var character = entity as MyCharacter; if (character != null) { if (character.IsPlayer) { type = MyDetectedEntityType.CharacterHuman; } else { type = MyDetectedEntityType.CharacterOther; } relationship = MyIDModule.GetRelation(sensorOwner, character.GetPlayerIdentityId(), MyOwnershipShareModeEnum.Faction); if (relationship == MyRelationsBetweenPlayerAndBlock.Owner || relationship == MyRelationsBetweenPlayerAndBlock.FactionShare) { name = character.DisplayNameText; } else { if (character.IsPlayer) { name = MyTexts.GetString(MySpaceTexts.DetectedEntity_CharacterHuman); } else { name = MyTexts.GetString(MySpaceTexts.DetectedEntity_CharacterOther); } } BoundingBoxD bound = character.Model.BoundingBox.Transform(character.WorldMatrix); return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, bound, timeStamp)); } relationship = MyRelationsBetweenPlayerAndBlock.Neutral; var floating = entity as MyFloatingObject; if (floating != null) { type = MyDetectedEntityType.FloatingObject; name = floating.Item.Content.SubtypeName; return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp)); } var backpack = entity as MyInventoryBagEntity; if (backpack != null) { type = MyDetectedEntityType.FloatingObject; name = backpack.DisplayName; return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp)); } var planet = entity as MyPlanet; if (planet != null) { type = MyDetectedEntityType.Planet; name = MyTexts.GetString(MySpaceTexts.DetectedEntity_Planet); //shrink the planet's bounding box to only encompass terrain boundingBox = BoundingBoxD.CreateFromSphere(new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MaximumRadius)); return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp)); } var voxelPhysics = entity as MyVoxelPhysics; if (voxelPhysics != null) { type = MyDetectedEntityType.Planet; name = MyTexts.GetString(MySpaceTexts.DetectedEntity_Planet); //shrink the planet's bounding box to only encompass terrain boundingBox = BoundingBoxD.CreateFromSphere(new BoundingSphereD(voxelPhysics.Parent.PositionComp.GetPosition(), voxelPhysics.Parent.MaximumRadius)); return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp)); } var voxel = entity as MyVoxelMap; if (voxel != null) { type = MyDetectedEntityType.Asteroid; name = MyTexts.GetString(MySpaceTexts.DetectedEntity_Asteroid); return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp)); } var meteor = entity as MyMeteor; if (meteor != null) { type = MyDetectedEntityType.Meteor; name = MyTexts.GetString(MySpaceTexts.DetectedEntity_Meteor); return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp)); } var missile = entity as MyMissile; if (missile != null) { type = MyDetectedEntityType.Missile; name = entity.DisplayName; return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp)); } //error case return(new MyDetectedEntityInfo(0, String.Empty, MyDetectedEntityType.Unknown, null, new MatrixD(), new Vector3(), MyRelationsBetweenPlayerAndBlock.NoOwnership, new BoundingBoxD(), MySandboxGame.TotalGamePlayTimeInMilliseconds)); }
internal void CreateShieldShape() { if (GridIsMobile) { _updateMobileShape = false; if (_shapeChanged) { CreateMobileShape(); } DetectionMatrix = ShieldShapeMatrix * MyGrid.WorldMatrix; DetectionCenter = MyGridCenter; _sQuaternion = Quaternion.CreateFromRotationMatrix(MyGrid.WorldMatrix); ShieldSphere.Center = DetectionCenter; ShieldSphere.Radius = ShieldSize.AbsMax(); } else { IMyUpgradeModule emitter; if (_isServer) { emitter = ShieldComp.StationEmitter.Emitter; } else { emitter = (IMyUpgradeModule)MyEntities.GetEntityById(DsState.State.ActiveEmitterId, true); } if (emitter == null) { UpdateDimensions = true; return; } var width = DsSet.Settings.Width; var height = DsSet.Settings.Height; var depth = DsSet.Settings.Depth; var wOffset = DsSet.Settings.ShieldOffset.X; var hOffset = DsSet.Settings.ShieldOffset.Y; var dOffset = DsSet.Settings.ShieldOffset.Z; var blockGridPosMeters = new Vector3D(emitter.Position) * MyGrid.GridSize; var localOffsetMeters = new Vector3D(wOffset, hOffset, dOffset) * MyGrid.GridSize; var localOffsetPosMeters = localOffsetMeters + blockGridPosMeters; var emitterCenter = emitter.PositionComp.GetPosition(); var offsetLMatrix = Matrix.CreateWorld(localOffsetPosMeters, Vector3D.Forward, Vector3D.Up); var worldOffset = Vector3D.TransformNormal(localOffsetMeters, MyGrid.WorldMatrix); var translationInWorldSpace = emitterCenter + worldOffset; OffsetEmitterWMatrix = MatrixD.CreateWorld(translationInWorldSpace, MyGrid.WorldMatrix.Forward, MyGrid.WorldMatrix.Up); DetectionCenter = OffsetEmitterWMatrix.Translation; var halfDistToCenter = 600 - Vector3D.Distance(DetectionCenter, emitterCenter); var vectorScale = new Vector3D(MathHelper.Clamp(width, 30, halfDistToCenter), MathHelper.Clamp(height, 30, halfDistToCenter), MathHelper.Clamp(depth, 30, halfDistToCenter)); DetectionMatrix = MatrixD.Rescale(OffsetEmitterWMatrix, vectorScale); ShieldShapeMatrix = MatrixD.Rescale(offsetLMatrix, vectorScale); ShieldSize = DetectionMatrix.Scale; _sQuaternion = Quaternion.CreateFromRotationMatrix(OffsetEmitterWMatrix); ShieldSphere.Center = DetectionCenter; ShieldSphere.Radius = ShieldSize.AbsMax(); } ShieldSphere3K.Center = DetectionCenter; WebSphere.Center = DetectionCenter; SOriBBoxD.Center = DetectionCenter; SOriBBoxD.Orientation = _sQuaternion; if (_shapeChanged) { SOriBBoxD.HalfExtent = ShieldSize; ShieldAabbScaled.Min = ShieldSize; ShieldAabbScaled.Max = -ShieldSize; _ellipsoidSa.Update(DetectMatrixOutside.Scale.X, DetectMatrixOutside.Scale.Y, DetectMatrixOutside.Scale.Z); BoundingRange = ShieldSize.AbsMax(); ShieldSphere3K.Radius = BoundingRange + 3000; WebSphere.Radius = BoundingRange + 7; _ellipsoidSurfaceArea = _ellipsoidSa.Surface; EllipsoidVolume = 1.333333 * Math.PI * DetectMatrixOutside.Scale.X * DetectMatrixOutside.Scale.Y * DetectMatrixOutside.Scale.Z; _shieldVol = DetectMatrixOutside.Scale.Volume; if (_isServer) { ShieldChangeState(); ShieldComp.ShieldVolume = DetectMatrixOutside.Scale.Volume; } } if (_shapeChanged) { var zeroMatrix = Matrix.Zero; var shieldMatrix = (Matrix)ShieldShapeMatrix; if (!_isDedicated) { _shellPassive.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true); // Bug - Cannot just change X coord, so I reset first. _shellActive.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true); _shellPassive.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true); _shellActive.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true); } ShieldEnt.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true); ShieldEnt.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true); ShieldEnt.PositionComp.LocalAABB = BoundingBox.CreateFromHalfExtent(Vector3.Zero, (float)ShieldSize.AbsMax()); ShieldEnt.PositionComp.WorldMatrix *= MyGrid.PositionComp.WorldMatrix.GetOrientation(); } ShieldEnt.PositionComp.SetPosition(DetectionCenter); BoundingBoxD.CreateFromSphere(ref WebSphere, out WebBox); BoundingBoxD.CreateFromSphere(ref ShieldSphere3K, out ShieldBox3K); }
private void UpdateState() { foreach (var p in ActiveProjetiles) { p.Info.Age++; p.Active = false; switch (p.State) { case ProjectileState.Destroy: p.DestroyProjectile(); continue; case ProjectileState.Dead: continue; case ProjectileState.Start: p.Start(); break; case ProjectileState.OneAndDone: case ProjectileState.Depleted: case ProjectileState.Detonate: p.ProjectileClose(); continue; } if (p.Info.Target.IsProjectile) { if (p.Info.Target.Projectile.State != ProjectileState.Alive) { p.UnAssignProjectile(true); } } if (p.FeelsGravity) { var update = p.FakeGravityNear || p.EntitiesNear || p.Info.Ai.InPlanetGravity && p.Info.Age % 30 == 0 || !p.Info.Ai.InPlanetGravity && p.Info.Age % 10 == 0; if (update) { p.Gravity = MyParticlesManager.CalculateGravityInPoint(p.Position); if (!p.Info.Ai.InPlanetGravity && !MyUtils.IsZero(p.Gravity)) { p.FakeGravityNear = true; } else { p.FakeGravityNear = false; } } p.Velocity += (p.Gravity * p.Info.AmmoDef.Trajectory.GravityMultiplier) * Projectile.StepConst; Vector3D.Normalize(ref p.Velocity, out p.Info.Direction); } if (p.AccelLength > 0 && !p.Info.TriggeredPulse) { if (p.SmartsOn) { p.RunSmart(); } else { var accel = true; Vector3D newVel; if (p.FieldTime > 0) { var distToMax = p.Info.MaxTrajectory - p.Info.DistanceTraveled; var stopDist = p.VelocityLengthSqr / 2 / (p.StepPerSec); if (distToMax <= stopDist) { accel = false; } newVel = accel ? p.Velocity + p.AccelVelocity : p.Velocity - p.AccelVelocity; p.VelocityLengthSqr = newVel.LengthSquared(); if (accel && p.VelocityLengthSqr > p.MaxSpeedSqr) { newVel = p.Info.Direction * p.MaxSpeed; } else if (!accel && distToMax <= 0) { newVel = Vector3D.Zero; p.VelocityLengthSqr = 0; } } else { newVel = p.Velocity + p.AccelVelocity; p.VelocityLengthSqr = newVel.LengthSquared(); if (p.VelocityLengthSqr > p.MaxSpeedSqr) { newVel = p.Info.Direction * p.MaxSpeed; } } p.Velocity = newVel; } } if (p.State == ProjectileState.OneAndDone) { p.LastPosition = p.Position; var beamEnd = p.Position + (p.Info.Direction * p.Info.MaxTrajectory); p.TravelMagnitude = p.Position - beamEnd; p.Position = beamEnd; } else { if (p.ConstantSpeed || p.VelocityLengthSqr > 0) { p.LastPosition = p.Position; } p.TravelMagnitude = p.Velocity * StepConst; p.Position += p.TravelMagnitude; } p.Info.PrevDistanceTraveled = p.Info.DistanceTraveled; p.Info.DistanceTraveled += Math.Abs(Vector3D.Dot(p.Info.Direction, p.Velocity * StepConst)); if (p.ModelState == EntityState.Exists) { var up = MatrixD.Identity.Up; MatrixD matrix; MatrixD.CreateWorld(ref p.Position, ref p.Info.VisualDir, ref up, out matrix); if (p.Info.AmmoDef.Const.PrimeModel) { p.Info.AvShot.PrimeMatrix = matrix; } if (p.Info.AmmoDef.Const.TriggerModel && p.Info.TriggerGrowthSteps < p.Info.AmmoDef.Const.AreaEffectSize) { p.Info.TriggerMatrix = matrix; } if (p.EnableAv && p.AmmoEffect != null && p.Info.AmmoDef.Const.AmmoParticle && p.Info.AmmoDef.Const.PrimeModel) { var offVec = p.Position + Vector3D.Rotate(p.Info.AmmoDef.AmmoGraphics.Particles.Ammo.Offset, p.Info.AvShot.PrimeMatrix); p.AmmoEffect.WorldMatrix = p.Info.AvShot.PrimeMatrix; p.AmmoEffect.SetTranslation(ref offVec); } } else if (p.EnableAv && p.AmmoEffect != null && p.Info.AmmoDef.Const.AmmoParticle) { var translation = p.AmmoEffect.WorldMatrix.Translation + p.TravelMagnitude; p.AmmoEffect.SetTranslation(ref translation); } if (p.DynamicGuidance) { if (p.PruningProxyId != -1) { var sphere = new BoundingSphereD(p.Position, p.Info.AmmoDef.Const.AreaEffectSize); BoundingBoxD result; BoundingBoxD.CreateFromSphere(ref sphere, out result); Session.ProjectileTree.MoveProxy(p.PruningProxyId, ref result, p.Velocity); } } if (p.State != ProjectileState.OneAndDone) { if (!p.SmartsOn && p.Info.Age > p.Info.AmmoDef.Const.MaxLifeTime) { p.DistanceToTravelSqr = p.Info.DistanceTraveled * p.Info.DistanceTraveled; p.EarlyEnd = true; } if (p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr) { p.AtMaxRange = true; if (p.FieldTime > 0) { p.FieldTime--; if (p.Info.AmmoDef.Const.IsMine && !p.MineSeeking && !p.MineActivated) { if (p.EnableAv) { p.Info.AvShot.Cloaked = p.Info.AmmoDef.Trajectory.Mines.Cloak; } p.MineSeeking = true; } } } } else { p.AtMaxRange = true; } if (p.Info.AmmoDef.Const.Ewar) { p.RunEwar(); } p.Active = true; } }
public void GetAllInSphere(List <T> result, ref BoundingSphereD sphere, uint flags = 0) { var box = BoundingBoxD.CreateFromSphere(sphere); GetAllInBox(result, ref box, flags); }
protected Vector3I.RangeIterator GetCellsIterator(BoundingSphereD sphere) { return(GetCellsIterator(BoundingBoxD.CreateFromSphere(sphere))); }
private void CreateShieldShape() { /* * Basically find the point on the surface of the ellipsoid given a normal vector. * Equation for ellipsoid is x^2/a^2 + y^2/b^2 ... = 1 * So given a normal vector x hat, y hat, z hat find the values for x y z that are parallel and satisfy that equation. * So x = dist*x normVec, y = dist * y normVec * a,b,c are the radii if the ellipsoid in X Y Z * So signed distance from surface is distance(point, origin) - distance(support(norm(point-origin)), origin) * support gives you the point on the surface in the given direction. */ Asleep = false; if (GridIsMobile) { _updateMobileShape = false; if (_shapeChanged) { CreateMobileShape(); } DetectionMatrix = ShieldShapeMatrix * MyGrid.WorldMatrix; DetectionCenter = MyGridCenter; _sQuaternion = Quaternion.CreateFromRotationMatrix(MyGrid.WorldMatrix); ShieldSphere.Center = DetectionCenter; ShieldSphere.Radius = ShieldSize.AbsMax(); } else { var emitter = ShieldComp.StationEmitter.Emitter; var width = DsSet.Settings.Width; var height = DsSet.Settings.Height; var depth = DsSet.Settings.Depth; var wOffset = DsSet.Settings.ShieldOffset.X; var hOffset = DsSet.Settings.ShieldOffset.Y; var dOffset = DsSet.Settings.ShieldOffset.Z; var blockGridPosMeters = new Vector3D(emitter.Position) * MyGrid.GridSize; var localOffsetMeters = new Vector3D(wOffset, hOffset, dOffset) * MyGrid.GridSize; var localOffsetPosMeters = localOffsetMeters + blockGridPosMeters; var emitterCenter = emitter.PositionComp.GetPosition(); var offsetLMatrix = Matrix.CreateWorld(localOffsetPosMeters, Vector3D.Forward, Vector3D.Up); var worldOffset = Vector3D.TransformNormal(localOffsetMeters, MyGrid.WorldMatrix); var translationInWorldSpace = emitterCenter + worldOffset; OffsetEmitterWMatrix = MatrixD.CreateWorld(translationInWorldSpace, MyGrid.WorldMatrix.Forward, MyGrid.WorldMatrix.Up); DetectionCenter = OffsetEmitterWMatrix.Translation; var halfDistToCenter = 600 - Vector3D.Distance(DetectionCenter, emitterCenter); var vectorScale = new Vector3D(MathHelper.Clamp(width, 30, halfDistToCenter), MathHelper.Clamp(height, 30, halfDistToCenter), MathHelper.Clamp(depth, 30, halfDistToCenter)); DetectionMatrix = MatrixD.Rescale(OffsetEmitterWMatrix, vectorScale); ShieldShapeMatrix = MatrixD.Rescale(offsetLMatrix, vectorScale); ShieldSize = DetectionMatrix.Scale; _sQuaternion = Quaternion.CreateFromRotationMatrix(OffsetEmitterWMatrix); ShieldSphere.Center = DetectionCenter; ShieldSphere.Radius = ShieldSize.AbsMax(); } ShieldSphere3K.Center = DetectionCenter; WebSphere.Center = DetectionCenter; SOriBBoxD.Center = DetectionCenter; SOriBBoxD.Orientation = _sQuaternion; if (_shapeChanged) { SOriBBoxD.HalfExtent = ShieldSize; ShieldAabbScaled.Min = ShieldSize; ShieldAabbScaled.Max = -ShieldSize; _ellipsoidSa.Update(DetectMatrixOutside.Scale.X, DetectMatrixOutside.Scale.Y, DetectMatrixOutside.Scale.Z); BoundingRange = ShieldSize.AbsMax(); ShieldSphere3K.Radius = BoundingRange + 3000; WebSphere.Radius = BoundingRange + 7; _ellipsoidSurfaceArea = _ellipsoidSa.Surface; EllipsoidVolume = 1.333333 * Math.PI * DetectMatrixOutside.Scale.X * DetectMatrixOutside.Scale.Y * DetectMatrixOutside.Scale.Z; _shieldVol = DetectMatrixOutside.Scale.Volume; if (_isServer) { if (Session.Enforced.Debug == 3) { Log.Line($"StateUpdate: CreateShieldShape - Broadcast:{DsState.State.Message} - ShieldId [{Shield.EntityId}]"); } ShieldChangeState(); ShieldComp.ShieldVolume = DetectMatrixOutside.Scale.Volume; } if (Session.Enforced.Debug == 3) { Log.Line($"CreateShape: shapeChanged - GridMobile:{GridIsMobile} - ShieldId [{Shield.EntityId}]"); } } if (!DsState.State.Lowered) { SetShieldShape(); } BoundingBoxD.CreateFromSphere(ref WebSphere, out WebBox); BoundingBoxD.CreateFromSphere(ref ShieldSphere3K, out ShieldBox3K); }