Экспортёр для 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

  • Генератор облаков

    Я написал эту шнягу, я даже заставил ее работать, но блин, она не хочет создавать прикольные облака, получаются только какие-то пасмурные небеса и усе… Еще я задолбался переделывать этот генератор, но я все-таки заставлю его делать то, что надо 🙂 Share this post: Share on X (Twitter) Share on Facebook Share on LinkedIn Share on…

  • Суббота на работе

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

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

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

  • Future Today

    Вот оно будущее, уже можно потрогать руками более менее простым смертным: На этой картинке видно то, что называется HUD (Heads Up Display), дисплей, проецируемый на лобовое стекло – вещь доступная раньше только пилотам современных истребителей и игроков во всякие игры. Тойота начинает вставлять это в новые лексусы (не очень доступно да) и в новые приусы…

  • Amazon.com

    Получил сегодня книжку, заказанную на амазоне – Steven Goodwin “Cross-platform game programming” (Charles River Media). Мощное чтиво, пока чуть-чуть пробежался, но меня уже радует. Как минимум в ней написано про кеш и то, что в него можно и не попасть при виртуальном вызове 🙂 По поводу оплаты и доставки – все просто – расплатился своей…

  • Я заболел

    Я стал одной из первых жертв весеннего тепла (ведь уже можно считать, что пришла весна 🙂 ). Разрадовавшись теплу я снял пуховик и одел кожанку с подстежкой, шапку снял. И намочил голову – на улице пошел дождь, а у кожанки нету капюшона. Теперь я сижу дома с квадратной головой и сильным насморком, жру таблетки и…