Java 3D LWJGL 〜Tutorial #3 OBJファイルをロードする〜

前回に引き続き、次はOBJファイルのロード(読み込み)を行います。

Git bookのページはこちら
参照するGithubはこちらです。

OBJファイルロード

作成したものは、以下のものです。(コピーして作成)

手順

Gitをクローンする

まずは、学習に使用するGitプロジェクト(LWJGL3のチュートリアル)をクローンします。
ここのリンクにGit bookがある(PDF)のでこのプロジェクトで行なっている内容の解説をしています(英語ですが。。。)

プロジェクトを移植する

これは、プロジェクトをクローンした時に、フォルダの階層が、1プロジェクト=chapter1-29になっているのでプロジェクトとして動きません。

まとめてクローンした場合は、プロジェクト単位で抜き出してやる必要があります。ビルドパスの関係ですね。。。

自分の場合は以下のようにやりました。

単純にクローン下プロジェクトの必要な部分(プログラムのパッケージ以下)をコピーして貼り付けてやるだけです。
そして、プログラムのビルドエラーが出ると思うのでそれを解消してやる必要があります。

ビルドエラーの原因としては、「クラスが見つからない」がほとんどです。なので、参照されるクラスが全てビルドパス上に存在すれば良いということです。

セットアップ時には、resourcesファイルも使用するのでこれも忘れないようにコピーしてあげましょう。

OBJファイルのロード

OBJファイルを読み込んでロードする。これの詳細は[Gitbookを見た方が良い]()のですが、如何せん英語なんだなぁ。。。コードと翻訳機能で、読んで見た所、以下のサイトを参考にしました。

こちらも同様に参考にしました。

OBJファイルをロードするのには

An OBJ file defines the vertices, texture coordinates and polygons that compose a 3D model.

と記載があるように、

  1. 各頂点
  2. テクスチャを貼り付けるための座標
  3. ポリゴンの座標

上記のデータをもとに、表示しますのでここの情報をOBJファイルからロードして必要な情報をモデルに設定します。

学習の進め方

これは自分の一番やりやすかった方法ですが、記載しておきます。

  1. Githubから参考にするプロジェクト(ソース)をクローン
  2. 説明などがあるドキュメント(今回はGit book)を用意
  3. 対象のChapterを読みながら、プログラムを読む。
  4. アプリを動かす。

シンプルかつ、時間がかかるけど一番効率の良い方法だと思います。

ポイントになるコード


上にあるように、DummyGameクラスがポイントになります。

public class DummyGame implements IGameLogic
上に示すように、このクラスにはIGameLogicというインターフェースが実装されているので、このインターフェースクラスで定義されているメソッドをオーバーライドすれば、基本的には動くものが作成できます。

サンプルとして「DummyGame」があると思うと飲み込みやすいのではないでしょうか?

そして実装するメソッドは以下のIGameLogoicの中身を見ればわかります。

public interface IGameLogic {
   // 初期表示する内容を実装します、今回はロードしたOBJファイルです。
    void init(Window window) throws Exception;
    // ここには、入力した時どのようなアクションを起こすか定義します。
    void input(Window window, MouseInput mouseInput);
   // 画面の更新処理です。
    void update(float interval, MouseInput mouseInput);
    // レンダリング(画面更新):ここら辺がまだ理解できていません。。。
    void render(Window window);
    // 画面の初期化、再描画するのに必要
    void cleanup();
}

上記の処理が大まかな処理です。

Objファイルをロードする処理

Gitからソースをクローンしてから、chapter-09のフォルダを開き、Mainクラスを実行します。するとエラーが出ます。
ファイルの参照ができないエラーです

[LWJGL] [ThreadLocalUtil] Unsupported JNI version detected, this may result in a crash. Please inform LWJGL developers.
Exception in thread "main" java.lang.RuntimeException: Image file [resources/models/default/default_texture.png] not loaded: > > Unable to open file
at org.lwjglb.engine.graph.Texture.(Texture.java:29)
at org.lwjglb.engine.graph.TextureCache.(TextureCache.java:13)
at org.lwjglb.engine.scene.Scene.(Scene.java:17)
at org.lwjglb.engine.Engine.(Engine.java:26)
at org.lwjglb.game.Main.main(Main.java:19)

これは、resources/models/default/default_texture.pngのようなファイル参照のパスが違っているためです。
これの原因は、IDEのビルドパス設定ですが、面倒なので「chapter-09/」を追加して実行しました。

まとめると、「resources/XXX/XXX/XX.XXX」のように書いている部分を「chapter-09/resources/XXX/XXX/XX.XXX」のように修正すればよいということです。エラーのある部分から、パス(ファイル)を指定しているコードを見つけるのが面倒ですが。。。

OBJLoaderを使用する(Runtimeエラーがあり使用不能でした。。。)

理論部分では、ちゃんとしたものですが、細かい部分Objファイルのmtlファイルの参照部分が読み込めないなど、致命的なミスがありました。。。

こちらのページにOBJLoaderクラスがありました。これを使用することを考えていこうと思います。
OBJファイルのロード方法、考え方に関しては上記の方法がわかりやすいとドキュメントにはありましたが、こちらのOBJLoaderには、クラスにまとまった形で実装されているようです。

OBJファイルのロード処理は次のような説明が参考になりました。

.obj ファイルでは、各行は要素のタイプを識別するトークンで始まります。

コメントは # で始まる行です。

  • トークン「v」は、座標 (x、y、z、w) を持つ幾何学的頂点を定義します。例: v 0.155 0.211 0.32 1.0。
  • トークン「vn」は、座標 (x、y、z) を持つ頂点法線を定義します。例: vn 0.71 0.21 0.82。これについては後で詳しく説明します。
  • トークン「vt」は、テクスチャ座標を定義します。例: vt 0.500 1.
  • トークン「f」は顔を定義します。これらの行に含まれる情報を使用して、インデックス配列を作成します。面が三角形としてエクスポートされる場合のみを扱います。いくつかのバリアントを持つことができます:
  • 頂点位置 (f v1 v2 v3) のみを定義できます。例: f 6 3 1. この場合、この三角形は、位置 6、3、および 1 を占める幾何学的頂点によって定義されます (頂点インデックスは常に 1 から始まります)。
  • 頂点位置、テクスチャ座標、法線 (f v1/t1/n1 v2/t2/n2 V3/t3/n3) を定義できます。例: f 6/4/1 3/5/3 7/6/5. 最初のブロックは「6/4/1」で、座標、テクスチャ座標、法線頂点を定義します。ここに表示されているのは位置です。つまり、6 番目のジオメトリ頂点、4 番目のテクスチャ座標、1 番目の頂点法線を選択します。

Gitのソースを眺める

上記のリンクOBJLoaderには次のクラスが定義されています。

軽く舐め回す程度にコードを眺めてみると次のような形で実装されていることがわかりました。

Obj.java:Objファイルを読み込み
Objフィルの中身を読んで、vertex(点),
OBJLoader.java:モデルのロード

これを理解するために参考にしたサイトを以下に照会します。参考になりました。

  1. (x, y, z, w)の意味が分からなかった。:「Unityのサイト:同次座標系:Wの正体」が参考になりました。
  2. 同時座標系の細かい部分

でわでわ。。。

関連ページのメニュー

LWJGLの学習履歴
Git bookの内容を学習しました。



投稿者:

takunoji

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

コメントを残す