Code Monkey home page Code Monkey logo

ardemosample's Introduction

[ING] - AR1日体験ハッカソンでのサンプルリポジトリ

1. 概要

こちらは、5/19に株式会社メルカリ様にて開催された「AR 1day Hackathon/お試し会」で実装したサンプルになります。基本的には.scn形式にした3Dモデルを画面内に表示し、SwiftUIを利用したUI関連実装とSceneKitを組み合わせたものになります。

(1)3DモデルとUI実装を組み合わせた解説動画:

YouTubeチャンネル「kavsoft」様のサンプル実装動画も応用を考えていく上で参考になると思います。

(2):3Dモデル表示をSceneKitを利用して実現する

このサンプルでは、Xcodeで変換した.scn形式の3Dモデル表示部分SceneKitを利用しています。UIViewRepresentableを利用してSCNViewのインスタンスをSwiftUIで表示する形を取っている点がポイントになります。

struct DetailCustomSceneView: UIViewRepresentable {

    // MARK: - `@Binding` Property

    @Binding var scene: SCNScene?

    // MARK: - Function

    func makeUIView(context: Context) -> SCNView {
        let view = SCNView()
        view.allowsCameraControl = false
        view.autoenablesDefaultLighting = true
        view.antialiasingMode = .multisampling2X
        view.scene = scene
        view.backgroundColor = .clear
        return view
    }

    func updateUIView(_ uiView: SCNView, context: Context) {}
}

3Dモデル表示と調整対応部分の実装例です。

// 👉 ① View要素内Property定義
// 表示対象SCNScene(SceneKit)をStateとして定義
@State private var scene: SCNScene?

// 👉 ② initializer内での調整処理
// SCNVector3: https://developer.apple.com/documentation/scenekit/scnvector3
// SCNVector4: https://developer.apple.com/documentation/scenekit/scnvector4
// (参考記事) https://appleengine.hatenablog.com/entry/2017/06/02/163647

// 処理1. 少しだけ手前側に斜めに倒すイメージにして見やすくする
self.scene?.rootNode.rotation = SCNVector4(
    1, // X軸
    0, // Y軸
    0, // Z軸
    0.1 * Float.pi // 角度(ラジアン)
)
// 処理2. 現在のサイズより1.28倍の拡大表示をする
self.scene?.rootNode.scale = SCNVector3Make(
    1.28, // X軸
    1.28, // Y軸
    1.28  // Z軸
)

SceneKitを利用した3Dモデル表示を回転可能にする部分の実装例です。

// 👉 ① スライダー要素のModifier処理部分の抜粋
.gesture(
    // DragGestureと連動して回転する様な形を実現する
    DragGesture()
       .updating($temporaryOffsetValue, body: { currentValue, outputValue, _ in
           // MEMO: -64.0をしているのは調整のため
           outputValue = currentValue.location.x - 64.0
       })
)
.onChange(of: temporaryOffsetValue) {
    // MEMO: 変数「offset」が変更されるので、配置要素が合わせて回転する
    rotateSceneViewObject(animate: temporaryOffsetValue == .zero)
}

// 👉 ② Drag処理変化量に合わせて水平方向回転を実施するメソッド
// ②-1: View要素のProperyにDragGesture発動時に一時的に格納するための変数が定義されている
@GestureState private var temporaryOffsetValue: CGFloat = 0

// ②-2: DragGesture発動時に一時的に格納するための変数
private func rotateSceneViewObject(animate: Bool = false) {

    // ① Transition処理を開始する
    if animate {
        SCNTransaction.begin()
        SCNTransaction.animationDuration = 0.36
    }

    // この様な条件分岐にしないと綺麗に回転しなかったんですよねー...😇
    scene?.rootNode.eulerAngles.y = Float((temporaryOffsetValue * .pi) / 180.0)

    // ② Transition処理を実行する
    if animate {
        SCNTransaction.commit()
    }
}

(3):画面全体の構成

一覧から詳細画面へ遷移する様に見せる構成において、ポイントになり得る部分をまとめています。

// 👉 ① View要素のProperyに表示対象EntityをStateとして定義
@State private var selectedMaterial: MaterialEntity? = nil

// 👉 ② body要素内ではZStackを利用して画面状態に合わせて表示対象の内容をAnimationを利用して切り替える
// ※ 「.matchedGeometryEffect」Modifierの活用して一意なID名と@Namespaceで定義する名前空間との紐付けを利用する
var body: some View {
    NavigationStack {
        // 全体をZStackにして表示要素を重ねている
        // 👉 AndroidやFlutter等でよく見る「Hero」Animationの様なイメージ
        ZStack {
            // `@State`で定義した変数の状態を元にして表示状態を決定する
            if selectedMaterial == nil {
                // 一覧表示時のView全体要素 (全体はScrollView + Grid表示構成)     
            } else {
                // 拡大時のView全体要素
            }
        }
        .frame(width: screenWidth)
        .navigationTitle("3Dモデルを表示して回転させよう♻️")
        .navigationBarTitleDisplayMode(.inline)
    }
}

(4):3Dモデル入手する

※注意:

3Dモデルファイルが重かったので、.scn形式にした3Dモデルについては「Git LFS」を利用しています。

※1. 直接DLする場合は「こちら💁

※2. Git LFSの導入に関しては、下記にピックアップした資料も参考にできるかと思います。

# すでに「Git LFS」を利用している場合は下記コマンドを実行してください。
$ git clone [email protected]:fumiyasac/ARDemoSample.git
$ git lfs pull

2. ポイント整理

【📊 Presentation】

5/21にWantedly株式会社様で開催された「Mobile勉強会 Wantedly × チームラボ × Sansan #14」でも、こちらの内容を登壇しております。

【🖼️ Screenshots】

List Detail

【🎥 Movie】

matched_geometry_sample.mp4

【🍀 Guidance】

サンプル解説プレゼンテーション資料

ardemosample's People

Contributors

fumiyasac avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.