Houdiniから階層とトランスフォームを保持してFBXを書き出すHDAの配布

# 概要

Houdiniで階層とトランスフォームを保持してFBXを書き出すHDAを作ったので、標準機能の問題点と使用方法についてまとめます。
HDAとサンプルファイルはページの最後に書かれたURLからダウンロード出来ます。

# 標準機能の問題点

例えばMayaで図のようなタイヤとボディで分かれた車のモデルがあるとします。
タイヤのピボットは中心、ボディは原点に置かれてます。
<img src="https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585967846136_2020-04-04_11h37_14.png" width=49.5%> <img src="https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585967898850_2020-04-04_11h37_56.png" width=49.5%>

このモデルをHoudiniでリダクションし、FBXを書き出すと階層とトランスフォームが失われてしまいます。
<img src="https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585968597371__2020_04_04_11_49_43_586.jpg" width=49.5%> <img src="https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585968605237__2020_04_04_11_45_58_938.jpg" width=49.5%>


この問題を解決するにはオブジェクトごとにGeometryノードを分け、それをSubnetにまとめたものをOutコンテキストから書き出さないといけません。
![](https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585978294034_FBXHierarchy.png)


さらにLODとして持っていくには**LODGroup**という名前でヌルノードを作成し、コネクションを繋げます。
この際、同じネットワーク内に同名ノードを作成する事が出来ない為、同名オブジェクトにしたい場合は**fbx_node_name**と**fbx_node_path**というパラメータを作り、パスと名前を設定する必要があります。
![LODHierarchyDescription.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332597/4ceaaf6d-a142-d544-5025-2fdf32c9d274.png)

メニューの**File > Import > Filmbox FBX**でFBXをインポートすれば自動で階層を作ってくれますが、これらの方法は編集がしづらく、ファイルの更新もしづらくなってしまいます。
![](https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585970916343_FileMenuFBX.png)

この程度の階層であればなんとか出来ますが、もっと複雑な階層になるとかなり面倒です。

# HDAの実装方法

配布するHDAではアトリビュートから階層のパスとトランスフォームを読み取り、FBX書き出し時にPythonで自動構築します。

![](https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585979973759_PythonScript.png)

## 階層とトランスフォームのアトリビュート

では、階層とトランスフォームのアトリビュートをどのように作るかと言うとFileノードでFBXを読み込んだ場合、自動で**name**アトリビュートに階層、**fbx_translation**に位置、**fbx_rotation**に回転、**fbx_scale**にスケール値が読み込まれます。
![](https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585980176260_FBXAttribute.png)


HDAではデフォルトでこれらのアトリビュートから値を読み込むようになってるので、元の値を残す事で階層とトランスフォームを保持して書き出せます。
アトリビュート制御なので、Houdiniで一から作ったモデルでも簡単に階層とトランスフォームを持たせる事が可能です。

## LODの作成

LODを作成するには図のようにnameアトリビュートにLODGroupという名前の階層を持たせる事でLODとして書き出されます(画像はLOD0とLOD1が同じ位置に重なっています)。
![NamePreview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332597/6a125c0a-bcd8-8d78-25e1-957933151295.png)


それをMayaで読み込むと図のような階層とLODGroupを持ったモデルとして読み込まれます。
![](https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585922036922_BuildScene.png)


このモデルをUnreal Engineで直接インポートしてもLODが適切に読み込まれてるのが確認出来ます。
![](https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585981501735_LODPreview.gif)

# HDAのUIとパラメータ
**UI**
![](https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585982576521_HDAUI.png)

**パラメータ**

| パラメータ名 | 説明|
| ------ | -------------------------------------------------------------------------------------------------- |
| Render&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | FBXを書き出します。<br>Build Hierarchy From Attributeにチェックが入ってる状態で、階層用のアトリビュートが見つからない場合はボタンが押せないようになっています。 |                                                                                                 |

| Hierarchy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                        |                                     |
| -------------------------------- | ----------------------------------- |
| Build Hierarchy From Attribute | 階層用のアトリビュートを基に階層を構築します。             |
| Path Attribute                   | 階層用のアトリビュート名                        |
| Transform From Attribute         | トランスフォーム用のアトリビュートを基にトランスフォームを設定します。 |
| Translation Attribute            | 位置用のアトリビュート名                        |
| Rotation Attribute               | 回転用のアトリビュート名                        |
| Scale Attribute                  | スケール用のアトリビュート名                      |

| Export&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                 |                                                                              |
| ---------------------- | ---------------------------------------------------------------------------- |
| FBX SDK Version        | エクスポートするFBXファイルのSDKのバージョンを指定することができます。                                       |
| Export in ASCII Format | チェックを付けると、エクスポートするFBXファイルは人が解読できるASCIIフォーマットになります。チェックなしの場合、バイナリフォーマットになります。 |
| Output File            | ジオメトリを保存するファイル(拡張子を.fbxにしてください)。                                             |

# HDAとサンプルファイルのダウンロード

下記からHDAをダウンロードしてHDAが認識されるフォルダにコピーしていただくと**Sop**と**Rop**で**FBX Export**というノードが追加されます。

- [HDAをダウンロード](https://www.dropbox.com/s/l3wjlpa8sa8bs4y/FBXExport.hda?dl=1)
- [サンプルファイルをダウンロード](https://www.dropbox.com/s/0f3adhxnoseeaj3/Car.hiplc?dl=1)

| Sop                                                                                                                                        | Rop                                                                                                                                        |
| ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| ![](https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585982740256_TabMenuSop.png) | ![](https://paper-attachments.dropbox.com/s_4CE5D9C81ED938D6F2A33B018D0B6CFCD3FF61C571762AD5D436489EC2409120_1585982818637_TabMenuRop.png) |

# 最後に

今後、公式でこういった機能がFBXに付く可能性や、そもそもUSDなどFBXを使わないフローに代わる可能性がありますが、このHDAが皆さんの制作に少しでも役に立てば幸いです。

バグや機能要望等あればコメントに書いていただけると助かります。