Как получить все ключевые кадры (ключевые метки) в 3DS Max, используя его SDK

Прямо сейчас я могу получить все ключевые кадры (ключевые тики) из моей модели со скинами, используя 3DS API, если в моей модели есть контроллер преобразования, и в то же время этот контроллер преобразования имеет контроллер перевода и контроллер вращения, используя: Control* pos_max_controller = current_igame_node- >GetMaxNode()->GetTMController()->GetPositionController(); Control* rot_max_controller = current_igame_node->GetMaxNode()->GetTMController()->GetRotationController();

Но я обнаружил, что модель со скинами также может иметь другие виды контроллеров преобразования под этим контроллером преобразования (возможно, некоторым контроллером сплайна).

Но в этом случае я просто могу получить этот контроллер перевода (даже если он не лежит под TM Controller). И этот rot_max_controller в этом случае всегда равен 0.

Как я могу работать с любыми контроллерами Transform с любыми детскими контроллерами с помощью 3DS Max API?

Спасибо большое


person user3290770    schedule 16.02.2014    source источник
comment
Вы хотите, чтобы получить преобразования кости? или преобразование сетки? (Я думаю, что ваш вопрос немного сбивает с толку).   -  person IAmNoone    schedule 17.02.2014
comment
я хочу получить преобразования костей каждого ключевого кадра, как определено на этой дорожке анимации.   -  person user3290770    schedule 18.02.2014
comment
Вот что я делаю (дайте мне знать, если вы тоже этого хотите, я могу опубликовать код для вас): 1) Перебрать все кости в модификаторе кожи. 2) для каждой кости зациклить диапазон анимации и получить преобразование мира\родителя. 3) создать ключевые кадры для каждого кадра X в макс в формате, в который я экспортирую. Делая это таким образом, вы получаете преобразование независимо от того, какой контроллер используется (также IK и тому подобное).   -  person IAmNoone    schedule 18.02.2014
comment
спасибо за ответ. не могли бы вы опубликовать свой код здесь.   -  person user3290770    schedule 19.02.2014


Ответы (1)


Это взято из одного моего экспортера, который я сделал для игрового движка. Вместо того, чтобы заходить в контроллер для считывания данных, я получаю сам узел и читаю напрямую из узла, это означает, что кости можно анимировать любым способом и при этом экспортировать нормально.

 //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;
    }

Чтобы получить ключевые кадры и получить время этих ключевых кадров из объектов кости, вы можете использовать следующий код, не забудьте также настроить ключи вращения и масштабирования.

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 и выписать данные оттуда.

person IAmNoone    schedule 19.02.2014
comment
из вашего снимка кода кажется, что преобразования костей экспортируются в интервале кадров (от начала до конца). Я думаю, что вы просто экспортируете все кадры (может быть, 1000 кадров, если хотите), не учитывая, является ли текущий кадр ключевым кадром или нет. В нем будет больше данных, чем необходимо. Я хочу просто выводить каждый кадр, если в этом кадре есть ключевое преобразование (перевод или вращение). - person user3290770; 20.02.2014
comment
Привет, вы правы, расписываю покадрово. Я отредактировал свой ответ, чтобы вы могли увидеть, как получить ключевые кадры из вашего объекта кости и выполнить цикл, вы можете использовать это в сочетании с другим кодом, чтобы легко определить, когда записывать данные преобразования. - person IAmNoone; 20.02.2014
comment
спасибо за публикацию вашего кода. Я только что проверил ваш код в строке, где вы пытаетесь получить PositionController из Bone Node. Но на некоторых скинах его нет. взгляните на модель, загруженную с tf3dm.com/3d-model/cartoon -корова-7742.html. Мне просто интересно, почему этот позиционный контроллер равен нулю. Спасибо - person user3290770; 25.02.2014
comment
Похоже, это связано с тем, что модель, которую вы экспортируете, сделана с помощью Biped, и если вы посмотрите на панель «движение» для кости в biped, в ней будет указан контроллер положения как «BipPositionList», а не обычный «Контроллер положения XYZ». что обычная кость имеет. Поэтому вам нужно настроить код, получив двуногий BipPositionList и выписать данные оттуда. На данный момент у меня нет кода для этого, но это следующее в моем собственном списке того, что нужно делать. Вот скрипт «biped to bones», который превращает ваши двуногие в обычные кости, файлы . scriptspot.com/3ds-max/scripts/character-on-biped< /а> - person IAmNoone; 25.02.2014
comment
Скрипт 'biped tobones' потерпел неудачу из-за того, что все кости были слишком большими, но он может работать, если настроить его правильно. - person IAmNoone; 25.02.2014
comment
Я отредактировал свой ответ, чтобы также включить информацию о двуногом, если вы считаете, что мой ответ охватывает то, что вам нужно, не стесняйтесь пометить его как «принятый». Это облегчает другим быстрый поиск ответа, а также им видеть, что у вас есть ответ на ваш вопрос. - person IAmNoone; 26.02.2014
comment
еще один вопрос: можно ли просто с помощью кода C преобразовать этот Biped в обычные контроллеры. Или какой-то другой способ получить все данные ключевого кадра - person user3290770; 06.03.2014
comment
То, как я сделал это с нашей стороны, заключалось в том, чтобы экспортировать в FBX и снова импортировать модель, во время импорта она затем преобразует ее в обычные максимальные кости, и она легко экспортируется. Это будет то же самое, что и запекание двуногой анимации. - person IAmNoone; 06.03.2014
comment
Имейте в виду, что некоторые из импортируемых костей могут иметь одинаковые имена, поэтому, если вы зависите от имен костей, вам придется переименовать их все с помощью инструмента переименования, в противном случае вы получите несколько повторяющихся имен, если вы используете оснастку CAT. инструмент. - person IAmNoone; 06.03.2014
comment
большое спасибо за то, что указали на дублированные имена костей и на то, как конвертировать в нормальные макс кости с помощью экспорта и импорта через FBX - person user3290770; 07.03.2014
comment
И последнее, о чем я забыл упомянуть, это то, что когда вы импортируете его обратно, он несколько раз не применяет все импортированные кости к новому скину, поэтому просто убедитесь, что добавили их все, добавив те, которые не были назначены вручную. Причина в том, что если вы проверите «скин» для экспорта костей, то некоторых из них там нет, что нарушает преобразование родитель\потомок при экспорте, так как он не может найти родителя кости, но все выглядит хорошо в окне просмотра 3dsmax, потому что кости находится в иерархии. - person IAmNoone; 07.03.2014
comment
Я попробовал несколько примеров анимированных моделей, а также запустил пример проекта экспортера 3ds. Кажется, вы никогда не сможете получить доступ к ключевым кадрам. Вместо этого средство экспорта 3ds анализирует анимацию по фиксированному значению для каждого кадра. Я вижу ключевые кадры в Максе. Почему это? - person Stefan Agartsson; 15.04.2020