Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }