トップ | puarts.com
メモ  |  制作記  |  開発記  |  日常の記録  |  デジタルコンテンツ制作  |  ファイアーエムブレム  |  ゲーム  |  C/C++  |  C#  |  PC/ソフトウェア  |  Web 開発  |  スクリプト言語  |  その他プログラミング  |  
「MEL」に関連する記事一覧

0  1  2  3  4  5  

MEL スクリプトで menalray レンダリングを行う

2016/07/20
MEL 

どうしても MentalRay のバッチレンダリングがうまくいかない重い Maya シーンがあったので、MEL で無理やり1フレームずつずらして MentalRay のプレビューレンダーを行う方法で何とかレンダリングしました。無事レンダリングできて良かったです。

以下は 1 から 260 フレームまでを MentalRay でレンダリングする MEL スクリプトです。


for($frame = 1; $frame <= 260; ++$frame)
{
     currentTime -e $frame;
     Mayatomr -preview;
}

レンダリングした画像はデフォルトでは以下のディレクトリに書き出されます。

プロジェクトディレクトリ/images/tmp

このアプローチには昔も助けられたことがありました。知っているといざという時に役立ちます。スクリプトが柔軟に使えるソフトって本当に便利だと痛感します。

Maya キーフレームアニメーションを名前引きでコピーする

2016/07/16
MEL 

フリースクリプトを探せば普通にありそうですが、あるノードとそれ以下の階層のノードのキーを、同じ階層構造を持つ別のノードに名前引きでキーフレームをコピーする MEL スクリプトを作成したので貼っておきます。

同じ階層のコントローラを持つリグ同士でアニメーションをコピーするときに一発でコピーできます。

おじいちゃんとおばあちゃんのモデルを作ったので、アニメーションをリグ間で簡単にコピーできるように作成しました。


global proc CopyKeysByName(string $copySource, string $copyDestination)
{
    int $keyCount = `keyframe -q -keyframeCount $copySource`;
    if ($keyCount > 0)
    {
        copyKey -time ":" -float ":" {$copySource};
        pasteKey -option merge {$copyDestination};
    }
    
    string $sourceChildren[] = `listRelatives -children $copySource`;
    string $destChildren[] = `listRelatives -children $copyDestination`;
    for ($sourceChild in $sourceChildren)
    {
        string $splited[];
        int $numTokens = `tokenize $sourceChild ":" $splited`;
        string $sourceName = $splited[$numTokens - 1];
        for ($destChild in $destChildren)
        {
            int $numTokens = `tokenize $destChild ":" $splited`;
            string $destName = $splited[$numTokens - 1];
            if ($sourceName == $destName)
            {
                CopyKeysByName($sourceChild, $destChild);
                break;
            }
        }
    }
}

使用例


string $selections[] = `ls -sl`;
string $copySource = $selections[0];
string $copyDestination = $selections[1];
CopyKeysByName($copySource, $copyDestination);

MEL ミラーボールっぽく球状にスポットライトを配置する

2016/07/14
MEL 

Maya でミラーボールっぽいライトの演出をするため、画像のように球の中心から外に向かうスポットライトを複数作成する MEL スクリプトを作成しましたので貼っておきます。配置アルゴリズムはかなりいい加減です。


global proc createMirrorBallLight(int $lightCountX, float $spotLightConeAngle)
{
    float $increAngleX = 180.0 / ($lightCountX + 1);
    float $pi = 3.14159265359;
    for ($x = 0; $x < $lightCountX; ++$x)
    {
        float $angleX = ($x + 1) * $increAngleX - 90;
        int $lightCountY = $lightCountX * (cos($angleX * $pi / 180.0) * 0.5 + 0.5) + 1;
        float $increAngleY = 360.0 / $lightCountY;
        for ($y = 0; $y < $lightCountY; ++$y)
        {
            string $lightShapeName = `spotLight -coneAngle $spotLightConeAngle -penumbra $spotLightConeAngle`;
            string $tmp[] = `listRelatives -p $lightShapeName`;
            string $lightTransformName = $tmp[0];
            float $rotateAngleX = $angleX;
            float $rotateAngleY = $y * $increAngleY;
            float $rotateAngleZ = 0.0;
            rotate $rotateAngleX $rotateAngleY $rotateAngleZ $lightTransformName;
            rename $lightTransformName mirrorBallSpotLight;
        }
    }
    group -n mirrorBallSpotLightGroup "mirrorBallSpotLight*";
}

使用例


createMirrorBallLight(10, 10.0);

MEL ノードのアトリビュートを全てコピーする

2016/07/08
MEL 

Maya でノードコネクションはそのままにしておいて、コネクションのないアトリビュートは別のノードのアトリビュート値を全部コピーしたい、というときがよくあったので、特定のノードのアトリビュートを同じ種類の別のノードにすべてコピーする MEL スクリプトを作っておきました。大したものではないですが、貼っておきます。


global proc copyAllAttributes(string $sourceNode, string $destNode)
{
    if (`nodeType $sourceNode` != `nodeType $destNode`)
    {
        error("Node type mismatch between " + $sourceNode + " and " + $destNode + ".\n");
        return;
    }
    
    string $attrs[] = `listAttr -scalar -multi -keyable -visible -unlocked -connectable $sourceNode`;
    for ($attr in $attrs)
    {
        string $destAttr = $destNode + "." + $attr;
        string $connections[] = `listConnections $destAttr`;
        if (size($connections) > 0)
        {
            continue;
        }
        print("Copying  " + $destAttr + "\n");
        setAttr $destAttr `getAttr ($sourceNode + "." + $attr)`;
    }
}

使用例


copyAllAttributes("nParticleShape1", "nParticleShape2");

Maya 粉砕モデル作成ツール改良中

2016/06/25 10:08

昔作った粉砕モデル作成ツールを改良中です。 以下を改善しました。

もし需要があれば、整理して公開するかもですが、まぁ、市販のツール使ったほうが断然効率的です。すごく処理時間かかるし、メモリ食います。

MEL FF のボスが倒されて消えるときみたいなエフェクトを作る

2016/06/12 21:46
MEL 

昨日作った指数関数的に上昇するアニメーションのエクスプレッションを生成する MEL スクリプトを応用して、ファイナルファンタジーのボスを倒した時みたいに上から順番にポリゴンが上昇してゆくアニメーションを作成する MEL スクリプトを作成しましたので載せておきます。

やっていることはただ単に上にあるトランスフォームノードから順番に、上昇するアニメーション用のエクスプレッションを作成しているだけです。


global proc CreateExpresionForRiseAnimation(
    string $targets[],
    float $exponential_start_x,
    float $speed, float $speed_rand_range,
    float $time_offset, float $time_offset_rand_range)
{
    string $expName = "RiseAnim";
    string $exp = "float $start_frame="+$exponential_start_x+";\n";
    for ($target in $targets)
    {
        float $actual_speed = $speed + rand(-$speed_rand_range / 2.0, $speed_rand_range / 2.0);
        float $actual_time_offset = $time_offset + rand(0.0, $time_offset_rand_range);
        $exp += "{\n    float $speed = "+$actual_speed+";\n    float $frame_delay = "+$actual_time_offset+";\n    float $frame = frame + $start_frame - $frame_delay;\n    if ($frame < $start_frame)\n    {\n        $frame = $start_frame;\n    }\n    "+$target+".translateY = exp($frame * $speed) - exp($start_frame * $speed);\n}";
    }
    expression -s $exp -n $expName;
}

global proc MovePivotToBottomCenter(string $target)
{
    float $bb[] = `polyEvaluate -boundingBox $target`;
    float $pivot_x = ($bb[0] + $bb[1]) * 0.5;
    float $pivot_y = $bb[2];
    float $pivot_z = ($bb[4] + $bb[5]) * 0.5;
    move -a $pivot_x  $pivot_y $pivot_z ($target+".scalePivot") ($target+".rotatePivot");
}

global proc CreateExpressionForRisingFromTop(
    string $targets[],
    float $start_frame,
    float $delay_frame_rand_range,
    float $merge_expression_tolerance_y)
{
    for ($target in $targets)
    {
        MovePivotToBottomCenter($target);
    }
    
    while(size($targets) != 0)
    {
        print("Creating Expression..\n");
        float $max_y = GetMaximumTranslateY($targets);
        print("Translate Y for Creating Expression: " + $max_y + "\n");
        string $current_targets[];
        string $rest_of_targets[];
        clear $current_targets;
        clear $rest_of_targets;
        int $target_index = 0;
        int $rest_index = 0;
        for ($obj in $targets)
        {
            vector $pos = `xform -q -ws -rp $obj`;
            float $diff = abs($pos.y - $max_y);
            if ($diff < $merge_expression_tolerance_y)
            {
                $current_targets[$target_index] = $obj;
                ++$target_index;
            }
            else
            {
                $rest_of_targets[$rest_index] = $obj;
                ++$rest_index;
            }
        }
        CreateExpresionForRiseAnimation(
            $current_targets,
            -30.0,
            1.0 / 30.0, 1.0 / 30.0,
            $start_frame, $delay_frame_rand_range);
        $targets = $rest_of_targets;
        $start_frame += $delay_frame_rand_range;
    }
    
    print("Completed!\n");
}

使い方

  1. 適用したいポリゴンモデルをばらばらにする
  2. ばらばらにしたポリゴンのトランスフォームノードに対してこのスクリプトを実行

使用例


string $targets[]=`ls -sl -type transform`;
float $start_frame = `currentTime -q`;
float $delay_frame_rand_range = 30;
float $tolerance = 0.1;
CreateExpressionForRisingFromTop(
    $targets,
    $start_frame,
    $delay_frame_rand_range,
    $tolerance);

MEL モデルの底面中央にピボットを設定する

2016/06/12 10:53
MEL 

細切れにした大量のオブジェクトに対してピボットを分断した面に移動させる必要が出てきたので、ポリゴンモデルの底面にピボットを移動させるスクリプトを作ったので載せておきます。


global proc MovePivotToBottomCenter(string $target)
{
    float $bb[] = `polyEvaluate -boundingBox $target`;
    float $pivot_x = ($bb[0] + $bb[1]) * 0.5;
    float $pivot_y = $bb[2];
    float $pivot_z = ($bb[4] + $bb[5]) * 0.5;
    move -a $pivot_x  $pivot_y $pivot_z ($target+".scalePivot") ($target+".rotatePivot");
}

使用例


string $selected[]=`ls -sl -type transform`;
for ($target in $selected)
{
    MovePivotToBottomCenter($target);
}

Center Pivot(中央にピボット ポイントを移動)した後に、ポリゴンモデルの底面にピボットを合わせたくて手動で移動させることが今までもよくあったので、もっと前に作っておけばよかったです。

MEL 指数関数的に上昇するアニメーションを自動生成する

2016/06/11 20:28
MEL 

大したものではないですが、細切れにした大量のオブジェクトを指数関数的に上昇させるアニメーションを作るために、指数関数の Y 座標アニメーションのエクスプレッションを生成する MEL スクリプトを作りましたので載せておきます。


global proc CreateExpresionForRiseAnimation(
    string $targets[],
    float $exponential_start_x,
    float $speed, float $speed_rand_range,
    float $time_offset, float $time_offset_rand_range)
{
    string $expName = "RiseAnim";
    string $exp = "float $start_frame="+$exponential_start_x+";\n";
    for ($target in $targets)
    {
        float $actual_speed = $speed + rand(-$speed_rand_range / 2.0, $speed_rand_range / 2.0);
        float $actual_time_offset = $time_offset + rand(0.0, $time_offset_rand_range);
        $exp += "{\n    float $speed = "+$actual_speed+";\n    float $frame_delay = "+$actual_time_offset+";\n    float $frame = frame + $start_frame - $frame_delay;\n    if ($frame < $start_frame)\n    {\n        $frame = $start_frame;\n    }\n    "+$target+".translateY = exp($frame * $speed) - exp($start_frame * $speed);\n}";
    }
    expression -s $exp -n $expName;
}

使用例


string $targets[]=`ls -sl -type transform`;
CreateExpresionForRiseAnimation(
    $targets,
    -30.0,
    1.0 / 30.0, 1.0 / 30.0,
    0.0, 60.0);

MEL ポリゴン穴埋めで新規追加されたポリゴンに別のマテリアルを割り当てる

2016/06/11 11:10
MEL 

polyCloseBorder でポリゴンモデルの穴を埋めて、穴埋めのために新しく追加されたポリゴンには lambert1 を割り当てる MEL スクリプトです。

画像のように、ポリゴンモデルをバラバラにするモデル分割スクリプトなどで割れ目に別のマテリアルを割り当てたい場合に応用できます。


global proc FillHoleAndAssignInitialMaterial(string $target_name)
{
    int $prev_face_counts[] = `polyEvaluate -face $target_name`;
    polyCloseBorder -ch false $target_name ;
    int $face_counts[] = `polyEvaluate -face $target_name`;
    int $diff_count = $face_counts[0] - $prev_face_counts[0];
    if ($diff_count == 0)
    {
        return;
    }
    
    int $added_first_index = $prev_face_counts[0];
    int $last_index = $face_counts[0] - 1;
    sets -e -forceElement initialShadingGroup ($target_name+".f["+$added_first_index+":"+$last_index+"]");
}

使用例


string $selected[] = `ls -sl`;
FillHoleAndAssignInitialMaterial($selected[0]);

MEL 最小二乗法を用いた頂点群の1次関数直線への整列スクリプトの改良

2016/05/29
MEL 

昔作った 最小二乗法で頂点等を整列する MEL スクリプト が使いづらかったので改良しました。

具体的には、以前は引数で整頓する軸を指定しなければいけなかったんですが、軸を自動で選ぶように改良しました。

ソースコード


global proc int[] findAxisesSortedByDispersion(string $targets[])
{
    float $sums[3] = {0.0, 0.0, 0.0};
    float $n = size($targets);
    for($target in $targets)
    {
        float $pos[] = `xform -q -ws -t $target`;
        $sums[0] += $pos[0];
        $sums[1] += $pos[1];
        $sums[2] += $pos[2];
    }
    
    float $averages[3] = {$sums[0] / $n, $sums[1] / $n, $sums[2] / $n};
    float $dispersions[3] = {0.0, 0.0, 0.0};
    for($target in $targets)
    {
        float $pos[] = `xform -q -ws -t $target`;
        $dispersions[0] += abs($pos[0] - $averages[0]);
        $dispersions[1] += abs($pos[1] - $averages[1]);
        $dispersions[2] += abs($pos[2] - $averages[2]);
    }
    
    float $sorted_dispersions[] = `sort $dispersions`;
    int $max_axises[3] = {0, 0, 0};
    int $axis = 0;
    for ($axis = 0; $axis < 3; ++$axis)
    {
        if ($sorted_dispersions[2] == $dispersions[$axis])
        {
            $max_axises[0] = $axis;
        }
        if ($sorted_dispersions[1] == $dispersions[$axis])
        {
            $max_axises[1] = $axis;
        }
        if ($sorted_dispersions[0] == $dispersions[$axis])
        {
            $max_axises[2] = $axis;
        }
    }
    return $max_axises;
}

global proc alignToMinimumDispersionLine(string $targets[], int $axis_x, int $axis_y)
{
    float $n = size($targets);
    float $a, $b;
    float $y, $pos[];
    float $sum_x, $sum_y, $sum_xy, $sum_xx;

    $sum_x = $sum_y = $sum_xy = $sum_xx = 0.0;
    for($target in $targets)
    {
        $pos = `xform -q -ws -t $target`;
        $sum_x += $pos[$axis_x];
        $sum_y += $pos[$axis_y];
        $sum_xy += $pos[$axis_x]*$pos[$axis_y];
        $sum_xx += $pos[$axis_x]*$pos[$axis_x];
    }

    $slope = ($n*$sum_xy-$sum_x*$sum_y) / ($n*$sum_xx - $sum_x*$sum_x);
    $offset = ($sum_xx*$sum_y-$sum_xy*$sum_x) / ($n*$sum_xx - $sum_x*$sum_x);

    for($target in $targets)
    {
        $pos = `xform -q -ws -t $target`;
        $pos[$axis_y] = $slope * $pos[$axis_x] + $offset;
        xform -ws -t $pos[0] $pos[1] $pos[2] $target;
    }
}

global proc alignSelectedToMinimumDispersionLine2d()
{
    string $sels[] = `ls -sl`;
    string $targets[] = `filterExpand -sm 31 $sels`;
    int $target_axises[] = findAxisesSortedByDispersion($targets);
    alignToMinimumDispersionLine($targets, $target_axises[0], $target_axises[2]);
}

global proc alignSelectedToMinimumDispersionLine1d()
{
    string $sels[] = `ls -sl`;
    string $targets[] = `filterExpand -sm 31 $sels`;
    int $target_axises[] = findAxisesSortedByDispersion($targets);
    alignToMinimumDispersionLine($targets, $target_axises[0], $target_axises[1]);
}

使用例


// 2次元平面に整列
alignSelectedToMinimumDispersionLine2d();

// 1本の線に整列
alignSelectedToMinimumDispersionLine1d();

0  1  2  3  4  5  

にほんブログ村 ゲームブログ ファイアーエムブレムへ にほんブログ村 デザインブログ コンピュータグラフィックスへ

0.0324 sec

Copyright(C)2006-2018 wsp All Rights Reserved