Domanda

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

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top