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

  • КРИ 2K7

    Что-то смотрю модно стало писать отчёты про КРИ, напишу-ка и я один 🙂 6.04.07 Приехали в мск и поехали к ddima, который согласился меня с stalker_taurus принять у себя. Забросили весчи и поехали все вместе на конференцию. Первый день был каким-то не очень внятным, лекций почти не было, а то, что было – как-то не…

  • природа экспромптом

    Вчера в 8 вечера внезапно выбрались на природу на шашлыки. Было холодно, ветрено, но тёплая одежда спасала, а когда разожгли костёр, то вообще отлично стало всё. Оказалось, что даже если на улице холодно, то на природу всё равно можно выбираться, ближе к занавесу даже хотелось остаться с ночёвкой. Выехали недалеко под Киев, можно сказать даже…

  • howto: recover failed p5b flash

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

  • Perl

    Вчера у нас был кранч, по ходу пьесы оказалось, что нужно для игры написать скрипт, в который забить полтора десятка компонент с разными настройками – самая настоящая Monkey Job. И тут я вспомнил про то, что умею писать на перле. Написал скриптец для генерации кода за 15 минут и сэкономил эдак час времени, а может…

  • Отчёт: День восьмой (последний), возвращение

    В кои-то дни удалось выспаться. Пожалуй полезно, всё-таки вернувшись с горки и поужинав не начинать сразу пьянку, а тихонько свалить спать. В результате на утро состояние было очень даже радостным и позволило нормально рулить не отвлекаясь каждые полчаса на чашечку кавы. Стартовали мы даже по графику, в девять часов утра. Share this post: Share on…

  • Пластиковые карточки

    Сегодня в банке взял выписку со счета карточного. Надо было для того, чтобы подтвердить счет на пейпеле. Решил заодно подсчитать расходы по Турции, точнее перевод валют. Вывод меня порадовал: Карточка оказалась выгоднее налички Вот подсчеты Выписка: Сумма: 165 YTL Комиссия: 5.72 грн. Общая сумма: 578.15 грн Считаем: 165 лир – это 114 долларов по курсу…