Экспортёр для XSI

В свете последних тенденций борьбы с пиратством да и просто исходя из экономии денег (или их отсутствия), стало очень актуально переходить с мегадорогих пакетов разработки на что-то более дешёвое. Поэтому было решено написать плагин не для 3DMax или Maya, а для менее популярного XSI, но зато более финансово доступного.

Оказалось что всё очень даже неплохо. С версии 6 (судя по документации), данная среда поддерживает плагины, написанные на C#, а писать на нём подобные вещи – неописуемое удовольствие. Замечу, что написание и отладка базовой функциональности у меня заняла один день, правда пришлось выключить ICQ, IRC и браузер.


Итак, отправной точкой будет установка XSI – проблем с этим возникнуть не должно.
Чем данное приложение хорошо, так это тем, что оно умеет сгенерировать заготовку проекта на том языке, который мы выберем. Такой себе визард, но не в студию встроенный, а в XSI. Поэтому, чтобы облегчить себе жизнь – сгенерим заготовку для проекта на C#

Создание проекта

Запускаем среду, и в ней запускаем plugin manager (File->Plugin Manager). Выбираем закладку plugins, и жмём кнопку new, всплывет предложение выбрать тип плагина, я выбрал command, так как нам нужна кнопка, на которой будет слово “Export to gameformat”. Нам предложат кастомизировать проект – лучшее место для того, чтобы правильно назвать кнопочку, которая будет отвечать за экспорт и выбрать её местоположение в иерархии кнопок среды. Для того, чтобы она лежала в разделе File->Export нам нужно указать значение параметра Add to menu равным siMenuMainFileExport
Дальше вносим параметры по усмотрению и жмём кнопку Generate Code.
После этого запускаем студию, открываем полученный проект и начинаем программировать.

Программирование

XSI API не вызывает дикого отторжения, в отличие от некоторых других, и по началу вообще выглядит очень здорово. Но как и везде – находятся свои подводные камни, которые усложняют нашу жизнь.

Нам предоставляют три основных объекта

CXSIApplicationClass m_xsi;
CXSIFactoryClass m_fact;
CXSIUtilsClass m_utils;

При помощи которых можно получать доступ ко всем внутренностям. Есть, правда, ещё один класс, который нам заботливо забыли подсунуть при генерации проекта – это CXSIUIToolkitClass, штука, позволяющая получить доступ к пользовательскому интерфейсу. В нашем случае – это вызов диалогового окна, которое спросит у пользователя имя файла, в который он хочет экспортировать свою мега модель.
Использование выглядит приблизительно так:


CXSIUIToolkitClass toolkit = new CXSIUIToolkitClass();

FileBrowser fb = toolkit.FileBrowser;

fb.DialogTitle = “Select file to save model”;
fb.InitialDirectory = @”c:\”;

fb.ShowSave();

UberModelSerializer serializer = new UberModelSerializer(fb.FilePathName);

Дальше нам понадобится сцена, которую мы хотим экспортировать, и тут нам пригодится объект класса CXSIApplicationClass, у которого есть в наличии аксессор ActiveSceneRoot


CXSIApplicationClass xsi = new CXSIApplicationClass();
serializer.Serialize(xsi.ActiveSceneRoot);

Объекты, которые нарисовал художник являются детьми сцены, при чём в прямом смысле, поэтому доступ к ним мы получаем через scene.Children, замечу, что среди них ещё будет замешан источник освещения и камера.
Доступ к основным свойствам объекта получить вроде бы просто, но именно здесь нас ожидает первый камешек.
Т.к. физические свойства лежат в “разделе” Kinematics, то и мы пытаемся их извлечь оттуда.


obj.Kinematics.Global.Parameters[“posx”]

Вот так вот у нас должны извлечься глобальные координаты, но не тут-то было, мы получим некий com_object. Чтобы получить числовое значение, нам надо сделать вот так:


float.Parse( obj.Kinematics.Global.Parameters[“posx”].get_Value(0).ToString() )

Вот теперь в наших руках есть нормальное значение.
Ещё у объектов бывают custom параметры – параметры, которые пользователь сам задал, они извлекаются следующим образом:


obj.Properties[“CustomPSet”].Parameters[“speed”].get_Value(0).ToString()

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

Отладка

Отлаживать наш плагин очень легко и удобно. Нам нужно загрузить плагин в XSI, и студией подключиться к процессу, при этом порядок выполняемых действий не играет роли.
Загрузка плагина осуществляется следующим образом: В XSI открываем plugin manager, у нас будет открыта первая же закладка – Tree, жмём кнопку Load и выбираем DLL, которая получилась после сборки нашего проекта в студии.
Подключаемся к процессу XSI вот так: в студии жмём debug->Attach to process, в списке ищем XSI.exe и подключаемся к нему. Студия перейдёт в режим отладки – время расставлять breakpoints и готовиться читать debug log.
После того, как мы отладимся или поймём, что надо вносить изменения – отсоединяемся от процесса и выгружаем плагин из XSI. К счастью для того, чтобы сделать последнее нам не надо перегружать всю среду. Достаточно всё в том же менеджере плагинов в разделе tree выбрать наш и в контекстном меню, которое появляется по нажатию правой кнопки мыши нажать unload.
Сделать это нужно для того, чтобы среда отдала доступ к файлу, т.к. без этого компиляция закончится неудачей – студия не сможет записать новую DLL поверх старой.

Similar Posts

  • Диплом

    Вчера я защитил диплом, вроде даже на “отлично” 🙂 Интересно, что после того как я его защитил, мир не рухнул, не изменился и ничегошеньки не произошло 🙂 Наверно так и должно быть. Все равно, работу я нашел раньше, а больше после диплома ничего измениться и не должно было. Разве что интересно, как оно будет теперь…

  • Позднеосеннее катание

    Сегодня ходили небольшой морозостойкой компанией кататься по району. Прикольно однако – вроде бы и холодно, но если ветра нету, то ездить очень даже приятно, можно даже слалом катать – но почему-то не получалось – как-то ноги криво стояли 🙂 Но ощущения очень приятные после того, как погоняли, сидеть в тепле и пить горячий чай –…

  • Мойка машины

    Ездили сегодня с Олегом помыть машину, по ходу к нам прибился Виталя, который был готов на все, лишь бы не учить математику. Вот так мы с Олегом мыли машину А это Виталя отдыхал от математики, и исполнял маленькое наказание: Было прикольно – заработали бутылку водки – чувак на Chevrolet Takuma решил заехать поближе к лесу…

  • Славское 2007

    Съездили мы тут в Славское, на один денёк, в семь утра приехали и в половине седьмого вечера уже сели, или точнее, запрыгнули в обратный паравоз. Железнодорожники – проводники, кстати, похоже проходят курсы повышения квалификации где-то в аду, или отделении гестапо, так как топили в вагоне по самое не могу, термометр говорил, что было около 28…

  • Воспоминания об Иране. ч.1 – Прибытие

    Предложили мне недавно написать про мои впечатления от Ирана, и я подумал, что действительно, было бы интересно написать, а потом можно сравнить с нынешней ситуацией, т.к. мои воспоминания о той стране заканчиваются десять лет назад. Share this post: Share on X (Twitter) Share on Facebook Share on LinkedIn Share on Email Share on Reddit

  • Ghost in the shell:SAC 2nd GIG

    Начал смотреть второй сезон сериала, мне показалось или он действительно стал более атмосферным киберпанком? Вообще пока нравится, прикольно так, затягивает зрелище, первый сезон не было такого желания смотреть как сейчас второй. Начинает мешать работать 🙂 Share this post: Share on X (Twitter) Share on Facebook Share on LinkedIn Share on Email Share on Reddit