Exemplo n.º 1
0
        /// <summary>
        /// Tries to retrieve targeted <see cref="IMyTerminalBlock"/> on a grid within a given distance.
        /// </summary>
        private bool TryGetTargetedBlockInternal(double maxDist, out IMyTerminalBlock target)
        {
            IMyCubeGrid cubeGrid;
            IHitInfo    rayInfo;
            MatrixD     transform = MyAPIGateway.Session.Camera.WorldMatrix;
            Vector3D    headPos = transform.Translation, forward = transform.Forward;

            if (!LocalPlayer.IsSpectating)
            {
                headPos += (headPos - LocalPlayer.Position).Length() * forward;
            }

            LineD line = new LineD(headPos, headPos + forward * maxDist);

            target = null;

            if ((LocalPlayer.IsControllingCharacter || LocalPlayer.IsSpectating) &&
                LocalPlayer.TryGetTargetedGrid(line, out cubeGrid, out rayInfo))
            {
                // Retrieve blocks within about half a block of the ray intersection point.
                var    sphere = new BoundingSphereD(rayInfo.Position, (cubeGrid.GridSizeEnum == MyCubeSize.Large) ? 1.3 : .3);
                double currentDist = double.PositiveInfinity, currentCenterDist = double.PositiveInfinity;

                tempGrid.SetGrid(cubeGrid, true);
                targetBuffer.Clear();
                tempGrid.GetBlocksInsideSphere(cubeGrid, targetBuffer, ref sphere);

                foreach (IMySlimBlock slimBlock in targetBuffer)
                {
                    IMyCubeBlock cubeBlock = slimBlock?.FatBlock;

                    if (cubeBlock != null)
                    {
                        var topBlock = cubeBlock as IMyAttachableTopBlock;

                        if (topBlock != null)
                        {
                            cubeBlock = topBlock.Base;
                        }
                    }

                    var tBlock = cubeBlock as IMyTerminalBlock;

                    if (tBlock != null)
                    {
                        // Find shortest dist between the bb and the intersection.
                        BoundingBoxD box           = cubeBlock.WorldAABB;
                        double       newDist       = Math.Round(box.DistanceSquared(rayInfo.Position), 3),
                                     newCenterDist = Math.Round(Vector3D.DistanceSquared(box.Center, rayInfo.Position), 3);

                        // If this is a terminal block, check to see if this block is any closer than the last.
                        // If the distance to the bb is zero, use the center dist, favoring smaller blocks.
                        if (
                            (currentDist > 0d && newDist < currentDist) ||
                            (Math.Abs(currentDist - newDist) < 0.02 && newCenterDist < currentCenterDist)
                            )
                        {
                            target            = tBlock;
                            currentDist       = newDist;
                            currentCenterDist = newCenterDist;
                        }
                    }
                }
            }

            tempGrid.Reset();
            return(target != null);
        }
Exemplo n.º 2
0
 public static double Distance(this BoundingBoxD first, BoundingBoxD second)
 {
     return(Math.Sqrt(first.DistanceSquared(second)));
 }