忍者ブログ

軽Lab

 Javaを中心とした、プログラミング関係のナレッジベース

Home > Java 応用・実験 > Colladaファイルビュアーを作成する(5)

Colladaファイルビュアーを作成する(5)

今回はColladaファイルからメッシュ情報を抽出しJavaFX上で表示する方法について確認する。完成形は以下の画像のとおり。プログラムを全て見ていくと時間がかかるため、実装方針とサンプルプログラムについて確認する。なお、今回で連載『Colladaファイルビュアーを作成する』は一応の完了とする。将来的には、気が向いた時にでもモーションの取り込みも見ていきたい。




■ 課題整理

 前回までの記事でColladaファイル内のタグ情報を、Java Beansインスタンスとして取り込む方法を見てきた。しかし、Java Beansインスタンス内を見ると、各ノードの階層情報は表現できているが、基本的にはテキスト情報の集まりでしかない。例えばJava Beans内に画像URLの文字列は持っているが、JavaFX上で表示するための画像インスタンス(ImageViewクラス)の生成はできていない。現状態からJavaFX上で表示するための課題は以下のとおりである。

  1. JavaFXで表示するためのインスタンスを作成する必要がある
  2. 参照URLからインスタンスを参照するための機構が必要

 1に関してはJava Beansのノード階層をたどりJavaFXで表示するためのインスタンスを1つずつ作成すればよい。ただし、Colladaファイルにおいて『インスタンス化』が行われるまではウィンドウ表示してはないけない。このことは第3回の記事で見てきたとおりである。

 1の作業中、『宣言』を解析する間はプログラム内部に表示用インスタンスを貯蔵しておく。このときID情報を関連付けておけば、『インスタンス化』タグ内で参照URLをたどり、必要なインスタンスを後で取得できる。この作業が課題2である。実装方針としては、参照URL(文字列)から表示用インスタンスを取得するためのMap<String,Node>インスタンスを作成し、逐次登録と取得を行えるようにすればよい。ただし、valueをシーングラフに登録するNodeクラスそのものとしてしまうと独自の情報を付与できなくなるため、独自にDaeObjectという基底クラスを作成する。DaeObjectクラスを基底クラスとして、Colladaファイル内の各タグに対応する表示用クラスを作成しIDマップに登録していく。

■ 全体設計

 まずは全体設計。以下にクラス図を示す。



 ウィンドウ表示を行うTest3DModelImport2クラスを作成し、main関数はこのクラス内に記述する。ウィンドウにはカメラのxyz座標とxyz回転を指定できるようにスライダを配置。さらにカメラ位置をリセットするボタン、メッシュの面/線表示を切り替えるボタン、ジョイントの表示/非表示を切り替えるボタンを配置する。

 3Dモデルの情報はColladaDataクラスにまとめる。Colladaファイルから情報を読み込むには、静的クラスDae141FileLoaderのload関数を利用し、ファイル名を引数に渡すと戻り値にColladaDataインスタンスが取得できるように実装する。load関数内部では『宣言』タグを解析し、IDマップ(DaeIDMapクラス)に表示用のインスタンスを登録していく。『インスタンス化』タグが呼ばれた場合にはIDマップから表示するメッシュ情報を取得し、ColladfaDataクラスに登録していく。

■ 詳細設計

 次にColladaDataクラス内部を設計する。Colladaファイル内には以下の構造でデータが格納されている(詳細は公式ドキュメントを参照のこと)ため、これに対応するように表示用クラスを設計した。詳細は以下のとおり。

タグ 内容
LibraryGeometries 3Dモデルのメッシュ情報を保持。テクスチャ情報はmaterialへの参照として保持
LibraryImages テクスチャ画像情報(URLなど)を保持
LibraryEffects 3Dモデルの性質(テクスチャ画像や色、反射光の設定)。テクスチャ情報はimageへの参照として保持
LibraryMaterials 3Dモデルの表面(マテリアル)情報を保持。表面の性質情報はeffectへの参照として保持
LibraryControllers 3Dモデルのパーツのインスタンス化情報を保持。メッシュ情報はgeometryへの参照として、テクスチャ情報はmaterialへの参照として保持
LibraryVisualScenes 風景情報(VisualScene)を保持する。作成する風景の情報はcontrollerへの参照として保持。解析用ColladaファイルではVisualSceneが1つのみ
Scene インスタンス化するVisualSceneを指定。インスタンス化のスタート・ポイント



 IDマップに登録しやすいようにDaeObjectという基底クラスを作成する。DaeObjectクラスには全てのタグに共通する要素であるID(文字列)を保持させる。表示用クラスでは最終的にシーングラフに登録するGroupクラスとMeshViewクラスの階層構造を保持・作成する。イメージとしては以下のとおり

 親ノード ( Groupクラス )
 ┣ メッシュ1( MeshView )
 ┣ ・・・
 ┣ メッシュn  ( MeshView )
 ┣ 子ノード1( Groupクラス )
 ┃ ┗・・・
 ┃ ・・・
 ┗ 子ノードn( Groupクラス )

 ただし、ジョイントとメッシュを関連付けるため、ColladaData内部では以下の階層構造で3Dモデルデータを保持する。シーングラフに登録するデータはDaeVisualScene::getMeshNode関数で取得するようにする。ColladaDataクラスには、このDaeVisualSceneを取得するための関数ColladaData.getScene関数を追加する。

 ColladaData
 ┗ DaeVisualScene( 風景を表すクラス )
   ┗ DaeNode( 3Dモデルのパーツを表すクラス。シーングラフのGroupクラスを保持 )
     ┗ DaeGeometry( 3Dモデルのメッシュを表すクラス。シーングラフのMeshViewクラスを保持  )

 DaeNodeクラスでは3Dモデルの位置を表す座標変換や、パーツの階層構造を表すため子パーツへの参照を保持する。DaeJointクラスはDaeNodeクラスを継承しただけのクラスで、DaeNodeクラスが関節を表す場合に利用する。DaeImage,DaeMaterial,DaeEffect,DaeControllerクラスは最終的にDaeGeometryクラスにテクスチャなどの情報を与えるためのクラスであり、解析中に使用するためのテンポラリ・クラスとする。


■ サンプルプログラム

 以下に解析用Colladaファイルを取り込むサンプルプログラムを示す。サンプルでは解析用Colladaファイル内のメッシュ、テクスチャ、ジョイント情報を取得し、JavaFX上で表示している。なお、『とりあえず取り込む』的なプログラムであるため、すべてのColladaファイルを正常に取り込めるかは保障しないのであしからず。

◇サンプルコード
 Test3DModelImport2.7z(236KB)

◇フォルダ構成

 TestJavaFX
 ┣ src
 ┃ ┣ application_fx_functional
 ┃ ┃ ┗ Test3DModelImport2
 ┃ ┣ collada
 ┃ ┃ ┣ ColladaData.java
 ┃ ┃ ┣ Dae141FileLoader.java
 ┃ ┃ ┣ DaeIDMap.java
 ┃ ┃ ┣ DaeObject.java
 ┃ ┃ ┣ DaeVisualScene.java
 ┃ ┃ ┣ DaeController.java
 ┃ ┃ ┣ DaeGeometry.java
 ┃ ┃ ┣ DaeNode.java
 ┃ ┃ ┣ DaeNodeJoint.java
 ┃ ┃ ┣ DaeImage.java
 ┃ ┃ ┣ DaeMaterial.java
 ┃ ┃ ┗ DaeEffect.java
 ┃ ┗ org.collada._2005._11.colladaschema(JAXBで作成したクラス)
 ┗ 3dmodel
   ┗ Luka
     ┗ 1-texture
       ┣ luka.png
       ┗ luka1_0_1.dae

◇実行結果


◇注意点
  1. とりあえず表示するという目標であるため、いろいろな情報取込をスキップしている。ご了承を。
  2. JavaFXでは頂点に色が設定できないため、サンプルコードでは色情報を取り込んでいない
  3. JavaFXではマルチテクスチャに対応していないため、解析用Colladaファイルではエクスポート時にシングルテクスチャになるように設定している
  4. morphタグを処理するタイミングが不明なため、サンプルでは取り込んでいない。
Home > Java 応用・実験 > Colladaファイルビュアーを作成する(5)

- ランダム記事 -
- PR -

コメント

プロフィール

管理者:
 連絡はContactよりお願いします。

PR