Java OpenGL JOGLを使う〜 Objファイルを読む〜

2021-03-31 18:16:14 Wednesday前回は、JOGLを使用してみようと思ったのでとりあえずで、動かしてみました。

そして、OBJファイルなど他のアプリを使用して作成した3Dモデルをロードする方法を探してみましたが、なかなか見つからず。。。

結局はファイルを読み込んで生成する

調べていくと、見つかったのはファイルの内容から3Dモデルを生成する方法がありました。

よく考えてみれば、その通りだよな。。。ファイルに3Dモデルを生成するための情報が書いてあるからそれを読んで、表示する。。。

当たり前な話だ(笑)

そんなわけで、その方向で進めようと思った次第です。
そして、Blenderを使用する人が多いのですが、Blenderを使用するのに色々と覚えなくてはいけないことが多いのと、「絵心のないやつNo1」の自分としてはVoxcelのようにシンプルなアプリで手一杯なので、こちらを使用しようと思います。

Voxcelのテンプレート

下に示すように、デフォルトで用意されているデータを表示するとしたのようなイメージが見れます。

そして、「エクスポート」で出力したデータから上のイメージが作成されています。

なので、元になるデータを見て見ます。

まずは、ファイルの中身を見る

<chr_sword.obj>

# MagicaVoxel @ Ephtracy

# group
o 

# material
mtllib chr_sword.mtl
usemtl palette

# normals
vn -1 0 0
vn 1 0 0
vn 0 0 1
vn 0 0 -1
vn 0 -1 0
vn 0 1 0

# texcoords
vt 0.00195312 0.5
vt 0.0332031 0.5
vt 0.0371094 0.5
vt 0.0449219 0.5
vt 0.0605469 0.5
vt 0.166016 0.5
vt 0.634766 0.5
vt 0.638672 0.5
vt 0.962891 0.5
vt 0.974609 0.5
vt 0.978516 0.5
vt 0.982422 0.5
vt 0.994141 0.5

# verts
v 0.1 1.2 -1
v 0.1 1.2 -1.1
v 0.1 1.3 -1
v 0.1 1.3 -1.1
v 0.5 2 -1
v 0.5 2 -1.1
  ・
  ・
  ・
  ・
# faces
f 3/1/1 2/1/1 1/1/1
f 4/1/1 2/1/1 3/1/1
f 7/7/1 6/7/1 5/7/1
f 8/7/1 6/7/1 7/7/1
f 11/4/1 10/4/1 9/4/1
f 12/4/1 10/4/1 11/4/1
f 15/4/1 14/4/1 13/4/1
f 16/4/1 14/4/1 15/4/1
f 21/5/1 18/5/1 17/5/1
  ・
  ・
  ・

OBJファイル

※(w)もある キーワード 意味 内容
「#」 コメント 記述した行がプログラムには読まれない
「mtllib」 マテリアルファイル名 使用するマテリアルファイル名
「g」 グループ名 おそらく1つのOBJファイル内に2つ以上のオブジェクトを書き込んだ時に
どのオブジェクトのデータであるかを分ける為の名前
「usemtl」 マテリアル名 使用するマテリアル名
「v」 頂点座標値 「v x座標 y座標 z座標」と表現)
「vt」 テクスチャ座標値 テクスチャ座標データです。テクスチャ座標は基本的に2次元データ
「vn」 頂点法線ベクトル 「vn x座標 y座標 z座標」の形式
「f」 多角形面データ 「頂点座標番号/テクスチャ座標番号/頂点の法線ベクトル番号」各番号は上から1, 2, …と振られていると考えます

<サンプル>
例)
v 1.0, 1.0, 1.0 ←1
v 1.5, 1.5, 1.5 ←2

vt 1.7 1.7 1.7 ←1
vt 1.8 1.8 1.8 ←2

vn 2.0 2.0 2.0 ←1
vn 2.3 2.3 2.3 ←2

f 1/1/1 1/2/2

f 頂点座標番号/テクスチャ座標番号
f 頂点座標番号//頂点の法線ベクトル番号
f 頂点座標番号

「頂点法線ベクトル」がよくわからなかったけど、Cube(立方体)の場合は「面」になる部分が「6こ」なので、その座標(ベクトル)が下のようになっている

# normals
vn -1 0 0 # 1つめ
vn 1 0 0 # 2
vn 0 0 1 # 3
vn 0 0 -1 # 4
vn 0 -1 0 # 5
vn 0 1 0  # 6

しかし、細かいところがまだわからない。。。

<chr_sword.mtl>

# MagicaVoxel @ Ephtracy

newmtl palette
illum 1
Ka 0.000 0.000 0.000
Kd 1.000 1.000 1.000
Ks 0.000 0.000 0.000
map_Kd chr_sword.png

MTLファイル

キーワード 意味 内容
newmtl マテリアル名を定義 ここで定義した名前がマテリアルの名前になる
Ka アンビエントカラー RGB(0.0~1.0)
Kd ディフューズカラー RGB(0.0~1.0)
Ks スペキュラーカラー RGB(0.0~1.0)
map_Kd テクスチャ名 文字列

上のようなデータが記述されています。
そして、objファイルの公式な定義がどのようにされているのか?に関しては、ここのサイトを見る限りはっきりしていないようなので、深く追求することはしません(笑)

とにかく重要なのはこのファイルに定義されている項目と内容の理解です。そして、参考にするサイトはこちらです。
そして、抜粋ですが、下のような形で定義されているようです。

# (x,y,z[,w]) 座標によるジオメトリ頂点の一覧。w は任意であり、標準は 1.0 である。
  v 0.123 0.234 0.345 1.0
  v ...
  ...
  # (u, v [,w]) 座標によるテクスチャ座標の一覧。座標は0から1の間で変化することができる。w は任意であり、標準は 0 である。
  vt 0.500 1 [0]
  vt ...
  ...
  # (x,y,z) 形式による頂点法線の一覧; 法線は単位法線ではないかもしれない。
  vn 0.707 0.000 0.707
  vn ...
  ...
  # ( u [,v] [,w] ) 形式によるパラメータ空間頂点 ; 自由ジオメトリ文 (以下を参照)
  vp 0.310000 3.210000 2.100000
  vp ...
  ...
  # ポリゴン面要素 (以下を参照)
  f 1 2 3
  f 3/1 4/2 5/3
  f 6/4/1 3/5/3 7/6/5
  f ...
  ...

項目を整理する

単純な形のOBJファイルと上の「剣士?」のOBJファイルを比較して見ます。
<単純なOBJ>

この3Dモデルを表示するのに使用しているOBJファイルは
下のようなものです。

# MagicaVoxel @ Ephtracy

# group
o 

# material
mtllib try1.mtl
usemtl palette

# normals
vn -1 0 0
vn 1 0 0
vn 0 0 1
vn 0 0 -1
vn 0 -1 0
vn 0 1 0

# texcoords
vt 0.306641 0.5

# verts
v 0 2 0
v 0 2 -4
v 0 6 0
v 0 6 -4
v 4 2 0
v 4 2 -4
v 4 6 0
v 4 6 -4
v 0 2 0
v 0 6 0
v 4 2 0
v 4 6 0
v 0 2 -4
v 0 6 -4
v 4 2 -4
v 4 6 -4
v 0 2 0
v 4 2 0
v 0 2 -4
v 4 2 -4
v 0 6 0
v 4 6 0
v 0 6 -4
v 4 6 -4

# faces
f 3/1/1 2/1/1 1/1/1
f 4/1/1 2/1/1 3/1/1
f 5/1/2 6/1/2 7/1/2
f 7/1/2 6/1/2 8/1/2
f 11/1/3 10/1/3 9/1/3
f 12/1/3 10/1/3 11/1/3
f 13/1/4 14/1/4 15/1/4
f 15/1/4 14/1/4 16/1/4
f 19/1/5 18/1/5 17/1/5
f 20/1/5 18/1/5 19/1/5
f 21/1/6 22/1/6 23/1/6
f 23/1/6 22/1/6 24/1/6

group

<剣士><単純なOBJ>共に下のようになっています。

# group
o

意味がわからないので下のオブジェクトを見て見ます。オブジェクトが2つあります。

# group
g untitled1

うーむ、どうやら3Dオブジェクトが1つの場合は、「o」になるようだ。。。あまり深く追求しても意味がなさそうなので、ここで終わりにします。

material

# material
mtllib untitled1.mtl
usemtl palette

これは下のobjファイルです。

同様に、<剣士>

# material
mtllib chr_sword.mtl
usemtl palette

usemtlは使用するマテリアルの宣言でファイルの最後まで続くようですが、いまいち理解できませんでした。

最も単純な3Dモデル(Voxel)

ボックスが1つだけです。。。

OBJファイルを見て見ます。
ほぼ<単純なOBJ>と同じデータでした。
ファイルの行数も同じでした。。。

vnは立方体ならば、その角にある線の数を表すので6本あるのはわかったが、座標が何を示すのかがわからない。。。

Javaコード

参考にするコードはこちら
とりあえずは、このコードを基本にして行こうと思いますがもう少し調査が必要になります。

今日はここまでにします。

でわでわ。。。

https://yttm-work.jp/model_render/model_render_0002.html

投稿者:

takunoji

音響、イベント会場設営業界からIT業界へ転身。現在はJava屋としてサラリーマンをやっている。自称ガテン系プログラマー(笑) Javaプログラミングを布教したい、ラスパイとJavaの相性が良いことに気が付く。 Spring framework, Struts, Seaser, Hibernate, Playframework, JavaEE6, JavaEE7などの現場経験あり。 SQL, VBA, PL/SQL, コマンドプロント, Shellなどもやります。

コメントを残す