feel-physics / HoloMagnet3

Science (Physics) education app visualizes Magnetic Field for HoloLens
https://youtu.be/eiLB3NuWtVk
GNU General Public License v3.0
5 stars 1 forks source link
augmented-reality education hololens magnetic-fields mixed-reality physics visualization

HoloMagnet3

Physics education app visualizes Magnetic Field for HoloLens

Any teacher can use this app in your classrooms, and any researcher can use this app to write your paper.

We are very welcome to your contribution for education including porting to other platforms (such as Magic Leap One, Oculus Quest, iPad, Pixel3, and many others).

2019年5月22日:HoloMagnet37、3次元自動 2018年6月21日:(学会発表用)三重高校愛知総合工科高校授業風景320x180

日本語

Overview

This code is published to help understanding sessions of HoloLens app development in IT Tech conference which is held once a year by Microsoft Japan.

The reason why I published this open-source app is, because I was one of 17 personal sponsors who have Microsoft MVP Award (The Microsoft Most Valuable Professional award is given by Microsoft to "technology experts who passionately share their knowledge with the community.")

TOC

Characteristics

Light Load

2019年5月22日:HoloMagnet37、2次元 2019年5月22日:HoloMagnet37、3次元手動

The app executes the Physics calculation of each of 500 compasses on every frame, and the FPS is 58.

Specifically, it does not instantiate it's Shader. It executes Physics calculation in the single Shader. As a result, the load is very light.

Furthermore, the reason why the light weight is needed is explained in next subject "UI / Expression".

Does not instantiate shader

As the following codes, the Material is not operated by a Script. Valuables are set in the Shader which accept external valuables. They are assigned directly to the Shader by a Script.

CompassesManagedlySimultaneouslyUpdater.cs

void AssignMagnetPosition()
    {
        var np = barMagnet01NorthPole.transform.position;
        var sp = barMagnet01SouthPole.transform.position;
        var nv4 = new Vector4(np.x, np.y, np.z, 0);  // Convert to Vector4
        var sv4 = new Vector4(sp.x, sp.y, sp.z, 0);  // Convert to Vector4

        // Set coordinates to Shader of Material of NORTH side of compass
        CompassesModel.Instance.MatNorth.SetVector("_NorthPolePos", nv4);
        CompassesModel.Instance.MatNorth.SetVector("_SouthPolePos", sv4);
        // Set coordinates to Shader of Material of SOUTH side of compass
        CompassesModel.Instance.MatSouth.SetVector("_NorthPolePos", nv4);
        CompassesModel.Instance.MatSouth.SetVector("_SouthPolePos", sv4);
    }

As a result, the Shader is not instantiated and processed as a single Shader. That significantly reduces the calculation load.

Execute Physics calculation in Shader

As the following codes, Physics calculation is executed in a Shader.

MyCompassShader2.shader

// Define position vector of self (compass) as vecP
float3 vecP;
vecP = IN.worldPos;

// Define position vector of NORTH Pole as vecN
float3 vecN;
vecN.x = _NorthPolePos.x;
vecN.y = _NorthPolePos.y;
vecN.z = _NorthPolePos.z;

// Define position vector of SOUTH Pole as vecS
float3 vecS;
vecS.x = _SouthPolePos.x;
vecS.y = _SouthPolePos.y;
vecS.z = _SouthPolePos.z;

// Define displacement vector from self to bar magnet as vecDisN, vecDisS
float3 vecDisN, vecDisS;
vecDisN = vecP - vecN;
vecDisS = vecP - vecS;

// Get magnetic force vectors from two poles as vecF_N, vecF_S
float3 vecF_N, vecF_S;
vecF_N =        vecDisN / pow(length(vecDisN), 3);
vecF_S = -1.0 * vecDisS / pow(length(vecDisS), 3);

// Get resultant magnetic force vector as vecF
float3 vecF;
vecF = vecF_N + vecF_S;

As a result, Physics calculation is completed in GPU. It significantly reduces CPU load. Since the CPU power of HoloLens is very weak, it's important to transfer necessary processes to GPU.

UI / Expression

2019年5月22日:HoloMagnet37、3次元磁力線

More than 300 people in 5 countries at places including 11 schools were practically taken experience lessons / sessions with this app. Learning tests were taken in 3 schools, and all of them gave questionaires (both quantitative and qualitative). These results made the app experience better, and made the learning efficience and satisfaction degree increase. The devices are as followings:

UI

Expression

Lesson Scenes

The followings are lesson / session scenes. Appearance of the app was changing, because we improved step by step.

2018年5月21日-大阪メイカーズバザール 170829-MFT 22908671_1328002897323117_732263550_o 2018年6月21日:(学会発表用)三重高校愛知総合工科高校授業風景320x180 2018年3月8日-京進スクールワン四日市ときわ教室320x180 ★2018年4月13日:障碍者ITカレッジ(明るくした)320x180 2018年6月6日:津東高校v3-3-320x180 イギリスでのHoloLens授業 2018年10月22日:ガーナ教員研修(含生徒)短縮版360x180 2018年10月26日:ガーナ、ホ工科大学授業320x180 2018年11月10日:FabLab-Rwanda320x180 2018年11月13日:ルワンダビジネスマッチング320x180 2018年11月15日:tumba college of technology320x180 2018年11月15日:University of Rwanda320x180 2019年3月20日:グロサミ2019-320x180

Paper

We were asked by The Physics Education Society of Japan to write a paper about these knowledge. We already posted. The detail is going to be put on the journal. We are going to add the link to the paper on publication.

Structure

This is the structure figure of the app.

StructureDiagram

(Drawn with Qt Visual Graph Editor)

We drew simple original structure figure in order to express both class relations and activity flows.

  1. Large circle means Prefab, Middle size circle means class, Small circle means method.
  2. Arrows means paths of process from user

Rolls of classes against a Prefab is followings:

A beginner developer of HoloLens tends to create classes disorderly.

However, when you distinguish handler, model and controller classes against each Prefab, you can design with good prospect easily.

How to Build

Environment

Procedure

  1. Clone this repository
  2. Open the project with Unity
  3. Build into target folder (normally named "UWP")
  4. When the build finished, file explorer opens the project folder. Open the target folder.
  5. Open "HoloMagnet3.sln" with Visual Studio.
  6. Build -> Deploy to HoloLens
  7. Start app named "HoloMagnet3" in HoloLens

Usage

  1. Introduction scene in which you can grow accustomed to movement of a bar magnet
  2. One compass scene which shows the magnetic field
  3. Arranged in 2-Dimension compasses scene
  4. Arranged in 3-Dimension compasses scene

Acknowledgements

Contact

Email, Homepage, Facebook, Twitter, LinkedIn


日本語

本アプリは、「de:code 2019」(マイクロソフト社の開発者をはじめとするITに携わるすべてのエンジニアのための年に一度のテクニカルカンファレンス)において、

「Microsoft MVP アワード」(マイクロソフトの製品やテクノロジーに関する豊富な知識や経験を他者と共有することで、すべてのユーザーが最大限に製品を活用できるよう多大なサポートをおこなったコミュニティのリーダーに、マイクロソフトが感謝の意を表して授与する賞)の受賞者として、

セッション内容をより深く理解し実践するのに役に立つコード「パターンを用い、シンプルな UI を提供する、初心者でもできる HoloLens アプリ開発と Microsoft ストアへの登録方法~実際のソースコード構成図を見ながら~」という位置づけで公開したものです。

目次

特徴

軽量化

500個の方位磁針の個々の物理計算を毎フレームおこないながら、FPS 58を実現しています。

具体的には、シェーダをインスタンス化せずに、シェーダで物理計算をおこなって負荷を大幅に減らしています。

なお、軽量化が必要な理由については次項の「UI・表現」で説明します。

シェーダをインスタンス化しない

以下のように、マテリアルをスクリプトから操作せずに、シェーダに外部変数を受け取る変数を設定し、スクリプトからマテリアルを介さずにシェーダに直接値を代入しています。

CompassesManagedlySimultaneouslyUpdater.cs

void AssignMagnetPosition()
    {
        var np = barMagnet01NorthPole.transform.position;
        var sp = barMagnet01SouthPole.transform.position;
        var nv4 = new Vector4(np.x, np.y, np.z, 0);  //Vector4 に変換
        var sv4 = new Vector4(sp.x, sp.y, sp.z, 0);  //Vector4 に変換

        // 方位磁針の N 極側のマテリアルのシェーダに座標をセット
        CompassesModel.Instance.MatNorth.SetVector("_NorthPolePos", nv4);
        CompassesModel.Instance.MatNorth.SetVector("_SouthPolePos", sv4);
        // 方位磁針の S 極側のマテリアルのシェーダに座標をセット
        CompassesModel.Instance.MatSouth.SetVector("_NorthPolePos", nv4);
        CompassesModel.Instance.MatSouth.SetVector("_SouthPolePos", sv4);
    }

これによりシェーダがインスタンス化されず、単一のシェーダとして処理されるため、計算負荷を大幅に減らすことができます。

シェーダ内で物理計算を行う

以下のように、シェーダ内で物理計算を行っています。

MyCompassShader2.shader

// 自身(方位磁針)の位置ベクトルvecPを作成
float3 vecP;
vecP = IN.worldPos;

// N極の位置ベクトルvecNを作成
float3 vecN;
vecN.x = _NorthPolePos.x;
vecN.y = _NorthPolePos.y;
vecN.z = _NorthPolePos.z;

// S極の位置ベクトルvecSを作成
float3 vecS;
vecS.x = _SouthPolePos.x;
vecS.y = _SouthPolePos.y;
vecS.z = _SouthPolePos.z;

// 自身から棒磁石に対する変位ベクトルvecDisN、vecDisSを作成
float3 vecDisN, vecDisS;
vecDisN = vecP - vecN;
vecDisS = vecP - vecS;

// 極からの磁力ベクトルvecF_N, vecF_Sを求める
float3 vecF_N, vecF_S;
vecF_N =        vecDisN / pow(length(vecDisN), 3);
vecF_S = -1.0 * vecDisS / pow(length(vecDisS), 3);

// 磁力の合力ベクトルvecFを求める
float3 vecF;
vecF = vecF_N + vecF_S;

これにより、物理計算をGPU内で完結させることができ、CPUへの負荷を大幅に減らすことができます。HoloLensのCPUはとても非力なため、必要な処理をどれだけGPUに回せるかが重要です。

UI・外見

本アプリを用いた授業は、5カ国の10の学校で300人が体験しました。全員のアンケート(定量および定性)を収集し、それらを元に、アプリ体験をより良くし学習効果と満足度を上げるために、以下の工夫をおこないました。

表現

論文

これらの知見については日本物理教育学会から研究報告の執筆を依頼され、すでに投稿しました。学会誌に詳細が掲載される予定です。公開され次第リンクに変えます。

構成図

本アプリの構成図です。

StructureDiagram

クラス関係とアクティビティフローを両方表現するために、シンプルな独自の構成図を描きました。

  1. 大きな円がプレハブ、中くらいの円がクラス、小さい円がメソッドを表しています。
  2. 矢印が、ユーザからのアクションがどのような経路をたどって処理されるかを表しています。

プレハブに対するクラスの役割は以下の通りです。

HoloLensアプリを作成する際は、最初はどうしても無秩序にプレハブやクラスを作ってしまいがちです。

しかし、プレハブごとにハンドラ、モデル、コントローラクラスを作成すると、見通しの良い設計を手軽におこなうことができます。

ビルド方法

環境

  1. このリポジトリをクローンします
  2. Unityで、プロジェクトを開きます
  3. ビルド先フォルダ(「UWP」とするのが一般的)を指定してビルドします
  4. ビルドが終わるとプロジェクトフォルダがエクスプローラによって開かれるので、先ほど指定したフォルダを開きます
  5. 「HoloMagnet3.sln」ファイルを開きます
  6. Visual Studio を使って HoloLensに配置します
  7. 「HoloMagnet3」を起動します

操作

  1. 棒磁石の移動に慣れてもらうためのシーン(棒磁石しかない)
  2. 1つの磁界を表すコンパスのあるシーン
  3. 平面グリッド上にコンパスが並んでいるシーン
  4. 立体グリッド上にコンパスが並んでいるシーン

謝辞

連絡先

Email, Homepage, Facebook, Twitter, LinkedIn


© 2019 Feel Physics® All rights reserved.