ここからは Mesh IR → OBJ Export の正式仕様を、
あなたの昆虫 OS に完全にフィットする形でまとめるね。

OBJ はシンプルだけど、
Mesh IR の構造(parts / vertices / normals / uv / faces)を
どう正しく OBJ に落とすか
を OS として定義しておくと、
後でどんな昆虫でも安定して生成できる。

以下は OS の正式仕様書レベルで書く。


🧩 Mesh IR → OBJ Export の正式仕様

OBJ は以下の 4 種類の行で構成される:

  • v x y z(頂点)
  • vt u v(UV)
  • vn x y z(法線)
  • f i/j/k i/j/k i/j/k(三角形)

そして、昆虫 OS では パーツごとに OBJ を分ける。

例:

  • head.obj
  • thorax.obj
  • wing_front_L.obj
  • leg2_R.obj

MotionPatch は別 JSON として渡す。


🌟 1. OBJ ファイル構造(パーツ単位)

o <part_id>
mtllib <material_file>.mtl

# 頂点
v ...
v ...

# UV
vt ...
vt ...

# 法線
vn ...
vn ...

# 面
usemtl <material_name>
f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3

🧬 2. Mesh IR → OBJ の変換ルール

Mesh IR の構造はこうだった:

{
  "mesh": {
    "parts": [
      {
        "id": "thorax",
        "vertices": [[0,0,0], [0.1,0,0], ...],
        "normals":  [[0,1,0], [0.7,0.2,0], ...],
        "uv":       [[0,0], [1,0], ...],
        "faces":    [[1,2,3], [3,4,1]],
        "material": "body",
        "origin": [0,0,0],
        "parent": "head"
      }
    ],
    "materials": {
      "body": {
        "color": [0.2, 0.2, 0.2],
        "smooth": true
      }
    }
  }
}

これを OBJ に変換する。


🔥 3. v(頂点)生成仕様

v <x> <y> <z>
  • Mesh IR の vertices[] をそのまま出力
  • MotionPatch 適用後の座標であること
  • 単位は OS 内部単位(Roblox では後でスケール調整)

例:

v 0.000 0.100 0.000
v 0.100 0.000 0.000

🎨 4. vt(UV)生成仕様

vt <u> <v>
  • Mesh IR の uv[] をそのまま出力
  • 0〜1 の範囲
  • 翅(plane)は [0,0]〜[1,1] の矩形

例:

vt 0.0 0.0
vt 1.0 0.0

🌬 5. vn(法線)生成仕様

vn <nx> <ny> <nz>
  • Mesh IR の normals[] をそのまま出力
  • 正規化済みであること

例:

vn 0.0 1.0 0.0
vn 0.7 0.2 0.0

🧱 6. f(三角形)生成仕様

f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3
  • Mesh IR の faces[] は 1-based index
  • OBJ も 1-based index
    → そのまま使える

例:

f 1/1/1 2/2/2 3/3/3

🧩 7. マテリアル(MTL)生成仕様

OBJ と同時に .mtl を生成する。

newmtl body
Kd 0.2 0.2 0.2
Ns 10
d 1.0
illum 2

Mesh IR の materials を参照する。


🐛 8. パーツごとに OBJ を分割する理由

昆虫は:

  • head
  • thorax
  • abdomen
  • legs(6 本)
  • wings(4 枚)

という 階層構造を持つ。

MotionPatch は:

  • wing_flap → wing_front_L
  • leg_walk → leg2_R

のように パーツ単位で適用される。

だから OBJ もパーツ単位で分ける必要がある。


🧠 9. MotionPatch と OBJ の関係

  • OBJ:静的形状
  • MotionPatch:動きの IR
  • Roblox Loader:
    • OBJ → MeshPart
    • MotionPatch → Motor6D

つまり:

OBJ = 見た目
MotionPatch = 動き

この 2 つを 同時に Roblox に渡すのが正しい。


🌋 10. 最終的な OBJ Export パイプライン

昆虫 IR
   ↓
Geometry IR(primitive)
   ↓
MotionPatch 適用
   ↓
Mesh IR(vertices / normals / uv / faces)
   ↓
OBJ Export(パーツごと)
   ↓
Roblox Loader(Motor6D + Script)

次はどれを進めたい?

  • MotionPatch → Mesh IR の変形アルゴリズム(rotate/hinge/oscillate)
  • Roblox Loader(OBJ + MotionPatch → Model + Motor6D)
  • 昆虫 IR → Mesh IR の変換コード(Lua or Python)
  • 昆虫 IR の species プリセット(ant / beetle / bee / mantis)

どれでも深くいけるよ。