ARKit에서 입방체의 6면 각각에 다른 텍스처를 붙이는 방법 [추기 있음]

소개



iOS11(beta)에서 등장한 ARKit에서 놀고 있습니다. 약간의 아이디어로 재미있는 앱을 할 수 있을 것 같고 즐겁습니다.

입방체의 6면 각각에 별도의 텍스처를 붙이려고 했는데, 검색해도 명확한 설명을 찾을 수 없었으므로, 간단한 코드를 써 실험해 보았습니다.

※이 기사를 그려서 상당히 지나고 나서, 취급하고 있는 입체는 <입방체>가 아니라, <직방체>인 것을 깨달았습니다. 타이틀까지 바꾸면 검색성이 나빠지므로, 본고에서는 그대로 <입방체>로 통과하고 있습니다. (2020/06/02 추가)

환경


  • Xcode Version 9.0 beta 3 (9M174d)
  • iOS11 beta 11.0(15A5341f)
  • iPhone 6S (MKQW2J/A)

  • 좌표계 정보



    지면에 수직으로 서서 카메라를 앞으로 향해 iPhone을 잡고 있다고 가정합니다.

    앱 기동시의 iPhone의 위치가 원점이 되고, 자신으로부터 보고, 좌→우 방향이 X축의 정의 방향, 아래→상 방향이 Y축의 정의 방향이 됩니다. Z축은 정면→후면 방향이 양의 방향이 되므로, 조심할 필요가 있습니다.

    이 때 iPhone이 기울어져 있어도, 지면에 대해서 수직·수평이 기준이 되어 좌표계가 설정됩니다. 이 좌표계는 앱 기동 후에 설치되어 그 후 iPhone의 위치가 이동해도 원점의 위치와 축의 방향은 유지됩니다 (이것이 AR의 재미있는 곳).

    길이의 단위입니다만, 코드상의 1.0가 현실 세계의 1m에 대응합니다.

    텍스처를 붙이는 방법 시도



    입방체의 6면 모두에 동일한 텍스처를 붙이는 경우는 다음과 같이 하면 됩니다.
    cube.firstMaterial?.diffuse.contents = UIImage(named: "texture.png")
    6면 각각에 다른 텍스처를 붙이려고 했을 경우는, 노드의 materials 프로퍼티에, 텍스처의 배열을 주면 됩니다만, 순서나 방향이 어떻게 되는지 잘 모르기 때문에, 간단한 프로그램을 써 실험해 보겠습니다.

    그림과 같은 6면분의 텍스처를 준비했습니다.



    코드



    너비 10cm, 높이 20cm, 깊이 30cm의 입방체를 만들고 텍스처를 붙입니다. 변의 길이를 바꾸고 있는 것은, 면의 대응 관계를 알기 쉽도록입니다.

    GameScene.swift
        func makeCube() {
            // 幅10cm、高さ20cm、奥行き30cmの立方体を作成
            let cube = SCNBox(width: 0.1, height: 0.2, length: 0.3, chamferRadius: 0)
            let cubeNode = SCNNode(geometry: cube)
    
            // 6面、別々のテクスチャを貼る
            let m1 = SCNMaterial()
            let m2 = SCNMaterial()
            let m3 = SCNMaterial()
            let m4 = SCNMaterial()
            let m5 = SCNMaterial()
            let m6 = SCNMaterial()
    
            m1.diffuse.contents = UIImage(named: "texture_1.png")
            m2.diffuse.contents = UIImage(named: "texture_2.png")
            m3.diffuse.contents = UIImage(named: "texture_3.png")
            m4.diffuse.contents = UIImage(named: "texture_4.png")
            m5.diffuse.contents = UIImage(named: "texture_5.png")
            m6.diffuse.contents = UIImage(named: "texture_6.png")
    
            cube.materials = [m1, m2, m3, m4, m5, m6]
    
            // 初期位置の指定: 50cm画面奥、10cm上方に配置
            cubeNode.position = SCNVector3Make(0, 0.1, -0.5)
    
            self.rootNode.addChildNode(cubeNode)
        }
    

    결과



    이렇게 텍스처가 붙여집니다.

    앞에서 보았을 때, 즉 원점 측에서 Z 축 마이너스 방향으로 보았을 때의 이미지입니다.


    앞쪽에서 3개의 선분이 직교하고 있는 점이 원점으로, 빨강이 X축, 녹색이 Y축, 파랑이 Z축입니다.
    약간 위에서 내려다보고 있기 때문에, 입방체는 1,2,5의 면이 보입니다.

    안쪽에서 되돌아 보았을 때, 즉 Z 축 마이너스 방향에서 원점 방향을 보았을 때의 이미지입니다.


    화면 안쪽에 원점이 있고 X축, Y축, Z축이 직교하고 있습니다.
    약간 아래에서 올려다 보니 입방체는 3,4,6면을 볼 수 있습니다.

    전개도로 해 보면 이런 배치가 됩니다.



    결론



    Qiita에 기사를 쓰는 것은 처음입니다.

    초보적인 것입니다만, 자신이 모르는 것을 알았을 때, 그것을 공유하는 것으로, 어딘가의 누군가에게 도움이 되면 기쁜 일입니다.

    ARKit은 괴롭히고 흥미 롭습니다. 간단한 앱을 만들어 앱 스토어에서 게시하는 것을 목표로 하고 있습니다.

    좋은 웹페이지 즐겨찾기