这是距上次插件向导安装配置完毕以后的插件编写经历,其中遇到了不少问题。由于对3DMAX的接口了解很少,很多资料都是从网上整理的。很多资料需要自己筛检。
1.插件向导安装完毕以后就可以创建3Dmax导入插件的工程了,FileImport类型;其中的主要需要编辑的函数有几个,3DMax会在编译的时候发出提示信息:
其中重要的有const TCHAR *AnimationImp::Ext(int n)是设置导入文件后缀名称的。int AnimationImp::DoImport(const TCHAR *filename,ImpInterface *i, Interface *gi, BOOL suppressPrompts)是导入的实现;
2.接口i是导入接口,可以用它来设置一些动画播放范围等参数,gi是3Dmax的全局接口可以调用很多3Dmax的接口。
3.在DoImport函数里面实现自己的导入:
(1)从filename指向的文件里面按自己的格式读入文件内容。
(2)
//帧数
unsigned NumFrame;//每一帧间隔秒数
unsigned SecFrame ;
//骨骼节点数目
unsigned NumBone;
//帧间隔时间
TimeValue TimeFrame = SecToTicks(SecFrame);//设置帧播放范围ticks
Interval AnimateRange = Interval(0,(NumFrame-1)*TimeFrame);
i->SetAnimRange(AnimateRange);
//设置帧间隔ticks
SetTicksPerFrame(TimeFrame);
//挂起动画
SuspendAnimate();
//开始录制动画
AnimateOn();
上面这些步骤是必须要做的。
//开始一帧一帧的导入操作
for (int iFrame = 0;iFrame<NumFrame;iFrame++){
INode * pNode;
for (unsigned iNode = 0;iNode<NumNode;iNode++){
if(iFrame==0){
//创建每个骨骼的节点,在这里一定要注意,我开始就犯错了,每一帧都创建了这些节点,
//其实只需要第一帧的里面创建并存储起来就OK了,这样的话以后的帧只是找到对应的节点,做矩阵变化就行了。
Object *pBone = (Object*)gi->CreateInstance(GEOMOBJECT_CLASS_ID ,BONE_OBJ_CLASSID);
pNode = gi->CreateObjectNode(pBone);SkeletonINode.push_back(pNode);
//通过对象获得节点
}else{
pNode = SkeletonINode[iNode];
}
pNode->SetName("");
//设置节点CurrentTime点的世界矩阵,包括坐标和旋转,这里需要注意的是Matrix3的row[3]是trans坐标的x,y,z;
//在计算世界坐标的的时候需要跟父节点的坐标矩阵乘以本坐标点的矩阵信息
//这里要注意矩阵一定要计算正确,不然导入以后一团乱
//Tm当前矩阵信息
INode * ParentNode = pNode->GetParentNode();
WorldMatrix = Tm * ParentNode->GetNodeTM(CurrentTime);
pNode->SetNodeTM(CurrentTime,WorldMatrix);
//把节点连接在父节点上
ParentNode->AttachChild(pNode);
//其中可以用下面2个成员函数控制骨骼和节点显示与否
pNode->ShowBone(1);
pNode->Hide(TRUE);
}
}
//恢复动画
ResumeAnimate();