MAYA 绑定 创建 RPsolver IK 和添加拉伸。可以设置全局缩放

版权声明:大家好,我是笨笨,笨笨的笨,笨笨的笨,转载请注明出处,谢谢! https://blog.csdn.net/jx520/article/details/83341569

创建 RPsolver IK 和添加拉伸。可以设置全局缩放 //创建 feet IK grp 创建脚的IK组(3K5组,再多就是内外侧撇脚)。
最后更新时间 2013-11-25 20:38:42

//------------------Mel by jerryjin----------------------
//============================================ 数 据 层 =====================================================
//---------------------获取joint长度--------------------------
proc float getJointLength(string $jnt1, string $jnt2)
{
//get jnt1 worldspace position
float $jnt1Pos[] = `xform -q -ws -t $jnt1`;

//get jnt2 worldspace position
float $jnt2Pos[] = `xform -q -ws -t $jnt2`;

//calculate the vector between them
float $xcomp = $jnt2Pos[0] -$jnt1Pos[0];
float $ycomp = $jnt2Pos[1] -$jnt1Pos[1];
float $zcomp = $jnt2Pos[2] -$jnt1Pos[2];

vector $tmp = << $xcomp, $ycomp, $zcomp>>;

//get the vector length
float $res = mag($tmp);
return $res;
}
//-----------------------获取joint链长度---------------------------------
proc float getJointChainLength(string $jntStart, string $jntEnd)
{
	string $temp[0];
	float $len = 0;
	do
	{
		$temp = `listRelatives -p $jntEnd`;
		$len += getJointLength($temp[0], $jntEnd);
		$jntEnd = $temp[0];
	}
	while ($jntEnd != $jntStart);
	return $len;
}

//==========================================================================================================
//创建 IK 拉伸
proc int ikStretchy(string $ctrlName,string $jntStart,string $jntEnd,string $worldSpace,string $worldScaleAxis, string $jntScaleAxis)//$ctrlName:IKctrl, $jntStart:armJoint, $jntEnd:WristJoint, $ws:worldscale
{
	string $loc[0],$startLoc,$endLoc,$condition,$multiplyDivide,$swMultiplyDivide;
	//创建节点
	$loc = `spaceLocator -n ($ctrlName+"_startLoc")`;
	$startLoc = $loc[0];
	$loc = `spaceLocator -n ($ctrlName+"_endLoc")`;
	$endLoc = $loc[0];

	string $dimension = `shadingNode -au distanceDimShape`;
	string $dimensions[] = `listRelatives -p $dimension`;
	$dimension = rename($dimensions[0],($ctrlName+"_distance"));
	$dimensions = `listRelatives -c $dimension`;
	$dimension = $dimensions[0];

	$condition = `shadingNode -au -n ($ctrlName+"_condition") condition`;
	$multiplyDivide = `shadingNode -au -n ($ctrlName+"multiplyDivide") multiplyDivide`;

	//放置 定位器
	pointConstraint $jntStart  $startLoc;
	pointConstraint $ctrlName  $endLoc;

	//联接节点
    connectAttr ($startLoc + ".worldPosition[0]") ($dimension + ".startPoint");
    connectAttr ($endLoc + ".worldPosition[0]") ($dimension + ".endPoint");
	connectAttr ($dimension + ".distance") ($condition + ".firstTerm");
	connectAttr ($dimension + ".distance") ($condition + ".colorIfTrueR");
	setAttr ($condition + ".operation") 2;
	setAttr ($condition + ".secondTerm") (getJointChainLength($jntStart, $jntEnd));
	setAttr ($condition + ".colorIfFalseR") (getJointChainLength($jntStart, $jntEnd));

	setAttr ($multiplyDivide + ".operation") 2;

	connectAttr ($condition + ".outColorR") ($multiplyDivide + ".input1X");
	setAttr ($multiplyDivide + ".input2X") (getJointChainLength($jntStart, $jntEnd));

	//世界全局缩放
	if ($worldSpace != "" && `objExists $worldSpace`)
	{
		$swMultiplyDivide = `shadingNode -au -n ($ctrlName+"swMultiplyDivide") multiplyDivide`;
		setAttr ($swMultiplyDivide + ".operation") 1;
		setAttr ($swMultiplyDivide + ".input1X") (getJointChainLength($jntStart, $jntEnd));
		connectAttr ($worldSpace + $worldScaleAxis) ($swMultiplyDivide + ".input2X");
		connectAttr -f ($swMultiplyDivide + ".outputX")  ($condition + ".secondTerm");
		connectAttr -f ($swMultiplyDivide + ".outputX")  ($condition + ".colorIfFalseR");
		connectAttr -f ($swMultiplyDivide + ".outputX")  ($multiplyDivide + ".input2X");
	}

	//最终缩放比率输出来骨头
	string $temp[];
	do
	{	$temp = `listRelatives -p $jntEnd`;
		connectAttr -force ($multiplyDivide + ".outputX") ($temp[0] + $jntScaleAxis);
		$jntEnd = $temp[0];
	}
	while ($jntEnd != $jntStart);

	//请理、打组
	if (`objExists "distanceDimension_grp"`)
	{
			parent $dimension $startLoc $endLoc distanceDimension_grp;
	}else
	{
		group -n "distanceDimension_grp" $dimension $startLoc $endLoc;
	}
	return 1;
}

string $selected[] = `ls -sl`;
ikStretchy($selected[0],$selected[1],$selected[2],"main_grp",".sx",".sx");


//创建 RPsolver IK 目标是用于手臂,不知道腿用会顺利不。
proc int createIkRPsolver(string $ctrlName,string $ctrlPole,string $sj,string $ej)
{
	//createIK (前臂有 ForeArmRoll 骨头)
	string $handle[2],$multiplyDivide,$temp[];
	float $p[];
	$temp = `listRelatives -p $ej`;
	$handle = `ikHandle -sj $sj -ee $temp[0] -solver "ikRPsolver" -n ($ctrlName+"_ikHandle")`;
	$handle[1] = `rename $handle[1] ($ctrlName + "_effector")`;
	$p = `xform -q -ws -t $ej`;
	xform -ws -rp $p[0] $p[1] $p[2] -sp $p[0] $p[1] $p[2] $handle[1];

	//Wrist Translat
	pointConstraint $ctrlName $handle[0];

	//Wrist Rotate
	connectAttr ($ctrlName + ".ry") ( $ej + ".ry");
	connectAttr ($ctrlName + ".rz") ( $ej + ".rz");
	$multiplyDivide = `shadingNode -au -n ($ctrlName+"_multiplyDivide") multiplyDivide`;
	setAttr ($multiplyDivide + ".operation") 1;
	setAttr ($multiplyDivide + ".input2X") .6;
	connectAttr ($ctrlName + ".rx") ( $multiplyDivide + ".input1X");
	connectAttr ($multiplyDivide + ".outputX") ( $ej + ".rx");

	//ForeArmRoll
	$multiplyDivide = `shadingNode -au -n ($temp[0]+"_multiplyDivide") multiplyDivide`;
	setAttr ($multiplyDivide + ".operation") 1;
	setAttr ($multiplyDivide + ".input2X") .3;
	connectAttr ($ctrlName + ".rx") ( $multiplyDivide + ".input1X");
	connectAttr ($multiplyDivide + ".outputX") ( $temp[0] + ".rx");

	//ElbowPole Constraint
	poleVectorConstraint $ctrlPole $handle[0];

	//请理、打组
	if (`objExists "ikHandle_grp"`)
	{
		parent $handle[0] "ikHandle_grp";
	}else
	{
		group -n "ikHandle_grp" $handle[0];
	}
	return 1;
}

string $selected[] = `ls -sl`;
createIkRPsolver($selected[0],$selected[1],$selected[2],$selected[3]);

//创建 RPsolver IK 目标是用于腿。
proc int createLegIkRPsolver(string $ctrlName,string $ctrlPole,string $sj,string $ej)
{
	//createIK 
	string $handle[2],$multiplyDivide;
	
	$handle = `ikHandle -sj $sj -ee $ej -solver "ikRPsolver" -n ($ctrlName+"_ikHandle")`;
	$handle[1] = `rename $handle[1] ($ctrlName + "_effector")`;

	//Wrist Translat
	pointConstraint $ctrlName $handle[0];

	//Wrist Rotate
	//connectAttr ($ctrlName + ".r") ( $ej + ".r");

	//ElbowPole Constraint
	poleVectorConstraint $ctrlPole $handle[0];

	//请理、打组
	if (`objExists "ikHandle_grp"`)
	{
		parent $handle[0] "ikHandle_grp";
	}else
	{
		group -n "ikHandle_grp" $handle[0];
	}
	return 1;
}

string $selected[] = `ls -sl`;
createLegIkRPsolver($selected[0],$selected[1],$selected[2],$selected[3]);


//创建 feet IK grp 创建脚的IK组(3K5组,再多就是内外侧撇脚)。
proc int createFeetIkGroup(string $ikCtrl, string $ankleIK, string  $heelJoint, string  $ballJoint, string $toeJoint, string $prefix)
{
//    if (size($ikJointLoc) != 6)
//    {
//        error "最少要也选中,1 IK控制器,2 脚踝IK,3 脚掌骨,4 脚尖骨,5 脚根定位体 ,6 前缀!";
//    }
//    string $ikCtrl = $ikJointLoc[0];
//    string $ankleIK = $ikJointLoc[1];
//    string $ballJoint = $ikJointLoc[2];
//    string $toeJoint = $ikJointLoc[3];
//    string $heelJoint = $ikJointLoc[4];
//    string $prefix = $ikJointLoc[5];//string $prefix = "L";
    string $ballIK[] ,$toeIK[],$group[], $loc[0], $temp[];
    float $p[];

    //判断所选内容是否正确
    if (checkObjectType($ankleIK) == "ikHandle" && checkObjectType($ballJoint) == "joint" && checkObjectType($toeJoint) == "joint"  && checkObjectType($heelJoint) == "joint")
    {
        $temp = `listConnections ($ankleIK+".rotatePivot")`;
        catch(`delete $temp[0]`);

        $temp = `listConnections ($ankleIK+".endEffector")`;
        $temp = `listConnections ($temp[0]+".tx")`;

        $ballIK = `ikHandle -sj $temp[0] -ee $ballJoint -solver "ikSCsolver" -n ($ballJoint + "_ikHandle")`;
        rename $ballIK[1] ($ballJoint + "_effector");
        $toeIK = `ikHandle -sj $ballJoint -ee $toeJoint -solver "ikSCsolver" -n ($toeJoint + "_ikHandle")`;
        rename $ballIK[1] ($toeJoint + "_effector");

        //五个组的名字,先拼出来,方便后面用。
        $group[0] = ($prefix + "_ankleIK_grp");
        $group[1] = ($prefix + "_ballIK_grp");
        $group[2] = ($prefix + "_toeIK_grp");
        $group[3] = ($prefix + "_heel_grp");
        $group[4] = ($prefix + "_feet_grp");

        catch(`ungroup $group[0]`);
        catch(`ungroup $group[1]`);
        catch(`ungroup $group[2]`);
        catch(`ungroup $group[3]`);
        catch(`ungroup $group[4]`);
		catch(`ungroup ($prefix +  "_footInSide_grp")`);
		catch(`ungroup ($prefix +  "_footOutSide_grp")`);
		catch(`ungroup ($prefix +  "_footPiv_grp")`);

        //Group1 ankleIK_grp : 脚裸IK打组,轴心放到 ball
        $p = `xform -q -ws -t $ballJoint`;
        group -n $group[0] $ankleIK;
        xform -ws -piv $p[0] $p[1] $p[2];

        //Group2 ballIK_grp:( ballIK + toeIK )打组,轴心放到 ball
        group -n $group[1] $ballIK[0] $toeIK[0];
        xform -ws -piv $p[0] $p[1] $p[2];

        //Group3 toeIK_grp:(Group1 + Group2 )打组,轴心放到 toe
        $p = `xform -q -ws -t $toeJoint`;
        group -n $group[2] $group[0] $group[1];
        xform -ws -piv $p[0] $p[1] $p[2];

        //Group4 heel_grp:(Group3)打组,轴心放到 heel
        $p = `xform -q -ws -t $heelJoint`;
        group -n $group[3] $group[2];
        xform -ws -piv $p[0] $p[1] $p[2];

        //Group5 feet_grp:(Group4)打组,轴心放到 ankleIK
        $p = `xform -q -ws -t $ankleIK`;
        group -n $group[4] $group[3];
        xform -ws -piv $p[0] $p[1] $p[2];
		
		//inSide_grp
		group -n ($prefix +  "_footInSide_grp") $group[2];
		//outSide_grp
		group -n ($prefix +  "_footOutSide_grp");
		//footPiv_grp
		group -n ($prefix +  "_footPiv_grp") $group[3];	

        //为组4创建轴心 loc
        $p = `xform -q -ws -t $heelJoint`;
        $loc = `spaceLocator -n ($prefix + "_footPivLoc")`;// -p $p[0] $p[1] $p[2]`;
        group -n  ($prefix + "_footPivLoc_grp") $loc[0];
        xform -ws -t $p[0] $p[1] $p[2] ($prefix + "_footPivLoc_grp");
        parent ($prefix + "_footPivLoc_grp") $group[3];
		$temp = `listRelatives -shapes $loc[0]`;
		connectAttr -f ($temp[0] + ".worldPosition[0]") ($prefix + "_footPiv_grp.rotatePivot");

		setAttr ($prefix + "_footPiv_grp.displayHandle") 1;
		setAttr ($prefix + "_footPiv_grp.selectHandle") (getAttr ($ikCtrl +"_grp.tx")) (getAttr($ikCtrl +"_grp.ty")) $p[2] ;

        //在控制器上添加属性
        catch (`deleteAttr -attribute "toe" $ikCtrl`);
        catch(`addAttr -ln "toe"  -at double  -min -10 -max 10 -dv 0 $ikCtrl`);
        catch(`setAttr -e -keyable true ($ikCtrl + ".toe")`);

        catch (`deleteAttr -attribute "roll" $ikCtrl`);
        catch(`addAttr -ln "roll"  -at double  -min -10 -max 10 -dv 0 $ikCtrl`);
        catch(`setAttr -e -keyable true ($ikCtrl + ".roll")`);

        catch (`deleteAttr -attribute "side" $ikCtrl`);
        catch(`addAttr -ln "side"  -at double  -min -10 -max 10 -dv 0 $ikCtrl`);
        catch(`setAttr -e -keyable true ($ikCtrl + ".side")`);

		catch(`deleteAttr -attribute "footPivVisibe" $ikCtrl`);
		catch(`addAttr -ln "footPivVisibe"  -at double  -min 0 -max 1 -dv 0 $ikCtrl`);
        catch(`setAttr -e -keyable true ($ikCtrl + ".footPivVisibe")`);

		//设置 属性 连接 和 驱动关键帧
		connectAttr ($ikCtrl + ".footPivVisibe") ($prefix +  "_footPivLoc_grp.v");
    }
	return 1;
}

string $ikJointLoc[] = `ls -sl`;
createFeetIkGroup($selected[0],$selected[1],$selected[2],$selected[3],$selected[4],"R");

//设置驱动关键帧 (还没测试好不好用,感觉还有问题)
proc int setDK(string $driverAttr, string $driverValue, string $drivenAttr, string $drivenValue)
{
	$temp1 = `getAttr $driverAttr`;
	$temp2 = `getAttr $drivenAttr`;
	setAttr $driverAttr ((float)$driverValue);
	setAttr $drivenAttr ((float)$drivenValue);
	setDrivenKeyframe -itt "linear" -ott "linear" -cd $driverAttr $drivenAttr;
	setAttr $driverAttr $temp1;
	setAttr $drivenAttr $temp2;
	return 1;
}

猜你喜欢

转载自blog.csdn.net/jx520/article/details/83341569
ik