House generator
House painter
Bonus Tools の Paint Geometry Tool を使った町並みの景観を作るチュートリアルです。
でもまぁGoogleEarthがあれば(ry
‘MEL’ カテゴリーのアーカイブ
House generator & House painter
2006年11月25日 土曜日今まで損をしていたMayaの使い方
2006年11月22日 水曜日MM_mirrorPoseを少し修正
2006年11月20日 月曜日
オプションを増やしました。
OrientJointに合わせた形となっています。
MM_mirrorPose.mel
Xスケールに-1をかけた行列をオイラーに戻すと 0 0 -180
2006年11月19日 日曜日Xスケールに-1をかけた行列をオイラー角に戻すと 0 0 -180 で返されます。
先日見つけた公式がそう返しおるんですが、
なるほどと。
スプーンに映る自分の顔。。。みたいな感じでしょうか?
なんでやねーんっ!と突っ込みを入れたくなりますが、
天地逆になってしまうのをなんとか補正をつけないといけないなぁと思います。
//テストMEL locator1のスケールを-1にセットしてこのMELを実行します。
float $nx, $ny ,$nz;
float $ma[16];
$ma = `xform -q -m locator1`;
//変換公式
if(($ma[2] < 1.0) && (($ma[2] > -1.0))){
$ny = -asind($ma[2]);
$c = cosd($ny);
$nx = atan2d(($ma[6])/$c, $ma[10]/$c);
$nz = atan2d($ma[1]/$c, $ma[0]/$c);
}
else {
$nx = atan2d(-$ma[9],$ma[5]);
$ny = -atan2d($ma[2],0.0);
$nz = 0.0;
}
print $nx;
print ” “;
print $ny;
print ” “;
print $nz;
print “\n”;
※記事の訂正
2006年11月17日 金曜日オイラー角をオイラー角で変換した後のオイラー角
の変換公式に誤り(というか不具合)がありました。
こちらの方がより正常に動作すると思います。
//変換公式
if(($ma[2] < 1.0) && (($ma[2] > -1.0))){
$ny = -asind($ma[2]);
$c = cosd($ny);
$nx = atan2d($ma[6]/$c, $ma[10]/$c);
$nz = atan2d($ma[1]/$c, $ma[0]/$c);
}
else {
$nx = atan2d(-$ma[9],$ma[5]);
$ny = -atan2d($ma[2],0.0);
$nz = 0.0;
}
記事の方も訂正をしています。
参考にされていた方には誤った情報を流してしまいまして
誠に申し訳ございませんでした。
コワザ其の一 オイラー角を-90~90°の範囲にする方法
2006年11月17日 金曜日意地でもラジアンを使わない根性で編み出した小技。
if($nx > 90) {
$nx = $nx – 180;
}
else if($nx < -90) {
$nx = $nx + 180;
}
if($ny > 90) {
$nx = -$nx;
$ny = $ny – 180;
}
else if($ny < -90) {
$nx = -$nx;
$ny = $ny + 180;
}
if($nz > 90) {
$nx = -$nx;
$ny = -$ny;
$nz = $nz – 180;
}
else if($nz < -90) {
$nx = -$nx;
$ny = -$ny;
$nz = $nz + 180;
}
数値を入れるとこんな感じでMayaが動作するのを見て
真似て作りました。
コードに入れ込んでみたらあんまり役に立たなかった。
ちっ!
これだと半分だけなので残り半分をカバーできるように改良せねばなりません。
おちゃめなMaya4 シビアすぎるアークサイン
2006年11月16日 木曜日asind()を使っておりますと、ときーどき
// Error: line ***: Invalid argument(s) for asind.
のエラーを返します。
debug用にprintをかまして数値を読んでも 1 のはずなのに、
しかもif文を前にかましているのに。。。if($hoge < 1.0) =(等号)付けてないのに。。。
そんな時のTips、
asind(`min 1.0 $hoge`);
これで通りました。えぇ
1.0000024
とか値が入ってるんでしょうか。
厳格なMayaさん。
つーか、その前のif文通すなっつーの。
matrixの生成
2006年11月15日 水曜日なんとなく回転行列の使い方がわかり始めた今日この頃
4×4の行列変換が結構便利だということがわかりました。
しかし、理屈はわからないまま答えがポンと出てくるので、とても気持ち悪いです。
//ポイントと角度とスケールからマトリックスを生成
proc float[] _makeMatrix(float $point[], float $theta[], float $scale[]) {
float $ma[16];
float $px = $point[0];
float $py = $point[1];
float $pz = $point[2];
float $rx = $theta[0];
float $ry = $theta[1];
float $rz = $theta[2];
float $sx = $scale[0];
float $sy = $scale[1];
float $sz = $scale[2];
$ma[0] = $sx * cosd($ry)*cosd($rz);
$ma[1] = $sx * cosd($ry)*sind($rz);
$ma[2] = $sx * -sind($ry);
$ma[3] = 0;
$ma[4] = $sy * (sind($rx)*sind($ry)*cosd($rz) – cosd($rx)*sind($rz));
$ma[5] = $sy * (sind($rx)*sind($ry)*sind($rz) + cosd($rx)*cosd($rz));
$ma[6] = $sy * sind($rx)*cosd($ry);
$ma[7] = 0;
$ma[8] = $sz * (cosd($rx)*sind($ry)*cosd($rz) + sind($rx)*sind($rz));
$ma[9] = $sz * (cosd($rx)*sind($ry)*sind($rz) – sind($rx)*cosd($rz));
$ma[10] = $sz * cosd($rx)*cosd($ry);
$ma[11] = 0;
$ma[12] = $px;
$ma[13] = $py;
$ma[14] = $pz;
$ma[15] = 1;
return $ma;
}
//_makeMatrix({1.0, 2.0, 3.0}, {30.0, 60.0, 45.0}, {-1.0, 1.0, 1.0});
matrix関連のノードを見かけるので、APIには実装しているはずなんですが、
MELコマンドがないですねぇ。MELではやらんだろうということなのかな?
matrix関数がない
2006年11月14日 火曜日MELには実装されてないのでしょうか?
libを書くのが面倒です。
//逆matrix
proc float[] _reMatrix(float $ma[])
{
float $am[16];
//マトリックスの掛け算
$am[0] = $ma[0];
$am[1] = $ma[4];
$am[2] = $ma[8];
$am[3] = $ma[12];
$am[4] = $ma[1];
$am[5] = $ma[5];
$am[6] = $ma[9];
$am[7] = $ma[13];
$am[8] = $ma[2];
$am[9] = $ma[6];
$am[10] = $ma[10];
$am[11] = $ma[14];
$am[12] = $ma[3];
$am[13] = $ma[7];
$am[14] = $ma[11];
$am[15] = $ma[15];
return $am;
}
//座標変換
proc float[] _matrixRotate(float $pi[], float $sita[])
{
float $nx, $ny ,$nz;
float $me[16];
string $lo[] = `spaceLocator -p 0 0 0`;
rotate -r -os $pi[0] $pi[1] $pi[2];
$ma = `xform -q -m $lo`;
string $lo2[] = `spaceLocator -p 0 0 0`;
rotate -r -os $sita[0] $sita[1] $sita[2];
$mb = `xform -q -m $lo2`;
select -r $lo;
delete;
select -r $lo2;
delete;
$me = _matrixTimes($ma, $mb);
//変換公式
if(($ma[2] < 1.0) && (($ma[2] > -1.0))){
$ny = -asind($ma[2]);
$c = cosd($ny);
$nx = atan2d($ma[6]/$c, $ma[10]/$c);
$nz = atan2d($ma[1]/$c, $ma[0]/$c);
}
else {
$nx = atan2d(-$ma[9],$ma[5]);
$ny = -atan2d($ma[2],0.0);
$nz = 0.0;
}
※訂正 2006 11/18 変換公式を訂正しました。
return {$nx, $ny, $nz};
}
//逆変換
proc float[] _matrixReRotate(float $pi[], float $sita[])
{
float $nx, $ny ,$nz;
float $me[16];
string $lo[] = `spaceLocator -p 0 0 0`;
rotate -r -os $pi[0] $pi[1] $pi[2];
$ma = `xform -q -m $lo`;
string $lo2[] = `spaceLocator -p 0 0 0`;
rotate -r -os $sita[0] $sita[1] $sita[2];
$mb = `xform -q -m $lo2`;
select -r $lo;
delete;
select -r $lo2;
delete;
$mb = _reMatrix($mb);
$me = _matrixTimes($ma, $mb);
//変換公式
if(($ma[2] < 1.0) && (($ma[2] > -1.0))){
$ny = -asind($ma[2]);
$c = cosd($ny);
$nx = atan2d($ma[6]/$c, $ma[10]/$c);
$nz = atan2d($ma[1]/$c, $ma[0]/$c);
}
else {
$nx = atan2d(-$ma[9],$ma[5]);
$ny = -atan2d($ma[2],0.0);
$nz = 0.0;
}
※訂正 2006 11/18 変換公式を訂正しました。
return {$nx, $ny, $nz};
}
matrixを取るのにいちいちロケイターを作ってるのがカッコ悪いんですが。。。
数値から生成してくれないものか知らん?
オイラー角をオイラー角で変換した後のオイラー角
2006年11月13日 月曜日proc float[] _matrixTimes(float $pi[], float $sita[])
{
float $nx, $ny ,$nz;
string $lo[] = `spaceLocator -p 0 0 0`;
rotate -r -os $pi[0] $pi[1] $pi[2];
$ma = `xform -q -m $lo`;
string $lo2[] = `spaceLocator -p 0 0 0`;
rotate -r -os $sita[0] $sita[1] $sita[2];
$mb = `xform -q -m $lo2`;
select -r $lo;
delete;
select -r $lo2;
delete;
//マトリックスの掛け算
float $xx = $ma[0]*$mb[0] + $ma[1]*$mb[4] + $ma[2]*$mb[8] + $ma[3]*$mb[12];
float $xy = $ma[0]*$mb[1] + $ma[1]*$mb[5] + $ma[2]*$mb[9] + $ma[3]*$mb[13];
float $xz = $ma[0]*$mb[2] + $ma[1]*$mb[6] + $ma[2]*$mb[10] + $ma[3]*$mb[14];
float $xw = $ma[0]*$mb[3] + $ma[1]*$mb[7] + $ma[2]*$mb[11] + $ma[3]*$mb[15];
float $yx = $ma[4]*$mb[0] + $ma[5]*$mb[4] + $ma[6]*$mb[8] + $ma[7]*$mb[12];
float $yy = $ma[4]*$mb[1] + $ma[5]*$mb[5] + $ma[6]*$mb[9] + $ma[7]*$mb[13];
float $yz = $ma[4]*$mb[2] + $ma[5]*$mb[6] + $ma[6]*$mb[10] + $ma[7]*$mb[14];
float $yw = $ma[4]*$mb[3] + $ma[5]*$mb[7] + $ma[6]*$mb[11] + $ma[7]*$mb[15];
float $zx = $ma[8]*$mb[0] + $ma[9]*$mb[4] + $ma[10]*$mb[8] + $ma[11]*$mb[12];
float $zy = $ma[8]*$mb[1] + $ma[9]*$mb[5] + $ma[10]*$mb[9] + $ma[11]*$mb[13];
float $zz = $ma[8]*$mb[2] + $ma[9]*$mb[6] + $ma[10]*$mb[10] + $ma[11]*$mb[14];
float $zw = $ma[8]*$mb[3] + $ma[9]*$mb[7] + $ma[10]*$mb[11] + $ma[11]*$mb[15];
float $wx = $ma[12]*$mb[0] + $ma[13]*$mb[4] + $ma[14]*$mb[8] + $ma[15]*$mb[12];
float $wy = $ma[12]*$mb[1] + $ma[13]*$mb[5] + $ma[14]*$mb[9] + $ma[15]*$mb[13];
float $wz = $ma[12]*$mb[2] + $ma[13]*$mb[6] + $ma[14]*$mb[10] + $ma[15]*$mb[14];
float $ww = $ma[12]*$mb[3] + $ma[13]*$mb[7] + $ma[14]*$mb[11] + $ma[15]*$mb[15];
//変換公式
if(($ma[2] < 1.0) && (($ma[2] > -1.0))){
$ny = -asind($ma[2]);
$c = cosd($ny);
$nx = atan2d($ma[6]/$c, $ma[10]/$c);
$nz = atan2d($ma[1]/$c, $ma[0]/$c);
}
else {
$nx = atan2d(-$ma[9],$ma[5]);
$ny = -atan2d($ma[2],0.0);
$nz = 0.0;
}
※訂正 2006 11/18 変換公式を訂正しました。
return {$nx, $ny, $nz};
}
お試しコマンド
オイラー{0.0, 30.0, 0.0}を{30.0, 0.0, 0.0}回転させた時
_matrixTimes({0.0, 30.0, 0.0}, {30.0, 0.0, 0.0});
// Result: 33.690068 25.658906 16.102114 //
cheers!
おちゃめなMaya3 xformの謎
2006年11月11日 土曜日getAttr locator1.translate;
// Result: 4.549147 81.970932 -2.348332 //
xform -q -os -t locator1;
// Result: 70.437177 -40.261024 -12.770951 //
位置情報を取りたい時、上のように記述すると、
getAttr と xform で違う値を返すことがあります。
※正しい値は getAttr の方です。
これは一体どういうことなんでしょうか?
謎です。全然わからない。
何かクリアしなければならないものがあるんでしょうか?
今まで xform を多用してたのですが、
この所為で、うまく動かなかった。。。
なんでかなぁ?
とりあえず、今後は getAttr を使うことにします。
参ったっす。Mayaさん。。。
デプスマップシャドウで影の減衰を表現する方法
2006年11月9日 木曜日mixiでも昨年頃話題になっていた手法を用いてやってみました。

やっていることは、Light Infoにオブジェクトをコネクトして
それをライトのFilter Sizeにつなげています。
rampとmultiplyDivideは値の調整です。
影色にもついでにコネクトしています。
オブジェクト位置から離れると影がぼけるという考え方です。
しかし、これでは1つのオブジェクトしか対応できません。
ということで、困った時のレイヤーテクスチャで、
複数のオブジェクトをレイヤーで重ねてDarkenで合成しています。
これでFilter Sizeのマップを作るという感じでしょうか。
しかし、これでは不都合な場合が出てくることが判明。
影のボケ足近くに他のオブジェクトが重なった場合、
重なっているところの影がクリアになったりと。
う~ん、最初から考え直さないといけないなぁ。

こちらがデプスマップシャドウ レンダリング時間は1分と速く、仕上がりもなかなか綺麗なのですが。。。

こちらがレイトレース レンダリング時間 2分53秒。重い。。。
課題
オブジェクトが重なる場合の影の処理。
デプスマップシャドウではトランスペアレンシーで抜きたいところの影が抜けません。
これは何か方法はないのでしょうか?
以前日記でも紹介した事があるのですが、私が見つけた方法は、
ジオメトリを切り抜くというものでした。
しかし余りにも力技なのでもう少しまともな方法はないものかと。
それから、メンタルレイを使った場合、
トランスペアレンシーの切り抜きは可能なのですが、
カスタムアトリビュートのShadowMap の所の
Softnessで影のぼかしがLight Infoでは効きません。
どうも、また違ったシェーディングネットワークを組む必要がありそうです。
ご興味のある方はどうぞ
softshadow_depthmap.ma
知識よりも発想と思い知る
2006年10月19日 木曜日ミラーポーズのScriptを作ったのはいいけれど、
微妙にずれるところが許せない。
なんて思いながらいろいろアルゴリズムを考えていたわけですが、
力技くさい方法を思いつきました!!!
//反転後のオイラー角読取方法
locatorを作成。
ジョイントへオリエントコンストレイン。
その角度を(-x、180-y、-z)//角度の反転
これで反転後のlocatorのオイラー角(ワールド座標値)がわかります。
それをワールドスペースで反対側へ代入。
これをコード化すれば、どんなジョイントもほぼ完璧にミラー可能っす!
面倒なオプションは要りません(面倒な計算もいりません。。。orz)。
コンストレインって便利だなぁ~。
クォータニオンとオイラー角の相互変換
2006年10月18日 水曜日Mayaにはマトリックスの合成が簡単に行えるような関数群が用意されています。
ですから、知識さえあれば簡単にクォータニオンとオイラー角の相互変換が行える。。。はずなんですが、
悲しいかな、私にはそこんところの知識が足りません。
実際に回転させてから読むしかないかなぁ。
調べていてできた副産物
//任意のポイントを原点でθ角回転させた時のポイント座標
proc float[] _pointMatrix(float $point[], float $sita[]) {
//locator作成
string $lo[] = `spaceLocator -p 0 0 0`;
//locatorをθ角に回転
rotate -r -os $sita[0] $sita[1] $sita[2];
//変換マトリックス作成
$ma = `xform -q -m $lo`;
//作ったlocatorを削除
select -r $lo;
delete;
$po = pointMatrixMult($point, $ma);
return $po;
}
わしゃぁ角度が知りたいんじゃ。。。
ミラーポーズMEL
2006年10月17日 火曜日とてもシンプルなミラーポーズのMELです。
どうぞ使ってやってください。
MM_mirrorPose.mel
インストール方法
melファイルをscriptディレクトリに入れてください。
使い方は、
ルートジョイントを選択して、
コマンド MM_mirrorPose(0);
コマンド MM_mirrorPose(1);でウインドウが開きます。
シェルフに登録しておくと便利です。
注意点
スキニング前にジョイントオリエントをしておかないとうまく動作しません。
また、ジョイントオリエントしていても、
ジョイントオリエントの軸がx軸とずれていると、微妙にずれます。
テストした結果では、ジョイントオリエント”none”が最も正確に動作しました。
便利な使い方
選択したところから下の階層がミラーされますので、
腕だけとか、足だけ、手だけのミラーができます。
両方の手首を選択して実行すると、手のポーズがスワップします。
FBIK用にと考えていましたが、
何にでも使えると思います。
おちゃめなMaya2 オイラーはロール・ピッチ・ヨー
2006年10月17日 火曜日さらに深部に入り込んでしまった感が。。。
もう何が何やら、
オイラーの定義にしても、いろいろあるようで、
どれを信じれば良いのかわかりません。
こういうときはツールにしたがってMayaの流儀で行こう。
Mayaの場合、3軸を使って回転しています。
これってロール・ピッチ・ヨー?
よくわからないので、その辺は考えないように。。。
ただ、
rotate -r -os 30.0 0 0 ;
rotate -r -os 0 30.0 0 ;
rotate -r -os 0 0 30.0 ;
こうした時と、
rotate -r -os 30.0 30.0 30.0 ;
これの結果が違うのは何故なんでしょうか?
オイラーじゃないのかい?
未だに謎のジョイントオリエントの怪
2006年10月15日 日曜日ベクトルということで、一応の理解は得られたのですが、
ジョイントの持つJointOrientがやはりとても厄介なのです。
このJointOrientとジョイントの向き(つまりベクトル)がずれていた時の計算式がわかりません。
ベクトルの変換はどれもベクトル計算なので、
角度に再計算する方法がわからないんです。
この辺はどの辺りを探ればいいのでしょうか?
モーメント?
私にとっては未知の領域だ。
探求の旅は続く。。。
アハ体験
2006年10月14日 土曜日 |
\ __ /
_ (m) _ピコーン
|ミ|
/ `´ \
(’A`)
ノヽノヽ
くく
なんか私、勘違いしていたようです。
コンストレインをヒントにあれこれ試してましたら、
謎が解けました。
ジョイントはベクトル
なにを今更と言われそうですが、
これがわかっていなかった。
そもそもベクトルを理解していなかったと思います。
何か難しく考えすぎていました。
yz平面に対して、左右対称にするには、
RotateX * -1
RotateY * -1
RotateZ
でよかったんです。
アホだった。
悩み抜いた3日間。。。長かった。。。orz
ヒントをくださったその日暮さんありがとうございました。
ジョイントに含まれる厄介な情報
2006年10月13日 金曜日まず、手始めにポーズのミラーリングをと思いまして、
MELを組んでみているのですが、FKベースで考えると、
キャラクターごとにうまくいったりいかなかったり。
これは何故かなぁ~と試行錯誤しておりましたが、
どうもJointOrientが怪しいということになりました。
ジョイントはローカル座標値を持っているので、
回転軸はその座標系に依存するということで、
それを補完した形のコードを組まないといけません。
これが、もう厄介なことこの上ない。
※座標系に強い人ならなんてことはないんでしょうけど。。。
座標変換てどうするんだっけ?
そんでもってyz平面に対して対象となる角度というと。。。
とか考えてたら頭がわれそうに痛くなってきました。
かんちージョイントのセットアップがこんなところで仇になるとは。。。もうギブ。
retarget あやしいコマンドを発見
2006年10月12日 木曜日MELのリファレンスマニュアルを少しづつ調べておりましたら、
こんなコマンドを見つけてしまいました。
////////////////////////////////////////////////////////////
コマンド名
retarget
移動: 戻り値。 関連コマンド。 フラグ。 サンプル。
書式
retarget [-lowerBody string] [-lowerScale string] [-lowerScaleFactor double] [-upperBody string] [-upperScale string] [-upperScaleFactor double] [-scaleHandsFrom string] [-startFrame int] [-endFrame int] [-maintainOffset toggle] [-useExistingKeys toggle] [-restPoseFrame int] [select... ]
このコマンドは取り消しはできますが、照会および編集はできません。
このコマンドを使用して、キャラクタからモーションをテイクし、サイズの異なる別のキャラクタに再ターゲットを行います。
////////////////////////////////////////////////////////////
。。。実は実装してる???
なんで表立ってこのコマンドを使えるようにしてないのかと。
動かないのかなぁ。
当方、未検証です。
会社内部もぐちゃぐちゃなのかもとか勘ぐってしまう。どうなってんだよ~。
MELのリファレンスがいい加減な件
2006年10月11日 水曜日いざ、MELを組み始めようかとした時に、
マニュアルのMELリファレンスを見ながらコマンドを試しているのですが、
これがかなりいい加減なんです。
あての外れた戻り値だったり、
コマンド自体機能しなかったり、
このマニュアルでは逆引きもできないしと、
かなりの手探り状態で、少々根を上げています。
プロジェクトディレクトリを取得するコマンドって、
string $myScriptDir = `internalVar -userWorkspaceDir`;
のはずなんですが、
実際にはデフォルトのプロジェクトディレクトリを返します。
で、あれやこれや探ってみて
string $myScriptDir = `workspace -q -rootDirectory`;
これで何とか得られた訳ですが、
こんなやり方であってるんでしょうか?
得られたら文句言うなとか言われそうですが、
いちいちこれでは先が思いやられる。
おかしいぞ、MEL。マニュアルの記述がおかしすぎる!
廃止になったコマンドとかも全然整理できてないし。
海外サイトも調べてみましたけれど載ってないですねぇ。
しょうがないけど、
動いているファイルの中を探るしかないですねぇ。
ほしい機能を使っていそうな部分のMELを見て読み取ると。。。
なかなか手強いス。
clipEditor -q -sc がまともに動かない
2006年10月9日 月曜日クリップのアニメーションカーブの情報を取得しようとしていて躓いたのがコレ。
このコマンド、調べてみると、6.0辺りから使えなくなったみたいです。
代わりのMELはこちら
//クリップを選択
string $selClips[] = `ls -sl -type animClip`;
string $clip;
for( $clip in $selClips){
//ソースクリップ名を取得
string $source[] = stringArrayRemoveDuplicates(`listConnections -d false $clip`);
//ライブラリ名を取得
string $library[] = stringArrayRemoveDuplicates(`listConnections -type clipLibrary $source`);
//カーブを取得
string $animCurve[] = `ls -type animCurve (stringArrayRemoveDuplicates(listConnections($library)))`;
print ($clip + “\n”);
print $animCurve;
clear($source);
clear($library);
clear($animCurve);
}
参考
http://www.melscripting.com/forums/index.php?s=fb1f2cb5c40c0f96a2bf0c4a22244891&act=ST&f=3&t=362
http://lwplugdev.seesaa.net/article/15393434.html
ライブラリー化に際しての課題
2006年10月2日 月曜日折角モーション付けを行ってライブラリー化しているのだから、
このモーションをいろんなキャラクターに使いまわしたい。
そんな風に考えている人も多いのでは無いでしょうか?
しかし、いろいろ調べてみましたが、
今のところそれが実現できるのはMBくらいのようで、
Maya8でできるようになっているのかなぁ?と淡い期待を抱きながら、
今度(10/6)のセミナーを楽しみにしつつ、
なんとかできないものかとMELのコマンドと睨めっこしながらアルゴリズムを考えております。
ClipをTransferできるMELとか作ったら売れるかなぁ?
