/// <summary> /// Tests for path intersection with voxel. /// </summary> /// <returns>True iff path is clear; voxel does not intersect path.</returns> private bool TestVoxel(MyVoxelBase voxel, Capsule path, out Vector3? pointOfObstruction) { if (m_ignoreAsteroid) { m_logger.debugLog("Ignoring asteroid: " + voxel.getBestName()); pointOfObstruction = null; return true; } Vector3[] intersection = new Vector3[2]; if (!path.IntersectsAABB(voxel, out intersection[0])) { m_logger.debugLog("path does not intersect AABB. " + voxel.getBestName(), Logger.severity.TRACE); pointOfObstruction = null; return true; } if (!path.get_Reverse().IntersectsAABB(voxel, out intersection[1])) { m_logger.debugLog("Reversed path does not intersect AABB, perhaps it moved? " + voxel.getBestName(), Logger.severity.WARNING); pointOfObstruction = null; return true; } Capsule testSection = new Capsule(intersection[0], intersection[1], path.Radius); IMyVoxelMap asteroid = voxel as IMyVoxelMap; if (asteroid != null) { if (testSection.Intersects(asteroid, out pointOfObstruction)) return false; } // planet test is done by PlanetChecker m_logger.debugLog("Does not intersect path: " + voxel.getBestName(), Logger.severity.TRACE); pointOfObstruction = null; return true; }
public bool TestSlow(out MyEntity blockingPath, out Vector3? pointOfObstruction) { m_logger.debugLog(m_offendingEntities == null, "m_offendingEntities == null, did you remember to call TestFast()?", "TestSlow()", Logger.severity.FATAL); IMyCubeBlock ignoreBlock = m_ignoreEntity as IMyCubeBlock; foreach (MyEntity entity in m_offendingEntities) { m_logger.debugLog("checking entity: " + entity.getBestName(), "TestSlow()"); IMyVoxelBase voxel = entity as IMyVoxelBase; if (voxel != null) { if (m_ignoreAsteroid) { m_logger.debugLog("Ignoring asteroid: " + voxel.getBestName(), "TestSlow()"); continue; } Vector3[] intersection = new Vector3[2]; if (!m_path.IntersectsAABB(voxel, out intersection[0])) { m_logger.debugLog("path does not intersect AABB. " + voxel.getBestName(), "TestSlow()", Logger.severity.TRACE); continue; } if (!m_path.get_Reverse().IntersectsAABB(voxel, out intersection[1])) { m_logger.debugLog("Reversed path does not intersect AABB, perhaps it moved? " + voxel.getBestName(), "TestSlow()", Logger.severity.WARNING); continue; } Capsule testSection = new Capsule(intersection[0], intersection[1], m_path.Radius); IMyVoxelMap asteroid = voxel as IMyVoxelMap; if (asteroid != null) { if (testSection.Intersects(asteroid, out pointOfObstruction)) { blockingPath = entity; return false; } } else { MyPlanet planet = voxel as MyPlanet; if (planet != null && testSection.Intersects(planet, out pointOfObstruction)) { blockingPath = entity; return false; } } m_logger.debugLog("Does not intersect path: " + voxel.getBestName(), "TestSlow()", Logger.severity.TRACE); continue; } IMyCubeGrid grid = entity as IMyCubeGrid; if (grid != null) { if (m_profiler.rejectionIntersects(grid, ignoreBlock, out blockingPath, out pointOfObstruction)) return false; continue; } m_logger.debugLog("not a grid, testing bounds", "TestSlow()"); if (!m_path.IntersectsAABB(entity)) continue; if (!m_path.IntersectsVolume(entity)) continue; m_logger.debugLog("no more tests for non-grids are implemented", "TestSlow()", Logger.severity.DEBUG); pointOfObstruction = m_path.get_Line().ClosestPoint(entity.GetCentre()); blockingPath = entity; return false; } blockingPath = null; pointOfObstruction = null; return true; }
/// <summary> /// Gets a point outside of an asteroid. /// </summary> /// <param name="startPoint">Where to start the search from, must be inside WorldAABB, can be inside or outside asteroid.</param> /// <param name="direction">Direction from outside asteroid towards inside asteroid</param> /// <param name="buffer">Minimum distance between the voxel and exterior point</param> private Vector3D GetExteriorPoint_Asteroid(Vector3D startPoint, Vector3 direction, float buffer) { IMyVoxelMap voxel = m_targetVoxel as IMyVoxelMap; if (voxel == null) { m_logger.alwaysLog("m_targetVoxel is not IMyVoxelMap: " + m_targetVoxel.getBestName(), Logger.severity.FATAL); throw new InvalidOperationException("m_targetVoxel is not IMyVoxelMap"); } Vector3 v = direction * m_targetVoxel.LocalAABB.GetLongestDim(); Capsule surfaceFinder = new Capsule(startPoint - v, startPoint + v, buffer); Vector3? obstruction; if (surfaceFinder.Intersects(voxel, out obstruction)) return obstruction.Value; else { m_logger.debugLog("Failed to intersect asteroid, using surfaceFinder.P0", Logger.severity.WARNING); return surfaceFinder.P0; } }