用六种算法实现maya动画曲线光滑
2016-05-24 20:29
411 查看
在使用动补数据的时候,经常会有手脚等部位的抖动,特意写了个command,直接将动画曲线平滑一下,不用动画师大量的进行手调,下面是代码:
smoothAnimationCurveCmd.h
smoothAnimationCurveCmd.cpp
使用的时候mel用:smoothAnimCurve -md 0 -t "all" -it 1
python用:cmds.smoothAnimCurve(md = 0, t = "all", it = 1)
md为使用的方法,从0到5, it为迭代的次数,也就是你想进行几次光滑处理,type是类型,是“all”, 还是“select”。
结果如下:
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> 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 ); //MItDependencyNodes getAllObjectsAnimCurves(); //MItSelectionList getSelectObjectsAnimCurves(); private: MString type; int method; unsigned int iterations; MAnimCurveChange* pAnimCache; }; #endif
smoothAnimationCurveCmd.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/MSelectionList.h> #include <maya/MItSelectionList.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"; 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); 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 ); pAnimCache = new MAnimCurveChange(); 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); } } } MGlobal::displayInfo(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.reset(); 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[j]; // // 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 1
python用:cmds.smoothAnimCurve(md = 0, t = "all", it = 1)
md为使用的方法,从0到5, it为迭代的次数,也就是你想进行几次光滑处理,type是类型,是“all”, 还是“select”。
结果如下:
相关文章推荐
- 《21天学通C++》_4 2016.5.24
- JAVA1.8新特性
- 下拉框select,Jquery的data()方法,JavaScript join() 方法用于把数组中的所有元素放入一个字符串
- Spinner的简单学习
- unity3d 动作会产生抖动的问题
- List接口
- 10段代码打通js学习的任督二脉
- JAVA无锁编程--Atomic包的使用
- Dubbo大致介绍
- [bash] how to use bash-shell array
- 计蒜客之简单斐波那契
- Android常见Crash类型分析(一)
- CM+CDH安装遇到的问题
- Java字符串实例
- 输入错误的时候抖动视图
- JAVA8新特性
- Codeforces 616C The Labyrinth
- dev_queue_xmi函数详解
- BeautifulSoup高级应用 之 CSS selectors /CSS 选择器
- ASP.NET动态创建树