よくプロジェクションマッピングで見かける、キューブ上に分割された壁の一部が飛び出してくる演出を再現しようと思い、Maya のエクスプレッションで、そんな感じのアニメーションを作ってみました。コントローラとなる locator が一定距離近づいた壁は、locator に反発するような位置に移動して、飛び出した感じになります。
ついでに、この Expression を MEL で自動で作れるようにしたので、載せておきます。動画は 1600 分割したキューブに対してこの MEL で Expression を生成したものになります。
global proc CreateRepulsiveAnimation(string $targets[])
{
string $locatorNames[] = `spaceLocator`;
string $locatorName = $locatorNames[0];
addAttr -k true -ln "distanceThreshold" -at double $locatorName;
setAttr ($locatorName+".distanceThreshold") 10.0;
int $index = 0;
for ($target in $targets)
{
print("Creating expression for "+$index + "\n");
string $expName = "RepulsiveExpression";
string $exp="";
xform -cp $target;
addAttr -k true -ln "originX" -at double $target;
addAttr -k true -ln "originY" -at double $target;
addAttr -k true -ln "originZ" -at double $target;
float $rotatePivot[] = `xform -q -ws -rp $target`;
setAttr ($target+".originX") $rotatePivot[0];
setAttr ($target+".originY") $rotatePivot[1];
setAttr ($target+".originZ") $rotatePivot[2];
$exp+="{float $targetPos[] = {"+$target+".originX, "+$target+".originY, "+$target+".originZ};\n\nfloat $dx = $targetPos[0] - "+$locatorName+".translateX;\nfloat $dy = $targetPos[1] - "+$locatorName+".translateY;\nfloat $dz = $targetPos[2] - "+$locatorName+".translateZ;\n\nfloat $dist = sqrt($dx * $dx + $dy * $dy + $dz * $dz);\nfloat $normMult = 1.0 / $dist;\nfloat $normDx = $dx * $normMult;\nfloat $normDy = $dy * $normMult;\nfloat $normDz = $dz * $normMult;\nif ($dist < "+$locatorName+".distanceThreshold)\n{\n float $t = ("+$locatorName+".distanceThreshold - $dist);\n "+$target+".translateX = $normDx * $t;\n "+$target+".translateY = $normDy * $t;\n "+$target+".translateZ = $normDz * $t;\n}\nelse\n{\n "+$target+".translateX = 0.0;\n "+$target+".translateY = 0.0;\n "+$target+".translateZ = 0.0;\n}}";
expression -s $exp -n $expName;
++$index;
}
}
使用方法
- キューブ上に分割したポリゴンモデルを用意(Freeze Transform しておく)
- ポリゴンモデルのトランスフォームノード選択
- 下記 MEL スクリプトを実行
string $selections[] = `ls -sl`;
CreateRepulsiveAnimation($selections);
この MEL を実行すると、locator が作られて、選択したトランスフォームノードに originX、orignY、originZ というアトリビュートが追加されます。ご注意ください。
壁が飛び出る距離の閾値は自動で作られた locator の distanceThreshold というアトリビュートで調整できます。