goMMD - iOS MMD player アプリ開発ブログ

# 2022年7月 goMMDの開発に復帰

### 技術力不足のため壁にぶち当たって開発を保留していたのを再開

インターネットで流用出来そうな物を見つけたので、開発を続行します。
iOSでは、OpenGLES（OpenGLのバージョンが3.x)で止まり、更にAppleよりサポートされなくなりました。　iOS上の３DはMetal APIのみが指定されています。

以前書いた記事
[iOSアプリに利用したいMMD PMX まとめ](https://qiita.com/papipo111/items/0ba0c1320ec742d36394)

今回、iOS Swift及びiOS Metalへのアップグレードが出来そうなので実行に移しました。
使用するモジュールは、以下の物です。
[MMDViewer(github)](https://github.com/blackspotbear/MMDViewer)
Swift言語/Objective-c++, PMX model 及び VMD sample, bullet-physics, iOS Metal API
[Saba(quiita)](https://qiita.com/benikabocha/items/ae9d48e314f51746f453)
C++言語, PMX PMD VMD, bullet-physics, GLFW with OpenGL 4.x

[Saba](https://qiita.com/benikabocha/items/ae9d48e314f51746f453)は、かなり前から知っていたのですが、OpenGL 4.xが必要なので見をくっていました。
[MMDViewer](https://github.com/blackspotbear/MMDViewer)で全て解決するかなと期待して使って見たのですが、残念ながらサンプルのPMX modelしか動かず、それ以外のPMX modelは動きませんでした。
<code>Assertion failed: (fsum > SIMD_EPSILON), function convertJoint, file btSequentialImpulseConstraintSolver.cpp, line 1265.
</code>
今回、この二つ（[MMDViewer](https://github.com/blackspotbear/MMDViewer)と[Saba](https://qiita.com/benikabocha/items/ae9d48e314f51746f453))を組み合わせれば目的のアプリを作れると思い開発を再開する事にしました。

以前は、iOSアプリ<b>MMDPlayer</b>が有りましたが、アップルのアプリストアから姿を消し、その後、同じようなアプリが<b>アプリストア</b>や<b>Github</b>等では見つかりません。自作のアプリを世に出したいと思い頑張ってみます。

**開発中アプリ goMMD**

Note：
- Xcode
    - Object-c/c++とSwiftではBuild Settingsの項目が違うのでSwiftでObject-c/c++の項目の追加が分からない。Object-c/c++からSwiftへProjectの変更した場合Object-c/c++の項目は受け継がれる。
    - TARGETSのBuild PhasesのCopy Bundle Resourcesにソースファイルが含まれDuplicated symbolエラーが幾度か出た。その場合Copy Bundle Resourcesからソースファイルを消去して解決した。
    - 多階層のObjective-c　struct　pointerをSwiftへ現在のSwift APIでは出来ない。故にPMXやVMDのデータをObjective-c/c++で読み込んでもSwiftへ転送する方法がない。
- MMDViewer
    - DataReaderにてbone数などのcount(int32_t)の読み込みがuint32_tになっている様に思う。非参照値-1が処理されてない様に見受けられる。
        - ※ボーンや剛体などは、-1を非参照値として扱います。材質は材質モーフにより-1:全材質とみなします。
    - MMDView.swiftでpmxとvmdファイルを読み込んでPMXObjectに挿入している。mainLoop()にて、描画及びイベントアクションを管理。
        - setupSceneGraph()　PMXObjectをNodeオブジェクトへ挿入、Nodeオブジェクトをrootオブジェクトへ追加。
        - handlePan()　タッチイベントからのcameraビユウーのアップデート。
        - mainLoop()　timer管理、renderer.reshapeの実行、traverser.update()及びtraverser.draw()を実行。
- Saba
    - src/Saba/Model/MMD/pmx,pmd,vmdファイルのstructの定義がMMDFileString<Size>で定義されていて、実質内部メモリー領域はSize＋1が使われている。
    - src/Saba/Model/MMD/VMDAnimation.cppでpmx又はpmdファイルとvmdファイルをそれぞれ読み込んで内部で関連付けしている。
    - アニメーションのコントロールは、viewer/Saba/Viewer/Viewer.cpp(アプリケーションmain)で行われている。
        - viewer/Saba/Viewer/Viewer.cpp Viewer::Run()がmain loop。
        - viwer/Saba/Model/MMD/GLMMDModel.cppでVMDAnimation,MMDModel,VMDFileを読み込み管理している。
        - viewer/Saba/Model/MMD/GLMMDModelDrawerでMMDModelのOpen GL drawがされている。
            - Play(), Stop(), ResetAnimation(), Update(), Draw(), DrawShadowMap()

**2022年8月**
- MMDViewerをgoMMDへ移植してビルド。
- SabaのPMXFileへchar*からPMXモデルをロード出来るように変更。
- Saba C++オブジェクトをMMDViewerコードへ移植。
- Saba ZipReader classを追加。
    - Zip内のファイル名にUtf8及びShift-JISの両方を使用。
    - pmxファイルのUtf16からstd::stringに手間取った。
- Saba PMXFile/PMXModelでZipReaderからpmxファイルをロード。
    - PMXString/MMDFileString<Size>はストレージがSize＋1なので読み込み時はsizeof(variable)-1を使用。
- Saba VMDFileでZipReaderからvmdファイルをロード。
    - VMDString/MMDFileString<Size>でsizeof(variable)-1を使用。
- Saba VMDAnimationでZipReaderからpmx及びvmdファイルをロード。
- Object-c++ wrapper VMDAnimationObjc.(h,mm)を追加。Object-c++からC++クラスを使用。
- Swift wrapper VMDAnimation.swiftを追加。SwiftからObject-c++クラスを使用。
- Saba VMDAnimationで読み込んだPMXやVMDデータをSwiftへ転送出来ないのでMMDViewerコードからSabaのデータを使うのは断念。
- MMDViewerのPMXファイル読み込みをSabaのコードを参考にアップデートして見る。


<br>

**アーカイブ**
<details>
<summary>2022年7月</summary>
- goMMDをMMDViewerへ移植してビルド。<br>
- MMDViewerでgoMMDのXMLファイル及びモデルリストの表示。<br>
- PMXモデルデータはロード出来るが、モデルが上手く表示されない。<br>
</details>

<details>
<summary>2022年6月</summary>
- Swift言語サンプルアプリでXMLファイルを開いて表示。<br>
- Swift言語サンプルアプリでgoMMDのXMLファイル及びモデルリストの表示。<br>
</details>

<details>
<summary>2022年5月</summary>
- MMDSceneKitとMMDViewerをXcodeでビルドしてiPhone13 Proでテスト。<br>
- Swift言語でサンプルアプリを幾つかビルド。<br>
- YouTubeでSwiftアプリの開発動画を見る。
</details>

<details>
<summary>2018年9月</summary>
- <b>Saba</b>のコードを<b>goMMD</b>へ移植してビルド。
</details>