无法拖动ARKit SCNNode?

4

好的,像其他人一样,我在ARKit/世界空间中拖动/翻译SCNNode时遇到了困难。我查看了Dragging SCNNode in ARKit Using SceneKit和所有流行的问题,以及来自苹果的代码https://github.com/gao0122/ARKit-Example-by-Apple/blob/master/ARKitExample/VirtualObject.swift

我试图尽可能简化,并只是做了我在普通场景工具包游戏中所做的事情 - http://dayoftheindie.com/tutorials/3d-games-graphics/t-scenekit-3d-picking-dragging/

我可以轻松获取被点击的对象并存储当前手指位置:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        guard let touch = touches.first else { return }

        let results = gameView.hitTest(touch.location(in: gameView), types: [ARHitTestResult.ResultType.featurePoint])

        //TAP Test
        let hits = gameView.hitTest(touch.location(in: gameView), options: nil)
        currentTapPos = getARPos(hitFeature: hitFeature) //TAP POSITION

        if let tappedNode = hits.first?.node {

我的问题是,在更新时这样做没有动画效果。对象只会出现在我点击的位置,整体来说不起作用。
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        guard let touch = touches.first else { return }

        let results = gameView.hitTest(touch.location(in: gameView), types: [ARHitTestResult.ResultType.featurePoint])
        guard let hitFeature = results.last else { return }

        testNode.position = currentTapPos

我使用以下函数将其转换为SCNVector3:

func getARPos(hitFeature: ARHitTestResult)->SCNVector3
{

    let hitTransform = SCNMatrix4.init(hitFeature.worldTransform)
    let hitPosition = SCNVector3Make(hitTransform.m41,
                                     hitTransform.m42,
                                     hitTransform.m43)
    return hitPosition
}

我已经尝试过:

-使用向量进行翻译 -滑动手势(这会影响其他功能) -SCNAction.moveTo

我该怎么办?出了什么问题?


1
看一下苹果的新版本示例代码。现在它似乎有更简单、更清晰的拖动代码(使用手势识别器)。 - rickster
我的问题是我不能使用手势识别器,因为屏幕上有其他UI,它会干扰它。你看到有什么东西可以不使用平移手势来实现吗? - blue
SCNAction 有什么问题吗?我使用了平移手势,但我使用了 SCNAction 进行平滑转换。 - Alok Subedi
1个回答

6
我同意@Rickster的观点,苹果代码提供了一个更加健壮的示例,然而我有这个并且它似乎运行顺畅(当您使用PlaneDetection时会更加顺畅,因为特征点更加零散):
我不使用touchesBegan,而是在touchesMoved中完成工作。
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    //1. Get The Current Touch Point
    guard let currentTouchPoint = touches.first?.location(in: self.augmentedRealityView),
        //2. Get The Next Feature Point Etc
        let hitTest = augmentedRealityView.hitTest(currentTouchPoint, types: .existingPlane).first else { return }

    //3. Convert To World Coordinates
    let worldTransform = hitTest.worldTransform

    //4. Set The New Position
    let newPosition = SCNVector3(worldTransform.columns.3.x, worldTransform.columns.3.y, worldTransform.columns.3.z)

    //5. Apply To The Node
    nodeToDrag.simdPosition = float3(newPosition.x, newPosition.y, newPosition.z)

}

我可能完全错误地处理这个问题(如果是的话,我很乐意得到反馈)。

无论如何,我希望这可能有所帮助...... 您可以在此处查看其快速操作的视频:拖动SCNNode


谢谢!不得不将它从simdposition更改为其他选项,因为它没有从节点中心拖动,但还是非常感谢您! - blue
非常欢迎并且总是乐于接受挑战,尤其是那些我个人曾经失败过的挑战 :) - BlackMirrorz
你好奇地问,你为simdPosition放了什么? - BlackMirrorz
如果对象不在平面上而是悬浮在空中怎么办? - omarojo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接