Создание окна с помощью SceneKit и ARKit - swift


1

Я пытаюсь создать примитив с SceneKit и ARKit. По какой-то причине он не работает.

let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)

    let node = SCNNode(geometry: box)

    node.position = SCNVector3(0,0,0)

    sceneView.scene.rootNode.addChildNode(node)

Нужно ли мне также принимать координаты камеры?

Источник
  •  19
  •  4
  • 9 мар 2020 2020-03-09 14:05:21

4 ответа

2

Вы должны получить местонахождение и использовать координаты мира, чтобы поместить куб должным образом. Я не уверен (0,0,0) - это нормальное место для ARKit. Вы можете попробовать что-то вроде этого:
Поместите это в свой viewDidLoad:

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapFrom))
tapGestureRecognizer.numberOfTapsRequired = 1
self.sceneView.addGestureRecognizer(tapGestureRecognizer)

Затем добавьте этот метод:

@objc func handleTapFrom(recognizer: UITapGestureRecognizer) {
    let tapPoint = recognizer.location(in: self.sceneView)
    let result = self.sceneView.hitTest(tapPoint, types: ARHitTestResult.ResultType.existingPlaneUsingExtent)

    if result.count == 0 {
        return
    }

    let hitResult = result.first

    let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)

    let node = SCNNode(geometry: box)
    node.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.static, shape: nil)
    node.position = SCNVector3Make(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)

    sceneView.scene.rootNode.addChildNode(node)
}

Затем, когда вы коснетесь обнаруженной плоской поверхности, она добавит коробку на плоскости, где вы постучали.

  • 9 мар 2020 2020-03-09 14:05:22
2

Вы должны получить местонахождение и использовать координаты мира, чтобы поместить куб должным образом. Я не уверен (0,0,0) - это нормальное место для ARKit. Вы можете попробовать что-то вроде этого:
Поместите это в свой viewDidLoad:

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapFrom))
tapGestureRecognizer.numberOfTapsRequired = 1
self.sceneView.addGestureRecognizer(tapGestureRecognizer)

Затем добавьте этот метод:

@objc func handleTapFrom(recognizer: UITapGestureRecognizer) {
    let tapPoint = recognizer.location(in: self.sceneView)
    let result = self.sceneView.hitTest(tapPoint, types: ARHitTestResult.ResultType.existingPlaneUsingExtent)

    if result.count == 0 {
        return
    }

    let hitResult = result.first

    let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)

    let node = SCNNode(geometry: box)
    node.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.static, shape: nil)
    node.position = SCNVector3Make(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)

    sceneView.scene.rootNode.addChildNode(node)
}

Затем, когда вы коснетесь обнаруженной плоской поверхности, она добавит коробку на плоскости, где вы постучали.

  • 9 мар 2020 2020-03-09 14:05:22
3

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

override func viewDidLoad() {
    super.viewDidLoad()

    // Set the view delegate
    sceneView.delegate = self

    let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
    let node = SCNNode(geometry: box)
    node.position = SCNVector3(0,0,0)
    sceneView.scene.rootNode.addChildNode(node)
}

Он создает поле в исходной точке (0, 0, 0). К сожалению, ваше устройство находится внутри коробки, поэтому вы не можете видеть эту коробку прямо. Чтобы увидеть этот флажок, переместите устройство далеко.

Прикрепленное изображение является полем после перемещения моего устройства:

enter image description here

Если вы хотите увидеть его сразу, немного сдвиньте коробку, добавьте цвет и сделайте первый материал двойной стороной (чтобы увидеть его даже внутри или снаружи):

    let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
    box.firstMaterial?.diffuse.contents = UIColor.red
    box.firstMaterial?.isDoubleSided = true
    let boxNode = SCNNode(geometry: box)
    boxNode.position = SCNVector3(0, 0, -1)
    sceneView.scene.rootNode.addChildNode(boxNode)
  • 9 мар 2020 2020-03-09 14:05:22
3

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

override func viewDidLoad() {
    super.viewDidLoad()

    // Set the view delegate
    sceneView.delegate = self

    let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
    let node = SCNNode(geometry: box)
    node.position = SCNVector3(0,0,0)
    sceneView.scene.rootNode.addChildNode(node)
}

Он создает поле в исходной точке (0, 0, 0). К сожалению, ваше устройство находится внутри коробки, поэтому вы не можете видеть эту коробку прямо. Чтобы увидеть этот флажок, переместите устройство далеко.

Прикрепленное изображение является полем после перемещения моего устройства:

enter image description here

Если вы хотите увидеть его сразу, немного сдвиньте коробку, добавьте цвет и сделайте первый материал двойной стороной (чтобы увидеть его даже внутри или снаружи):

    let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
    box.firstMaterial?.diffuse.contents = UIColor.red
    box.firstMaterial?.isDoubleSided = true
    let boxNode = SCNNode(geometry: box)
    boxNode.position = SCNVector3(0, 0, -1)
    sceneView.scene.rootNode.addChildNode(boxNode)
  • 9 мар 2020 2020-03-09 14:05:22