You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何编程旋转USDZ 3D模型?解决AR明信片模型朝向问题

解决AR模型站立姿势问题:旋转3D模型使其脚部接触明信片

当然可以通过编程方式调整模型的旋转,让它的脚部稳稳站在检测到的明信片上!问题出在你的3D模型初始朝向和AR图像锚点的坐标系不匹配,导致模型背部贴在了平面上。咱们一步步来修正:

首先,先修正代码里的变量名错误

你的代码里有几处变量名不一致的问题(比如把dogScene写成了shipScene),先把这些改对,避免编译错误:

guard let url = Bundle.main.url(forResource: "shipScene", withExtension: "usdz") else {
    fatalError()
}

let mdlAsset = MDLAsset(url: url)
let dogScene = SCNScene(mdlAsset: mdlAsset)
let dogNode = dogScene.rootNode.childNodes.first! // 这里原来写的shipScene,要改成dogScene

核心:调整模型的旋转角度

AR图像锚点(ARImageAnchor)的坐标系中,检测到的明信片平面是XY平面,Z轴垂直于平面向外。你的模型当前背部接触平面,说明它的初始朝向和这个坐标系不匹配。我们可以通过修改SCNNode的eulerAngles属性来旋转模型,让脚部对齐平面。

尝试添加旋转代码

在设置dogNode.position之后,添加旋转逻辑。比如,如果模型默认是背部朝向Z轴负方向(也就是贴在平面上的方向),绕X轴旋转180度就能让脚部朝下:

dogNode.position = SCNVector3Zero
dogNode.position.z = 0.15
// 添加旋转:绕X轴旋转180度,让脚部站在平面上
dogNode.eulerAngles.x = .pi 

如果这个角度不对(比如模型还是侧着的),可以尝试调整其他轴的旋转,比如:

  • 绕Y轴旋转90度:dogNode.eulerAngles.y = .pi/2
  • 组合旋转:dogNode.eulerAngles = SCNVector3(.pi, .pi/2, 0)

这些数值需要根据你的shipScene.usdz模型的初始朝向微调——不同的3D模型导出时的姿态可能不一样,多试几个角度就能找到合适的。

调整位置(可选)

如果旋转后模型还是有点悬浮或者穿透平面,可以微调position的Z值(比如改成0.05),让模型刚好站在明信片表面。

修改后的完整renderer(_:nodeFor:)方法

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)
        guard let dogNode = dogScene.rootNode.childNodes.first else {
            return node
        }
        
        dogNode.position = SCNVector3Zero
        dogNode.position.z = 0.15
        // 关键旋转代码,根据模型实际情况调整角度
        dogNode.eulerAngles.x = .pi
        
        planeNode.addChildNode(dogNode)
        node.addChildNode(planeNode)
    }
    return node
}

原理很简单:eulerAngles控制节点在三个轴上的旋转弧度(180度等于.pi弧度,90度等于.pi/2),通过调整这些值,就能把模型的姿态修正为站立在明信片上的样子。

内容的提问来源于stack exchange,提问作者brockhampton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 11:17:35