mieki256's diary



2017/03/16(木) [n年前の日記]

#1 [ruby] 3Dモデルデータファイルを読み込んでRubyから使いやすい形に整形するRubyスクリプトを書いた

Ruby + gosu + opengl で実験する際、一々モデルデータを紙に描いて座標を決めて配列にしていくのが面倒臭かったので、Wavefront形式(.obj)の3Dモデルデータファイルを読み込んで、Rubyから使いやすい形に整形して標準出力に出力する Rubyスクリプトを書いてみたり。

_mieki256/tinywavefrontobj

tinywavefrontobj.rb というファイルをダウンロードして実行すれば使える、はず。

Wavefront形式の全ての属性に対応してるわけではないけれど、実験用の頂点配列、法線配列、uv配列、面配列(頂点インデックス配列)をちょこっと作りたい時にはひとまず使える、のではないかなと。

使用例その1。 :

例えば、blender でこういうモデルデータを作成して、Wavefront(.obj)形式でエクスポート。

tinywavefrontobj_ss01.png

ちなみに、Wavefront形式は、三角形ポリゴンと四角形ポリゴンを混在できるのだけど…。後になってからRubyスクリプト側で、面配列(頂点インデックス配列)のみを眺めてそれぞれ三角ポリゴンか四角ポリゴンかを判別するのはおそらく不可能。故に、エクスポート時に「三角面化」にチェックを入れて、全てのポリゴンを三角ポリゴンにしちゃったほうがいいと思う。

tinywavefrontobj_ss02.png

tinywavefrontobj.rb を使って整形出力。
ruby tinywavefrontobj.rb sample.obj

こういう結果が得られる。
@vertexes = [
  1.0, -1.0, 0.0,  # 0
  -1.0, 1.0, 0.0,  # 1
  -1.0, -1.0, 0.0,  # 2
  1.0, 1.0, 0.0,  # 3
]

@normals = [
  0.0, 0.0, 1.0,  # 0
  0.0, 0.0, 1.0,  # 1
  0.0, 0.0, 1.0,  # 2
  0.0, 0.0, 1.0,  # 3
]

@faces = [
  0, 1, 2,  # 0
  0, 3, 1,  # 1
]
これをRubyソースに貼り付ければ実験に使えるだろうと。

jsonやyamlで出力。 :

json や yaml でも出力できる。

ruby tinywavefrontobj.rb sample.obj --json > sample.json
{"vertex":[1.0,-1.0,0.0,-1.0,1.0,0.0,-1.0,-1.0,0.0,1.0,1.0,0.0],"normal":[0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,1.0],"face":[0,1,2,0,3,1]}

ruby tinywavefrontobj.rb sample.obj --yaml > sample.yml
---
vertex:
- 1.0
- -1.0
- 0.0
- -1.0
- 1.0
- 0.0
- -1.0
- -1.0
- 0.0
- 1.0
- 1.0
- 0.0
normal:
- 0.0
- 0.0
- 1.0
- 0.0
- 0.0
- 1.0
- 0.0
- 0.0
- 1.0
- 0.0
- 0.0
- 1.0
face:
- 0
- 1
- 2
- 0
- 3
- 1

Rubyスクリプト側で、例えば以下のような感じで書けば、jsonファイルを読み込んで、頂点配列、法線配列、uv配列、面配列(頂点インデックス配列)を得られる。
    require 'json'
    ...
    vertex_array = nil
    normal_array = nil
    uv_array     = nil
    face_array   = nil
    File.open("sample.json") { |file|
      hash = JSON.load(file)
      vertex_array = hash["vertex"]
      normal_array = hash["normal"] if hash.key?("normal")
      uv_array     = hash["uv"] if hash.key?("uv")
      face_array   = hash["face"]
    }
    ...
    if uv_array
      puts "use texture"
    end
    if normal_array
      puts "use normal"
    end

RUbyソース内から呼び出して使う。 :

以下のように書けば、Rubyソース内から呼び出して使うこともできる。
    require_relative 'tinywavefrontobj'
    ...
    o = TinyWaveFrontObj.new("sample.obj", true, true)
    vertex_array = o.get_vertex_array
    normal_array = o.get_normal_array
    uv_array     = o.get_uv_array
    face_array   = o.get_face_array
    ...
    if o.use_uv
      puts "use texture"
    end
    
    if o.use_normal
      puts "use normal"
    end

以上です。

過去ログ表示

Prev - 2017/03 - Next
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project