摘要:本文将带你了解Maya教程之用六种算法实现maya动画曲线光滑,希望本文对大家学Maya有所帮助
本文将带你了解Maya教程之用六种算法实现maya动画曲线光滑,希望本文对大家学Maya有所帮助
在使用动补数据的时候,经常会有手脚等部位的抖动,特意写了个command,直接将动画曲线平滑一下,不用动画师大量的进行手调,下面是代码:smoothAnimationCurveCmd.h#ifndef _smoothAnimationCurve_#define _smoothAnimationCurve_ #include <maya/MPxCommand.h>#include <maya/MObject.h>#include <maya/MSyntax.h>#include <maya/MFnAnimCurve.h>#include <maya/MAnimCurveChange.h>#include <maya/MItDependencyNodes.h>#include <maya/MSelectionList.h>#include <maya/MItSelectionList.h> class SmoothAnimationCurveCmd: public MPxCommand{public: SmoothAnimationCurveCmd(); virtual ~SmoothAnimationCurveCmd(); virtual MStatus doIt( const MArgList& ); virtual MStatus redoIt(); virtual MStatus undoIt(); virtual bool isUndoable() const { return true; } static void *creator(){ return new SmoothAnimationCurveCmd; } static MSyntax newSyntax(); MStatus compliceMethod( MFnAnimCurve &fnAnim, MAnimCurveChange *animCache ); MItSelectionList getSelectObjectsAnimCurves(); private: MString type; int method; unsigned int iterations; MAnimCurveChange* pAnimCache; }; #endifsmoothAnimationCurveCmd.cpp#include "smoothAnimationCurveCmd.h"#include <maya/MGlobal.h>#include <maya/MFnPlugin.h>#include <maya/MDagPath.h>#include <maya/MPlugArray.h>#include <maya/MObjectArray.h>#include <maya/MArgDatabase.h>#include <maya/MAnimUtil.h> using namespace std; const char *typeFlag = "-t", *typeLongFlag = "-type";const char *methodFlag = "-md", *methodLongFlag = "-method";const char *iterationsFlag = "-it", *iterationsLongFlag = "-iterations";const char *helpFlag = "-h", *helpLongFlag = "-help";const char *helpText = "The smoothAnimCurve command is used to smooth animcurve." "\nIt has three parameter." "\nFlags:" "\n -h -help " "\n -it -iterations Int" "\n -md -method Int" "\n -t -type String" "\nSupported Mode: sel(smooth animation curve only for selected objects)" "\n all(smooth all animation curves which in the scene)" "\nFor quick help use: help smoothAnimCurve"; SmoothAnimationCurveCmd::SmoothAnimationCurveCmd(){ type = "all"; method = 1; iterations = 1; pAnimCache = NULL;} SmoothAnimationCurveCmd::~SmoothAnimationCurveCmd(){ delete pAnimCache; pAnimCache = NULL;} MSyntax SmoothAnimationCurveCmd::newSyntax(){ MSyntax syntax; syntax.addFlag( typeFlag, typeLongFlag, MSyntax::kString ); syntax.addFlag( methodFlag, methodLongFlag, MSyntax::kLong ); syntax.addFlag( iterationsFlag, iterationsLongFlag, MSyntax::kLong); syntax.addFlag( helpFlag, helpLongFlag ); return syntax;} MStatus SmoothAnimationCurveCmd::doIt( const MArgList &args ){ MStatus stat; unsigned int j; MArgDatabase argData( syntax(), args, &stat ); if( !stat ) return stat; if ( argData.isFlagSet( typeFlag ) ) argData.getFlagArgument( typeFlag, 0, type ); if ( argData.isFlagSet( methodFlag ) ) argData.getFlagArgument( methodFlag, 0, method ); if ( argData.isFlagSet( iterationsFlag ) ) argData.getFlagArgument( iterationsFlag, 0, iterations ); if ( argData.isFlagSet(helpFlag) ) { setResult( helpText ); return MS::kSuccess; } pAnimCache = new MAnimCurveChange(); if(type == "all"){ MItDependencyNodes animCurves(MFn::kAnimCurve); for (; !animCurves.isDone(); animCurves.next()) { MObject currentItem = animCurves.item(); if ( currentItem.isNull() ) { continue; } MFnAnimCurve fnCurve (currentItem); unsigned int numKeys = fnCurve.numKeys(); if (numKeys <= 2) { continue; } else { for (j = 0; j < iterations; j++) { compliceMethod(fnCurve, pAnimCache); } } } } if(type == "sel"){ MObject mAnimCurveObj; MItSelectionList animCurveTempIter = getSelectObjectsAnimCurves(); for(; animCurveTempIter.isDone() != true; animCurveTempIter.next()){ animCurveTempIter.getDependNode(mAnimCurveObj); //cout << mAnimCurveObj.fullPathName() << endl; if ( mAnimCurveObj.isNull() ) { continue; } MFnAnimCurve fnCurve (mAnimCurveObj); unsigned int numKeys = fnCurve.numKeys(); if (numKeys <= 2) { continue; } else { for (j = 0; j < iterations; j++) { compliceMethod(fnCurve, pAnimCache); } } } } MGlobal::displayInfo(MString("type: ") + type + " " + MString("method: ") + method + " " + MString("interations: ") + iterations); return stat;} MItSelectionList SmoothAnimationCurveCmd::getSelectObjectsAnimCurves(){ MSelectionList selection; MSelectionList animCurvesTemp; /*selection.clear(); animCurvesTemp.clear();*/ MGlobal::getActiveSelectionList( selection ); MItSelectionList iter( selection ); unsigned int j, k; for( ; !iter.isDone(); iter.next() ) { MPlugArray mPlugArray; MAnimUtil::findAnimatedPlugs( selection, mPlugArray ); for (j = 0; j < mPlugArray.length(); j++) { MObjectArray mObjArray; MAnimUtil::findAnimation(mPlugArray[j], mObjArray); for (k = 0; k < mObjArray.length(); k++ ) { MObject animCurveNode = mObjArray[k]; if (!animCurveNode.hasFn (MFn::kAnimCurve)) { continue; } //MFnAnimCurve animCurve (animCurveNode); animCurvesTemp.add( animCurveNode ); //MGlobal::getSelectionListByName( animCurve.name(), animCurvesTemp); } } } MItSelectionList iterAnimCurvesTemp( animCurvesTemp); //MItDependencyNodes iterAnimcurves( iterAnimCurvesTemp, MFn::kAnimCurve ); return iterAnimCurvesTemp;} MStatus SmoothAnimationCurveCmd::compliceMethod( MFnAnimCurve &fnAnim, MAnimCurveChange *pAnimCache){ MStatus stat; unsigned int i; double tempValue; unsigned int numKeys = fnAnim.numKeys(); //pAnimCache = new MAnimCurveChange(); switch ( method ) { case 0://三点线性 for (i = 2; i < numKeys - 2; i++) { tempValue = (fnAnim.value(i - 1) + fnAnim.value(i) + fnAnim.value(i + 1))/3; fnAnim.setValue(i, tempValue, pAnimCache); } break; case 1://五点二次滤波 for (i = 2; i < numKeys - 2; i++) { tempValue = (12*(fnAnim.value(i - 1) + fnAnim.value(i + 1)) -3*(fnAnim.value(i - 2) + fnAnim.value(i + 2)) + 17*fnAnim.value(i))/35; fnAnim.setValue(i, tempValue, pAnimCache); } break; case 2://五点钟形滤波 for (i = 2; i < numKeys - 2; i++) { tempValue = (0.11f*(fnAnim.value(i - 2) + fnAnim.value(i + 2)) + 0.24f*(fnAnim.value(i - 1) + fnAnim.value(i + 1)) + 0.3f*fnAnim.value(i)); fnAnim.setValue(i, tempValue, pAnimCache); } break; case 3://三点汉明滤波 for (i = 2; i < numKeys - 2; i++) { tempValue = (0.07f*(fnAnim.value(i - 1)) + 0.86f*(fnAnim.value(i)) + 0.07f*(fnAnim.value(i + 1))); fnAnim.setValue(i, tempValue, pAnimCache); } break; case 4://三点钟形滤波 for (i = 2; i < numKeys - 2; i++) { tempValue = 0.212f*fnAnim.value(i - 1) + 0.576f*fnAnim.value(i) + 0.212*fnAnim.value(i + 1); fnAnim.setValue(i, tempValue, pAnimCache); } break; default://五点汉明滤波 for (i = 2; i < numKeys - 2; i++) { tempValue = 0.04f*(fnAnim.value(i - 2) + fnAnim.value(i + 2)) + 0.24f*(fnAnim.value(i - 1) + fnAnim.value(i + 1)) + 0.44f*(fnAnim.value(i)); fnAnim.setValue(i, tempValue, pAnimCache); } break; } return stat;} MStatus SmoothAnimationCurveCmd::undoIt(){ if( pAnimCache != NULL ) pAnimCache -> undoIt(); return MS::kSuccess;} MStatus SmoothAnimationCurveCmd::redoIt(){ if( pAnimCache != NULL ) pAnimCache -> redoIt(); return MS::kSuccess;} MStatus initializePlugin( MObject obj ){ MFnPlugin plugin( obj, "Lulongfei", "1.0" ); MStatus stat; stat = plugin.registerCommand( "smoothAnimCurve", SmoothAnimationCurveCmd::creator, SmoothAnimationCurveCmd::newSyntax ); if ( !stat ) stat.perror( "registerCommand failed" ); return stat;} MStatus uninitializePlugin( MObject obj ){ MFnPlugin plugin( obj ); MStatus stat; stat = plugin.deregisterCommand( "smoothAnimCurve" ); if ( !stat ) stat.perror( "deregisterCommand failed" ); return stat;}使用的时候mel用:smoothAnimCurve -md 0 -t "all" -it 1python用:cmds.smoothAnimCurve(md = 0, t = "all", it = 1)md为使用的方法,从0到5, it为迭代的次数,也就是你想进行几次光滑处理,type是类型,是“all”, 还是“select”。结果如下:
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Maya频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号