ARKit - (2)

catcota·2022년 2월 1일
0

ARKit

목록 보기
2/2
post-thumbnail

AR이란?

  • 현실의 정보를 센서 등을 통해 받아들이고 평가한 후 그 데이터에 추가적인 정보로 다시 표현하는 것
  • 6s, 아이패드 프로 혹은 2017년 이후에 나온 것 지원 가능
  • iOS12, Xcode10 에서 디버깅 및 빌드 가능
  • 시뮬레이터에서 테스트 못함 -> 실제 기기로 테스트 진행하기

AR구현을 위해 애플이 제공하는 프레임워크

  • SpriteKit, Metal(애플의 3D그래픽 엑셀러레이터), SceneKit

좌표계

  • z축은 나를 기준으로 내쪽인지 내 반대쪽인지 = user centric approach
    • x,y에 따라
    • allinment setting에 따라 내쪽인지 내 반대쪽인지 인식한다
  • x : 왼, 오른 / y : 위, 아래
  • 기기의 x,y축의 원점을 기준으로
    • 오른쪽 : x 값 증가
    • 위로갈수록(카메라쪽) : y 값 증가
    • 내쪽으로 : z 값 증가

Scenekit

node

SCNNode : 씬 그래프에서 3D객체를 나타내는 것

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.

  • AR로 디스플레이되는 물체들은 node라고 칭한다.
  • rootNode : scene내에서 Scenekit에 의해 그려지는 것들의 좌표체계를 정의한다. 즉 기준점이 된다는 뜻. rootNode에 추가되는 childNode는 rootNode를 기준으로 좌표체계가 형성된다.
    The rootNode object in a scene defines the coordinate system of the world rendered by SceneKit.
  • node의 position, rotation, scale 속성을 이용하거나 trasform 속성을 이용하여 transformation구현한다.

  • rootNode와 childNode는 node계층(scene graph)로 묶여있지만 그렇다고 해서 visual적인 부분들까지 계층을 이루는 것은 아니다(예를들어 root node를 이루는 색이 빨간색이라고 해서 cildNode도 빨간색이 되진 않는다.)

  • 노드에 SCNGeometry객체를 추가해서 2D, 3D 물체가 화면에 보이도록 한다.

  // 예시
      let pyramid = SCNNode(geometry: SCNPyramid(width: 0.1,
                                                     height: 0.1,
                                                     length: 0.1))
  • SCNGeometry의 종류

오일러 앵글

  • SceneKit로 표현한 2D, 3D물체자체를 회전시키거나 SCNAction등을 이용해 물체를 회전전 시키고 싶을 때 x, y, z축에 따른 다음과 같은 분류를 이용해 구현한다.

    pitch : rotation around X-axis
    Yaw : rotation around Y-axis
    Roll: rotation around Z-axis

  • 예를들어 튜브모양의 물체를 x축기준 시계방향으로 45도 ,y 축 기준 반시계방향으로 20도, z축기준 반시계방향으로 45보 만큼 회전시켜서 화면에 표시하고 싶을 때 다음과 같이 메소드를 구현할 수 있다.


extension Int {
    func floatToRadius() -> CGFloat {
        return CGFloat(self) * CGFloat.pi / 100.0
    }
}

// viewcontroller내부에서 구현한 메서드 
func drawTube() {
	let tube = SCNNode(geometry: SCNTorus(ringRadius: 0.05,
                                              pipeRadius: 0.03))
        tube.geometry?.firstMaterial?.diffuse.contents = UIColor.gray
        tube.geometry?.firstMaterial?.specular.contents = UIColor.white
        tube.position = SCNVector3(0.0, 0.2, -0.2)
        tube.eulerAngles = SCNVector3(-45.floatToRadius(), 20.floatToRadius(), 45.floatToRadius())
        
        sceneView.scene.rootNode.addChildNode(tube)
    }

Action

  • SceneKit에서 객체의 비쥬얼적인 부분을 애니메이션형태로 바꿀 수 있도록 하는 것 (growing, shrinking, 명도조절 등등)

  • 객체에 액션 을 붙이고 특정 타임에 그 액션을 실행하라고 하는 것

만약 액션 객체가 없다면?

  • 애니메이션 구현하려면 매 트랙마다 애니메이션이 되도록 구현해야됨. 여러가지 자잘한 일들이 많음.
  • 하지만 액션 을 붙이면 알아서 잘 구현되도록 해결해줌
  1. 구현방법
  • 예를들어 8초동안 y축 기준으로 360도를 돌아야 한다고 해보자
    //1. 액션객체 만들기 
    let tubeAction = SCNAction.rotate(by: 360.floatToRadius(),
                                              around: SCNVector3(x: 0, y: 1, z: 0),
                                              duration: 8)
    //2. 액션객체를 AR객체에 붙이기 
       tube.runAction(indefinitelyRotate) {
                print("회전이끝났습니다.")
            }
  1. 액션의 종류
    • 병렬 - parallel
    • 직렬 - sequence
    • 반복 - 특정 수 만큼 방복 repeat n times
    • 무제한 반복 - repeat indefinitely 액션만들기 → 해당 액션을 무제한 방복하는 액션 만들기 → 마지막 액션을 run
      let tubeAction = SCNAction.rotate(by: 360.floatToRadius(),
                                                around: SCNVector3(x: 0, y: 1, z: 0),
                                                duration: 8)
      let indefinitelyRotate = SCNAction.repeatForever(tubeAction)
              
      tube.runAction(indefinitelyRotate) {
                  print("회전이끝났습니다.")
              }
  2. 궁금점
    1. sceneView의 rootNode에 추가하는 순서가 액션 추가하는 것과 상관 있나? → 상관없음, 액션 전 후로 해도 동일하게 동작

scnassets 이용해 SCNScene 만들기

  1. 방법 : SCNScene 객체 생성 → scene의 노드 중 해당 childNode가져오기
func drawOrbitingShip() {
		//SCNScene 객체 생성
        let scene = SCNScene(named: "art.scnassets/ship.scn")
        
        //childNode가져오기 
        let ship = (scene?.rootNode.childNode(withName: "ship", recursively: false))!
        
        //childNode가 어떻게 보여질지 결정 
        ship.position = SCNVector3(1, 0, 0)
        ship.scale = SCNVector3(0.3, 0.3, 0.3)
        ship.eulerAngles = SCNVector3(0, 100.floatToRadius(), 0)
        sphere.addChildNode(ship)
    }
  1. SCNScene이란?
  • 노드계층을 담고 있는 컨테이이자 화면에 보이는 3Dscene를 포함하는 전역적인 properties
  • SceneKit을 이용해서 3D컨텐츠를 표현하기 위해선 노드의 계층과 비주얼적인 요소를 표현하는 attribute들을 담고있는 scene을 만들어야 한다. 특히 3D visual 에디터를 이용해서 이런 assets을 만들 수 있다.
  1. scene을 만들 수 있는 가장 쉬운 방법
  • Xcode의 SceneKit Scene Editor를 사용하기
    1. Belnder같은 3D 에디터로부터 asset을 가져오기
    2. scene editor는 .scn파일을 만드는데 앱 번들에선 .scnassets폴더로 저장된다. 프로젝트 빌드 시 xcode가 scene파일을 최적화한다.
profile
to be iOS Developer

0개의 댓글