Nikolai Prokofev
Nikolai Prokofev

Reputation: 184

Place node in front of the camera and rotate

I want to show a pointer when a user double taps on a sceneView. For this, I want to use SCNTorus because at some angle it is a circle.

let geometry = SCNTorus(ringRadius: 0.01, pipeRadius: 0.001)
let node = SCNNode(geometry: geometry)

I already get a vector from hitTest that I use as a position for the node

private func getVector(for point: CGPoint) -> SCNVector3? {

    guard let hitTest = self.sceneView.hitTest(point, types: .featurePoint).first else {
       return nil
    }
    let transform = SCNMatrix4.init(hitTest.worldTransform)
    let vector = SCNVector3Make(transform.m41, transform.m42, transform.m43)
    return vector
}

How can I transform it to always appear as a circle when the node added.

For vertical device position rotating by .pi/2 along X-axis works great but it breaks when devices move in a space, so I can not hardcode the angle

node.eulerAngles.x = .pi / 2
sceneView.scene.rootNode.addChildNode(node)

I believe I need to sceneView.pointOfView somehow to apply the transformation. But I stuck here.

Here is the full code

@objc private func didDoubleTap(_ sender: UITapGestureRecognizer) {
    
    let point = sender.location(in: sceneView)
    guard let vector = getVector(for: point) else { return }
    guard let pov = sceneView.pointOfView else { return }
    guard let camera = sceneView.session.currentFrame?.camera else { return }

    let geometry = SCNTorus(ringRadius: 0.01, pipeRadius: 0.001)
    let node = SCNNode(geometry: geometry)
    node.position = vector
    node.eulerAngles.x = .pi / 2
    sceneView.scene.rootNode.addChildNode(node)
    animatePointingNode(node)
}

Upvotes: 0

Views: 349

Answers (1)

Nikolai Prokofev
Nikolai Prokofev

Reputation: 184

I was able to solve the issue by setting eulerAngles.y to be equal to camera's Y and adjusting camera's X by .pi/2

guard let camera = sceneView.session.currentFrame?.camera else { return }

pointerNode.position = vector
pointerNode.eulerAngles.x = camera.eulerAngles.x + .pi / 2
pointerNode.eulerAngles.y = camera.eulerAngles.y

Upvotes: 1

Related Questions