【发布时间】:2017-12-05 07:11:09
【问题描述】:
我想在我的场景中添加一个节点,保持相对于相机的位置,但保持场景的方向/旋转。到目前为止我在哪里......
当我点击屏幕时,我会在场景中添加一个锚点,其变换等于相机的变换。然后在didUpdateNode 中,也就是锚节点设置其位置信息时,我添加了一个包含模型的子节点,该模型具有position.z = -0.5。模型节点直接添加到摄像机前面的场景中,并反映摄像机的旋转属性。手机向下倾斜并成一定角度时,可能看起来像这样:
模型节点,受锚节点旋转数据的影响,旋转方式与相机相同。这个特殊的模型出现在它的一边——我不担心,它只是一个占位符。也忽略顶部的红色按钮,用于调试。
到目前为止,一切都很好。
我想要做的是让旋转信息基本上“重置”,因此它会出现在与我的相机相同的高度,并面向默认的正面位置。如果我以不同的方式旋转相机并在房间内移动,则会在不同的位置添加其他模型,但仍保持相同的高度和相同的方向。
这可能看起来像这样。想象一下,我刚刚点击屏幕添加了对象,它以标准高度显示,并且与场景相关,而不是相机旋转。
我尝试过使用节点的eulerAngles、rotation 和orientation 属性,但无法使其令人满意地工作。这是我到目前为止的代码。我创建了一个空白场景,并使用标准 SceneKit 项目中的ship.scn 作为模型:
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
var anchors = [ARAnchor]()
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
// Create a new scene
let scene = SCNScene(named: "scene.scn")!
// Set the scene to the view
sceneView.scene = scene
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingSessionConfiguration()
configuration.planeDetection = .horizontal
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
if anchors.contains(anchor) {
// Create a new scene
let scene = SCNScene(named: "art.scnassets/ship.scn")!
let shipNode = scene.rootNode.childNode(withName: "ship", recursively: true)!
shipNode.position.z = -5
node.addChildNode(shipNode)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if let currentFrame = sceneView.session.currentFrame {
let translation = matrix_identity_float4x4
let transform = simd_mul(currentFrame.camera.transform, translation)
let anchor = ARAnchor(transform: transform)
anchors.append(anchor)
sceneView.session.add(anchor: anchor)
}
}
}
}
【问题讨论】:
-
关于模型位置:您到底想重置什么?你想让飞机出现在你的相机高度吗?在固定的恒定高度?飞机总是出现在你的相机的北边?在镜头前开吗?关于模型方向:你希望它有一个与相机无关的常数(比如总是向北,总是垂直)还是混合(比如总是面向相机,总是垂直)?
-
@Guig 理想情况下,我希望在世界上创建一个平面,其中 z 坐标将从南到北移动,x 坐标从西到东,所以在我的初始节点中我试图创建那。我确实省略了让飞机与北方对齐的细节,因为这涉及核心位置,这是下一步。现在我只需要通俗地说,它是平的且不旋转的,就好像它直接坐在地板上一样。
标签: ios scenekit scnnode arkit arscnview