2008年10月30日木曜日

blender - セルフシャドウ

普段Blenderで作業するときは、標準でONになってる機能を片っ端からOFFにして作業しています。

・・・が、ちょっとセルフシャドウやってみたくなって、スポットライト付けてBufShadowをONにして、マテリアルのShadow関連をONにして、プレビュー。




↑とりあえず髪だけ完成したところ。顔も素体も3ヶ月ぶりくらいにいじり中です。


セルフシャドウいいっすなー。Viewerのほうにも是非付けたいなぁ。



セルフシャドウ無しだとこうなる。

2008年10月27日月曜日

blender - 髪モデリング

松井めし画術HP
http://mattaku.sa-ra-sa.com/

の方が、以前やっていた方法をBlenderでやってみました。

まず、このような髪になる形状を作ります。前髪用と後ろ髪用を作りました。


それから、ボーンを仕込みます。ObjectのparentをArmatureにした後、髪の一番したのボーンに、IKを適用し、その下にIKのtarget用ボーンを仕込みます。IKはUseTailして、chainLenは、targetを除いたボーン数-1、またtargetのConを外し、親ボーンを一番上のボーンにします。これで、くねくね曲がるフサが出来上がり。


Objectモードで、そのフサのObjectと、Armatureを選択肢、Ctrl-Dでコピーしながら、髪を作っていきます。


ここで気付いたんですが、頭のてっぺんを慎重に定めて、このようにすると作りやすいです。


それから、髪を一通り満足いくまで作ると、こうなりました。


これで、ボーン入りの髪が出来上がりです。

Blenderでレンダリングするだけなら、ここまでで問題ないですが、リアルタイム用には、このボーンやポリゴン数は邪魔です。というわけで、ここからは、ポリ数削る人用。

ObjectモードでObjectを選択肢、このスクリプトを適用します。
ここで、Objectにsubsurfが付いてると、subsurfが適用された、ポリ数の多いメッシュが出来てしまうので注意です。
最初のフサ作る時点でsubsurf無しの状態で作るとおkです。

するとObjectのコピーが作られ、ボーンの変形がそれに適用されるので、元々いじってたArmature付きのやつを消してしまいましょう。



後は、この髪を鬼のように編集するのみです・・・。しかしここからが長い戦いになりそうなような・・・。


何かハルヒっぽくなってきたけど、ハルヒじゃないです。

blender - 同じAction一掃(3)

今期は、個人的に、アニメが非常に良いと思うので、何か1体作ろうと思っています。

が、既に、大河さん@とらドラ!3Dをpixivで発見しましたし、
なぎ3Dは既に2体確認してます。
その上、神だと思ってる方が、ざんげちゃん3D作ってました…!萌え死ぬ!
CLANNADは、ドワンゴがゲーム作っちゃってますし。

ここは、盛るしか…

-------------------------

python 同じAction一掃(2)
http://blendermoe.blogspot.com/2008/10/blender-python-action.html


さて、↑の続きです。

リアルタイム用途で使う場合(GameEngineも多分含まれる?未調査)、
IK有りで作っている場合、上記スクリプトで減量すると、IKのあるタイミングで、IKの関連するボーンにキーを打っておかないといけません。(実行時にIK計算するんだったら別ですが…)

これは、多分pythonスクリプトでは不可能に近いので、内部のソースに組み込むことにします。
といっても、これが意外にややこしくて、今日ずっとハマってました。

IKある無い/ Use Tailしてるしてない/ Targetある無い/ PoleTargetある無い/ NLAの場合の時間

くらいに気をつけて、書いてみると超遅くなりました。まぁ今回は最後に1回これ通せば良いので、遅くてもOK…。


結果


と言う感じに。

…が、PoleTargetのことすっかり忘れてて、viewerで実行したら、手足が微妙におかしい!
なんてこったい!続く。


ちなみに簡単そうに書いてるけど、落とし穴がめちゃくちゃ多いです…。疲れた。。

-----------------

気を取り直して、PoleTarget対応。
が、やはりおかしい。
っていうか、スクリプトで無駄なキーを消去した時点でおかしい。

IPOの数値で、同じのが3つ続いたら、真ん中の1つを消すという、実に単純明快な方法だから、間違えるはずないんだけど…

と思って、IPOエディタ見たら、、あれっ!?



黄色の区間、確かに足が動いているし、TransformPropertiesのLoc値も変わっているのに、IPOは全然変わってない!!!!1

これは、ひょっとして、またしてもPythonじゃあ出来ませんフラグか!?
(IPOで駄目ってことはPoseの行列取り出して比較するわけだけど、NLAなしの1Actionなら、キー打ってるところに、フレーム設定して、Pose適用すれば、行けるが、NLA有りの複数Actionなら、フレーム設定したところでBlendされるので、強制的にNLAをActionモードに変えないといけないけど、それがPythonからでは出来ない。)

2008年10月25日土曜日

blender - GreasePencil を使ってみる



1.GreasePencilでイラストをトレース(お絵描き)
2.BezierCurveに変換してみる。うーん、Bezierっていってもこれじゃあ直線と変わらないな…。
3.さらにそれをMeshに変換してみる。
4.Editモードで、Ctrl-Lでストロークを選択し、CurveをCloseした後、Shift-Fで面付ける。
5.標準で入ってるscriptのPolyReducerでポリ数削減
6.Editモードで、Alt-J(convert triangles to quads)したあと、eで押し出してみた



こうなった。
スカルプトの素くらいには使えるかも…?

2008年10月24日金曜日

etc - MMDの解析が進んでてびっくり


出た!MikuMikuDanceのPMDモデルを編集するツール「PMDエディタ」
http://vocaloid.blog120.fc2.com/blog-entry-2017.html
Ver.3になってマルチモデル対応になり、初音ミク、弱音ハク、鏡音リン・レンの3DモデルがPMDファイルで供給されるようになったが、なんとそのPMDファイルを自作するためのツール「PMDエディタ」を作っている人がいるそうで、実際に解説動画が投稿されたもよう。


MMDのモデルデータについて語るスレ
http://jbbs.livedoor.jp/bbs/read.cgi/music/23040/1219738115/


なんとかしてMMDにデータを持ってこようとしているようです。
Blenderも結構話題になってるみたい。
Blender用のPMDインポータ/エクスポータまであるのか・・・凄いな

でもそこまでするなら、全部Blenderでやったほうが…

etc - zoomeにあげてみた

またしてもテスト動画です・・・。

*)盛大に音でます!注意


最初の1分以降、適当に前作りかけてたのとか色々混ぜてみた。
途中動かないところは未実装です…

2008年10月23日木曜日

etc - コンボリューション

コンボリューションのカーネル値を時間的に変化させると面白そうだなー

と思ったので、まずはそのコンボリューションから。
重そうだから3x3で。でもHDRよりは軽いんじゃないかな?どうなんだろう。
HDRも当然要ると思っているんだけど、難しそうなので保留中…。

平滑化


鮮鋭化





というわけで、なかなか良い感じ。
ちなみに数字はリリースモードだったりデバッグモードだったりするので、気にしないでくだしあ。

あとはカーネルにキーを打ちまくるのだー。

2008年10月22日水曜日

etc - PooalSystem

PooalSystem
3Dエンジンによるポリゴンのリアルタイム表示に重点を置いた
アドベンチャーゲーム作成用スクリプトシステムです

http://toshiaki-great.hp.infoseek.co.jp/program.html

・描画エンジンにDirectXを使用し、高速なリアルタイムレンダリングを実現。
・DirectXの標準データ形式であるXファイルの読み込みをサポートし、3Dモデル表示によるアドベンチャーゲーム作成が可能。
・XMLベースの簡易スクリプトによりゲーム内容を記述するため、プログラム言語の知識やコンパイラなしにゲーム作成が可能。
・BMP,PNG,TGA等の各種画像形式の読み込みをサポートし、2D画像中心のゲームを作成することが可能。
・WAV,MID,MP3等の各種音声形式の読み込みと再生をサポート。
・デバッグ専用実行ファイルによるスクリプト実行ログの出力をサポートし、スクリプトやプログラム実行時に発生した問題を容易に解析することが可能。





こんなのあったのかぁぁぁ~!
スクリプトファイルも全部XMLで、なんか俺のやってることに似てる…!

あ、ちなみにXファイルはDirectX10でサポート対象外になりましたけどね。

blender - BlenderのPythonの機能を勝手に拡張する

5 他のアプリケーションへの Python の埋め込み
http://www.python.jp/doc/nightly/ext/embedding.html


を参考に、勝手にBlenderのPythonモジュール(っていうのか?)を追加してみました。
Blenderを独自ビルドできてる人なら、思ったより簡単に出来るかと思います。
あ、ちなみに結局SCONSは使わずに、projectfiles_vc7/blender の中のプロジェクトからビルドしてます。

手順
1.BPY_pythonの中に、自作Pythonモジュール用のヘッダとc/cppファイルを入れる
(ファイルは他のファイルがあるところと同じディレクトリに置く)
2.BPY_pythonのblender.cに、そのヘッダをincludeし、最後のほうに
  PyDict_SetItemString(dict, "BDx", BDx_Init()); //BDxは使いたいモジュール名
 を追加
3.自作Pythonモジュール用のヘッダに、
  PyObject *BDx_Init(); //BDxは(ry
 と宣言
4.他のモジュールを参考に実装。
  自分の場合こんな感じに(↓)。適当なサンプル化するのが面倒だったので本番コードです。
 (BLO_write~ってのは、呼び出したい自作C++メソッド)



#include "BLO_writeXML.h"
#include "BDx.h"

///* copy and paste from World.c *///
#include "DNA_scene_types.h" /* for G.scene */
#include "DNA_userdef_types.h"
#include "BKE_global.h"
#include "BKE_world.h"
#include "BKE_main.h"
#include "BKE_library.h"
#include "BKE_texture.h"
#include "BLI_blenlib.h"
#include "BSE_editipo.h"
#include "BIF_keyframing.h"
#include "BIF_space.h"
#include "mydevice.h"
#include "Ipo.h"
#include "MTex.h"
#include "gen_utils.h"
#include "gen_library.h"
#include "MEM_guardedalloc.h"
///////////////////////////////////

static PyObject* write_xml_mesharm(PyObject* self, PyObject* args)
{
char* target_dir;
if (PyArg_ParseTuple(args, "s", &target_dir)) {
if (BLO_write_XML(target_dir, BLO_WRITEXML_MESH | BLO_WRITEXML_ARMATURE, NULL))
return Py_BuildValue("i", 1);
}
return Py_BuildValue("i", 0);
}

static PyObject* write_xml_empty(PyObject *self, PyObject* args)
{
char* target_dir;
if (PyArg_ParseTuple(args, "s", &target_dir)) {
if (BLO_write_XML(target_dir, BLO_WRITEXML_EMPTY, NULL))
return Py_BuildValue("i", 1);
}
return Py_BuildValue("i", 0);
}

static PyObject* write_xml_camera(PyObject *self, PyObject* args)
{
char* target_dir;
if (PyArg_ParseTuple(args, "s", &target_dir)) {
if (BLO_write_XML(target_dir, BLO_WRITEXML_CAMERA, NULL))
return Py_BuildValue("i", 1);
}
return Py_BuildValue("i", 0);
}

static PyObject* write_xml_lamp(PyObject *self, PyObject* args)
{
char* target_dir;
if (PyArg_ParseTuple(args, "s", &target_dir)) {
if (BLO_write_XML(target_dir, BLO_WRITEXML_LAMP, NULL))
return Py_BuildValue("i", 1);
}
return Py_BuildValue("i", 0);
}

static PyObject* write_xml_world(PyObject *self, PyObject* args)
{
char* target_dir;
if (PyArg_ParseTuple(args, "s", &target_dir)) {
if (BLO_write_XML(target_dir, BLO_WRITEXML_WORLD, NULL))
return Py_BuildValue("i", 1);
}
return Py_BuildValue("i", 0);
}

static char M_BDx_doc[] = "The Blender BDx module\n\n\
This module provides access to XMLExporting functions for BDxViewer\n\n";

struct PyMethodDef M_BDx_methods[] = {
{"writeMeshArmature", write_xml_mesharm, METH_VARARGS,M_BDx_doc},
{"writeEmpty", write_xml_empty, METH_VARARGS, M_BDx_doc},
{"writeCamera", write_xml_camera, METH_VARARGS, M_BDx_doc},
{"writeLamp", write_xml_lamp, METH_VARARGS, M_BDx_doc},
{"writeWorld", write_xml_world, METH_VARARGS, M_BDx_doc},
{NULL, NULL, 0, NULL}
};

PyObject *BDx_Init() {
PyObject *submodule;

submodule = Py_InitModule3( "Blender.BDx", M_BDx_methods, M_BDx_doc );

return submodule;
}


5.Blenderのエディタで、


import Blender
from Blender import *

print BDx.writeEmpty('folderName') # 成功すると"1"が表示される
print "finished!!!"


というように、普通に自作メソッドが実行できるようになります!

2008年10月19日日曜日

etc - さよなら絶望先生15



届いてました。漫画に特別付録でDVDが付いて、3470円のやつです。
事前情報によると、大量のパロが入っているらしいので楽しみです。

--------------

なんか珍しく忙しかったので何も進んでないです。

今週の予定は
・エクスポーターでpython対応と最適化
・コンバーターでCOLLADA吐くかも
・他、PVとかGAとか2Dとか、気が向いた順に。

2008年10月17日金曜日

etc - CUDAでリアルタイムレイトレーシング

>IchikawaSoftLaboratory & Bio_100%提供のリアルタイムレイトレーシングのベンチマークソフト
http://forum.nvidia.co.jp/EokpControl?&tid=10498&event=HE0004


というのがあったので、早速試してみました。

環境は、Celeron420 2GHz(overclocked) + GeForce8600GTです。



なんとこのヘボ環境でも10~15fps出ました!(数字の割りに滑らかじゃない気もしますが・・)

っていうか、Bio_100%って最近HP復活してたのは知ってたけど、まだ活動してるのかな。
自分はギリギリゆとりじゃないくらいの世代なので、全然知らないけど、何か凄いグループらしいですね。

Blenderはマルチプラットフォーム重視してるから、CUDAにしてもDirectX11にしても、対応することは無いと思いますが、この並列処理能力は良いですね~。折角CUDA使える環境なので、卒業研究で使おうかと思ってます。丁度良い感じに並列プログラミングの講義も取ってるし。いずれ完全にマルチコアの時代になるので、この辺は力入れておかないと。

2008年10月16日木曜日

viewer - 2.48に移行しました

2.48が出たということで、移行しました。
2.46のときは、少しコードの変更が必要だったんだけど、今回は特に変更無く、そのまま動きました。

ここ最近、ほとんどBlenderでレンダリングしてなくて、今後もますますその傾向が強くなっていく予定です。右のギャラリーくらいの品質で普通に100fps越えるし、10体くらい出しても40~50fpsくらい出てるし、バグも減ってきた(と思いたい)し。

というわけでviewerを地味に更新してます。

2008年10月15日水曜日

blender - Bathroom Demo

blender.jp - ゲームエンジンデモ:Bathroom Demo
http://blender.jp/modules/news/article.php?storyid=2186


やってみました。



ポリ数1万弱とはいえ、1024x1024のテクスチャをマルチでガンガン使って、クロスシミュありで、40fps(@Geforce8600GT)程度というのは、(以前と比べて)なかなか好成績だと思います。アヒル10匹投げたら強制終了しましたが・・・;;


------

気付いている人は気付いていると思いますが

GameEngineのLogicBlockは、Sensors、Controller、Actuatorから成ります。
このSensors、Controller、Actuatorというのは、おそらく人工知能分野のエージェントに由来しているものです。
つまり、GameEngineを極めるついでに、人工知能も勉強すれば一石二鳥というわけです。

さぁ、そこの情報学科の暇な人、Blenderをやりましょう~

2008年10月14日火曜日

etc - オープンソースのソフトウェアライセンス


について詳しく書いてある本が出てたので購入。

100ページほど読んだんですが、かなり丁寧に書いてあって、曖昧だった部分がしっかり理解できそうです。
また、オープンソースの歴史についても詳しく書いてありました。

副題がオープンソースxソフトウェア開発xビジネスとなっているとおり、オープンソースをビジネスに使うことにも触れています。SIerで"オープン系"とか言ってるやつですね。

ソフトウェアライセンスの基礎知識 (単行本)
http://www.amazon.co.jp/dp/4797347368


--------

しかし、オープンソースのおかげで、最低限越えないといけない壁が高くなってて、新規参入が難しい市場になっているような気がします。プログラマな自分としては、望まい未来とは思えないんですよね。

っていうか、そんな高性能なもの無料で公開すんなーーー!<全国の有名フリーソフト作者へ

WEBサービスだって、広告収入しかないのに無料無料で。
無料が当たり前になるから、誰もソフトウェアを買わない。
これが正しい市場のあり方でしょうか?

という自分も、紙copi、PacketixDesktopVPN、初音ミク、あとゲーム3つほどしか買ってませんが・・。

etc - GoogleBloggerEntryEraser作りました

GoogleBloggerのブログ記事を、複数まとめて非表示/削除するためだけの、クライアントを作りました。

まったく、このくらい標準で出来るようにしといて欲しい・・・。







ダウンロードはブログ右からどうぞ。
間違って記事が削除されても責任は取れませんので、削除ではなく、非表示(下書き)にするほうをお勧めします。

2008年10月13日月曜日

etc - 雲

CEDEC 2008 - コンピュータが知性でコンテンツを自動生成--プロシージャル技術とは(前編)
- プロシージャル技術による雲の生成
http://journal.mycom.co.jp/articles/2008/10/08/cedec03/007.html


ん?以前どこかで見たことが…

と思ったら

ニコニコ動画 - Blenderで雲
http://www.nicovideo.jp/watch/sm4790585


おぉぉ、これだっ。

で、これか

Alan's Cloud Generator
http://blenderartists.org/forum/showthread.php?t=118973



こちらは論文とか動画とか
Realistic and Fast Cloud Rendering
http://niniane.org/clouds/



なにこれ、すごすぎ。この中を飛ぶだけでPV完成じゃん。



あと、空と雲でゲームといえば、これですねー。

ACECOMBATチームが描くもう1つの「空」- スカイ・クロラ
http://namco-ch.net/sky_crawlers/index.php


3日後発売予定です。

2008年10月12日日曜日

blender - リップシンクツール製作でC#入門(5)[完成]

ShapeKeyRecorderで作成したキーを、Blenderで読み込むためのスクリプトを、追加しました。



これで、一応バージョン1完成ということにします。
結局4日掛かってしまいました。

PythonScriptでの読込みが、かなりのクセモノでした。
なんか読込むのに、手動でKey作成しとかないといけないって、面倒じゃない?と思われるかもしれませんが、スクリプトからKeyBlockを追加する手段が多分無いです><

etc - LipSync凄い!

紛らわしいから新規エントリに再掲。

リップシンクツールを製作開始して、3日で作るはずが、現在4日目突入しました…。

既にめちゃくちゃ高性能のリップシンクツールがありました!!(泣)
LipSync @ ウィキ
http://www32.atwiki.jp/lipsync/pages/1.html


1年くらい作りこんでる!!
ソースコードも公開してるし!!!
なんてこったーーーーーー。
でも、もう出来てしまったので、自分の使うけど。
(機能が無い分、手軽さでは負けて無いはず。)


このツールは、保存はバイナリだけど、デフォルトで「はとぅねベンチ」用のスクリプトを吐けるみたいだから、それをBlenderから読み込むスクリプト書けば・・・

あぁ、つまり、どっちにしろスクリプトは書かないといけないのか

俺が次に実装しようかと思ってた機能が既にあるし・・・・・・。(まぁ所要時間10分程度で出来る機能だけど。)

(リアルタイム入力のFAQ)
1回押されたキーに該当するエントリは、次のキー入力が来るまでON状態が持続していると判定されます(→キーを押し続ける必要はない)。この持続を意図的に切る場合は、スペースキーを押します。


あとでVS2008インスコしてソース読むか・・・。
やっぱ簡単に作れそうだと思ったやつは、大抵誰か作ってるから、徹底的にググったほうがいいな。

------------------------

ちょっと色々試したので、LipSyncでリアルタイム入力するまでの、使い方書いておきます。

1.ツール→同時再生する曲 から再生したい曲を追加
2.編集→ビデオの長さを変更 から再生時間を指定
3.編集→空のキャラクタを追加 から適当にキャラを追加
4.表示→タイムテーブルとシンクロをチェック
5.再生して、「a, i, u, e, o」のどれかを押すと、キーが打てる模様。矢印キー押すと、何故か入力できなくなるので注意。


手動入力するとき、タイムライン上をドラッグすると入力できるんだけど、重なった部分の処理が凄い。

2008年10月11日土曜日

blender - リップシンクツール製作でC#入門(4)

今日がツール製作3日目で、今日で終わらせる予定だったんですが・・
昨日友人と借りてきた映画見て、そっから徹夜でゲームで対戦して、寝て起きたら午後4時で、カレー作って食べて3日目19時。それから開発して現在21時です。

本体部分は大体出来たので公開しました。
C#入門3日目のソースコードも付いてます。


ダウンロードは、ブログ右のShapeKeyRecorderからどうぞ。

あと3時間でかんなぎが始まるまでにBlenderへのインポーター作ります!

やべ、はじまったorz

そして終わった。アニメが。


スクリプトもうちょいかかりそう…
ShapeKeyだけ扱い違ってややこしいです。

2008年10月10日金曜日

blender - リップシンクツール製作でC#入門(3)

録画(?)できるようになりました。



録画よりもスクロールバーの調整が面倒だった。
シークしたとき移動させたりとか。
あとスペースキー押すとメディアプレイヤーの一時停止のショートカットと被ってて、しかも回避方法が多分なくて。しょうがないから再生押したら強制的に右上の使ってないテキストボックスにフォーカス移すようにしたりとか。


ちょっとコードが長くなってきたので、出来たときに一緒に公開ということで。
コードが欲しいんじゃなくて、成果物が欲しいです。

今気づいたけど、メディアプレイヤーってスロー再生にも対応してたのか~。いやー便利便利。

blender - リップシンクツール製作でC#入門(2)



左上のmultilineテキストボックスをuserInput、右上のreadonlyテキストボックスをvowelという名前にしました。
userInputのKeyPressイベントで、改行が入力されると、vowelに母音が表示されるようにします。


折角C#なのでforeachというのを使ってみました。あと、文字の判別は正規表現を使ってみました。IsHiraganaってやつは、これ本当に使えるのか!?と思いますが、使えました。


private void userInput_KeyPress(object sender, KeyPressEventArgs e)
{
if (sender != this.userInput) return;

// Enterキーが押された
if (e.KeyChar == '\r')
{
// ひらがな以外の文字が無いチェック
if (!Regex.IsMatch(
this.userInput.Text, @"^\p{IsHiragana}*$", RegexOptions.Multiline))
{
MessageBox.Show("ひらがなのみで入力してください");
return;
}

// 入力を母音に変換
convertInputToVowel();
}
}

// 入力した歌詞を元に、母音のテキストボックスに母音を表示する
// 表示する文字は a i u e o n のどれか
private void convertInputToVowel()
{
// vowelテキストを消去
vowel.Text = "";

// 各行の母音をvowelテキストボックスに表示
string[] songLines = this.userInput.Text.Split('\n');
foreach(string line in songLines)
{
string vowelLine = "";

foreach (char c in line)
{
// 「っ」は無視
if (c == 'っ') continue;

string s = c.ToString();
// a
if (Regex.IsMatch(s,
"[あかさたなはまやらわ]|[がざだばぱ]"))
{
vowelLine += "a";
}
// i
if (Regex.IsMatch(s,
"[いきしちにひみり]|[ぎじぢびぴ]"))
{
vowelLine += "i";
}
// u
if (Regex.IsMatch(s,
"[うくすつぬふむゆる]|[ぐずづぶぷ]"))
{
vowelLine += "u";
}
// e
if (Regex.IsMatch(s,
"[えけせてねへめれ]|[げぜでべぺ]"))
{
vowelLine += "e";
}
// o
if (Regex.IsMatch(s,
"[おこそとのほもよろを]|[ごぞどぼぽ]"))
{
vowelLine += "o";
}
// 「にゃ」「にゅ」「にょ」などの特殊なケースは
// でかい文字のほうを消して、小さい文字の母音にする
if (Regex.IsMatch(s, "[ゃゅょ]"))
{
vowelLine
= vowelLine.Substring(0, vowelLine.Length - 1);
if (c == 'ゃ') { vowelLine += "a"; }
if (c == 'ゅ') { vowelLine += "u"; }
if (c == 'ょ') { vowelLine += "o"; }
}
// 「ん」は、母音の代わりに「n」を割り当てる
// (タイミング入力時に押さないのが難しいため)
if (c == 'ん')
{
vowelLine += "n";
}
}
this.vowel.Text += vowelLine + "\r\n";
}
}



続いて、ファイルを読み込んで音楽を再生します。
ツールボックスからMenuStripを追加して、それに、挿入-音声と追加しました。

音声メニューの名前をinsertMusicにし、ダブルクリックすると勝手にClickイベント入力画面になります。

そこに以下のように入力。

private void insertMusic_Click(object sender, EventArgs e)
{
this.openFileDialog1.ShowDialog();
this.axWindowsMediaPlayer1.settings.autoStart = false;
this.axWindowsMediaPlayer1.URL = this.openFileDialog1.FileName;
}



ファイルの読込みと再生が出来ました。

・・・ちょっとペースあげるか。

ドラッグアンドドロップでの入力にも対応

private void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] s = (string[]) e.Data.GetData(DataFormats.FileDrop, false);
if (s.Length > 0)
{
this.axWindowsMediaPlayer1.URL = s[0];
}
}

private void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.All;
else
e.Effect = DragDropEffects.None;
}

2008年10月9日木曜日

blender - リップシンクツール製作でC#入門(1)

リップシンクツールを3日以内に作るお!という企画です。
ついさっき思いついたのでやります。

もちろんC#に入門するのは俺です。
現在、遥か昔に、@ITの入門記事を流し読みした程度の能力で、ほとんど忘れています。というか何も作ったこと無いです。


まず始めにVisualStudio2005を開いて、C#のWindowsApplicationのプロジェクトを作ります。

次に、欲しい機能や、操作方法をあれこれ考えながら、適当にツールボックスから部品を配置します。

ツールボックスで右クリックして、アイテムの選択を押すと、COMコンポーネントとかいうMSっぽい名前のがあり、中にメディアプレイヤーがあるようです。面倒なのでこれを貼り付けましょう。


なんかそれっぽい画面が出来ました。

ここまで全く何も実装していません。


ユーザー視点(っていっても自分なんだけど)での使い方を考えます。

----------

1に、ひらかなで歌詞を入力します。
2に、入力した歌詞の母音が表示されます。
挿入で音声ファイルを読み込みます。
3の再生ボタンを押すと、タイミング入力可能状態になり、曲の歌詞にあわせて、1語1語スペースキーでタイミングをリアルタイムに入力します。
4に入力結果のタイムラインが表示され、微調整できます。
適当な形式で保存した後、Blenderからpythonスクリプトで、インポートします。

----------

えーっと、こういう風に使いたいという希望であって、出来る保障は全くありません。(汗

まぁ気楽に行きましょう。4の実装が一番難しそうですねー。

etc - ExpressionEncoder

ExpressionEncoderは、どうやらWMVエンコードツールみたいです。

Microsoft Expression Encoder 2 の機能
http://www.microsoft.com/japan/products/expression/features/default.aspx?key=encoder




手持ちの動画をimportして、Encodeを押すと、デフォルトで512x384のストリーミング向けのWMVが出来上がりました。品質もVC-1など、かなり詳細に設定できるみたいです。WMVはSilverLightでも扱える動画形式らしいです。(Expressionシリーズは全てSilverLight向けみたいです。)

でもWMVなのでニコ動向きではないですね・・。MP4あたりサポートしてくれたらいいのになぁ。

2008年10月8日水曜日

blender - python でのPoseとActionとIpo

IK付いてるボーンがあったとして、それのtargetだけにキーを打ったものから、
chainlenで関連しているボーン全てに、targetのキーと同じタイミングに、キーを打ちたいんです。

このようにして、chainlenで関連してるボーンと、IKtargetを、Poseとして取得できます。

# ----------------------------------
# return ik related bones
# [ [ armature, [targets], [chanedBones]], ...]
# ----------------------------------
def getIKChains():
ikChains = []
scene = Blender.Scene.GetCurrent()
armatures = [ob for ob in scene.objects if ob.type == 'Armature']

for arm in armatures:
pose = arm.getPose()
for boneName in pose.bones.keys():
bone = pose.bones[boneName]
for con in bone.constraints:
if con.type == Constraint.Type.IKSOLVER:
targets = []
chainedBones = []

targets.append(
pose.bones[con[Constraint.Settings.BONE]])

clen = con[Constraint.Settings.CHAINLEN]
ikBone = bone;
chainedBones.append(ikBone)
for i in range(clen):
chainedBones.append(ikBone.parent)
ikBone = ikBone.parent

ikChains.append([arm, targets, chainedBones])

return ikChains

# debug
for chain in getIKChains():
for i in range(len(chain)):
arm = chain[0]
target = chain[1]
bones = chain[2]
print arm
print target
print bones



・・・・が、BlenderのPythonAPIでは、PoseとActionの関連付けを調べることがどうやっても出来ないのではないかと思うんです。

なんのこっちゃって感じですが、これがアニメーションのエクスポートに非常に重要で、まともにアニメーション吐けるスクリプトが無い最大の原因ではないかと思っています。

内部のコードでは、ActionChannelからPoseChannelにできます。Pythonではこれが無いんです。PoseからIpoを取得することもできませんし、ActionからIpoを取得しても対応するPoseは分かりません。

どなたかご存知でしたら、教えてください。

ということで、結局内部組込みのエクスポーターで処理することに。
Python以外にも、拡張する方法(DLLとかかな?)があるらしいんだけど、そっち調べても結局できなかったら意味ないし。
確実に出来る方法を取らないと、いくら時間あっても足りねえ。

2008年10月7日火曜日

blender - python 同じAction一掃(2)

…遥か昔

blender - python 同じAction一掃
http://blendermoe.blogspot.com/2007/11/blender-python-action.html


というのをやったんですが、これには重大なミスがありまして、
2つ続けて同じ値があった場合、消していたんですが、よく考えたら3つ連続したときに真ん中のを消さないと、バグってしまうんですよね。

これまた、遥か昔に気づいていたんですが、そのころはリアルタイムレンダリングしていなかったので、別に一掃する必要ないじゃんということで、放っておきました。


さて、リアルタイムレンダに移行して、データ量も考えないといけなくなったので、再び手を加えることにしました。ついでに、NLA上にある全てのActionに対して適用するように変更しました。

はい、こちら


import Blender
from Blender import *
from Blender.Armature import *

# ----------------------------------
# delete same IpoCurves
#
# return list of deleted for print
# [[ipo,curve,index], [ipo,curve,index] ...]
#
# ipos : list of Ipos
# frameNums : list of frame numbers
# ----------------------------------
def deleteSameCurve(ipos, frameNums):
deleted = []
for ipo in ipos:
if (ipo == None):
continue
for curve in ipo:
pre = None
prepre = None
index = 0
for time in frameNums:
# nothing
if (len(curve.bezierPoints) == 0):
continue
# not existed bezierPoint at time
if ([x for x in curve.bezierPoints if x.pt[0] == time] == []):
continue

value = curve[time]
# there are 3 same points, delete second
if (pre != None and prepre != None and
pre == value and prepre == value):
length = len(curve.bezierPoints)
curve.delBezier(index - 1 - length)
deleted.append([ipo, curve, index - 1])
else:
prepre = pre
pre = value
index += 1

return deleted

# ----------------------------------
# delete same IpoCurves from Armatures
# see: deleteSameCurve(ipos, framNums)
#
# return list of deleted for print
# [[[arm1's deleted elements], [arm2's], ... ]]
#
# ----------------------------------
def deleteSameAction():
deleted = []
frames = []
for act in NLA.GetActions().itervalues():
ipos = act.getAllChannelIpos().values()
frames = act.getFrameNumbers()
deleted.append(deleteSameCurve(ipos, frames))
return deleted

# ----------------------------------
# execute
# ----------------------------------

#printing is slow.. debug only
#print deleteSameAction()

print "start!"
deleteSameAction()
print "finish!!!"



結果







というわけで、成功してますが、データに関する非常に危険なスクリプトなので、必ずバックアップを取ってから実行してください。うまく行く保障は全くありません。
Blenderのテキストエディタで開いて、Alt-Pで実行後、コンソールにfinish!!!と表示されたら成功です。(割と時間かかります)


さて、うまく行ったものの、実はこのままではリアルタイム用途には使えないのです。IKを使用しているので、IKが関連するボーンにキーを打ち直さないといけません。

というわけで、続く!

blender - Perfumeの踊り練習(2)

注意!めっさ音でます。
video

とりあえず長さはこのくらいで。テストのためポリ数控えめ。
先に大まかにモーション付けると、やる気がでますね!
あとは詳細を作りこむのと、演出か。。

最低でもMikuMikuDanceには負けたく無いと思っているんですが、MikuMikuDanceの凄い人たちはモーション上手すぎですよね。
そろそろMikuMikuDanceを卒業して、オリジナルモデルがガンガン出てきてくれないかなーと思っているんですが、あんまり出てきませんし・・・。勿体無いなぁ。



現在のキーは、このくらい

2008年10月6日月曜日

etc - ExpressionDesignレビュー

すっかり作るの忘れていた国際学生証を作って、Expression Studioを無償で手に入れたので、レビュー。
学生じゃなくなっても使えるので、学生の人で持ってない人は、早めに手に入れておきましょう!

Expression Designとは、
革新的なベクタ描画ツール、および元のイメージを損なわないエフェクトをベクタ イメージまたはインポートされたビットマップ イメージに適用して、創造性を発揮することができます。ベクタ パスの柔軟性を保ちながらハードエッジや自然なストロークを適用できます。Expression Design は、デザイナーのために、デザイナーによってゼロから作られたツールです。


とMSの公式サイトから引用してきましたが

ExpressionDesignは、『Expression』というソフトを作っていた香港のCreature Houseという企業を、MSが買収して作りられたツールです。まぁ間違ってはいないか。

また、Expression Media 2 というのも付いてますが「Microsoft が 2006 年 6 月に買収した iView MediaPro 製品をベースとしています。」だそうです(公式FAQより)

さて、主要なセールスポイント
http://www.microsoft.com/japan/products/expression/features/default.aspx?key=design
公式ページを参照してもらうとして、地味な機能中心に自分視点で見て行きたいと思います。


まず、起動すると、メモリ使用量が80Mで、1600x1200の96dpiを新規作成すると、6Mくらい増えますね。


さて、デフォルトの800x600、96dpiで新規作成し、適当に線を引きました。
線を引くと赤色の矢印付きで、ガイドが描画されています。
最近のソフトだけあってUIカッコイイっすね。


最大まで拡大したところがこちら。64倍まで拡大できるんですね。
アンチエイリアスも綺麗に掛かってます。


さて、Expressionといえば、パスに様々な種類のストロークを割り当てられるのが特徴です。
画像のようにカテゴリ分けされてあって、デフォルトでもかなりの数のストロークが入ってます。



塗りつぶしは、ベタ塗り、グラデ、テクスチャ、から選べるようです。
グラデは、線形か球状ですね。
塗りに対して、値を入力することで、移動や回転が出来ます。
個人的にこれは無いわー、と思います。


MSの開発者も、さすがにこれは無いわーと思ったのか、一応グラデだけに関しては、マウスのドラッグで指定できるツールがありました。(画像右)
グラデ開始点から終了点までドラッグすることで、グラデの位置を指定できます。
…が、ドラッグ中に再描画されないので、これに関してはInkscapeのほうが良いですね。
個人的に、グラデの指定は、オムニグラフ(mac専用のvisio見たいなソフトです)の指定法が斬新で使いやすいと思いますね。



切り取り系のツールは、ハサミで、画像右のように切断できます。
また、スライスというツールでは、画像左のように、作成中の画像からラスタ画像として切り抜けます。
切り抜いた時点で容量まで表示されていて、手が込んでますね。



そして、Expressionといえばコレ! ストロークの作成機能です。
自分でストロークを作れるんですよね。
ストローク関連は、大切な機能なんですが、実装するのかなり大変でしょうね。他人事じゃあないですが(汗。



最後にエクスポート機能です。
普通にsaveで保存しようとすると、Expression形式でしか保存できません。
外部アプリで使うにはExportから出力するようです。
対応形式は上記の通り。
MSだけに、XAML対応が売りみたいですねー。

そういやSilverLightは、インストールすらしてません…。今後流行るでしょうか?
ああいうLightWeightなものは、流行り廃りが激しいし、初心者でも手軽に出来てしまうし、熟練したオッサンプログラマが遊びでやってる印象があるので、どうもやろうとは思わないんですよね。今は他にもっとやることあるだろ俺っと。


以上。あ、書き忘れたけど、パスの作成は、フリーハンドでベジエになるやつと、イラレとほぼ同じショーットカットで地道に点打っていく方法がありました。

2008年10月5日日曜日

blender - Perfumeの踊り練習

しようとするも挫折。とりあえず形だけ作って、後で細部のモーションを作る作戦。

*音出ます!注意

eyeVio登録してみた。えーっと、ワイドになってしまうのか。
つまりワイドで録画すればいいのかな・・?

素晴らしすぎるコピー曲はhttp://www.nicovideo.jp/watch/sm1546702を勝手に使わせてもらいました。

見本があると(精度を気にしなければ)サクサク進むので、このまま1分くらいまで満足いくまで作りこんでニコ動にもあげてみるかな。

作業画面。NLAは便利で効率的だけど、つなぎ目が難しいなぁ。



ちなみに、他のオリジナル曲で、PV作ってたんだけど、リピートでその曲掛けっ放しにしてたら、早速飽きてしまって、制作意欲無くなってしまった。

2008年10月4日土曜日

etc - ゲーム3D数学



新刊買ってきた。

ゲーム3D本と言えば、他にゲームプログラミングのための3Dグラフィックス数学がありますが、そちらは数学寄りの解説で、こっちは実装寄りです。とりあえず3400円は安いので、買い。

それからCGWORLD。いつも買って無いけど、SIGGRAPHに釣られて購入。

-----

物理演算難航中。
色々読んで、ぼんやり分かってきたけど、どうせならGPUでこういうのやりたい…。

-----

Perfumeのエレクトロ・ワールドのPV見たら、凄すぎて噴いた。
JPOPのPVとしては、宇多田ヒカルのTravering以来の衝撃かも。

で、理想と現実のギャップが激しくて、PVが全然出来無いわけですが、
やっぱニコ動にUPするわけだし、俺デザイナーじゃないから、パクってパクってパクリまくる方針です。
オリジナルに勝てないと分かっていても。