Swift/Swift 개발 노트

[iOS/SceneKit] 다른 모델의 노드를 추가해보자

힛해 2024. 8. 26. 00:52
728x90

https://developer.apple.com/documentation/scenekit/scnnode

 

SCNNode | Apple Developer Documentation

A structural element of a scene graph, representing a position and transform in a 3D coordinate space, to which you can attach geometry, lights, cameras, or other displayable content.

developer.apple.com

 

기존 모델에 다른 모델의 특정 노드를 불러와보자!

 

기존 3D 모델이다

 

현재 상태로도 굉장히 귀엽지만 엑세서리를 모델에서 원하는 노드를 불러와서 합쳐줄 것이다.

 

추가하려는 모델이다.

돌멩이에 안경을 씌워주어보자!

 

필요한 작업이 두가지 있다.

  1. 기존 scene.rootNode에 안경 노드 추가하기
  2. 안경 노드 position 설정해주기

 

1. 안경 모델 불러오기

let accessoryNode = addAccessory()
scene.rootNode.addChildNode(accessoryNode)

func addAccessory() -> SCNNode {
    let scene = SCNScene(named: "scn 경로") ?? SCNScene()
    
    if let accessoryNode = scene.rootNode.childNode(withName: "원하는 특정 노드이름", recursively: true) {
        accessoryNode.name = "accessory"
        return accessoryNode
    }
}

 

SCNScene으로 원하는 모델을 불러와주고 rootNode.childeNode(withName:)으로 특정 노드를 반환해주자!

 

가독성 및 편의성을 위해 node명을 정의해주자.

 

 

2. 크기 조절하기

기존 모델과 크기를 맞추기위해 크기 조절 함은 엑세서리 노드를 불러와준뒤에 실행시켜주자.

 let accessoryNode = addAccessory()
    scene.rootNode.addChildNode(accessoryNode)
    

    for node in scene.rootNode.childNodes {
          node.scale = SCNVector3(x: 2, y: 2, z: 2) // 스케일 값을 조정하여 모델의 크기를 조절
      }

 

 

3. 포지션 설정하기

추가하려는 모델의 위치를 설정했더라도 다른 모델에 추가를 하면 임의의 위치에 노드가 추가된다.

 

포지션값을 설정해주지 않으면 아래의 사진처럼 임의의 위치에 모델이 위치하게 된다.

 

오른쪽 아래에 둥둥 떠있는 안경...

 

추후 사용자가 위치를 변경하거나 악세서리들이 추가될때 다른 위치에 보이게 하려면 updateUIView에 포지션 설정 함수를 넣어주는 것이 좋기에 updateUIView에서 포지션을 설정해주자

func updateUIView(_ uiView: SCNView, context: Context) {
...
if let accessoryNode = scene.rootNode.childNode(withName: "accessory" , recursively: true){
            moveNodeToPosition(node: accessoryNode, x: 0.0, y: 0.0, z: 0.25) // x, y, z 값은 원하는 위치로 설정
        }
...

 

그럼 아래와 같이 모델에 정상적으로 안경이 씌워진다.

 

그런데 초기 시점이 위와 같이 이상하다.

 

노드가 추가될때 기존 rotate 값에 변경이 있는걸까.

    let boundingBox = scene.rootNode.boundingBox
    let minVector = boundingBox.min
    let maxVector = boundingBox.max
    let center = SCNVector3(
        (minVector.x + maxVector.x) / 2,
        (minVector.y + maxVector.y) / 2,
        (minVector.z + maxVector.z) / 2
    )
    
    // 중심을 원점으로 이동
    scene.rootNode.position = SCNVector3(-center.x, -center.y, -center.z)
    
    for node in scene.rootNode.childNodes {
        node.scale = SCNVector3(x: 2, y: 2, z: 2) // 스케일 값을 조정하여 모델의 크기를 조절
    }

 

중신값을 계산해서 포지션을 설정해주었는데 여전히 바뀌지 않았다.

 

 

문제는 바로 추가한 모델에 설정되어있는 카메라 때문이었다...

 

 

결과화면

 

 

아주아주 마음에 든다..!!