如何在Swift中以编程方式旋转USDZ文件中的3D模型?

3

我目前的应用程序可以检测明信片图片。一旦检测到,我会在其上放置一只狗的3D模型。问题是,该模型当前背部坐在明信片上,而不是它的脚。

有没有办法通过编程来旋转模型,使其脚站在明信片上?

class ViewController: UIViewController, ARSCNViewDelegate {
    
    @IBOutlet var sceneView: ARSCNView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        sceneView.delegate = self
    }
    
//MARK-: WHERE I CONFIGURE MY APP TO DETECT AN IMAGE

    override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            
            let configuration = ARImageTrackingConfiguration()
            
            guard let trackedImages = ARReferenceImage.referenceImages(inGroupNamed: "Photos", bundle: Bundle.main) else {
                print("No images available")
                return
            }
            
            configuration.trackingImages = trackedImages
            configuration.maximumNumberOfTrackedImages = 7
            
            sceneView.session.run(configuration)
    }
    
//MARK-: WHERE I PLACE A PLANE/DOG MODEL (named: shipScene) OVER THE DETECTED IMAGE

     func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
            
            let node = SCNNode()
            
            if let imageAnchor = anchor as? ARImageAnchor {
                let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)

                plane.firstMaterial?.diffuse.contents = UIColor(white: 1, alpha: 0.8)

                let planeNode = SCNNode(geometry: plane)
                planeNode.eulerAngles.x = -.pi / 2

                guard let url = Bundle.main.url(forResource: "shipScene", withExtension: "usdz") else { fatalError() }
                let mdlAsset = MDLAsset(url: url)
                let dogScene = SCNScene(mdlAsset: mdlAsset)
                let dogNode = shipScene.rootNode.childNodes.first!

                shipNode.position = SCNVector3Zero
                shipNode.position.z = 0.15
                
                planeNode.addChildNode(shipNode)
                node.addChildNode(planeNode)
            }
            
            return node
    }
    
}

我想我可以使用一个版本的

shipNode.position.x

要移动模型,但任何尝试只是将模型移动(而不是旋转)。

2个回答

1
首先,您需要从场景中检索模型节点。请注意,节点的名称与场景的名称不同!您可以在“场景图”层次结构中找到您的节点。
let model = scene.rootNode.childNode(withName: "myModel", recursively: true)!

然后您可以使用 rotation 属性旋转它:
model.rotation.y = -CGFloat.pi / 2

或者使用 eulerAngles 属性:
model.eulerAngles = SCNVector3(0, -CGFloat.pi/2, 0)

或者使用 orientation 属性:
model.orientation = SCNVector4(0, 1, 0, -CGFloat.pi/2)

注意节点的枢轴点位置。旋转应该围绕枢轴点进行。


0

Swift 版本 5.7

已有一个被接受的答案解决了这个问题。

此外,对于那些需要一些创意的人,以下是如何使用动画同时旋转和缩放

let node = scene.rootNode.childNode(withName: "Cube_001", recursively: true)!
node.runAction(SCNAction.rotateBy(x: 1, y: 1, z: 3, duration: 3.1))
node.runAction(SCNAction.scale(by: 2, duration: 3.1))

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