トップへ戻るニュースフォーラムFLASH-ML 過去ログBak@Flaダウンロードよくある質問と答
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
メイン
   コーダーズルーム【スクリプト系】
     Alternativa3dで、3Dデータをロードする際のメソッドの役割について
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
piggy
Åê¹ÆNo.46933
投稿日時: 2011-1-28 17:25
新米
居住地:
投稿: 18
使用環境:
●OS:Win XP
●ソフト:
 flash CS5,
 Director 11.5,
 illustrator CS3
Alternativa3dで、3Dデータをロードする際のメソッドの役割について
こんにちは。

Flashの3Dエンジン「Alternativa3d_7.6」の検証をしております。

「Alternativa3DExamples\src\parsersexample」内にある
「ParsersExample.as」の解読を進めているのですが、
不明な点があって投稿させていただきました。

以下にスクリプトを抜粋します。
(import処理やonEnterFrame処理の箇所は割愛します)

引用:

var loader3ds:URLLoader = new URLLoader();
loader3ds.dataFormat = URLLoaderDataFormat.BINARY;
loader3ds.load(new URLRequest("parsersexample/model.3DS"));
loader3ds.addEventListener(Event.COMPLETE, on3dsLoad);

var loaderCollada:URLLoader = new URLLoader();
loaderCollada.dataFormat = URLLoaderDataFormat.TEXT;
loaderCollada.load(new URLRequest("parsersexample/model.DAE"));
loaderCollada.addEventListener(Event.COMPLETE, onColladaLoad);

private function on3dsLoad(e:Event):void {
 // Model parsing
 var parser:Parser3DS = new Parser3DS();
 parser.parse((e.target as URLLoader).data, "parsersexample/");
 trace(parser.objects);
 ★↓不明点1
 var mesh:Mesh = parser.getObjectByName("Cylinder01") as Mesh;
 mesh.x -= 100;
 rootContainer.addChild(mesh);
 
 ★↓不明点2
 // Loading of textures
 var materialLoader:MaterialLoader = new MaterialLoader();
 materialLoader.load(parser.textureMaterials);
}

private function onColladaLoad(e:Event):void {
 // Model parsing
 var parser:ParserCollada = new ParserCollada();
 parser.parse(XML((e.target as URLLoader).data), "parsersexample/");
 trace(parser.objects);
 var mesh:Mesh = parser.getObjectByName("Cylinder01") as Mesh;
 mesh.x = 100;

 ★↓不明点3
 mesh.weldVertices();
 mesh.weldFaces();

 rootContainer.addChild(mesh);

 // Loading of textures
 var materialLoader:MaterialLoader = new MaterialLoader();
 materialLoader.load(parser.textureMaterials);

}



上記のように不明な箇所が3つあります。

■不明点1:
var mesh:Mesh = parser.getObjectByName("Cylinder01") as Mesh;

この部分の処理は、「3dsファイル内の"Cylinder01"モデルのメッシュ情報(=ポリゴン情報)を変数meshに格納する」
でよろしいでしょうか?

その場合、"Cylinder01"という名称を取得するには、3dsファイルをモデリングソフトなどで開いてモデル名を調べるしかないのでしょうか?

■不明点2:
var materialLoader:MaterialLoader = new MaterialLoader();

「Alternativa3d」では、モデルデータとテクスチャデータは分けなければならないのでしょうか?
(サンプルでは、モデルデータと同階層にtexture.jpgが置いてあります)
モデルデータ上で設定したテクスチャ情報は反映されない、
ということでしょうか…?

■不明点3:
mesh.weldVertices();
mesh.weldFaces();

この処理が何をしているのかわかりません。
この処理を無くしてもモデルが生成されました。
Colladaファイル特有の処理なのでしょうか?
(英文のマニュアルを見て頂点情報もしくはUVマップに関係したものだろうか?と思っているのですが…)

AS3に関する理解が足りず、勘違いなどしているかとは
思いますが、
もしよろしければご教示いただけると助かります。

よろしくお願いいたします。

ゲスト
Åê¹ÆNo.46934
投稿日時: 2011-1-28 23:51
Re: Alternativa3dで、3Dデータをロードする際のメソッドの役割について
こんにちは、ClockMaker の Yasu です。

こちらのお返事ですが、@narutohyper さんから回答を頂いたので代理で投稿させていただきますね。

==========================

引用:
■不明点1:
var mesh:Mesh = parser.getObjectByName("Cylinder01") as Mesh;
この部分の処理は、「3dsファイル内の"Cylinder01"モデルのメッシュ情報(=ポリゴン情報)を変数meshに格納する」でよろしいでしょうか?


正しいです。

parse されたモデルはただの Object3DContainer 型で、中に「様々な形式の Object3D を継承したモデル」が入っています。もちろん、この場合 parser 自体をそのまま使用する事ができますが、いろんな処理を行う上でこの中の「様々なモデル」を扱う上でコード内で把握する必要が出てきます。

その為、ここでは parse されたモデルを取り出し、変数 mesh にキャストして、格納しています。ちなみに「様々なモデル」と書きましたが、モデルの構造によって大きく次の 3 つの型で登録されています。

1. Mesh
単純なポリゴンによるモデル

2. Skin
内部に Bone (Joint) を持ったモデル

3. Object3D
その他のオブジェクト
3DSMax(.3DS) や Blender (.DAE) など 3D ツールでシーンを保存した場合など、カメラやライト等が含まれる場合があります。それらのオブジェクトは Object3D 型で入っています。なお、現行のバージョンである Alternativa3D 7.6 ではそれらを取り扱う事はできません。

引用:
その場合、"Cylinder01" という名称を取得するには、3ds ファイルをモデリングソフトなどで開いてモデル名を調べるしかないのでしょうか?


モデル名を把握している場合は、この方法が一番早いですが、それが判らない場合等は、以下の様な方法でコード上で調べる事ができます。

//----------------------------------------------------
//objectの抜き出し
//----------------------------------------------------
var objects:* = parser.objects;
//var objects:Object3DContainer = parser.objects as Object3DContainer;
var count:int = objects.length;
var i:int;

for (i = 0;  i < count; i++) {
	//モデル名お調べるだかなら以下だけでOK
	trace(objects[i].name)

	if (objects[i].constructor == Skin) {
		//アーマチュアー(Bone)を関連付けされたMeshはSkinとして書き出される
		var skin:Skin = objects[i] as Skin;
		//必ず、calculateBindingMatrices(BoneとSkin位置関係Matrixを再計算して割り当てる)を実行。
		//しないと、3Dモデルがつぶれます。(時に、ぐちゃぐちゃになる)
		skin.calculateBindingMatrices()

		rootContainer.addChild(skin);
	} else if (objects[i].constructor == Mesh) {
		//Boneが関連付けされていないMeshはMeshとして書き出される
		var mesh:Mesh = objects[i] as Mesh;
		rootContainer.addChild(mesh);

	} else	{
		//カメラや、ライトは、Object3Dとして書き出される。
		//現Verでは取り扱えないので無視
	}
}


==========================

引用:
■不明点2:
var materialLoader:MaterialLoader = new MaterialLoader();

「Alternativa3d」では、モデルデータとテクスチャデータは分けなければならないのでしょうか?
(サンプルでは、モデルデータと同階層にtexture.jpgが置いてあります)
モデルデータ上で設定したテクスチャ情報は反映されない、
ということでしょうか…?


モデルデータは、モデルを保存した時のテクスチャーのパスを絶対パスで保持しております。parse 済みモデルでは、それらの情報を元に内部で必要な分だけ TextureMaterial を作成して保持しており、各 Face への UV マッピングも自動で行われております。

ただし、Alternativa3D では、勝手に Texture に使用している画像を Load してくれたりはしませんw
自分で、画像を読み込む必要があります。

この MaterialLoader は、この画像の読み込み処理をまとめて行ってくれるクラスです。materialLoader.load の引数は、Vector.<TextureMaterial> となっており、複数の TextureMaterial を同時に渡す事ができます。なお、画像のパスは、TextureMaterial.diffuseMapURL (String)で指定する事もできます。

…が、読み込んだモデルからは parser.textureMaterials プロパティで Vector.<TextureMaterial> を取得できるのでこの値で一気に Load させます。


var materialLoader:MaterialLoader = new MaterialLoader();
materialLoader.load(parser.textureMaterials);



1つ注意点としては、上に書いた「モデルは絶対パス(Local 環境・・・つまり PC のパス)で画像の位置を保持している」というところでネット上にアップした場合等は、そのままでは上手く読めなくなります。その為内部でパスを相対にする必要があるのですが、parse 時に指定している第2引数の String がその為の情報となり、この引数で指定している位置からの相対で画像を読み込むようになります。

※以下はモデルと同じ位置にテクスチャを置いてモデルに設定した場合で、モデルが parsersexample/model.3DS の場合
parser.parse((e.target as URLLoader).data, "parsersexample/");


==========================

引用:
■不明点3:
mesh.weldVertices();
mesh.weldFaces();

この処理が何をしているのかわかりません。
この処理を無くしてもモデルが生成されました。
Colladaファイル特有の処理なのでしょうか?
(英文のマニュアルを見て頂点情報もしくはUVマップに関係したものだろうか?と思っているのですが…


3D ツールでモデルを作成した場合、意外と無駄な面や無駄な点が混在する場合が多いです。
(ツール上で同じ1つの頂点のつもりでも、実は 0.0001px ずれてて違う点になってるとか、まったく同じ、Texture、UV、頂点でも2枚 Face が重なっている等・・・)

こういった無駄な点や無駄な面を放置しておくと著しくパフォーマンスに影響がでてきます。weldVertices()とweldFraces()の 2 つの命令は、そのような無駄な点や面を丸め込む(同じ物なら1つにまとめる、多少の誤差も引数のしきい値内ならまとめる)為のメソッドとなっています。

非常にきれいなモデルの場合は変化ありませんが、適当モデルの場合は頂点数等が適用前と後で変化するはずです。
piggy
Åê¹ÆNo.46940
投稿日時: 2011-1-31 10:57
新米
居住地:
投稿: 18
使用環境:
●OS:Win XP
●ソフト:
 flash CS5,
 Director 11.5,
 illustrator CS3
Re: Alternativa3dで、3Dデータをロードする際のメソッドの役割について
ClockMakerのYasu 様

大変丁寧にご教示していただき、本当にありがとうございます。
お手数をおかけして申し訳ありません。

また、@narutohyper様にも合わせてお礼を述べさせていただきます。
本当にありがとうございます。

引用:

1. Mesh
単純なポリゴンによるモデル

2. Skin
内部に Bone (Joint) を持ったモデル

3. Object3D
その他のオブジェクト


正直なところ、このような基本の情報を得るために何を調べればいいのかも分かりませんでした…
まさに目から鱗でした。
モデルの分類はこのようになっているのですね。
「Parser」クラスから内部オブジェクトを調べるというやり方も、なるほど、と思いました。


引用:

ただし、Alternativa3D では、勝手に Texture に使用している画像を Load してくれたりはしませんw
自分で、画像を読み込む必要があります。


理解しました。
他の3Dアプリケーションでモデルデータを丸ごとロードすることに慣れていましたので、疑問に感じてしまいました。
必ず必要な処理、ということで覚えておきます。


引用:

ツール上で同じ1つの頂点のつもりでも、実は 0.0001px ずれてて違う点になってるとか、まったく同じ、Texture、UV、頂点でも2枚 Face が重なっている等・・・)

こういった無駄な点や無駄な面を放置しておくと著しくパフォーマンスに影響がでてきます。


理解しました。
過去に3Dデータを変換しようとしたときに、このようなモデルの頂点情報の誤差があってうまくいかないケースがあったように思います。
ということは、Colladaに限らず、3dsでも行っておいた方がより確実なのかもしれませんね。
検証してみます。


ClockMakerのYasu 様、
@narutohyper様、

丁寧に教えていただき、ありがとうございました。
とても助かりました。
引き続き検証を進めてみようと思います。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 
Copyright (C) 2003 FLASH-japan. All rights reserved.
Powered by Xoops