Machineboy空

RealityKit 입문 - Models .usdz 본문

언어/swift

RealityKit 입문 - Models .usdz

안녕도라 2024. 10. 12. 17:17

 

.usdz파일을 넣어보자!

 

https://developer.apple.com/augmented-reality/quick-look/

 

Quick Look Gallery - Augmented Reality - Apple Developer

Embed Quick Look views in your apps and websites to let users see incredible detailed renderings in 3D or AR.

developer.apple.com

 // 방법 1: sync하게 가져오기, 작은 glitch가 생길 수 있다.
 /// modelEntity.load = synchronous function, doesn't perform asynchronously
/// so we have to use an async function that will allow us to load a model in the background so we don't get that glitch
            
guard let pancake = try? ModelEntity.load(named: "pancakes") else {
       fatalError("Shoe model was not found.")
}
// 방법2: async하게 가져오기

import Foundation
import ARKit
import RealityKit
import Combine


class Coordinator: NSObject, ARSessionDelegate {
    
    weak var view: ARView?
    var cancellable: AnyCancellable?
   
    @objc func handleTap(_ recognizer: UITapGestureRecognizer) {
        
        guard let view = self.view else { return }
        let tapLocation = recognizer.location(in: view)
        
        let results = view.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .vertical)
        
        if let result = results.first {
            
            // create anchor entity
            //let anchor = AnchorEntity(world: result.worldTransform) 이렇게도 가능
            let anchor = AnchorEntity(raycastResult: result)
            
            /// tell us when entity has been loaded
            cancellable = ModelEntity.loadAsync(named: "pancake")
                .sink { loadComletion in
                    if case let .failure(error) = loadComletion {
                        print("Unable to load model \(error)")
                    }
                    self.cancellable?.cancel()
                } receiveValue: { entity in
                    anchor.addChild(entity)
                }
 
            // add anchor to the scene
            view.scene.addAnchor(anchor)
        }
    }
}

여러 개의 3D 모델 파일을 넣어보자!

// 1) append로 그냥 넣었을 때

@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
        
        guard let view = self.view else { return }
        let tapLocation = recognizer.location(in: view)
        
        let results = view.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .horizontal)
        
        if let result = results.first {
            
            // create anchor entity
            //let anchor = AnchorEntity(world: result.worldTransform) 이렇게도 가능
            let anchor = AnchorEntity(raycastResult: result)
            
            /// tell us when entity has been loaded
            cancellable = ModelEntity.loadAsync(named: "pancakes")
                .append(ModelEntity.loadAsync(named: "robot"))
                .collect()  /// with a single stream of array of data
            
                .sink { loadComletion in
                    if case let .failure(error) = loadComletion {
                        print("Unable to load model \(error)")
                    }
                    self.cancellable?.cancel()
                } receiveValue: { entities in
                    entities.forEach{
                        /// $0은 각 entity를 말한다
                        anchor.addChild($0)
                    }
                }
 
            // add anchor to the scene
            view.scene.addAnchor(anchor)
        }
    }
// 위치 변경
var x: Float = 0.0
                    
                    entities.forEach{ entity in
                        
                        
                        entity.position = simd_make_float3(x, 0, 0)
                        anchor.addChild(entity)
                        x += 0.3
                    }

.usdz with Animations

와 기존 샘플 모델 활용했는데.. 애니메이션 퀄리티가 대박이다.

거기다 어제 계속 찾아헤매던 Plane 빌보드 기능도 이미 내장되어 있다...

저 reality 파일을 잘 분석하면 될 것같은데 !

 

 

@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
        
        guard let view = self.view else { return }
        
        /// Already added, 추가하지 말기!
        guard view.scene.anchors.first ( where: { $0.name == "astronautAnchor"}) == nil else {
            return
        }
        
        let tapLocation = recognizer.location(in: view)
        
        let results = view.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .horizontal)
        
        if let result = results.first {
            
            // create anchor entity
            //let anchor = AnchorEntity(world: result.worldTransform) 이렇게도 가능
            let anchor = AnchorEntity(raycastResult: result)
            
            /// tell us when entity has been loaded
            cancellable = ModelEntity.loadAsync(named: "astronaut")
            
                .sink { loadComletion in
                    if case let .failure(error) = loadComletion {
                        print("Unable to load model \(error)")
                    }
                    self.cancellable?.cancel()
                } receiveValue: { entity in
                    anchor.name = "astronautAnchor"
                    anchor.addChild(entity)
                }
 
            // add anchor to the scene
            view.scene.addAnchor(anchor)
        }
    }

 

역시 교육은 정보를 습득하는 가장 빠르고 쉬운 방법이랬다.. 강의 최고

다음 시간은 Real Composer를 어떻게 쓰는지 알아보겠음