Cinema 4D で USDZ を作るのがつらい

[MoAR](https://whatever.co/moar/) の "[Watching](https://whatever.co/moar/ja/watching/)" というコンテンツを作ったときに [Cinema 4D](https://www.maxon.net/ja/cinema-4d) から USDZ フォーマットで 3D データを作ろうとして大変だった話。

# Domingo は Cinema 4D 使い

Whatever New York には [Domingo Gamonoso](https://whatever.co/ja/team/domingo/) という流体やパーティクルシミュレーションを使った素敵な作品をつくるデザイナーが所属しています。MoAR のコンテンツを作るにあたってせっかくなので Whatever New York チームにも参加してもらってひとつコンテンツを作ってもらおうと企画が始まりました。

わたしは Domingo が得意とするようなプリレンダーの 3D CG と MoAR のようなリアルタイム 3D CG のワークフローや必要とする技術がかなり違うことは理解していましたが、企画次第でなんとかなるかなーと考えていました。

# Cinema 4D から USDZ を出力する

当時の最新版である Cinema 4D R26 にはすでに USD (USDZ) のエクスポート機能が標準で搭載されていました。しかし実際にはかなり機能が限定されていて Watching で必要としていたスキニングアニメーションも出力することができませんでした…😇

# 別の形式で出力して変換する

じゃあ別の形式で出力してコンバートすればよいかと [glTF 形式でスキニングアニメーションを出力するチュートリアル](https://www.youtube.com/watch?v=F4ENlmauh-s)を探しだして同様にやってみるもなぜかうまく書き出せない…

さすがに FBX ならちゃんと出力できるだろうとやってみると書き出しは問題なし。Blender で開くと Cinema 4D と同様の動きをしている。

別のコンテンツ用の USDZ 作成フローとして Blender → `glTF` → [Reality Converter](https://developer.apple.com/jp/augmented-reality/tools/) → `USDZ` というのは成功していたので、Blender で正常に見えていれば USDZ まで持っていけそうということでやってみたらようやく成功。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/52eb1e34-71af-9d75-04b1-32ad373e7c92.gif" width="100%"  />

左下が Cinema 4D のオリジナルのスキニングアニメーション。
左上が FBX 出力したものを Blender で開いた状態。
右上が Blender から glTF で出力したものを Babyron Sandobox で開いた状態。
右下が glTF を Reality Converter で USDZ 変換した状態。

すべて同じように見えてるのでこれで OK！

# ...かと思いきや

実際に使用する手のモデルを同じフローで変換すると Blender で FBX を開いた段階でぶっ壊れている。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/ccb29d45-9748-9b97-8ddc-8681c0a81427.png)
手のメッシュとボーンの位置が全然ちがうしそのせいでメッシュがめちゃくちゃに変形されてしまっている…

# Reality Converter は FBX が読める

glTF から USDZ へコンバートできていたのですっぽり頭から抜けていましたが、Reality Converter は別途 FBX SDK をインストールすることで FBX から USDZ に変換することができます。
![fbx.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/d733fff8-3d22-1943-571d-568fe1cc814e.gif)
で、やってみたらそれっぽくできてる！けど指差し形状に変形しながら前後に移動するという動きの前後移動が同時にできない。スキニングアニメーションと単純な移動が組み合わせられない。おしい。

どうにかならないかといろいろ編集してるうちに最後には Reality Converter の変換時にエラーを吐くようになってしまい結局 Reality Converter で FBX から 直接 USDZ に変換するのは諦めることに。

# スキニングアニメーションいらないのでは…

全体に演出を改めて見直したところ壁が壊れる以前の指のスキニングアニメーションは壁があるので見えないのでなくても成立するのでは？という話になりベイクしたメッシュを単純に前後に動かすだけにしました。<br/><br/>

<iframe width="100%" height="700" src="https://www.youtube.com/embed/_3ns1kQbEZA?rel=0" title="RPReplay Final1661839741" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

1. Cinema 4D から FBX でエクスポート。
1. Blender で位置とかマテリアルを調整して glTF でエクスポート。
1. Reality Converter で USDZ に変換。

という手順で SceneKit まで持ってきて、あとは適切なタイミングでアニメーションを開始しています。


結局 Cinema 4D はモデリングとマテリアル設定だけやって、動かすのを含めて仕上げは Blender でやるのが一番安定してよい感じになりました。（Cinema 4D つらい、Blender で最初から作れば楽…

# つらすぎてボツになったコンテンツのほうの話

"Watching" の他にもう一つ New York チームと作ろうとしていた作品がありました。
ビル前を歩いてる人が巨大なサメに釣られるという内容なのでまず歩く人を作ってもらったのですが…

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/01ae1f25-8c24-6176-6411-a946ae0d5c04.gif" width="100%" />

ボディが遥か彼方にすっとんでいてやばい…

なんとか調整してボディがすっとんで行かないようになっても glTF にすると何故かワープしていて、Reality Converter で USDZ にするとワープがさらにひどく…
![walking2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/dea53b4f-c891-34ce-1510-6ef5b07a1632.gif)
上が glTF で下が USDZ。

なんとか調整してワープしないようにしてもらったけどやっぱりちょっとなんか変…
![walking3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/addfd6b5-2ecc-0177-46d4-2fd2553efcd6.gif)
歩きモーションは右足と左足の2歩分が1モーションになっていてモーション終了タイミングで次の位置に動かしてもういちど最初から2歩分を再生するっていう仕組みでずっと続けて歩く仕組みになっています。

↑のキューブはその2歩分のアニメーションの原点なんですがどうも原点を動かすアニメに問題がありそう…
![walking4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/748c5c22-f2c4-5960-86cf-ae118ba01988.gif)
というわけで Cinema 4D で4点を順番に移動するアニメを作って FBX → glTF → USDZ で変換してみると Cinema 4D 上では各点のを瞬間移動するように Key Interpolation を Step に指定しているにもかかわらず最終的な USDZ では中間に位置するフレームがあるように見える…

Blender で FBX を開いてキーフレームを確認してみるとなんとなく理由がわかりまして、
![frameinterpolation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/305c779c-a08a-e648-90d8-631182721b10.png)
値が変わるフレーム間がリニアに補間されてるっぽいんですね。SceneKit に組み込んでみてもやっぱりこのポイントで中間フレーム位置に一瞬移動するのでループがうまくつながらない。

ただこの状態の USDZ を Preview.app で開くと意図通りきれいに歩いてるんです。
![walking5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/d3b31433-5066-a3c3-8933-1d9d25a616e9.gif)
（どうやら Preview.app と SceneKit のキーフレームの解釈に違いがあるっぽい…？）

もうわけわかんないなーこのコンテンツ成立させるためにはまだ解決しないといけない Issue がコレ以外にもいろいろあるなー時間ないなーってことでお蔵入りとなりましたとさ…

# Unity

Blender とか Reality Converter とか glTF とかいろいろ手間をかけてやれたらいいなを諦めてようやくまともに SceneKit で使える USDZ が作れたわけなんですが、これ、Unity だと Cinema 4D から書き出した FBX はほぼそのまま再現できてしまって今回くらった問題が全然おこらないんです…

# SceneKit と Cinema 4D の相性

最悪。特にボーンがはいったスキニングアニメーションは無理。USDZ 書き出しは中途半端だし glTF はまだもうちょいまともだけどうまくいったりかなかったりだし FBX はちゃんと出るけど Reality Converter 側がうまく解釈しきれなかったりで全くおすすめできない。

Blender の USD 書き出しもイマイチだけど Reality Conveter で glTF を USDZ にすればだいたい問題なくいける。

別コンテンツ "[emoc](https://whatever.co/moar/ja/emoc/)" では Maya から USDZ 作ってたりするのでそっちのがより安定かも。来週の記事に期待。