Exemplo n.º 1
0
        /// <summary>
        /// <para>Test line segment between startPosition and targetPosition for obstructing entities.</para>
        /// <para>Tests for obstructing voxel map, character, or grid.</para>
        ///// <param name="shortTest">When checking voxels, shortens the line by 1 m, needed to interact with an entity that may be on the surface of the voxel.</param>
        /// </summary>
        public static bool Obstructed <Tignore>(LineD line, IEnumerable <Tignore> ignoreList, bool checkVoxel = true, bool checkPlanet = DefaultCheckPlanet) where Tignore : IMyEntity
        {
            List <MyLineSegmentOverlapResult <MyEntity> > potentialObstruction = ResourcePool <List <MyLineSegmentOverlapResult <MyEntity> > > .Get();

            MyGamePruningStructure.GetAllEntitiesInRay(ref line, potentialObstruction);
            bool result = Obstructed(line, potentialObstruction.Select(overlap => overlap.Element), ignoreList, checkVoxel, checkPlanet);

            potentialObstruction.Clear();
            ResourcePool <List <MyLineSegmentOverlapResult <MyEntity> > > .Return(potentialObstruction);

            return(result);
        }
Exemplo n.º 2
0
        public static bool IntersectsVoxel(ref CapsuleD capsule, out MyVoxelBase hitVoxel, out Vector3D hitPosition, bool checkPlanet, double capsuleLength = -1d)
        {
            Profiler.StartProfileBlock();
            if (capsuleLength < 0)
            {
                Vector3D.Distance(ref capsule.P0, ref capsule.P1, out capsuleLength);
            }
            double   halfLength = capsuleLength * 0.5d;
            Vector3D temp; Vector3D.Add(ref capsule.P0, ref capsule.P1, out temp);
            Vector3D middle; Vector3D.Multiply(ref temp, 0.5d, out middle);

            double          radius      = halfLength + capsule.Radius;
            BoundingSphereD worldSphere = new BoundingSphereD()
            {
                Center = middle, Radius = radius
            };

            List <MyVoxelBase> voxels = ResourcePool <List <MyVoxelBase> > .Get();

            MyGamePruningStructure.GetAllVoxelMapsInSphere(ref worldSphere, voxels);

            foreach (MyVoxelBase voxel in voxels)
            {
                if ((voxel is MyVoxelMap || voxel is MyPlanet && checkPlanet) && Intersects(ref capsule, voxel, out hitPosition, capsuleLength))
                {
                    hitVoxel = voxel;
                    voxels.Clear();
                    ResourcePool.Return(voxels);
                    Profiler.EndProfileBlock();
                    return(true);
                }
            }

            voxels.Clear();
            ResourcePool.Return(voxels);

            hitVoxel    = null;
            hitPosition = Vector3.Invalid;
            Profiler.EndProfileBlock();
            return(false);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Estimates the proximity between a given capsule and any voxel.
        /// </summary>
        /// <param name="capsule">The capsule to test for intersection, the points must be at least one metre apart.</param>
        public static double ProximityToVoxel(ref CapsuleD capsule, out MyVoxelBase hitVoxel, out Vector3D hitPosition, bool checkPlanet, double capsuleLength = -1d)
        {
            Profiler.StartProfileBlock();
            if (capsuleLength < 0)
            {
                Vector3D.Distance(ref capsule.P0, ref capsule.P1, out capsuleLength);
            }
            double   halfLength = capsuleLength * 0.5d;
            Vector3D temp; Vector3D.Add(ref capsule.P0, ref capsule.P1, out temp);
            Vector3D middle; Vector3D.Multiply(ref temp, 0.5d, out middle);

            double          radius      = halfLength + capsule.Radius;
            BoundingSphereD worldSphere = new BoundingSphereD()
            {
                Center = middle, Radius = radius
            };

            List <MyVoxelBase> voxels = ResourcePool <List <MyVoxelBase> > .Get();

            MyGamePruningStructure.GetAllVoxelMapsInSphere(ref worldSphere, voxels);

            double closestProx = double.MaxValue;

            hitPosition = Globals.Invalid;
            foreach (MyVoxelBase voxel in voxels)
            {
                if (voxel is MyVoxelMap || voxel is MyPlanet && checkPlanet)
                {
                    if (voxel is MyPlanet)
                    {
                        LineSegmentD line;
                        ResourcePool.Get(out line);
                        line.From = capsule.P0;
                        line.To   = capsule.P1;

                        double minDistSq       = line.DistanceSquared(voxel.GetCentre());
                        double maxPlanetRadius = ((MyPlanet)voxel).MaximumRadius;

                        ResourcePool.Return(line);

                        if (minDistSq > maxPlanetRadius * maxPlanetRadius)
                        {
                            Logger.DebugLog("Skip planet from: " + line.From + ", to: " + line.To + ", planet centre: " + voxel.GetCentre() + ", min dist sq to centre: " + minDistSq + ", max planet radius: " + maxPlanetRadius);
                            continue;
                        }
                        Logger.DebugLog("Check planet from: " + line.From + ", to: " + line.To + ", planet centre: " + voxel.GetCentre() + ", min dist sq to centre: " + minDistSq + ", max planet radius: " + maxPlanetRadius);
                    }

                    double proximity = Proximity(ref capsule, voxel, ref hitPosition, capsuleLength);
                    if (proximity < closestProx)
                    {
                        Logger.TraceLog("proximity is less than closest. proximity: " + proximity + ", closest: " + closestProx);
                        closestProx = proximity;
                    }
                    if (closestProx < 1d)
                    {
                        Logger.TraceLog("closest under 1: " + closestProx);
                        hitVoxel = voxel;
                        voxels.Clear();
                        ResourcePool.Return(voxels);
                        Profiler.EndProfileBlock();
                        return(closestProx);
                    }
                }
            }

            voxels.Clear();
            ResourcePool.Return(voxels);

            hitVoxel = null;
            Profiler.EndProfileBlock();
            return(closestProx);
        }
Exemplo n.º 4
0
 public static void Get <T>(out T item) where T : new()
 {
     item = ResourcePool <T> .Get();
 }
Exemplo n.º 5
0
 public static void Return <T>(T item) where T : new()
 {
     ResourcePool <T> .Return(item);
 }