Во-первых... если ваше приложение ограничено ситуацией, когда устройство установлено постоянно, и пользователь никогда не может перемещать или поворачивать его, использование ARKit для отображения оверлейного контента на канале камеры - это своего рода "убийство комаров из пушки". ситуации. С тем же успехом вы могли бы во время разработки решить, какая проекция камеры нужна вашему 3D-движку, использовать «глупую» подачу камеры с вашим 3D-движком, работающим поверх, и не нуждаться в iOS 11 или устройстве с поддержкой ARKit.
Таким образом, вы можете подумать о своем сценарии использования или технологическом стеке, прежде чем приступать к конкретным решениям и обходным путям.
Что касается вашей более конкретной проблемы...
ARPlaneAnchor
полностью доступен только для чтения, потому что его вариант использования полностью доступен только для чтения. Он существует с единственной целью дать ARKit возможность предоставить вам информацию об обнаруженных самолетах. Однако, получив эту информацию, вы можете делать с ней все, что захотите. И с этого момента вам больше не нужно держать ARPlaneAnchor
в уравнении.
Возможно, вы запутались из-за типичного варианта использования для обнаружения плоскости (и отображения на основе SceneKit):
- Включите обнаружение самолетов
- Ответьте на
renderer(_:didAdd:for:)
, чтобы получить ARPlaneAnchor
объектов
- В этом методе возвращайте виртуальный контент для связи с якорем плоскости.
- Позвольте
ARSCNView
автоматически расположить это содержимое так, чтобы оно соответствовало положению плоскости.
Однако, если положение вашего самолета статично по отношению к камере, вам все это не нужно.
Вам нужно, чтобы ARKit управлял размещением вашего контента в сцене только в том случае, если это размещение требует постоянного управления, как в случае обнаружения плоскости в реальном времени (ARKit уточняет свои оценки местоположения и протяженности плоскости и обновляет якорь соответственно). Если вы выполнили поиск самолетов заранее, вы не будете получать обновления, поэтому вам не нужен ARKit для управления обновлениями.
Вместо этого ваши шаги могут выглядеть примерно так:
- Знать, где находится самолет (положение в мировом пространстве).
- Установите положение вашего виртуального контента в положение плоскости.
- Добавьте содержимое непосредственно в сцену.
Другими словами, ваше «Решение 2» — это шаг в правильном направлении, но недостаточно далеко. Вы хотите заархивировать не сам экземпляр ARPlaneAnchor
, а содержащуюся в нем информацию — и тогда при разархивировании вам не нужно заново создавать экземпляр ARPlaneAnchor
, вам просто нужно использовать эту информацию.
Итак, если это то, что вы делаете для размещения контента с «живым» обнаружением плоскости:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
let extent = planeAnchor.extent
let center = planeAnchor.center
// planeAnchor.transform not used, because ARSCNView automatically applies it
// to the container node, and we make a child of the container node
let plane = SCNPlane(width: CGFloat(extent.x), height: CGFloat(extent.z))
let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = .pi / 2
planeNode.simdPosition = center
node.addChildNode(planeNode)
}
Затем вы можете сделать что-то подобное для размещения статического контента:
struct PlaneInfo { // something to save and restore ARPlaneAnchor data
let transform: float4x4
let center: float3
let extent: float3
}
func makePlane(from planeInfo: PlaneInfo) { // call this when you place content
let extent = planeInfo.extent
let center = float4(planeInfo.center, 1) * planeInfo.transform
// we're positioning content in world space, so center is now
// an offset relative to transform
let plane = SCNPlane(width: CGFloat(extent.x), height: CGFloat(extent.z))
let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = .pi / 2
planeNode.simdPosition = center.xyz
view.scene.rootNode.addChildNode(planeNode)
}
// convenience vector-width conversions used above
extension float4 {
init(_ xyz: float3, _ w: Float) {
self.init(xyz.x, xyz.y, xyz.z, 1)
}
var xyz: float3 {
return float3(self.x, self.y, self.z)
}
}
person
rickster
schedule
25.07.2017
ARPlaneAnchor
не соответствуетNSCoding
- person Paolo   schedule 25.07.2017