particleShapeのアトリビュートとか結構決めうちだったような。。。
修正するついでにPython化しようと思ってたけど、めんどくさくて放置。
global proc bakeInstance()
{
string $instanceObj[];
string $sel[];
string $tmpStr;
string $tmpStrArray[];
string $particleShape[];
string $copiedObj[];
string $ppName;
string $rotAttr;
string $scaleAttr;
string $idAttr;
int $particleCnt;
int $startFrame;
int $curFrame;
int $endFrame;
int $cnt;
int $instanceCnt;
int $tmpInt;
int $isCopy[];
float $particlePos[];
float $particleRot[];
float $particleScale[];
float $objScale[];
float $instanceId[];
float $amount;
float $curStep;
float $stepValue;
float $status;
// instancerを選択し
$sel = `ls -sl`;
// instancerが選択されていなかったらエラーを返す
if($sel[0] == "" || `nodeType $sel[0]` != "instancer")
{
error "select instancer";
}
// particleShapeも取得
$particleShape = `listConnections ($sel[0] + ".inputPoints")`;
// lifespanがLive foreverではなかったらエラーを返す
if(`getAttr ($particleShape[0] + ".lifespanMode")` != 0)
{
error "only lifespanMode \"Live forever\"";
}
// rotationのアトリビュート名
$rotAttr = `particleInstancer -name $sel[0] -q -rotation $particleShape`;
$scaleAttr = `particleInstancer -name $sel[0] -q -scale $particleShape`;
$idAttr = `particleInstancer -name $sel[0] -q -objectIndex $particleShape`;
// Bakeするframeのレンジ
// timerSliderから取得
$startFrame = `playbackOptions -q -min`;
$curFrame = `playbackOptions -q -min`;
$endFrame = `playbackOptions -q -max`;
// instanceされているオブジェクト名を取得(配列)
$instanceObj = `listConnections ($sel[0] + ".inputHierarchy")`;
// instacneされているオブジェクトの数を取得
$instanceCnt = `getAttr ($sel[0] + ".hierarchyCount")`;
// progressWindowの準備
$amount = 0;
$stepValue = 100.0 / ($endFrame - $startFrame);
$status = 0;
$curStep = 0;
progressWindow
-title "instanceBake"
-progress $amount
-minValue $startFrame
-maxValue $endFrame
-status ("bake:" + $status + "%")
-isInterruptable true;
// 処理するframeの間
while(true)
{
// ESCが押されるか、最後まで処理が進んだら終了
if(`progressWindow -query -isCancelled`)
{
select $copiedObj;
group -n ($sel[0] + "BakeObj");
// parent -w;
progressWindow -endProgress;
error "instanceBake cancelled";
}
if($curFrame > $endFrame) break;
// frameを進めて・・・
currentTime $curFrame;
// particle数を取得
$particleCnt = `getAttr ($particleShape[0] + ".count")`;
// そのframeで存在するparticleの数の分処理
for($cnt = 0; $cnt < $particleCnt; $cnt++)
{
// perParcile
$ppName = $particleShape[0] + ".pt[" + $cnt + "]";
// そのinstanceオブジェクトはコピー済み?
if(!($isCopy[$cnt]))
{
// 未コピーだったらコピーし
// particleIdとオブジェクト名を配列に格納
$instanceId = `getParticleAttr -at $idAttr $ppName`;
$tmpInt = $instanceId[0];
$tmpStrArray = `duplicate -rr $instanceObj[ $tmpInt ]`;
$copiedObj[$cnt] = $tmpStrArray[0];
// 発生したタイミングでvisibilityにキーを打つ
setKeyframe -at "visibility" -s 0 -v 0 -t ($curFrame - 1) $copiedObj[$cnt];
setKeyframe -at "visibility" -s 0 -v 1 -t ($curFrame) $copiedObj[$cnt];
// スケールを取得
if($scaleAttr !="")
{
$particleScale = `getParticleAttr - at $scaleAttr $ppName`;
$tmpStr = $copiedObj[$cnt] + ".scale";
$objScale = `getAttr $tmpStr`;
$particleScale[0] *= $objScale[0];
$particleScale[1] *= $objScale[1];
$particleScale[2] *= $objScale[2];
setAttr $tmpStr $particleScale[0] $particleScale[1] $particleScale[2];
setKeyframe $tmpStr;
}
// コピー済みフラグを立てる
$isCopy[$cnt] = true;
}
// particleのポジションを取得
$particlePos = `getParticleAttr -at worldPosition $ppName`;
$tmpStr = $copiedObj[$cnt] + ".translate";
setAttr $tmpStr $particlePos[0] $particlePos[1] $particlePos[2];
setKeyframe $tmpStr;
// 同じく回転を取得
if($rotAttr != "")
{
$particleRot = `getParticleAttr -at $rotAttr $ppName`;
$tmpStr = $copiedObj[$cnt] + ".rotate";
setAttr $tmpStr $particleRot[0] $particleRot[1] $particleRot[2];
setKeyframe $tmpStr;
}
}
$curFrame++;
// progressWindowの処理
$amount = $curFrame;
$curStep += $stepValue;
$status = `floor($curStep)`;
progressWindow -edit
-progress $curFrame
-status("bake:" + $status + "%");
}
// Bakeオブジェクトを、グループに分けて終了
select $copiedObj;
group -n ($sel[0] + "BakeObj");
// parent -w;
progressWindow -endProgress;
print("// instanceBake finished");
}
0 件のコメント:
コメントを投稿