[MEL]mirror pose工具

       今天给动画组写一个mirror pose工具。目前动画在进行layout制作,为了加快摆pose速度,快速mirrorPose还是很重要的。

思路:

1.mirror类别:单向/双向。单向是只从A—>B或者B—>A,双向为A<—>B互换。

2.mirrorPose需要mirror的部分为:头,手,身体,脚。分别需要mirror的属性为(暂时没有拉伸):

         头:rx,ry,rz

        身体:rx,ry,rz。 

        手/脚:(FK)rx,ry,rz;(IK)tx,ty,tz,rx,ry,rz。

3.互换过程归纳:

        头:只需要将ry=>-ry,rz=>-rz

        身体:只需要将ry=>-ry,rz=>-rz

        手:(FK)rx=>rx,ry=>ry,rz=>rz ;  (IK)tx=-tx,ty=-ty,tz=-tz

        脚:(FK)rx=>rx,ry=>ry,rz=>rz ;  (IK)tx=-tx,ty=ty,tz=tz

       (测试了半天才发现手和脚的绑定不一致,坑爹!)

4.核心算法:

       最麻烦的是手和脚的mirror。A、B之间属性互换正常思路为:A=>C,B=>A,C=>B。但是这样执行效率较低,所以决定再加一个D。

       需要写的函数为:

  • 从A读取(rx,ry,rz)数据存入内存(C)。
  • 从B读取(rx,ry,rz)数据存入内存(D)。
  • 从A读取(tx,ty,tz)数据存入内存(C')。
  • 从B读取(tx,ty,tz)数据存入内存(D')。
  • 将C给B
  • 将D给A
  • 将C'给B
  • 将D'给A

5.UI

先将UI写出来:


代码为:

global proc phoenixMirrorPoseUI()
{
	if (`window -q -ex phoenixMirrorPoseWindow`) deleteUI phoenixMirrorPoseWindow;
	
	//Main Window
	window -title "DH_phonenix_mirrorPoseTool"  -maximizeButton false  -sizeable false -w 340 -h 160 phoenixMirrorPoseWindow;
	
	//Main Column Layout
		columnLayout -cw 500 -adjustableColumn 1;
		
			separator -w 400 -h 15;
			
			radioButtonGrp 	-numberOfRadioButtons 3
							-label "镜像类别:" 
							-labelArray3 "A-->B" "B-->A" "A<-->B"
							-select 1
							-columnWidth4  50 80 80 80
							-columnAlign4 "left" "left" "left" "left" 
							customChannelRadioButtonGrp;

		    separator -w 400 -h 15;	
			checkBoxGrp	-numberOfCheckBoxes 4
						-label "镜像部分:"
						-labelArray4 "头" "手" "身体" "脚"
						-valueArray4 1 1 1 1 
						-columnWidth5  55 80 80 80 80
						-columnAlign4 "left" "left" "left" "left"  
						flipTranslateCheckBoxGrp;
			separator -w 400 -h 15;
			columnLayout  -columnAlign "left";
		        text "       ";
		        rowLayout -nc 2;
		        text "                                     ";
				button  -align "right"
				       -w 150
				       -backgroundColor 0.1 0.5 0.1
				       -highlightColor 1 1 1  
				       -label "Apply" 
				       -c ("apply");
				
	showWindow phoenixMirrorPoseWindow;
}
phoenixMirrorPoseUI

6.函数:

看起来很多,但是实际上各个函数之间只有名称的差别。

  • 从A读取参数(rx,ry,rz):
global proc QA_attr_r(){
string $selCon[]=`ls -sl`;
global vector $tempValueR_C[]; clear  $tempValueR_C;
int $i;
for($eachCrv in $selCon) {
    float $buffer[] = `getAttr ($eachCrv+".r")`;
    $tempValueR_C[$i] = <<$buffer[0],$buffer[1],$buffer[2]>>;
    $i++;
    }
print   $tempValueR_C;
};

  • 从B读取参数(rx,ry,rz):
global proc QB_attr_r(){
string $selCon[]=`ls -sl`;
global vector $tempValueR_D[]; clear  $tempValueR_D;
int $i;
for($eachCrv in $selCon) {
    float $buffer[] = `getAttr ($eachCrv+".r")`;
    $tempValueR_D[$i] = <<$buffer[0],$buffer[1],$buffer[2]>>;
    $i++;
    }
print   $tempValueR_D;
};
  • 从A读取参数(tx,ty,tz):
global proc QA_attr_t(){
string $selCon[]=`ls -sl`;
global vector $tempValueT_C[]; clear  $tempValueT_C;
int $i;
for($eachCrv in $selCon) {
    float $buffer[] = `getAttr ($eachCrv+".t")`;
    $tempValueT_C[$i] = <<$buffer[0],$buffer[1],$buffer[2]>>;
    $i++;
    }
print   $tempValueT_C;
};
  • 从B读取参数(tx,ty,tz):
global proc QB_attr_t(){
string $selCon[]=`ls -sl`;
global vector $tempValueT_D[]; clear  $tempValueT_D;
int $i;
for($eachCrv in $selCon) {
    float $buffer[] = `getAttr ($eachCrv+".t")`;
    $tempValueT_D[$i] = <<$buffer[0],$buffer[1],$buffer[2]>>;
    $i++;
    }
print   $tempValueT_D;
};
  • 将C给B
global proc RC_2_B(){
string $selCon[]=`ls -sl`;
global vector $tempValueR_C[]; 
int $i;
for($eachValue in $tempValueR_C) {
    setAttr ($selCon[$i]+".r") ($eachValue.x) ($eachValue.y) ($eachValue.z) ;
    $i++;
    }

}
  • 将D给A
global proc RD_2_A(){
string $selCon[]=`ls -sl`;
global vector $tempValueR_D[]; 
int $i;
for($eachValue in $tempValueR_D) {
    setAttr ($selCon[$i]+".r") ($eachValue.x) ($eachValue.y) ($eachValue.z) ;
    $i++;
    }

}


  • 将C'给B
global proc TC_2_B(){
string $selCon[]=`ls -sl`;
global vector $tempValueT_C[]; 
int $i;
for($eachValue in $tempValueT_C) {
    setAttr ($selCon[$i]+".t") ($eachValue.x) ($eachValue.y) ($eachValue.z) ;
    $i++;
    }

}

  • 将D'给A
global proc TD_2_A(){
string $selCon[]=`ls -sl`;
global vector $tempValueT_D[]; 
int $i;
for($eachValue in $tempValueT_D) {
    setAttr ($selCon[$i]+".t") ($eachValue.x) ($eachValue.y) ($eachValue.z) ;
    $i++;
    }

}

7.各个部分的镜像函数
首先确定所选择的角色名字:
global proc string GetSelNa(string $selCon){
string $selA[]; clear $selA;
tokenize   $selCon ":"  $selA;
if($selA[0] == "")
print "please select a subject with a \":\"";
return  $selA[0];   
}
mirrorR:
global proc mirror_R(){
string $selCon[]=`ls -sl`;
for($eachCon in $selCon) {
	float $tempR[] = `getAttr ($eachCon+".r")`;
    setAttr ($eachCon+".r") $tempR[0] (-$tempR[1]) (-$tempR[2]);
    }

}

mirrorT:

global proc mirror_T(){
string $selCon[]=`ls -sl`;
for($eachCon in $selCon) {
	float $tempT[] = `getAttr ($eachCon+".t")`;
    setAttr ($eachCon+".t") (-$tempR[0]) (-$tempR[1]) (-$tempR[2]);
    }
}
头:
global proc phoenix_headMirror(){
	
	string $selA[] = `ls -sl`;
	string $charName = `GetSelNa $selA[0]`;
	string $headName = ($charName+":"+"Head_Ctrl");
	string $neckName = ($charName+":"+"NeckFK_Ctrl");
	select -r $headName $neckName;
	
	mirror_R;
}


身体:

global proc phoenix_bodyMirror(){
	
	string $selA[] = `ls -sl`;
	string $charName = `GetSelNa $selA[0]`;
	string $AuxilName = ($charName+":"+"ChestAuxil_Ctrl");
	string $chestName = ($charName+":"+"ChestFK_Ctrl");
	string $splineName = ($charName+":"+"SplineFK_Ctrl");
	string $rootIKName = ($charName+":"+"RootIK_Ctrl");
	string $rootName = ($charName+":"+"Root_Ctrl");
	select -r $AuxilName $chestName $splineName $rootIKName $rootName;	
    mirror_R;	
}
手:
global proc phoenix_bodyMirror(){
	
	string $selA[] = `ls -sl`;
	string $charName = `GetSelNa $selA[0]`;
	string $AuxilName = ($charName+":"+"ChestAuxil_Ctrl");
	string $chestName = ($charName+":"+"ChestFK_Ctrl");
	string $splineName = ($charName+":"+"SplineFK_Ctrl");
	string $rootIKName = ($charName+":"+"RootIK_Ctrl");
	string $rootName = ($charName+":"+"Root_Ctrl");
	select -r $AuxilName $chestName $splineName $rootIKName $rootName;	
    mirror_R;	
}

global proc phoenix_handMirror(){
	
    string $selA[] = `ls -sl`;
	string $charName = `GetSelNa $selA[0]`;
	string $IKFKSWConNameLft = $charName+":"+"L_WristSwitch_Ctrl";
	string $IKFKSWConNameRgt = $charName+":"+"R_WristSwitch_Ctrl";
	
    float $IKOrFK_temp1 = `getAttr $IKFKSWConNameLft+".ikfkBlend"`;
    float $IKOrFK_temp2 = `getAttr $IKFKSWConNameRgt+".ikfkBlend"`;
    if($IKOrFK_temp1!=$IKOrFK_temp2)
    {error "建议先使用IKFK无缝切换工具切换到同一状态再使用本工具!";}
    else if($IKOrFK_temp1==0)
    {
    	int $mirrorStyle=`radioButtonGrp -q -select customChannelRadioButtonGrp`;
    	if($mirrorStyle==1){
    		select -r 
    		($charName+":"+"L_Scapula_Ctrl")
    		($charName+":"+"L_ShoulderFK_Ctrl")
    		($charName+":"+"L_ElbowFK_Ctrl")
    		($charName+":"+"L_WristFK_Ctrl")
    		;
    		QA_attr_r;
    		select -r
    		($charName+":"+"R_Scapula_Ctrl")
    		($charName+":"+"R_ShoulderFK_Ctrl")
    		($charName+":"+"R_ElbowFK_Ctrl")
    		($charName+":"+"R_WristFK_Ctrl")
    		;
    		RC_2_B;
    		} 
    	else if($mirrorStyle==2){
    		select -r 
    		($charName+":"+"R_Scapula_Ctrl")
    		($charName+":"+"R_ShoulderFK_Ctrl")
    		($charName+":"+"R_ElbowFK_Ctrl")
    		($charName+":"+"R_WristFK_Ctrl")
    		;
    		QA_attr_r;
    		select -r
    		($charName+":"+"L_Scapula_Ctrl")
    		($charName+":"+"L_ShoulderFK_Ctrl")
    		($charName+":"+"L_ElbowFK_Ctrl")
    		($charName+":"+"L_WristFK_Ctrl")
    		;
    		RC_2_B;
    		}
    	else{
    	    select -r 
    		($charName+":"+"L_Scapula_Ctrl")
    		($charName+":"+"L_ShoulderFK_Ctrl")
    		($charName+":"+"L_ElbowFK_Ctrl")
    		($charName+":"+"L_WristFK_Ctrl")
    		;
    		QA_attr_r;
    		
    	    select -r 
    		($charName+":"+"R_Scapula_Ctrl")
    		($charName+":"+"R_ShoulderFK_Ctrl")
    		($charName+":"+"R_ElbowFK_Ctrl")
    		($charName+":"+"R_WristFK_Ctrl")
    		;
    		QB_attr_r;
    		RC_2_B;
    		
    		select -r 
    		($charName+":"+"L_Scapula_Ctrl")
    		($charName+":"+"L_ShoulderFK_Ctrl")
    		($charName+":"+"L_ElbowFK_Ctrl")
    		($charName+":"+"L_WristFK_Ctrl")
    		;
    		RD_2_A;}
    	}
      else {
      	int $mirrorStyle=`radioButtonGrp -q -select customChannelRadioButtonGrp`;
    	if($mirrorStyle==1){
    		
    		select -r ($charName+":"+"L_WristIKPole_Ctrl")
    		          ($charName+":"+"L_WristIK_Ctrl");
    		QA_attr_t;
    		select -r ($charName+":"+"L_WristIK_Ctrl");
    		QA_attr_r;
    		select -r ($charName+":"+"R_WristIKPole_Ctrl")
    		          ($charName+":"+"R_WristIK_Ctrl");
    		TC_2_B;
    		mirror_T;
    		select -r ($charName+":"+"R_WristIK_Ctrl");
    		RC_2_B;
    		}
      	
      	if($mirrorStyle==2){
      		select -r ($charName+":"+"R_WristIKPole_Ctrl")
    		          ($charName+":"+"R_WristIK_Ctrl");
    		QA_attr_t;
    		select -r ($charName+":"+"R_WristIK_Ctrl");
    		QA_attr_r;
    		select -r ($charName+":"+"L_WristIKPole_Ctrl")
    		          ($charName+":"+"L_WristIK_Ctrl");
    		TC_2_B;
    		mirror_T;
    		select -r ($charName+":"+"L_WristIK_Ctrl");
    		RC_2_B;
    		
    		}
      	else{
      		select -r ($charName+":"+"L_WristIKPole_Ctrl")
    		          ($charName+":"+"L_WristIK_Ctrl");
    		QA_attr_t;
      		select -r ($charName+":"+"L_WristIK_Ctrl");
      		QA_attr_r;
      		
      		
      		select -r ($charName+":"+"R_WristIKPole_Ctrl")
    		          ($charName+":"+"R_WristIK_Ctrl");
    		QB_attr_t;
    		TC_2_B;
    		mirror_T;
      		select -r ($charName+":"+"R_WristIK_Ctrl");
      		QB_attr_r;
      		RC_2_B;
      		
      		select -r ($charName+":"+"L_WristIKPole_Ctrl")
    		          ($charName+":"+"L_WristIK_Ctrl");
    		TD_2_A;
    		mirror_T;
      		select -r ($charName+":"+"L_WristIK_Ctrl");
      		RD_2_A;
      		}
      	
      	}
}
脚:
global proc phoenix_footMirror(){
	
    string $selA[] = `ls -sl`;
	string $charName = `GetSelNa $selA[0]`;
	string $IKFKSWConNameLft = $charName+":"+"L_AnkleSwitch_Ctrl";
	string $IKFKSWConNameRgt = $charName+":"+"R_AnkleSwitch_Ctrl";
	
    float $IKOrFK_temp1 = `getAttr ($IKFKSWConNameLft+".ikfkBlend")`;
    float $IKOrFK_temp2 = `getAttr ($IKFKSWConNameRgt+".ikfkBlend")`;
    if($IKOrFK_temp1!=$IKOrFK_temp2)
    {error "建议先使用IKFK无缝切换工具切换到同一状态再使用本工具!";}
    else if($IKOrFK_temp1==0)
    {
    	int $mirrorStyle=`radioButtonGrp -q -select customChannelRadioButtonGrp`;
    	if($mirrorStyle==1){
    		select -r 
    		($charName+":"+"L_HipFK_Ctrl")
    		($charName+":"+"L_KneeFK_Ctrl")
    		($charName+":"+"L_AnkleFK_Ctrl")
    		;
    		QA_attr_r;
    		select -r
    		($charName+":"+"R_Scapula_Ctrl")
    		($charName+":"+"R_HipFK_Ctrl")
    		($charName+":"+"R_KneeFK_Ctrl")
    		($charName+":"+"R_AnkleFK_Ctrl")
    		;
    		RC_2_B;
    		} 
    	else if($mirrorStyle==2){
    		select -r 
    		($charName+":"+"R_HipFK_Ctrl")
    		($charName+":"+"R_KneeFK_Ctrl")
    		($charName+":"+"R_AnkleFK_Ctrl")
    		;
    		QA_attr_r;
    		select -r
    		($charName+":"+"L_Scapula_Ctrl")
    		($charName+":"+"L_HipFK_Ctrl")
    		($charName+":"+"L_KneeFK_Ctrl")
    		($charName+":"+"L_AnkleFK_Ctrl")
    		;
    		RC_2_B;
    		}
    	else{
    	    select -r 
    		($charName+":"+"L_HipFK_Ctrl")
    		($charName+":"+"L_KneeFK_Ctrl")
    		($charName+":"+"L_AnkleFK_Ctrl")
    		;
    		QA_attr_r;
    		
    	    select -r 
    		($charName+":"+"R_HipFK_Ctrl")
    		($charName+":"+"R_KneeFK_Ctrl")
    		($charName+":"+"R_AnkleFK_Ctrl")
    		;
    		QB_attr_r;
    		RC_2_B;
    		
    		select -r 
    		($charName+":"+"L_HipFK_Ctrl")
    		($charName+":"+"L_KneeFK_Ctrl")
    		($charName+":"+"L_AnkleFK_Ctrl")
    		;
    		RD_2_A;}
    	}
      else {
      	int $mirrorStyle=`radioButtonGrp -q -select customChannelRadioButtonGrp`;
    	if($mirrorStyle==1){
    		
    		select -r ($charName+":"+"L_AnkleIKPole_Ctrl")
    		          ($charName+":"+"L_AnkleIK_Ctrl");
    		QA_attr_t;
    		select -r ($charName+":"+"L_AnkleIK_Ctrl");
    		QA_attr_r;
    		select -r ($charName+":"+"R_AnkleIKPole_Ctrl")
    		          ($charName+":"+"R_AnkleIK_Ctrl");
    		TC_2_B;
    		//mirror_T;
    		float $tempFootTxL = `getAttr ($charName+":"+"R_AnkleIK_Ctrl"+".tx")`;
    		setAttr ($charName+":"+"R_AnkleIK_Ctrl"+".tx") (-$tempFootTxL);
    		select -r ($charName+":"+"R_AnkleIK_Ctrl");
    		RC_2_B;
    		
    		
    		}
      	
      	if($mirrorStyle==2){
      		select -r ($charName+":"+"R_AnkleIKPole_Ctrl")
    		          ($charName+":"+"R_AnkleIK_Ctrl");
    		QA_attr_t;
    		select -r ($charName+":"+"R_AnkleIK_Ctrl");
    		QA_attr_r;
    		select -r ($charName+":"+"L_AnkleIKPole_Ctrl")
    		          ($charName+":"+"L_AnkleIK_Ctrl");
    		TC_2_B;
    		//mirror_T;
    		float $tempFootTxR = `getAttr ($charName+":"+"L_AnkleIK_Ctrl"+".tx")`;
    		setAttr ($charName+":"+"L_AnkleIK_Ctrl"+".tx") (-$tempFootTxR);
    		select -r ($charName+":"+"L_AnkleIK_Ctrl");
    		RC_2_B;
    		
    		}
      	else{
      		select -r ($charName+":"+"L_AnkleIKPole_Ctrl")
    		          ($charName+":"+"L_AnkleIK_Ctrl");
    		QA_attr_t;
      		select -r ($charName+":"+"L_AnkleIK_Ctrl");
      		QA_attr_r;
      		
      		
      		select -r ($charName+":"+"R_AnkleIKPole_Ctrl")
    		          ($charName+":"+"R_AnkleIK_Ctrl");
    		QB_attr_t;
    		TC_2_B;
    		//mirror_T;
    		float $tempFootTxR = `getAttr ($charName+":"+"R_AnkleIK_Ctrl"+".tx")`;
    		setAttr ($charName+":"+"R_AnkleIK_Ctrl"+".tx") (-$tempFootTxR);
      		select -r ($charName+":"+"R_AnkleIK_Ctrl");
      		QB_attr_r;
      		RC_2_B;
      		
      		select -r ($charName+":"+"L_AnkleIKPole_Ctrl")
    		          ($charName+":"+"L_AnkleIK_Ctrl");
    		TD_2_A;
    		//mirror_T;
    		float $tempFootTxL = `getAttr ($charName+":"+"L_AnkleIK_Ctrl"+".tx")`;
    		setAttr ($charName+":"+"L_AnkleIK_Ctrl"+".tx") (-$tempFootTxL);
      		select -r ($charName+":"+"L_AnkleIK_Ctrl");
      		RD_2_A;
      		}
      	
      	}
}


7.主函数:
先写个切换模式:
global proc mirrorMode(int $mode)
{
	if($mode==0){
		phoenix_headMirror;
		}
	else if($mode==1){
		phoenix_handMirror;
		}
	else if($mode==2){
		phoenix_bodyMirror;
		}
	else if($mode==3){
		phoenix_footMirror;
		}	
	}

然后是Apply:

global proc apply(){
	
	int $partsOfMirror[] = `checkBoxGrp -q  -valueArray4 flipTranslateCheckBoxGrp`;
	int $i=0;
	for($i=0;$i<4;$i++){	
		if($partsOfMirror[$i]==1)
		{mirrorMode $i;}
		else{}		
		}
    print "success!";
}




Done!!!


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页