private static bool Obstruction(ref TargetInfo info, ref Vector3D targetPos, Projectile p) { var ai = p.Info.Ai; var obstruction = false; for (int j = 0; j < ai.Obstructions.Count; j++) { var ent = ai.Obstructions[j]; var voxel = ent as MyVoxelBase; var dir = (targetPos - p.Position); var entWorldVolume = ent.PositionComp.WorldVolume; if (voxel != null) { if (!ai.PlanetSurfaceInRange && (entWorldVolume.Contains(p.Position) != ContainmentType.Disjoint || new RayD(ref p.Position, ref dir).Intersects(entWorldVolume) != null)) { var dirNorm = Vector3D.Normalize(dir); var targetDist = Vector3D.Distance(p.Position, targetPos); var tRadius = info.Target.PositionComp.LocalVolume.Radius; var testPos = p.Position + (dirNorm * (targetDist - tRadius)); var lineTest = new LineD(p.Position, testPos); Vector3D?voxelHit = null; using (voxel.Pin()) voxel.RootVoxel.GetIntersectionWithLine(ref lineTest, out voxelHit); obstruction = voxelHit.HasValue; if (obstruction) { break; } } } else { if (new RayD(ref p.Position, ref dir).Intersects(entWorldVolume) != null) { var transform = ent.PositionComp.WorldMatrixRef; var box = ent.PositionComp.LocalAABB; var obb = new MyOrientedBoundingBoxD(box, transform); var lineTest = new LineD(p.Position, targetPos); if (obb.Intersects(ref lineTest) != null) { obstruction = true; break; } } } } if (!obstruction) { var dir = (targetPos - p.Position); var ray = new RayD(ref p.Position, ref dir); foreach (var sub in ai.SubGrids) { var subDist = sub.PositionComp.WorldVolume.Intersects(ray); if (subDist.HasValue) { var transform = ai.MyGrid.PositionComp.WorldMatrixRef; var box = ai.MyGrid.PositionComp.LocalAABB; var obb = new MyOrientedBoundingBoxD(box, transform); if (obb.Intersects(ref ray) != null) { obstruction = sub.RayCastBlocks(p.Position, targetPos) != null; } } if (obstruction) { break; } } if (!obstruction && ai.PlanetSurfaceInRange && ai.MyPlanet != null) { double targetDist; Vector3D.Distance(ref p.Position, ref targetPos, out targetDist); var dirNorm = dir / targetDist; var tRadius = info.Target.PositionComp.LocalVolume.Radius; targetDist = targetDist > tRadius ? (targetDist - tRadius) : targetDist; var targetEdgePos = targetPos + (-dirNorm * tRadius); if (targetDist > 300) { var lineTest1 = new LineD(p.Position, p.Position + (dirNorm * 150), 150); var lineTest2 = new LineD(targetEdgePos, targetEdgePos + (-dirNorm * 150), 150); obstruction = VoxelIntersect.CheckSurfacePointsOnLine(ai.MyPlanet, ref lineTest1, 3); if (!obstruction) { obstruction = VoxelIntersect.CheckSurfacePointsOnLine(ai.MyPlanet, ref lineTest2, 3); } } else { var lineTest = new LineD(p.Position, targetEdgePos, targetDist); obstruction = VoxelIntersect.CheckSurfacePointsOnLine(ai.MyPlanet, ref lineTest, 3); } } } return(obstruction); }
private static bool Obstruction(ref TargetInfo info, ref Vector3D targetPos, Projectile p) { var ai = p.Info.Ai; var obstruction = false; for (int j = 0; j < ai.Obstructions.Count; j++) { var ent = ai.Obstructions[j]; var voxel = ent as MyVoxelBase; var dir = (targetPos - p.Position); if (voxel != null) { var voxelVolume = ent.PositionComp.WorldVolume; if (voxelVolume.Contains(p.Position) != ContainmentType.Disjoint || new RayD(ref p.Position, ref dir).Intersects(voxelVolume) != null) { var dirNorm = Vector3D.Normalize(dir); var targetDist = Vector3D.Distance(p.Position, targetPos); var tRadius = info.Target.PositionComp.LocalVolume.Radius; var testPos = p.Position + (dirNorm * (targetDist - tRadius)); var lineTest = new LineD(p.Position, testPos); Vector3D?voxelHit = null; using (voxel.Pin()) voxel.RootVoxel.GetIntersectionWithLine(ref lineTest, out voxelHit); obstruction = voxelHit.HasValue; if (obstruction) { break; } } } else { if (new RayD(ref p.Position, ref dir).Intersects(ent.PositionComp.WorldVolume) != null) { var rotMatrix = Quaternion.CreateFromRotationMatrix(ent.WorldMatrix); var obb = new MyOrientedBoundingBoxD(ent.PositionComp.WorldAABB.Center, ent.PositionComp.LocalAABB.HalfExtents, rotMatrix); var lineTest = new LineD(p.Position, targetPos); if (obb.Intersects(ref lineTest) != null) { obstruction = true; break; } } } } if (!obstruction) { var dir = (targetPos - p.Position); var ray = new RayD(ref p.Position, ref dir); foreach (var sub in ai.SubGrids) { var subDist = sub.PositionComp.WorldVolume.Intersects(ray); if (subDist.HasValue) { var rotMatrix = Quaternion.CreateFromRotationMatrix(ai.MyGrid.WorldMatrix); var obb = new MyOrientedBoundingBoxD(ai.MyGrid.PositionComp.WorldAABB.Center, ai.MyGrid.PositionComp.LocalAABB.HalfExtents, rotMatrix); if (obb.Intersects(ref ray) != null) { obstruction = sub.RayCastBlocks(p.Position, targetPos) != null; } } if (obstruction) { break; } } if (!obstruction && ai.PlanetSurfaceInRange && ai.MyPlanet != null) { var dirNorm = Vector3D.Normalize(dir); var targetDist = Vector3D.Distance(p.Position, targetPos); var tRadius = info.Target.PositionComp.LocalVolume.Radius; var testPos = p.Position + (dirNorm * (targetDist - tRadius)); var lineTest = new LineD(p.Position, testPos); using (ai.MyPlanet.Pin()) obstruction = VoxelIntersect.CheckSurfacePointsOnLine(ai.MyPlanet, lineTest, 2); //obstruction = voxelHit.HasValue; } } return(obstruction); }