如何在 Swift 中以编程方式旋转 USDZ 文件中的 3D 模型?
How to rotate a 3D model in a USDZ file programmatically in Swift?
我的应用目前正在检测一张明信片图片。检测到后,我将狗的 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
要移动模型,但任何尝试都只是移动模型(而不是旋转它)。
首先你必须从场景中检索模型节点。请注意节点名称与场景名称不同!您可以在 Scene graph
层次结构中找到您的节点。
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)
注意你的节点的pivot point
在哪里。旋转应该围绕枢轴点。
我的应用目前正在检测一张明信片图片。检测到后,我将狗的 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
要移动模型,但任何尝试都只是移动模型(而不是旋转它)。
首先你必须从场景中检索模型节点。请注意节点名称与场景名称不同!您可以在 Scene graph
层次结构中找到您的节点。
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)
注意你的节点的pivot point
在哪里。旋转应该围绕枢轴点。