Как узнать, недоступна ли поверхность, обнаруженная ARKit?

Я работаю над приложением с фреймворками ARKit и SceneKit. В моем приложении я включил обнаружение поверхности (я следовал за образцом размещения объектов, предоставленным Apple). Как определить, что обнаруженная поверхность больше не доступна? То есть изначально только если пользователь обнаружил поверхность в ARSession, я разрешаю ему разместить 3D-объект.

Но если пользователь быстро перемещается или фокусируется где-то, обнаруженная площадь поверхности теряется. В этом случае, если пользователь пытается разместить другой объект, я не должен позволять ему размещать его, пока он снова не отсканирует пол и не исправит поверхность.

Есть ли какой-нибудь делегат, который может сообщить нам, что обнаруженная поверхность больше не доступна?

2 ответа

Есть функции делегата, которые вы можете использовать. Делегат является ARSCNViewDelegate

У него есть функция, которая renderer(_:didRemove:for:) Это срабатывает, когда ARAnchor был удален. Вы можете использовать эту функцию для выполнения некоторых операций при удалении поверхности.

ARSCNViewDelegate Ссылка

Есть два способа "потерять" поверхность, поэтому существует несколько подходов к решению такой проблемы.


Как отмечено в другом ответе, есть ARSCNViewDelegate метод, который вызывает ARKit, когда якорь удаляется из сеанса AR. Тем не менее, ARKit не удаляет привязки самолета во время сеанса работы - как только он обнаружил самолет, он предполагает, что самолет всегда там. Так что этот метод вызывается только если:

  1. Вы удаляете якорь самолета, передавая его session.remove(anchor:), или же
  2. Вы сбрасываете сеанс, запустив его снова с .removeExistingAnchors вариант.

Я не уверен, что первое - хорошая идея, но со вторым важно справиться, поэтому вы, вероятно, хотите, чтобы ваш делегат справился с этим хорошо.


Вы также можете "потерять" поверхность, пропустив ее из поля зрения - например, ARKit обнаруживает стол, а затем пользователь поворачивается, чтобы камера больше не была направлена ​​на стол или рядом с ним.

Сам ARKit не предлагает никакой помощи для решения этой проблемы. Тем не менее, он дает вам всю информацию, необходимую для математики. Вы получите положение, ориентацию и размер привязки плоскости, чтобы вы могли рассчитать четыре ее угловых точки. И вы получаете матрицу проекции камеры, так что вы можете проверить, есть ли какая-либо точка в усечении просмотра.

Так как вы уже используете SceneKit, есть также способы заставить SceneKit сделать математику за вас... Работа в обратном направлении:

  1. SceneKit дает вам isNode(_:insideFrustumOf:) тест, так что если у вас есть SCNNode чья ограничительная рамка соответствует размеру вашей плоскости привязки, вы можете передать это вместе с камерой (view.pointOfView) чтобы узнать, виден ли узел.
  2. Чтобы получить узел, ограничивающий прямоугольник которого совпадает с привязкой к плоскости, реализуйте ARSCNViewDelegatedidAdd а также didUpdate обратные вызовы для создания / обновления SCNPlane чье положение и размеры соответствуют ARPlaneAnchorЦентр и степень. (Не забудьте перевернуть самолет в сторону, так как SCNPlane по умолчанию вертикально ориентирован.)
  3. Если вы не хотите, чтобы эта плоскость была видна в представлении AR, установите ее материалы прозрачными.
Другие вопросы по тегам