将 scene/USDZ 文件动态缩放到平面?
Dynamically scale scene/USDZ file to plane?
目前,我的应用程序正在跟踪图像。一旦找到,它会将 3D 模型放在它的正上方。我的问题是:是否可以将 USDZ/scene 文件自动缩放到平面?
我目前正在跟踪一张明信片(5X7 英寸),我希望模型在检测到后直接放在明信片上(与我的大多数 3d 模型相比非常小)。我目前必须手动进入每个文件并对其进行缩放,但这会花费大量手动时间。
我想会有一种更简单的方法来以编程方式缩放模型,但不确定。
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
}
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-:CODE WHERE I PLACE MY 3D MODEL
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: "hamburguer", withExtension: "usdz") else { fatalError() }
let mdlAsset = MDLAsset(url: url)
let shipScene = SCNScene(mdlAsset: mdlAsset)
// let shipScene = SCNScene(named: "retro.scn")!
let shipNode = shipScene.rootNode.childNodes.first!
shipNode.position = SCNVector3Zero
shipNode.position.z = 0.15
planeNode.addChildNode(shipNode)
node.addChildNode(planeNode)
}
return node
}
}
您可以尝试使用如下内容:
let width = 10 //calculate the length of the target image
let nodeWidth = shipNodeLength //calcualate the length of the original model
if width > 0 {
if nodeWidth > width {
scale = width/nodeWidth
} else {
scale = nodeWidth/width
}
}
shipNode.scale = SCNVector3(scale, scale, scale)
目前,我的应用程序正在跟踪图像。一旦找到,它会将 3D 模型放在它的正上方。我的问题是:是否可以将 USDZ/scene 文件自动缩放到平面?
我目前正在跟踪一张明信片(5X7 英寸),我希望模型在检测到后直接放在明信片上(与我的大多数 3d 模型相比非常小)。我目前必须手动进入每个文件并对其进行缩放,但这会花费大量手动时间。
我想会有一种更简单的方法来以编程方式缩放模型,但不确定。
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
}
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-:CODE WHERE I PLACE MY 3D MODEL
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: "hamburguer", withExtension: "usdz") else { fatalError() }
let mdlAsset = MDLAsset(url: url)
let shipScene = SCNScene(mdlAsset: mdlAsset)
// let shipScene = SCNScene(named: "retro.scn")!
let shipNode = shipScene.rootNode.childNodes.first!
shipNode.position = SCNVector3Zero
shipNode.position.z = 0.15
planeNode.addChildNode(shipNode)
node.addChildNode(planeNode)
}
return node
}
}
您可以尝试使用如下内容:
let width = 10 //calculate the length of the target image
let nodeWidth = shipNodeLength //calcualate the length of the original model
if width > 0 {
if nodeWidth > width {
scale = width/nodeWidth
} else {
scale = nodeWidth/width
}
}
shipNode.scale = SCNVector3(scale, scale, scale)