现在,如果我的模型具有变换控制器,同时此变换控制器具有平移控制器和旋转控制器用: Control* pos_max_controller = current_igame_node->GetMaxNode()->GetTMController()->GetPositionController(); Control* rot_max_controller = current_igame_node->GetMaxNode()->GetTMController()->GetRotationController();
但我发现,蒙皮模型也可以在该变换控制器(可能是一些样条控制器)下有其他类型的变换控制器。
但在这种情况下,我只能得到那个翻译控制器(即使它不在 TM 控制器下面)。在这种情况下,rot_max_controller始终为 0。
如何使用 3DS Max API 处理任何类型的转换控制器和任何类型的儿童控制器?
谢谢
我为游戏引擎所做的一个导出器中获取的。我不是进入控制器读出数据,而是获取节点本身并直接从节点读取,这意味着骨骼可以以任何方式进行动画处理,并且仍然可以正常导出。
//jountCount is the number of bones in the skin modifier,
for (int currbone=0;currbone<jointCount;currbone++)
{
int time = GetCOREInterface()->GetTime();
INode* boneNode = skin->GetBone(currbone);
//animEnd and anim Begin is set in my GUI. for example frame 10 to 100
int totalKeyframeTime = animEnd - (animBegin);
int myticks = GetTicksPerFrame();
fprintf(s_pStreammma,"t<Bone id="%i">n",currbone);
fprintf(s_pStreammma, "tt<position num="%i">n",totalKeyframeTime);
Point3 ang;
Matrix3 nodeTM2;
Matrix3 objTM2;
Point3 objTrans2;
TimeValue tval;
for(int v = 0; v < totalKeyframeTime; ++v)
{
tval = TimeValue(animBegin +v);
nodeTM2 = boneNode->GetNodeTM(tval * myticks);
objTM2 = boneNode->GetObjectTM(tval * myticks);
objTrans2 = objTM2.GetTrans();
INode *parent = node->GetParentNode();
Matrix3 parent_TM = parent->GetNodeTM(tval * myticks);
Matrix3 local_tm = (parent_TM - objTM2);
if(currbone == 0)
{
parent = node;
}
else
{
parent = boneNode->GetParentNode();
}
Matrix3 localTransform = nodeTM2 * Inverse(parent->GetNodeTM(tval * myticks));
Point3 vLocalPos = localTransform.GetTrans();
fprintf(s_pStreammma,"ttt<k t="%i" x="%f" y="%f" z="%f"/>n",(animBegin +v),vLocalPos.x,vLocalPos.y,vLocalPos.z);
}
fprintf(s_pStreammma,"tt</position>n");
fprintf(s_pStreammma, "tt<rotation num="%i">n",totalKeyframeTime);
for(int v = 0; v < totalKeyframeTime; ++v)
{
tval = TimeValue(animBegin +v);
INode *parent = node->GetParentNode();
Matrix3 parent_TM = parent->GetNodeTM(tval * myticks);
nodeTM2 = boneNode->GetNodeTM(tval * myticks);
objTM2 = boneNode->GetObjectTM(tval * myticks);
if(currbone == 0)
{
parent = node;
}
else
{
parent = boneNode->GetParentNode();
}
Matrix3 local_tm = nodeTM2 * Inverse(parent->GetNodeTM(tval * myticks));
QuatToEuler(local_tm,ang,0,false);
fprintf(s_pStreammma,"ttt<k t="%i" x="%f" y="%f" z="%f"/>n",(animBegin +v),ang.x /3.14*180,ang.y /3.14*180,ang.z /3.14*180);
}
fprintf(s_pStreammma,"tt</rotation>n");
//scale
fprintf(s_pStreammma, "tt<scale num="%i">n",totalKeyframeTime);
for(int v = 0; v < totalKeyframeTime; ++v)
{
fprintf(s_pStreammma,"ttt<k t="%i" x="%f" y="%f" z="%f"/>n",(animBegin +v),1.0,1.0,1.0);
}
fprintf(s_pStreammma,"tt</scale>n");
fprintf(s_pStreammma,"tt</Bone>n");
animStartTimeTemp +=1;
}
若要获取关键帧,并从骨骼对象中获取这些关键帧的时间,可以使用以下代码,请记住调整旋转\缩放键。
Control *c;
c = boneNode->GetTMController()->GetPositionController();
IKeyControl *ikeys = GetKeyControlInterface(c);
if (!ikeys) return;
int numkeys = rootBone->NumKeys();
IKey* mykey;
for (int key=0;key < numkeys; key++)
{
ikeys->GetKey(key,mykey);
TimeValue keytime;
keytime = mykey->time;
}
对于两足动物,它将位置控制器列为"BipPositionList",而不是常规骨骼具有的常规"位置XYZ控制器"。因此,您需要通过获取两足动物BipPositionList来自定义代码,并从那里写出数据。