スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
先日友人に頼まれたので、
先程ぱぱっと簡単なツールを作ってみました。

友人曰く、画角を設定する時に特定のオブジェクトの大きさを
変えないまま設定できるようカメラが自動的に移動するようにしてほしい、との事。

幸い最近ずっと S3D 用のカメラリグを作成した事もあり
カメラ周りの計算式は色々と把握していたのですぐに作る事ができました。

カメラ関係のツールを作るにあたって何より重要な式がこれ。

1022_01.png

カメラからある点までの距離を dist、画角を aov とすると、
レンダリングされる範囲 width は width = 2 * dist * tand(aov / 2.0) で表されるのです。

少し複雑な式に見えるかも知れませんが全然そんな事はありません。

首を左に傾けて、左の側の三角形だけに注目してみてください。
底辺はもちろん dist で、カメラのある角の角度が aov / 2.0、
高さにあたる辺の長さは width / 2.0 です。
これでタンジェントの式にあてはめると以下のようになります。
aov は弧度法ではなく度数法で表すのが一般的なので tan ではなく tand とします。

1022_2.png

そして両辺に2をかけて width について解いただけですね。

この式、何かと役に立つと思います。
S3D 用カメラリグを作る時は何度もお世話になりました。

そして今回、友人に頼まれて作ったものも結局この式の
width を不変に、そして aov をパラメータにして dist の値を出せばいいだけの話なのです。

このようになりました。

string $selList[] = `ls -sl`;
if(`size $selList` != 2) error "Select a camera and a object before execution.";
string $shpList[] = `listRelatives -s $selList[0]`;
string $cam = $selList[0];
string $obj = $selList[1];
string $camShp = $shpList[0];
print `nodeType $camShp`;
if(`nodeType $camShp` != "camera")
error "Select a camera and a object before execution.";

vector $camPos = `xform -q -ws -t $cam`;
vector $objPos = `xform -q -ws -t $obj`;
vector $camLocal = `getAttr ($cam+".translate")`;
vector $camLocalO = $camPos - $camLocal;
vector $vect = $camPos - $objPos;
vector $drct = `unit $vect`;
float $distBe4 = `mag $vect`;
float $inch2mm = 0.03937;
float $apertX = `getAttr ($camShp+".horizontalFilmAperture")`;
float $focal = `getAttr ($camShp+".focalLength")`;
float $aovBe4 = 2 * atand(0.5 * $apertX/($focal * $inch2mm));

string $expName = "autoReverseZoom_exp";
string $expStr =
("float $distBe4 = "+$distBe4+";\n"+
"float $aovBe4 = "+$aovBe4+";\n"+
"vector $objPos = <<"+($objPos.x)+","+($objPos.y)+","+($objPos.z)+">>;\n"+
"vector $drct = <<"+($drct.x)+","+($drct.y)+","+($drct.z)+">>;\n"+
"vector $localO = <<"+($camLocalO.x)+","+($camLocalO.y)+","+($camLocalO.z)+">>;\n\n"+
"float $inch2mm = "+$inch2mm+";\n"+
"float $apertX = "+$camShp+".horizontalFilmAperture;\n"+
"float $focal = "+$camShp+".focalLength;\n"+
"float $aovAft = 2 * atand(0.5 * $apertX/($focal * $inch2mm));\n\n"+
"float $distAft = $distBe4 * tand($aovBe4/2.0) / tand($aovAft/2.0);\n"+
"vector $posAft = $objPos+$drct * $distAft;\n"+
$cam+".translateX = ($posAft.x)-($localO.x);\n"+
$cam+".translateY = ($posAft.y)-($localO.y);\n"+
$cam+".translateZ = ($posAft.z)-($localO.z);\n");

expression -s $expStr -n $expName;


あまり綺麗なコードではありませんがご勘弁を。。

カメラ、オブジェクトの順に選択してから実行し、
画角を適当にいじってみてください。
自分でも作り終わって実行してみてから気づいたのですが、
結局は逆ズームを自動的にできるようにしているだけですね。

ここで厄介だったのが、translate アトリビュートの値は
必ずしもワールド座標ではないという事です。
これは Maya ユーザからしたら当たり前の事ではあるのですが、
こういった Mel やエクスプレッションを書くときにはなかなか厄介です。

一応 translate アトリビュートと xform コマンドによるワールド座標の取得を
うまく組み合わせてどんな場合でもできるようにしたつもりなのですが。
もっと効率的な書き方が他にあるのでしょうか。。

次に機会があれば例の S3D 用カメラの中の一部もご紹介できればと思っています。
コメント
管理者のみ閲覧可能にする
Profile
HN らい

都内某社テクニカルディレクター
都内某専門学校講師
都内某企業講師
元中国某社S3Dスーパーバイザー
Contact
(ENGLISH OK. 可以用中文。)
Categories
Archives
RSS Link
QR Code