[MEL]mirror pose工具

标签: MEL 镜像工具 魔法动画
21人阅读 评论(0) 收藏 举报
分类:

       今天给动画组写一个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!!!


查看评论

Maya Mel GUI入门

在写mel程序时,友好的用户界面是很重要的,因此需要掌握一些基本控件的使用方法,在学习的过程中,也留给自己作为笔记,同时也希望能对有需要的人有些帮助。 1.创建一个window,里面可以包含很多的...
  • Andrewseu
  • Andrewseu
  • 2015-12-22 10:51:58
  • 2556

maya mel新手入门要注意的小地方

maya 变量问题 Error: Line 1.10: Invalid redeclaration of variable as a different type. 5 编辑器快捷功能 有些人可能...
  • shenmifangke
  • shenmifangke
  • 2016-08-13 09:58:45
  • 1659

maya_mel_语言大全

  • 2010年09月09日 18:17
  • 2.98MB
  • 下载

mel笔记

1.所有的变量都以美元符号($)开头,变量名只能用字母、数字、下划线组成,不能包括空格和特定的字符,不能以数字开头,但可以使用下划线和数字;变量名区分大小写. 例如: 2.六种变量类型:整型、浮点...
  • Andrewseu
  • Andrewseu
  • 2015-07-14 10:32:28
  • 1663

mel加载一个物体不同姿态的模型实现动画效果

题目,我从VS导出一个物体的不同姿态生成一系列obj文件 然后想通过MAYA MEL来实现这一系列的动画 script如下: global proc loadObjs() { st...
  • seamanj
  • seamanj
  • 2015-12-18 22:50:45
  • 723

mel滤波器算法设计

什么是mel滤波器呢?mel滤波器是在mel频率上均匀分布的三角滤波器          mel频率与时域频率之间的关系是:          me滤波器在mell频率上均匀分布,那么他的带宽...
  • wolfseek
  • wolfseek
  • 2014-11-02 16:25:59
  • 1748

maya mel里面button 函数传参问题

mel里面直接使用带参函数是没有问题的,和其他语言一样, 但是用到button的时候就会有奇怪的写法 因为要改写一个mel脚本,所以又继续看了mel的button带参问题 如果是按钮 要...
  • shenmifangke
  • shenmifangke
  • 2016-12-27 13:56:08
  • 743

Maya Mel 窗口显示

一小段Mel if (`window -exists $w`){ deleteUI -window $w; } string $w = `window -title "哈哈" -wh 480...
  • fengda2870
  • fengda2870
  • 2013-02-02 22:27:16
  • 2166

Maya Mel 脚本语言的第一个小案例

在脚本编辑器中新建一个表达式 expression -name "Count"; 在“窗口”下拉菜单中找到“动画编辑器”,“表达式编辑器” 点击“选择过滤器”,选择“按表达式名称”,找到...
  • fengda2870
  • fengda2870
  • 2013-02-02 00:41:16
  • 2426

maya mel/python编辑器

  • 2010年12月18日 21:00
  • 13.48MB
  • 下载
    个人资料
    等级:
    访问量: 115
    积分: 50
    排名: 175万+
    文章分类
    文章存档