public List <MyVoxelBase> GetAllOverlappingWithSphere(ref BoundingSphereD sphere) { List <MyVoxelBase> voxels = new List <MyVoxelBase>(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, voxels); return(voxels); }
bool IMyShipController.TryGetPlanetElevation(MyPlanetElevation detail, out double elevation) { var blockPosition = this.PositionComp.GetPosition(); if (!MyGravityProviderSystem.IsPositionInNaturalGravity(blockPosition)) { elevation = double.PositiveInfinity; return(false); } var boundingBox = PositionComp.WorldAABB; var nearestPlanet = MyGamePruningStructure.GetClosestPlanet(ref boundingBox); if (nearestPlanet == null) { elevation = double.PositiveInfinity; return(false); } switch (detail) { case MyPlanetElevation.Sealevel: elevation = ((boundingBox.Center - nearestPlanet.PositionComp.GetPosition()).Length() - nearestPlanet.AverageRadius); return(true); case MyPlanetElevation.Surface: var controlledEntityPosition = CubeGrid.Physics.CenterOfMassWorld; Vector3D closestPoint = nearestPlanet.GetClosestSurfacePointGlobal(ref controlledEntityPosition); elevation = Vector3D.Distance(closestPoint, controlledEntityPosition); return(true); default: throw new ArgumentOutOfRangeException("detail", detail, null); } }
public void AddToGamePruningStructure() { MyGamePruningStructure.Add(this); foreach (var child in Hierarchy.Children) { child.Entity.AddToGamePruningStructure(); } }
public void UpdateGamePruningStructure() { MyGamePruningStructure.Move(this); foreach (var child in Hierarchy.Children) { child.Entity.UpdateGamePruningStructure(); } }
public void RemoveFromGamePruningStructure() { MyGamePruningStructure.Remove(this); foreach (var child in Hierarchy.Children) { child.Entity.RemoveFromGamePruningStructure(); } }
public override void UpdateBeforeSimulation100() { base.UpdateBeforeSimulation100(); if (m_particleVectorUp == Vector3.Zero) { if (Entity.Physics.LinearVelocity != Vector3.Zero) { m_particleVectorUp = -Vector3.Normalize(Entity.Physics.LinearVelocity); } else { m_particleVectorUp = Vector3.Up; } m_particleVectorUp.CalculatePerpendicularVector(out m_particleVectorForward); } Vector3D pos = Entity.PositionComp.GetPosition(); var planet = MyGamePruningStructure.GetClosestPlanet(pos); MeteorStatus orig = m_meteorStatus; if (planet != null && planet.HasAtmosphere && planet.GetAirDensity(pos) > 0.5f) { m_meteorStatus = MeteorStatus.InAtmosphere; } else { m_meteorStatus = MeteorStatus.InSpace; } if (orig != m_meteorStatus && m_dustEffect != null) { m_dustEffect.Stop(); m_dustEffect = null; } if (m_dustEffect != null && !InParticleVisibleRange) { m_dustEffect.Stop(); m_dustEffect = null; } if (m_dustEffect == null && InParticleVisibleRange) { if (MyParticlesManager.TryCreateParticleEffect(m_particleEffectNames[(int)m_meteorStatus], out m_dustEffect)) { UpdateParticlePosition(); m_dustEffect.UserScale = Entity.PositionComp.Scale.Value; } } m_soundEmitter.Update(); if (Sync.IsServer && MySandboxGame.TotalGamePlayTimeInMilliseconds - m_timeCreated > Math.Min(MAX_TRAJECTORY_LENGTH / SPEED, MAX_TRAJECTORY_LENGTH / Entity.Physics.LinearVelocity.Length()) * 1000) { CloseMeteorInternal(); } }
public override void UpdateAfterSimulation100() { //Debug.Assert(MyExternalReplicable.FindByObject(this) != null, "Planet replicable not found, but it should be there"); base.UpdateAfterSimulation100(); if (m_physicsShapes != null) { ProfilerShort.Begin("Study shapes to remove"); foreach (var physicsShape in m_physicsShapes) { BoundingBoxD box; if (physicsShape.Value != null) { box = physicsShape.Value.PositionComp.WorldAABB; box.Min -= box.HalfExtents; box.Max += box.HalfExtents; } else { Vector3 min = (Vector3)physicsShape.Key * PHYSICS_SECTOR_SIZE_METERS + PositionLeftBottomCorner; box = new BoundingBoxD(min, min + PHYSICS_SECTOR_SIZE_METERS); } m_entities.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, m_entities); bool keep = false; foreach (var entity in m_entities) { if (entity.Physics != null && !entity.Physics.IsStatic) { keep = true; } } if (!keep) { m_sectorsPhysicsToRemove.Add(physicsShape.Key); } } foreach (var shapeToRemove in m_sectorsPhysicsToRemove) { MyVoxelPhysics physics; if (m_physicsShapes.TryGetValue(shapeToRemove, out physics)) { if (physics != null) { physics.Close(); } } m_physicsShapes.Remove(shapeToRemove); } m_sectorsPhysicsToRemove.Clear(); ProfilerShort.End(); } }
public static void UpdateGamePruningStructure(this MyEntity thisEntity) { if (thisEntity.Parent == null && thisEntity.InScene) { //Debug.Assert(thisEntity.Parent == null, "Only top most entity should be in prunning structure"); MyGamePruningStructure.Move(thisEntity); //foreach (var child in thisEntity.Hierarchy.Children) child.Container.Entity.UpdateGamePruningStructure(); } }
public static void RemoveFromGamePruningStructure(this MyEntity thisEntity) { MyGamePruningStructure.Remove(thisEntity); //if (thisEntity.Hierarchy != null) //{ // foreach (var child in thisEntity.Hierarchy.Children) // child.Container.Entity.RemoveFromGamePruningStructure(); //} }
public void RemoveFromGamePruningStructure() { MyGamePruningStructure.Remove(this); if (Hierarchy != null) { foreach (var child in Hierarchy.Children) { child.Container.Entity.RemoveFromGamePruningStructure(); } } }
private void UpdateFloraAndPhysics() { BoundingBoxD box = this.PositionComp.WorldAABB; box.Min -= PHYSICS_SECTOR_SIZE_METERS; box.Max += PHYSICS_SECTOR_SIZE_METERS; m_entities.Clear(); m_sectorsToKeep.Clear(); MyGamePruningStructure.GetAllTopMostEntitiesInBox <MyEntity>(ref box, m_entities); Vector3I increment = m_storage.Size / (m_numCells + 1); ProfilerShort.Begin("Myplanet::update physics"); foreach (var entity in m_entities) { if (entity.MarkedForClose || entity is MyPlanet || entity is MyVoxelMap) { continue; } Vector3D position = entity.PositionComp.GetPosition(); double distance = (WorldMatrix.Translation - position).Length(); if (IsInRange(position) == false) { continue; } var predictionOffset = ComputePredictionOffset(entity); if (CanSpawnFlora) { ProfilerShort.Begin("Myplanet:: spawn flora"); if ((predictionOffset.LengthSquared() > 0.03 || entity == MySession.LocalCharacter) && distance > m_planetInitValues.MinimumSurfaceRadius) { SpawnFlora(position); } ProfilerShort.End(); } var shapeBox = entity.PositionComp.WorldAABB; shapeBox.Inflate(MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES); shapeBox.Translate(predictionOffset); GeneratePhysicalShapeForBox(ref increment, ref shapeBox); } if (m_entities.Count < 1 && m_hasGeneratedTexture == true) { m_storage.DataProvider.ReleaseNoiseHelpTexture(); m_hasGeneratedTexture = false; } ProfilerShort.End(); }
public static void AddToGamePruningStructure(this MyEntity thisEntity) { if (thisEntity.Parent != null) { return; } //Debug.Assert(thisEntity.Parent == null,"Only top most entity should be in prunning structure"); MyGamePruningStructure.Add(thisEntity); //disabled for performance //to re enable this feature implement way to query hierarchy children //foreach (var child in thisEntity.Hierarchy.Children) // child.Container.Entity.AddToGamePruningStructure(); }
private void UpdatePlanetPhysics(ref BoundingBoxD box) { ProfilerShort.Begin("PlanetPhysics"); Vector3I increment = m_storage.Size / (m_numCells + 1); MyGamePruningStructure.GetAproximateDynamicClustersForSize(ref box, INTRASECTOR_OBJECT_CLUSTER_SIZE, m_clustersIntersection); foreach (var res in m_clustersIntersection) { var shapeBox = res; res.Inflate(MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES); GeneratePhysicalShapeForBox(ref increment, ref shapeBox); } m_clustersIntersection.Clear(); ProfilerShort.End(); }
public MyVoxelBase GetOverlappingWithSphere(ref BoundingSphereD sphere) { MyVoxelBase ret = null; MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, m_tmpVoxelMapsList); foreach (var voxelMap in m_tmpVoxelMapsList) { if (voxelMap.DoOverlapSphereTest((float)sphere.Radius, sphere.Center)) { ret = voxelMap; break; } } m_tmpVoxelMapsList.Clear(); return(ret); }
void CheckObjectInVoxel() { if (m_checkObjectInsideVoxel >= m_synchronizedFloatingObjects.Count) { m_checkObjectInsideVoxel = 0; } if (m_synchronizedFloatingObjects.Count > 0) { var floatingObjectToCheck = m_synchronizedFloatingObjects[m_checkObjectInsideVoxel]; var localAabb = (BoundingBoxD)floatingObjectToCheck.PositionComp.LocalAABB; var worldMatrix = floatingObjectToCheck.PositionComp.WorldMatrix; var worldAabb = floatingObjectToCheck.PositionComp.WorldAABB; using (m_tmpResultList.GetClearToken()) { MyGamePruningStructure.GetAllVoxelMapsInBox(ref worldAabb, m_tmpResultList); //Debug.Assert(m_tmpResultList.Count == 1, "Voxel map AABBs shouldn't overlap!"); foreach (var voxelMap in m_tmpResultList) { if (voxelMap != null && !voxelMap.MarkedForClose && !(voxelMap is MyVoxelPhysics)) { if (voxelMap.AreAllAabbCornersInside(ref worldMatrix, localAabb)) { floatingObjectToCheck.NumberOfFramesInsideVoxel++; if (floatingObjectToCheck.NumberOfFramesInsideVoxel > MyFloatingObject.NUMBER_OF_FRAMES_INSIDE_VOXEL_TO_REMOVE) { //MyLog.Default.WriteLine("Floating object " + (floatingObjectToCheck.DisplayName != null ? floatingObjectToCheck.DisplayName : floatingObjectToCheck.ToString()) + " was removed because it was inside voxel."); if (Sync.IsServer) { RemoveFloatingObject(floatingObjectToCheck); } } } else { floatingObjectToCheck.NumberOfFramesInsideVoxel = 0; } } } } } m_checkObjectInsideVoxel++; }
void CheckObjectInVoxel() { if (m_checkObjectInsideVoxel >= m_synchronizedFloatingObjects.Count) { m_checkObjectInsideVoxel = 0; } if (m_synchronizedFloatingObjects.Count > 0) { var floatingObjectToCheck = m_synchronizedFloatingObjects[m_checkObjectInsideVoxel]; BoundingBoxD aabb = floatingObjectToCheck.PositionComp.WorldAABB; using (m_tmpResultList.GetClearToken()) { MyGamePruningStructure.GetAllEntitiesInBox(ref aabb, m_tmpResultList); MyVoxelMap voxelMap = m_tmpResultList.Find(m_isVoxelMapPredicate) as MyVoxelMap; if (voxelMap != null && !voxelMap.MarkedForClose) { float unused; var penetrationAmountNormalized = voxelMap.GetVoxelContentInBoundingBox(aabb, out unused); var penetrationVolume = penetrationAmountNormalized * MyVoxelConstants.VOXEL_VOLUME_IN_METERS; var penetrationRatio = penetrationVolume / aabb.Volume; if (penetrationRatio >= 1.0f) { floatingObjectToCheck.NumberOfFramesInsideVoxel++; if (floatingObjectToCheck.NumberOfFramesInsideVoxel > MyFloatingObject.NUMBER_OF_FRAMES_INSIDE_VOXEL_TO_REMOVE) { //MyLog.Default.WriteLine("Floating object " + (floatingObjectToCheck.DisplayName != null ? floatingObjectToCheck.DisplayName : floatingObjectToCheck.ToString()) + " was removed because it was inside voxel."); if (Sync.IsServer) { RemoveFloatingObject(floatingObjectToCheck); } } } else { floatingObjectToCheck.NumberOfFramesInsideVoxel = 0; } } } } m_checkObjectInsideVoxel++; }
private void UpdateFloraAndPhysics() { BoundingBoxD box = this.PositionComp.WorldAABB; box.Min -= PHYSICS_SECTOR_SIZE_METERS; box.Max += PHYSICS_SECTOR_SIZE_METERS; m_entities.Clear(); m_sectorsToKeep.Clear(); MyGamePruningStructure.GetAllTopMostEntitiesInBox <MyEntity>(ref box, m_entities); Vector3I increment = m_storage.Size / (m_numCells + 1); ProfilerShort.Begin("Myplanet::update physics"); foreach (var entity in m_entities) { if (entity.MarkedForClose || entity is MyPlanet || entity is MyVoxelMap) { continue; } Vector3D position = entity.PositionComp.GetPosition(); double distance = (WorldMatrix.Translation - position).Length(); if (IsInRange(position) == false) { continue; } var predictionOffset = ComputePredictionOffset(entity); if (CanSpawnFlora) { ProfilerShort.Begin("Myplanet:: spawn flora"); SpawnFlora(position); ProfilerShort.End(); } var shapeBox = entity.PositionComp.WorldAABB; shapeBox.Inflate(MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES); shapeBox.Translate(predictionOffset); GeneratePhysicalShapeForBox(ref increment, ref shapeBox); } ProfilerShort.End(); }
public override void UpdateAfterSimulation100() { base.UpdateAfterSimulation100(); if (CanSpawnFlora && MySession.LocalHumanPlayer != null) { Vector3D playerPosition = MySession.LocalHumanPlayer.GetPosition(); if (IsInRange(playerPosition) && !MySandboxGame.IsDedicated) { GenerateFloraGraphics(playerPosition); } } m_sectorsToRemove.Clear(); if (m_physicsShapes != null) { foreach (var physicsShape in m_physicsShapes) { m_entities.Clear(); BoundingBoxD box = physicsShape.Value.PositionComp.WorldAABB; box.Min -= 2.0 * box.HalfExtents; box.Max += 2.0 * box.HalfExtents; MyGamePruningStructure.GetAllTopMostEntitiesInBox <MyEntity>(ref box, m_entities); if (m_entities.Count < 2) { m_sectorsToRemove.Add(physicsShape.Key); } } } foreach (var shapeToRemove in m_sectorsToRemove) { MyVoxelPhysics physics; if (m_physicsShapes.TryGetValue(shapeToRemove, out physics)) { physics.Close(); } m_physicsShapes.Remove(shapeToRemove); } m_sectorsToRemove.Clear(); }
private bool TestPlacement() { if (MySession.Static.ControlledEntity != null && (MySession.Static.GetCameraControllerEnum() == MyCameraControllerEnum.Entity || MySession.Static.GetCameraControllerEnum() == MyCameraControllerEnum.ThirdPersonSpectator || MySession.Static.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator)) { for (int i = 0; i < m_previewVoxelMaps.Count; ++i) { var aabb = m_previewVoxelMaps[i].PositionComp.WorldAABB; using (m_tmpResultList.GetClearToken()) { MyGamePruningStructure.GetTopMostEntitiesInBox(ref aabb, m_tmpResultList); if (TestPlacement(m_tmpResultList) == false) { return(false); } } } if (m_planetMode) { for (int i = 0; i < m_copiedVoxelMaps.Count; ++i) { MyObjectBuilder_Planet builder = m_copiedVoxelMaps[i] as MyObjectBuilder_Planet; if (builder != null) { using (m_tmpResultList.GetClearToken()) { BoundingSphereD sphere = new BoundingSphereD(m_pastePosition, builder.Radius * 1.1f); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, m_tmpResultList); if (TestPlacement(m_tmpResultList) == false) { return(false); } } } } } } return(true); }
private static void StartSurprise(object senderEvent) { BoundingSphereD sphere = new BoundingSphereD(new Vector3D(-18.75f, -2.5f, -1.25f), 2); m_getEntities.Clear(); MyGamePruningStructure.GetAllEntitiesInSphere(ref sphere, m_getEntities); m_spawnMedical = null; foreach (var entity in m_getEntities) { m_spawnMedical = entity as MyMedicalRoom; if (m_spawnMedical != null) { m_spawnMedical.OnClose += delegate { m_spawnMedical = null; }; break; } } m_started = true; }
bool IMyShipController.TryGetPlanetPosition(out Vector3D position) { var blockPosition = this.PositionComp.GetPosition(); if (!MyGravityProviderSystem.IsPositionInNaturalGravity(blockPosition)) { position = Vector3D.Zero; return(false); } var boundingBox = PositionComp.WorldAABB; var nearestPlanet = MyGamePruningStructure.GetClosestPlanet(ref boundingBox); if (nearestPlanet == null) { position = Vector3D.Zero; return(false); } position = nearestPlanet.PositionComp.GetPosition(); return(true); }
private void CheckObjectInVoxel() { if (m_checkObjectInsideVoxel >= m_synchronizedFloatingObjects.Count) { m_checkObjectInsideVoxel = 0; } if (m_synchronizedFloatingObjects.Count > 0) { MyFloatingObject obj2 = m_synchronizedFloatingObjects[m_checkObjectInsideVoxel]; BoundingBoxD localAABB = obj2.PositionComp.LocalAABB; MatrixD worldMatrix = obj2.PositionComp.WorldMatrix; BoundingBoxD worldAABB = obj2.PositionComp.WorldAABB; using (m_tmpResultList.GetClearToken <MyVoxelBase>()) { MyGamePruningStructure.GetAllVoxelMapsInBox(ref worldAABB, m_tmpResultList); foreach (MyVoxelBase base2 in m_tmpResultList) { if (base2 == null) { continue; } if (!base2.MarkedForClose && !(base2 is MyVoxelPhysics)) { if (!base2.AreAllAabbCornersInside(ref worldMatrix, localAABB)) { obj2.NumberOfFramesInsideVoxel = 0; continue; } obj2.NumberOfFramesInsideVoxel++; if ((obj2.NumberOfFramesInsideVoxel > 5) && Sync.IsServer) { RemoveFloatingObject(obj2); } } } } } m_checkObjectInsideVoxel++; }
public static void AddToGamePruningStructure(this MyEntity thisEntity) { MyGamePruningStructure.Add(thisEntity); }
/** * Scan sectors arround entities in planet and update them accordingly. */ private void UpdateSectors(bool serial, ref BoundingBoxD box) { // Prepare sectors for update foreach (var sp in m_planetEnvironmentSectors) { sp.Value.PrepareForUpdate(); } // Find all entities, spawn physics arround ships and players, spawn graphics arround cameras ProfilerShort.Begin("Update Sectors"); MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, m_entities, MyEntityQueryType.Dynamic); foreach (var entity in m_entities) { // entity is MyPlanet || entity is MyVoxelMap || entity is MyEnvironmentItems should all be static // If any of that changes keep in mind they must be skipped // It is also important to avoid adding physics where there are no clusters, otherwise the entities won't get activated properly. if (entity.MarkedForClose || entity.Physics == null || entity.Physics.IsStatic) { continue; } Vector3 position = entity.PositionComp.GetPosition() - WorldMatrix.Translation; double distanceSq = position.LengthSquared(); var predictionOffset = ComputePredictionOffset(entity); if (CanSpawnFlora && RUN_SECTORS && distanceSq >= Ranges.PLANET_PHYSICS_SCAN_MIN && distanceSq <= Ranges.PLANET_PHYSICS_SCAN_MAX) { ProfilerShort.Begin("EntitySpawn"); position += predictionOffset; MyPlanetSectorId sectId; GetSectorIdAt(position, out sectId); MyPlanetEnvironmentSector sector; if (!m_planetEnvironmentSectors.TryGetValue(sectId, out sector) || !sector.HasEntity) { ForEachSector(position, SECTOR_PHYSICS_EXTENT + SECTOR_KEEP_INFLATE, SectorPhysicsDelegate); } if ((sector != null || m_planetEnvironmentSectors.TryGetValue(sectId, out sector)) && !sector.ShouldClose) { // Make sure other entities in same sector do not cause new scans. sector.HasEntity = true; } ProfilerShort.End(); } } if (CanSpawnFlora && RUN_SECTORS) { ProfilerShort.Begin("MainCameraSpawn"); Vector3D position = MySector.MainCamera.Position - WorldMatrix.Translation; double distanceSq = position.LengthSquared(); if (distanceSq > Ranges.PLANET_GRAPHICS_SCAN_MIN && distanceSq < Ranges.PLANET_GRAPHICS_SCAN_MAX) { ForEachSector(position, SECTOR_LOD1_EXTENT + SECTOR_KEEP_INFLATE, SectorGraphicsDelegate); } ProfilerShort.End(); // Remove sectors marked for removal and enqueue sectors with pending operations. ProfilerShort.Begin("Recycle Sectors"); m_sectorsToRemove.Clear(); foreach (var sp in m_planetEnvironmentSectors) { var sector = sp.Value; using (sector.AcquireStatusLock()) { sector.EvaluateOperations(); if (sector.ShouldClose) { if ((sector.PendingOperations & MyPlanetEnvironmentSector.SERIAL_OPERATIONS_MASK) != 0) { // This will close the sector here if necessary. sector.DoSerialWork(false); } Debug.Assert(sector.IsClosed); m_planetSectorsPool.Deallocate(sector); m_sectorsToRemove.Add(sp.Key); } else if (sector.ParallelPending) { if (!sector.IsQueuedParallel && sector.ParallelPending) { sector.IsQueuedParallel = true; SectorsToWorkParallel.Enqueue(sector); } } else if (sector.SerialPending && !sector.IsQueuedSerial) { SectorsToWorkSerial.Enqueue(sector); sector.IsQueuedSerial = true; } } } // Remove from the dictionary all the sectors that were closed foreach (var sector in m_sectorsToRemove) { m_planetEnvironmentSectors.Remove(sector); } ProfilerShort.End(); ProfilerShort.Begin("Schedule Tasks"); // Lastly we start the sectors worker if any work is left in the queue. if (!m_sectorsWorking) { if (SectorsToWorkParallel.Count > 0) { m_sectorsWorking = true; if (serial) { ParallelWorkCallback(); SerialWorkCallback(); } else { Parallel.Start(m_parallelWorkDelegate, m_serialWorkDelegate); } } else { SerialWorkCallback(); } } ProfilerShort.End(); } ProfilerShort.End(); WrapCounters(); }
public static void RemoveFromGamePruningStructure(this MyEntity thisEntity) { MyGamePruningStructure.Remove(thisEntity); }
public static void UpdateGamePruningStructure(this MyEntity thisEntity) { MyGamePruningStructure.Move(thisEntity); }
public MyDetectedEntityInfo Raycast(double distance, Vector3D direction) { if (Vector3D.IsZero(direction)) { throw new ArgumentOutOfRangeException("direction", "Direction cannot be 0,0,0"); } //mods can disable raycast on a block by setting the distance limit to 0 (-1 means infinite) if (distance <= 0 || (BlockDefinition.RaycastDistanceLimit > -1 && distance > BlockDefinition.RaycastDistanceLimit)) { return(new MyDetectedEntityInfo()); } if (AvailableScanRange < distance || !this.CheckIsWorking()) { return(new MyDetectedEntityInfo()); } AvailableScanRange -= distance; var startPos = this.WorldMatrix.Translation; var targetPos = startPos + direction * distance; //try a physics raycast first //very accurate, but very slow List <MyPhysics.HitInfo> hits = new List <MyPhysics.HitInfo>(); MyPhysics.CastRay(startPos, targetPos, hits); foreach (var hit in hits) { var entity = (MyEntity)hit.HkHitInfo.GetHitEntity(); if (entity == this) { continue; } m_lastRay = new RaycastInfo() { Distance = distance, Start = startPos, End = targetPos, Hit = hit.Position }; return(MyDetectedEntityInfoHelper.Create(entity, this.OwnerId, hit.Position)); } //long-distance planet scanning //fastest way is to intersect planet bounding boxes then treat the planet as a sphere LineD line = new LineD(startPos, targetPos); var voxels = new List <MyLineSegmentOverlapResult <MyVoxelBase> >(); MyGamePruningStructure.GetVoxelMapsOverlappingRay(ref line, voxels); foreach (var result in voxels) { var planet = result.Element as MyPlanet; if (planet == null) { continue; } double distCenter = Vector3D.DistanceSquared(this.PositionComp.GetPosition(), planet.PositionComp.GetPosition()); var gravComp = planet.Components.Get <MyGravityProviderComponent>(); if (gravComp == null) { continue; } if (!gravComp.IsPositionInRange(startPos) && distCenter > planet.MaximumRadius * planet.MaximumRadius) { var boundingSphere = new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MaximumRadius); var rayd = new RayD(startPos, direction); var intersection = boundingSphere.Intersects(rayd); if (!intersection.HasValue) { continue; } if (distance < intersection.Value) { continue; } var hitPos = startPos + direction * intersection.Value; m_lastRay = new RaycastInfo() { Distance = distance, Start = startPos, End = targetPos, Hit = hitPos }; return(MyDetectedEntityInfoHelper.Create(result.Element, this.OwnerId, hitPos)); } //if the camera is inside gravity, query voxel storage if (planet.RootVoxel.Storage == null) { continue; } var start = Vector3D.Transform(line.From, planet.PositionComp.WorldMatrixInvScaled); start += planet.SizeInMetresHalf; var end = Vector3D.Transform(line.To, planet.PositionComp.WorldMatrixInvScaled); end += planet.SizeInMetresHalf; var voxRay = new LineD(start, end); double startOffset; double endOffset; if (!planet.RootVoxel.Storage.DataProvider.Intersect(ref voxRay, out startOffset, out endOffset)) { continue; } var from = voxRay.From; voxRay.From = from + voxRay.Direction * voxRay.Length * startOffset; voxRay.To = from + voxRay.Direction * voxRay.Length * endOffset; start = voxRay.From - planet.SizeInMetresHalf; start = Vector3D.Transform(start, planet.PositionComp.WorldMatrix); m_lastRay = new RaycastInfo() { Distance = distance, Start = startPos, End = targetPos, Hit = start }; return(MyDetectedEntityInfoHelper.Create(result.Element, this.OwnerId, start)); } m_lastRay = new RaycastInfo() { Distance = distance, Start = startPos, End = targetPos, Hit = null }; return(new MyDetectedEntityInfo()); }
public void GetAllOverlappingWithSphere(ref BoundingSphereD sphere, List <MyVoxelBase> voxels) { MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, voxels); }
private bool TestPlacement() { if (MySession.ControlledEntity != null && (MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Entity || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.ThirdPersonSpectator)) { for (int i = 0; i < m_previewVoxelMaps.Count; ++i) { var aabb = m_previewVoxelMaps[i].PositionComp.WorldAABB; using (m_tmpResultList.GetClearToken()) { MyGamePruningStructure.GetAllEntitiesInBox(ref aabb, m_tmpResultList); foreach (var entity in m_tmpResultList) { m_tmpResultHashset.Add(entity.GetTopMostParent()); } foreach (var entity in m_tmpResultHashset) { //ignore asteroids if (entity is MyVoxelBase) { continue; } //ignore stations if (entity is MyCubeGrid) { var grid = entity as MyCubeGrid; if (grid.IsStatic) { continue; } } switch (m_previewVoxelMaps[i].GetVoxelRangeTypeInBoundingBox(entity.PositionComp.WorldAABB)) { case MyVoxelRangeType.EMPTY: break; case MyVoxelRangeType.MIXED: { m_tmpResultList.Clear(); m_tmpResultHashset.Clear(); return(false); } break; case MyVoxelRangeType.FULL: { m_tmpResultList.Clear(); m_tmpResultHashset.Clear(); return(false); } break; default: throw new InvalidBranchException(); break; } } m_tmpResultHashset.Clear(); } } } return(true); }