private void Move(Vector3 move)
        {
            Vector3 displacement = Vector3.ProjectOnPlane(move, currentFace.plane.normal);

            Vector3 potentialPosition = position + displacement;

            if (currentFace.source.IsPointInsideFace(potentialPosition, EpsilonOffset))
            {
                position = potentialPosition;
            }
            else
            {
                Vector3 clampedPosition     = currentFace.SnapToFace(position, displacement);
                Vector3 clampedDisplacement = clampedPosition - position;
                position = clampedPosition;
                Vector3 cutDisplacement = displacement.normalized * (displacement.magnitude - clampedDisplacement.magnitude); // + 2 * EpsilonOffset
                if (progress != null && progress.HasNextFace && progress.NextFace.IsPointInsideFace(position, EpsilonOffset))
                {
                    progress.currentFace++;
                    currentFace = new CachedFace(progress.CurrentFace);
                    var ray = new Ray(position, Vector3.down);
                    currentFace.plane.Raycast(ray, out float enter);
                    position = ray.GetPoint(enter);
                    while (progress.HasNextPoint && !progress.IsCurrentPointOnCurrentOrNextFaces())
                    {
                        progress.currentPoint++;
                    }
                    Move(cutDisplacement);
                }
                else
                {
                    position += currentFace.CastDisplacementOnClosestEdge(position, cutDisplacement);
                }
            }
        }