Lightwaveから書き出したColladaのスケール

まいど。
ニッチな情報を情報社会の狭間目掛けて垂れ流すよ(というか自分メモ)

Lightwaveから例の方法によってColladaファイルを出力すると、なんだか小さ過ぎますよね。試しにLightwave上で1メートル角のキューブを作って置いてみるとこんな具合。

Lightwaveで1メートル角のオブジェクトをPV3Dで表示すると(1) – wonderfl build flash online

はいはい。何も見えないね。でも画面の中央に点があるよ!
つまり、Pv3Dの1 = Lightwaveの1メートルらしい。ちっさ!

毎度スケールかけるのが面倒なので、なんか設定を探してみたら、このへんに「unit」タグが単位についてなんやらしてる記述が。但し変えても効果なし。
オブジェクトのサイズをColladaファイル自身でスケールさせるなら、Colladaファイルをテキストエディタで開けて、「library_visual_scenes」の中の「scale」を変えるといいらしい。

Lightwaveで1メートル角のオブジェクトをPV3Dで表示すると(2) – wonderfl build flash online

おっきくなった!
オブジェクトが入れ子になってて、本体じゃなくラッパーの方がスケールされてるっぽいですね。
なんか気色悪いけど、まあいいか。

あけましておめでとうございます

年もとっくにあけてもう4日ですが、あけましておめでとうございます。
寝ぼけ眼のヤマダです。
そろそろ一部の皆様のお手元にお年賀が届く頃かと思い、とりあえずのご挨拶。
あなたのデスクトップでタイガーI後期型のラジコンを走らせて遊んでください。届いてないよ!っていう人はココからDLして印刷するとイイネ!
※概ね「どこが寅年かワカラン」と不評です

バカが戦車でやってくる

増殖

秋葉原のまんだらけに増殖中。

お値段ひゃく ごまん えん!!

アキバの民は特に興味が無い様子。
当局が写真を撮ってたら、通行中のアキバBOYSが

「ねえねえあれ何の人形?」

「なんだっけ、イエローマジックなんとか?」

…マジカイヤ。

ホンモノだってさ!

福田興業先生、情報ありがとうございます!

LightwaveからColladaファイルを書き出すよ

おまっとさんでございます。
こんなニッチなエントリーに興味を持ってくれる方人が居るようなので、書き出し方法を説明するよ!

大雑把に説明すると、Lightwave → DirectX形式 → Unwrap3D → Collada形式 という手順で行います。



Lightwave3Dの9.6にはColladaExportが追加されていて、これで書き出せる!と思っていたら無理でした。

正確に言うと、アニメーションしないデータならUVテクスチャ付きで書き出せます。というか、Lightwave上のアニメーションの有無に関係なく、アニメに関するデータが書き出されていません。用途にもよりますが、アニメなしのデータを構造体にすれば、まあロボットみたいなものなら表示できるんでしょうが、キャラクターなどのボーンが入った入ったモデルならば、そもそもの頂点データがどう変化したかを書き出せないと意味がありません。

というわけで、車のボディとか家とかを書き出せばいいやって人は、Lightwaveの9.6を使うとイイネ!


その1.準備しよう

作成に使ったのはLightwave3Dの7.5です。DirectXのエクスポーターさえ動けば、ほかのバージョンでもなんとかなるでしょう。

それ以外に必要なものは以下のような感じ。

  • Lightwave形式でアニメーションしてるデータ
  • Lightwave3DのDirectX Exporter
  • Ultimate Unwrap 3D
    (UV編集とかするソフト。いろんなデータを読み書きできて5000円くらい。SE版でイイヨ)

一番最後の「Unwrap3D」はキーの発行に1~2日くらいかかるので、すごく急いでいる人はご注意を。

※コレにたどり着くまで、結構いろいろなコンバーターを試してみましたけど、概ねぜんぜんダメだったので、これから他のソフトで人柱になろうという人はご連絡ください。試したことがあるやつかもしれません。


その2.モデルデータを整理しよう

まずはモデルの準備から。

なんでもいいので、ボーンが埋まってて動くデータをご準備ください。サンプルは昔作った何か。

モデル作成で注意するところは、

  • ウェイトの合計が100%を超えないように作ること
    (DirectXのデータとしてはNGぽい。ColladaならOKかも)
  • 三角ポリゴンにしておくこと(サブパッチ不可)

これくらいです。UVMapはちゃんと引き継がれるみたいです。三角ポリゴン化については、DirectXのプラグイン設定でも出来るんですが、Papervisionで使うような低ポリゴンのモデルは分割位置がモロに形に影響しますので、自分で割っておくのがよろしい。

テキトーなアニメーションを付けてレンダリングしたのはこんな感じ


その3.DirectX形式のデータを書き出そう

作ったデータをプラグインを使って書き出します。このとき、シーンデータは必ず複製しておいてください。DirectXのプラグインでIKの動作を出力したい場合、全フレームにキーフレームを作ってしまうので、オリジナルのデータをブチ壊します。危険なのでよろしくどうぞ。

書き出し設定はこんな感じ。

Exportタブ

「Export」タブはほぼチェックで。
DirectX8で、Text形式で書き出します。(生データを見てチェックする事があるかもしれません故)


このへんは適当に。


TextureタブでFlashに読める画像形式に変換しましょう。オリジナルが既にJpegとかで、そのまま使える場合にはここは不要。(絵がボケたら困る場合は、モデル作る段階でやっておくこと)


Animationタブは、カメラとライトは要らないのでチェック外します。IK使ってる場合はボーンにキーフレームを埋め込まないと動かないので、一番下をチェック。

設定できたらExportしましょう。
ポイントが飛び出したりしてうまくいかない場合は、頂点のウェイトが100%以外に設定されているポイントがないか調べてみるといいかも。


その4.Unwrap3Dで変換

ここまで出来たらあとは簡単。Unwrap3Dに読み込んでやります。

ここから、File > Save as… で Collada File(*.dae)を選んで書き出すだけ!
たぶんUV編集とかも出来るんじゃろうね。


その5.Papervisionに読み込んでみよう

あとは読むだけなんですけど、これにも地味な問題が3つほど。

1つ目は、Lightwaveでの座標系と、Collada上の座標系とで単位の概念が違っていて、モデルがものすごく小さく表示されてしまうんですね。まあCGソフト使ってると昔はよくあった話。
これはLightwave側であらかじめ大きくしておくか、Actionscriptでスケールしてやるかで解決。

2つ目は、ColladaのImageパスがうまく通らずにテクスチャが読み込めない場合。
これはテキストエディタでColladaファイルを開いてあげて、Libraly_imagesってタグの中身をゴニョゴニョやると解決。

3つ目はPapervision自体のリビジョン。デバッガで覗いてみると分かるんですが、微妙に古いのを使ってると、UVマップの値が全部0と1になってしまっていて、テクスチャ画像の左上1ピクセルしか表示されないのですね。これは知らないと結構ハマる。
Maxから書き出したオブジェクトは起こらない現象なので、たぶんオブジェクトの座標が小さすぎるのが原因じゃないかと。(主に推測)
そんな時にはできるだけ新しいのをリポジトリから取ってきて使いましょう。ちなみに私が確認したのはリビジョン876です。これより新しければ多分大丈夫。

じゃ、さっくり読み込んでみよう!

コードはこんな感じです。


package {
import flash.events.Event;

import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.parsers.DAE;
import org.papervision3d.view.BasicView;

public class Lightwave2Collada extends BasicView
{
public var dae:DAE;
public var target:DisplayObject3D;

public function Lightwave2Collada()
{
//変換したオブジェクト
dae = new DAE(true,null,true);
dae.scale = 300;
dae.load("export.dae");
scene.addChild(dae);

//カメラのターゲット
target = new DisplayObject3D();
target.y = 400;
scene.addChild(target);

camera.y = 800;
camera.target = target;

stage.addEventListener(Event.ENTER_FRAME, _enterFrameHandler)
}

private function _enterFrameHandler(e:Event):void{
dae.rotationY += 1;
startRendering();
}
}
}

うまくいきましたカナ?
「オレも出来た!」っていう人はお知らせ頂けるとうれしかったり。

当方、かれこれ15年くらいLightwave使ってるのでこんな面倒な手順踏んでますけど、普通にメインのツールがMaxの人は、ColladaMaxを使うと楽チンに書き出せるヨ!

ではでは。

Lightwave to Papervision3D

やっと出来た…アニメ付きのデータをLightwaveから出力。
ウレシー!!

Lightwave9.6に付いているCollada Exporterは、オブジェクト単体ならUVMapごと出力可能。でも、アニメのデータをちゃんと書き出せてないっぽい。テキストエディタで開いてみたら明らかにデータ少ないし。

唯一、MaxからのExportがまともに動くのは知ってたんだけど、いまさらMax覚える気にはならない+たいして使わないソフトに50万出すのは無駄なので、意地になってLightwaveからの出力方法を探しましたよ…

でも力尽きたから説明は後日。
ちゃんとしたモーションが付いたデータも後日。

タイムスタンプが1234567890になると聞いて

はじめてのWonderfl

あけましておめでとうも言わずに、いまさらWonderflデビュー。
「Wonderfl で LocalConnection」

Wonderfl で LocalConnection – wonderfl build flash online

うごいたよーん(あたりまえ)

DAEクラスの動作

冬になるとどんどん冬眠モードになるヤマダです。

Papervision3D で Collada ファイルをロードする時には DAE クラスを使うんですが、これの挙動がイマイチよく分からないので調べてみた。

//インスタンス化。
//false は初期化が終わったあとにアニメを再生するかどうかのフラグ
var dae:DAE = new DAE(false);

//Colladaファイルを読み込み開始
dae.load(asset);

この時、asset に String で URL を渡した場合は Colladaファイルのロードを行い、既にロード済みのCollada を XML として渡した場合は、直接Colladaのパースを行うっぽい。
org.papervision3d.objects.parsers.DAE クラスの 314行目あたりで、

if(asset is XML)
{
	this.COLLADA = asset as XML;
	this.parser.loadDocument(asset);
}
else if(asset is ByteArray)
{
	this.COLLADA = new XML(ByteArray(asset));
	this.parser.loadDocument(asset);
}
else if(asset is String)
{
	this.filename = String(asset);
	this.parser.read(this.filename);
}
else
{
	throw new Error("load : unknown asset type!");
}

みたいな感じで型の判別をやってる。

で、何らかのソフトを使ってColladaを書き出すと、だいたいはDAEファイルに対するテクスチャのパスがいい加減で、そのままロードできない事が多々あるんですね。
修正するのは簡単で、ColladaのXMLファイルを開くと、「library_images」 っていうノードがあるので、手書きで直す場合にはココを相対パスに書き換えてやればいい。

で、ですよ。
これをAIRとかのアプリでリクエスタを立ち上げて画像を選択し、一箇所のフォルダにコピーする的なプログラムを書こうと思ったら、このDAEクラスの変な癖に衝突。
 
 
脳内の妄想では、

Colladaを作業用フォルダにコピー

XMLとしてロード
 ↓
ノードを解析して画像のリストを取得
 ↓
画像のノード毎にテクスチャのファイルを選択して作業フォルダにコピー
 ↓
XMLのノードを動く内容に上書き
 ↓
DAE.load(asset) で上書き済みのXMLを渡して表示
 
 
みたいな事を考えてた訳です。
しかーし…
DAEクラスさん、どうも直接XMLを渡した時にはパスの解決をやってくれないらしいんです。

しかも、

public var baseUrl:String;
public var texturePath:String;

とか、解決用にあるっぽいパラメタを buildFileInfo() っていう関数が上書きしとるやん。filename = “./meshes/rawdata_dae” って何だよ。
再生するSWFから相対的に見た meshes フォルダに入れとけよっていう事なんだろうけどもだ。作業フォルダから読みたいちゅう話やで。

これが原因で、内部的に buildImagePath() 関数で baseURLに対して勝手なパスを生成してしまうので、画像のロード先がどうやっても制御できなくなってしまうと。
 
 
要するにこういうこと。

  • URLを指定した場合(うまくいくケース)
    DAE をロード → URLに対してテクスチャの絶対パスを生成してテクスチャをロード
  • XMLを指定した場合(なんだかコケるケース)
    勝手に “./meshes/rawdata_dae” を基準にしたパスを生成

 
 
仕方が無いので、DAEクラス を extend して、”./meshes/rawdata_dae” の部分を変数として扱えるようにしてみました。

//ここをインスタンスの外からコントロールできるようにした
public var fileNameDefault:String = "./meshes/rawdata_dae";

/**
*
* @param	asset
* @return
*/

override protected function buildFileInfo( asset:* ):void
{
	this.filename = asset is String ? String(asset) : fileNameDefault;

	// make sure we've got forward slashes!
	this.filename = this.filename.split("\").join("/");

	if( this.filename.indexOf("/") != -1 )
	{
		// dae is located in a sub-directory of the swf.
		var parts:Array = this.filename.split("/");
		this.fileTitle = String( parts.pop() );
		this.baseUrl = parts.join("/");
	}
	else
	{
		// dae is located in root directory of swf.
		this.fileTitle = this.filename;
		this.baseUrl = "";
	}
}

PV3D以外のライブラリではどんな感じなんだろ?
時間ができたら試してみよう。

CS4の新機能を見ていたら

Photoshop CS4 Extended で 3Dモデルを読み込んで、直接ペイントできるとか書いてあるし…

「Photoshop CS4 Extendedは一般的な3Dフォーマットを幅広くサポートしているので、OBJ、U3D、KMZ、Colladaの各形式の読み込みと書き出し、および3DS形式の読み込みが行えます。」

ということは、Papervision用のデータをここで修正して吐き出す、なんてことが普通に出来る訳ですかね?書き出し対応してるところを見ると大丈夫なんだろうけど。アニメ付きのデータはどうなるんだ?

なんだか3Dレンダリングエンジンが入ってるし、予想外だわこれ。またAdobe税だわこれ。レンダラは分離するのが定石なのに、いまさら感もあると言えばあるのだけれど…OpenGLで表示系を書き直した都合でいろいろ出来ちゃった、みたいな流れなのかもしれませんな。

でも、Photoshpに入れずに単独のアプリにしたほうが軽くて良かったのではと。バージョン上がる度にどんどんヘヴィになると、実務に皺が寄ってしまうのですよね。
単純なお絵かきなら「Sai」の方が軽くて使いやすいもんなあ…

テクスチャの更新

テクスチャを外出しする話の続き。
オブジェクトの外に置いたテクスチャに線を描いて、リアルタイムに反映するサンプルを作ってみた。
(右の黄色い四角に描く)

サンプル