コード例 #1
0
        public BlockSelection GetSelectedBlock(float maxDistance, BlockFilter filter = null)
        {
            float distanceSq = 0;

            // Get the face where our ray will exit
            BlockFacing lastExitedBlockFace = GetExitingFullBlockFace(pos, ref lastExitedBlockFacePos);

            if (lastExitedBlockFace == null)
            {
                return(null);
            }

            float maxDistanceSq = (maxDistance + 1) * (maxDistance + 1);

            // Wander along the block exiting faces until we collide with a block selection box
            while (!RayIntersectsBlockSelectionBox(pos, filter))
            {
                if (distanceSq >= maxDistanceSq)
                {
                    return(null);
                }

                pos.Offset(lastExitedBlockFace);

                lastExitedBlockFace = GetExitingFullBlockFace(pos, ref lastExitedBlockFacePos);
                if (lastExitedBlockFace == null)
                {
                    return(null);
                }

                distanceSq = pos.DistanceSqTo(ray.origin.X - 0.5f, ray.origin.Y - 0.5f, ray.origin.Z - 0.5f);
            }


            if (hitPosition.SquareDistanceTo(ray.origin) > maxDistance * maxDistance)
            {
                return(null);
            }


            return(new BlockSelection()
            {
                Face = hitOnBlockFace,
                Position = pos.Copy(),
                HitPosition = hitPosition.SubCopy(pos.X, pos.Y, pos.Z),
                SelectionBoxIndex = hitOnSelectionBox
            });
        }
コード例 #2
0
ファイル: AABBIntersectionTest.cs プロジェクト: Archina/vsapi
        public bool RayIntersectsBlockSelectionBox(BlockPos pos, BlockFilter filter)
        {
            if (filter?.Invoke(pos, blockSelectionTester.GetBlock(pos)) == false)
            {
                return(false);
            }

            Cuboidf[] selectionBoxes = blockSelectionTester.GetBlockIntersectionBoxes(pos);
            if (selectionBoxes == null)
            {
                return(false);
            }

            bool intersects = false;

            for (int i = 0; i < selectionBoxes.Length; i++)
            {
                tmpCuboidd.Set(selectionBoxes[i]).Translate(pos.X, pos.Y, pos.Z);
                if (RayIntersectsWithCuboid(tmpCuboidd, ref hitOnBlockFaceTmp, ref hitPositionTmp))
                {
                    if (intersects && hitPosition.SquareDistanceTo(ray.origin) <= hitPositionTmp.SquareDistanceTo(ray.origin))
                    {
                        continue;
                    }

                    hitOnSelectionBox = i;
                    intersects        = true;
                    hitOnBlockFace    = hitOnBlockFaceTmp;
                    hitPosition.Set(hitPositionTmp);
                }
            }

            return(intersects);
        }
コード例 #3
0
        public bool RayIntersectsBlockSelectionBox(BlockPos pos, BlockFilter filter)
        {
            if (filter?.Invoke(pos, blockSelectionTester.GetBlock(pos)) == false)
            {
                return(false);
            }

            Cuboidf[] selectionBoxes = blockSelectionTester.GetBlockIntersectionBoxes(pos);
            if (selectionBoxes == null)
            {
                return(false);
            }

            bool intersects = false;
            bool wasDecor   = false;

            for (int i = 0; i < selectionBoxes.Length; i++)
            {
                tmpCuboidd.Set(selectionBoxes[i]).Translate(pos.X, pos.Y, pos.Z);
                if (RayIntersectsWithCuboid(tmpCuboidd, ref hitOnBlockFaceTmp, ref hitPositionTmp))
                {
                    bool isDecor = selectionBoxes[i] is DecorSelectionBox;
                    if (intersects && (!wasDecor || isDecor) && hitPosition.SquareDistanceTo(ray.origin) <= hitPositionTmp.SquareDistanceTo(ray.origin))
                    {
                        continue;
                    }

                    hitOnSelectionBox = i;
                    intersects        = true;
                    wasDecor          = isDecor;
                    hitOnBlockFace    = hitOnBlockFaceTmp;
                    hitPosition.Set(hitPositionTmp);
                }
            }

            if (intersects && selectionBoxes[hitOnSelectionBox] is DecorSelectionBox dsb)
            {
                Vec3i posAdjust = dsb.PosAdjust;
                if (posAdjust != null)
                {
                    pos.Add(posAdjust);
                }
            }

            return(intersects);
        }