スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

モーション関係(fbx->独自形式での懊悩)

今はキャラクターのモデルとアニメーションにfbxをassimpに食わせて独自形式にしてしまってるわけだけど、blenderのfbx出力とか変換について。
まずあれなのかな、よくわからないけどfbxってキーフレームを補間したりするカーブの定義ってないためか、フレーム単位ずつすべてポーズが焼きこまれていてデータ量がすさまじく多い。(たぶんそうするのがfbxの作法なのかなあ?、或いはゲーム利用でこのほうが楽?まあソフト間でデータ移動するための中間フォーマットだからかね・・)、

たとえばXNAのサンプルなんかではコンテンツパイプラインで処理したデータから実行時にはキーフレーム補間をせずに毎フレームにその時間の変形行列を読み出すだけ。(だと思う。あとデータ自体ののFPS補間はコンテンツパイプラインがしてるような感じがする。blender初期設定では24FPSとして書き出されてるので。ちょっと曖昧なのでわからない)

確かにメモリは食うけど補間しないので処理は速い。メモリと処理のせめぎ合いがシビアな環境だと、とくにXNAのターゲットにする箱○ではこれがまず現実的なものなのだろうか。

実際現在つくってるものではモーション数が結構多くなってきていて、前述の毎フレームに変形行列を持っておくにはメモリも厳しい(読み込み時に圧縮ファイル介すと使うとOoMする、トータルでかなり大きな容量になってしまう等)ので、「うーん・・・」とか思いながらファイル変換時にキーフレームを一定間隔で削除してデータを削減して、空いたところを補間してた。

そして、その方法は問題があった。まずなんか「それでいいのか感」が漂うこと。そしてblenderで作っているモーションのピークが消される可能性が高いということ。なので、想定していたモーションとはちょっとだけヌルめのモーションが再生される感じ。ヌルめのモーションって意味がわからないけど。キーフレームを打ったピークに到達しないってことね。

なのでいろいろ調べたけど、使えないかなあと思っていたこのfbxエクスポータの謎のオプション。
スクリーンショット 2014-06-22 03.50.59
まあこれはモーションデータの中で、フレーム間の値変化量を見てその差が大きければそのキーは出力するとかしないとかの設定なわけだが、このオプションでキーフレーム自体は削減できる。しかし実態にタイムラインに打ったキーフレームはまったく無視。なのでここにこだわるのは即終了。

そういうわけでfbxエクスポータのpythonスクリプトを眺めながら、キーが打たれたフレームだけ出力するにはどう変更したらいいかなーと考えたけど、そもそも方式というかなんというか無理。pythonわかんないし。

fbxは複雑で見たくもないしバージョンごとにフォーマット違うしではっきりいって絶対に直接かかわりたくない。なにか手を加えて全体のデータ整合性がなくなって読み込めなくなり、どこを修正したらいいのかさっぱり・・っていう状態に陥るのは目に見えている・・。

なので別のアプローチ、キーを打ったフレームの位置だけをさらに別のファイルとして書き出し、コンバート時にそれを参照する。最終的なファイルにはそのフレームだけ保存するということにした。

なんだけどblender上、アクションのなかで打たれているキーの位置の一覧を取得するのに苦労した。
とりあえずちゃんと出力データ量は減り、必要なキーフレームのみのアニメーションデータを出力することはできた。
まあ継続メンテナンスしながらやらないと・・・。テストデータ(ゲーム用の1シーン)では問題なく動かせたけど、他のシーンで問題でたら泣く。
せっかくなのでシーンの各アクションで打たれたキーフレームの一覧を取得するpython。
#--------------------------------------------------------------------------------
print(str(len(bpy.data.actions))+"\n")
for action in bpy.data.actions:
print(action.name+"\n")
hash = {}
for fcurve in action.fcurves:
if fcurve.data_path.startswith("pose.bones"):
for point in fcurve.keyframe_points:
hash[point.co.x]="true";
else:
continue
if(len(hash)>1):
print(str(len(hash))+"\n)"
for k,v in hash.items():
frame = str(k)+"\n"
print("%s" % frame)
#--------------------------------------------------------------------------------
インデント死んでる・・・

ちなみになんかいろいろ書いたけど独自解釈が多く含まれてるので間違ってたらごめん。
スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

zerobyteorbit

Author:zerobyteorbit
deathpiyoがgameをdevelopしたり、musicをcomposeしたり迷走したりする。

現在は迷走中。

under the lotusはリビルドのために考え中。

deathpiyo twitter

UnderTheLotus test3h(download)
I'm thinking about rebuilding UTL.


同人音楽アルバム
[Lovers Immortality]
-Japanease-
Lovers Immortality -works until worldend- DLsite.com直リンク
Melonbooks DL
-English-
Lovers Immortality -works until world end- Link to DLsite.com

18+
【東の森の魔女2 VS 魔王 -終宴する世界と肛虐(逆)の魔女たち-】
東の森の魔女2 VS 魔王 -終宴する世界と肛虐(逆)の魔女たち- DLsite.com直リンク
DMM.同人

紹介ページ


【地下迷宮の機械姦自壊オナニー生活。】
地下迷宮の機械姦自壊オナニー生活。 DLsite.com直リンク
DMM同人

紹介ページ




DLSite
Link to DLsite.com

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
FC2カウンター
検索フォーム
RSSリンクの表示
リンク
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。