سؤال

Right now I can get all Key Frames(Key Ticks) out of My skinned Model using 3DS API, if my model has a Transform Controller and at the same time this transform controller has Translation Controller and Rotation Controller using: Control* pos_max_controller = current_igame_node->GetMaxNode()->GetTMController()->GetPositionController(); Control* rot_max_controller = current_igame_node->GetMaxNode()->GetTMController()->GetRotationController();

But I found, a skinned model can also have other kinds of transformation controllers underneath that Transform Controller(maybe Some Spline Controller).

But in this case, I just can get that translation controller( even if it is not lying underneath TM Controller). And that rot_max_controller in this case is always 0.

How can I handle any kinds of Transform Controller with any kinds of kid controllers using the 3DS Max API?

Thank you very much

هل كانت مفيدة؟

المحلول

This is taken from one of my exporter that I've done for a game engine. Instead of going into the controller to read out the data, I get the node itself and read from the node directly, this means that the bones can be animated in any way and still export fine.

 //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, "\t\t<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,"\t\t\t<k t=\"%i\" x=\"%f\" y=\"%f\" z=\"%f\"/>\n",(animBegin +v),vLocalPos.x,vLocalPos.y,vLocalPos.z);
        }
        fprintf(s_pStreammma,"\t\t</position>\n");
        fprintf(s_pStreammma, "\t\t<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,"\t\t\t<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,"\t\t</rotation>\n");

        //scale
        fprintf(s_pStreammma, "\t\t<scale num=\"%i\">\n",totalKeyframeTime);
        for(int v = 0; v < totalKeyframeTime; ++v)
        {
            fprintf(s_pStreammma,"\t\t\t<k t=\"%i\" x=\"%f\" y=\"%f\" z=\"%f\"/>\n",(animBegin +v),1.0,1.0,1.0);
        }
        fprintf(s_pStreammma,"\t\t</scale>\n");
        fprintf(s_pStreammma,"\t\t</Bone>\n");
        animStartTimeTemp +=1;
    }

To get keyframes, and get the time of these keyframes from the bone objects you can use the following code, remember to adjust for rotation \ scale keys as well.

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;

                }

for biped it lists the position controller as 'BipPositionList', and not the regular 'Position XYZ controller' that a regular bone has. So you need to customize the code by getting the biped BipPositionList and write out the data from there.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top