Search code examples
swiftscenekitarkitscene

How to get the size of 3D model? From a USDZ file/scene?


I want to get the size of a 3D model from a USDZ file/ a scene in Swift. How can I do so? Currently I have a USDZ file imported in swift and then converted into a scene in code:

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-: WHERE I CONVERT THE USDZ FILE INTO A SCENE TO DISPLAY

    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 shipScene = SCNScene(mdlAsset: mdlAsset)
                let shipNode = shipScene.rootNode.childNodes.first!

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

Is the correct code to use

shipNode.boundingBox.max

But I'm a little confused how to use the boundingBox since there is a max/min value? Which one do I use? Or how do I even use it?


Solution

  • From the documentation

    For example, if a geometry’s bounding box has the minimum corner {-1, 0, 2} and the maximum corner {3, 4, 5}, all points in the geometry’s vertex data have an x-coordinate value between -1.0 and 3.0, inclusive.

    and so

    let width = boundingBox.max.x - boundingBox.min.x
    let height = boundingBox.max.y - boundingBox.min.y
    let depth = boundingBox.max.z - boundingBox.min.z