Введение в моделирование для авиасимулятора FlightGear
Для чего и для кого написана эта статья?
В настоящее
время авиасимулятор FlightGear переживает определенный подъем интереса
со стороны пользователей и разработчиков, в том числе и в нашей стране.
Если для пользователей информации довольно много (хотя и англоязычной),
то разработчики моделей вынуждены довольствоваться ограниченным хелпом
по анимации. Кроме того, многие вещи, описанные в штатной документации
симулятора, заметно устарели.
В настоящее время готовится
очередной стабильный релиз FlightGear 0.9.11 и ведется интенсивная
работа по переходу на новую графическую подсистему - OpenSceneGraph.
Проект динамично развивается, и как мне кажется, вполне способен
расширить свою нишу и увеличить пользовательскую базу.
Я
попробую свести в этой статье некоторые свои наработки по моделированию
на платформе FlightGear, и базовые сведения, чтобы дать возможность
заинтересовавшимся моделлерам попробовать свои силы на новом,
интересном и, на мой взгляд, перспективном направлении.
Кроме непосредственно информации для разработчиков моделей
FlightGear, я надеюсь, данная статья будет интересна и коллегам с
других платформ, в первую очередь - MSFS. Быть может, кому-нибудь из
них покажется интересным этот авиасимулятор, и те возможности, которые
он предоставляет авторам моделей. Хотелось бы избежать "священной
войны" - недостатки FlightGear в частности и открытого софта в целом
безусловно существуют, но не об этом тут речь.
Думаю, что обычным пользователям тоже будет интересно
посмотреть, как устроены их модели. лишних знаний не бывает, и я буду
рад, если эта статья поможет кому-нибудь пофиксить глюки или добавить
недостающую фичу к своей любимой модели.
Поехали:)
Структура модели
Модель самолета в FlightGear состоит
в общем из тех же компонентов, как и в MSFS. Можно выделить визуальную
модель - то, что мы видим снаружи, панель приборов - двумерную панель и
трехмерную ВК, а так же динамику - систему параметров, определяющих
движение модели в мире FGFS. Кроме того, модель может использовать
различные подсистемы (звук, субмодели) - реализованные автором модели
либо входящие в комплект поставки симулятора в виде готовых блоков.
Все
модели находятся в директории FlightGear/Aircraft. Для юниксов это
будет где-то в /usr/local/share/FlightGear/Aircraft, для винды -
Program FilesFlightGeardataAircraft. Все дальнейшие пути я буду
указывать для юниксовой версии, пользователям винды следует сменить
слэш на обратный. Никакого различия, с точки зрения моделлера, между
версиями симулятора под разные операционные системы нет. Не существует
моделей отдельно "под винду" или "под линукс" - они все абсолютно
одинаковы. Принята следующая структура каталогов:
Aircraft/модель/Model - тут находится визуальная модель, ее текстуры и конфигурационные файлы
Aircraft/модель/Panels - панели приборов. Обычно тут находятся только конфигурационные файлы.
Aircraft/модель/Panels/Instruments - тут лежат 2D приборы (их XML - файлы)
Aircraft/модель/Panels/Instruments/Textures - тут лежат текстуры для 2D приборов (файлы с расширением RGB).
Aircraft/модель/Panels/Instruments-3d/
- тут находятся 3d приборы. Обычно для каждого 3d-прибора выделяется
собственный каталог, где лежат трехмерные объекты, текстуры и XML-файлы.
Aircraft/модель/Sounds - понятное дело, звуки. WAV-файлы.
Aircraft/модель/Systems - конфигурационные файлы подсистем
В корневом каталоге модели обычно файлы именуются следующим образом:
Aircraft/модель/модель.xml - файл динамики.
Aircraft/модель/модель-set.xml
- главный конфигурационный файл модели. Объединяет все части модели в
единое целое. Кроме того, в этом файле устанавливаются начальные
значения для различных параметров модели. Тут же переопределяются
клавиши, настраиваются режимы внешнего и внутреннего обзора, задается
уровень топлива "по умолчанию". Таким образом, производится необходимая
инициализация переменных симулятора. Все параметры из этого файла
загружаются в дерево свойств (Property Tree) симулятора. Что это такое,
будет рассмотрено позднее.
В корневом каталоге модели можно поместить сплаш-скрин, который будет показан при загрузке модели, хотя это и необязательно.
Данной
структуры каталогов следует придерживаться - не все пути можно
переопределить. Хотя я, например, выношу Instruments и Instruments-3d в
корень модели - просто потому, что имхо так удобнее.
Визуальная модель
Вопросы трехмерного моделирования в
данной статье не рассматриваются. Во-первых, потому, что я не могу
похвастаться большим опытом в данной области, а во-вторых, потому, что
визуальные модели для FGFS ничем не отличаются от моделей для любых
других современных авиасимуляторов (с учетом возможности конвертации
форматов, конечно). Вы можете использовать свой любимый 3D редактор, и
руководствоваться подробными факами и хелпами, которых есть, например,
на форумах авсим.ру. FlightGear понимает .3ds и .ac, причем второй
формат (AC3D), на мой взгляд, предпочтительней, потому что текстовый -
иногда это может пригодиться, и кроме того, он хорошо документирован.
Вы можете пользоваться готовыми моделями, взятыми из сети, а если
возникают "трудности перевода" - всегда можно воспользоваться
blender-ом. Этот редактор читает и пишет почти все, что существует в
трехмерной виртуальности, и вполне пригоден для создания моделей "с
нуля", но его интерфейс, на мой взгляд, создавался для инопланетян, и я
его ниасилил, сознаюсь честно.
FlightGear не читает mdl/bgl
(несмотря на обещания авторов PLIB). Есть очень ограниченная поддержка
mdl, но все это служит, скорее, иллюстративным целям. Не следует
надеяться, что FGFS сможет использовать модели для MSFS, по крайней
мере без серьезных трудозатрат по ручной разборке модели.
Это
связано с тем, что симуляторы по-разному комбинируют объекты и код
модели. Если для FG эти сущности разнесены по разным файлам, то MS
собирает все это в один объектный модуль. В этом, имхо, и кроется
основная трудность создания конвертора "из BGL во что-нибудь еще". BGL
- это полноценный процедурный язык программирования, и модель для MSFS
содержит в себе кроме объектов - полигонов и текстур, еще и код
анимации со своими условиями, ветвлениями итд. Не так сложно вытащить
модель, как правильно расставить анимированные объекты. Поэтому, на мой
взгляд, полноценный конвертер форматов невозможен - всегда потребуется
ручная обработка. Хотя, я был бы рад ошибиться в этих своих
предположениях. Проекты таких конвертеров существуют...
Авторы
FlightGear пошли другим путем. Модель и анимация разнесены по разным
файлам. При загрузке модели загружаются только трехмерные объекты -
вертексы, полигоны, текстуры. Все остальное игнорируется, поэтому для
загрузки в симулятор пригодны модели, созданные в любых 3D редакторах,
даже и тех, которые не поддерживают анимацию. Анимация в FlightGear
делается отдельно, с помощью специального интерфейса и отдельных
конфигурационных файлов.
Загрузить визуальную модель в FlightGear довольно просто. Давайте попробуем сделать это "с нуля".
Вначале,
нам нужен какой-нибудь трехмерный объект. Вы можете наваять некое
подобие самолета в своем любимом редакторе, но можно просто
воспользоваться готовым файлом, например
FlightGear/Models/Geometry/tuxcopter.ac
Создайте директорию test в своем домашнем каталоге, а в ней - директорию Model.
Сделайте
символическую ссылку test-> FlightGear/Aircraft/test. Это
единственное место, где нам понадобятся рутовые права. Как тут быть
пользователям винды - я не знаю. Придется, наверно, создать
Aircraft/test под администратором и открыть ее пользователю на запись.
Впрочем, насколько я знаю, под виндой все сидят с правами
администраторов, так что тут не должно быть проблем...
Создайте файл test/test-set.xml, и запишите в него следующее:
<PropertyList> <sim> <description>Test FlightGear Model</description> <model> <path>Aircraft/test/Model/test-model.xml</path> </model> <flight-model>null</flight-model> </sim> </PropertyList>
Это
главный файл модели. Тут мы пишем короткое описание модели и ставим
ссылку на файл визуальной модели Model/test-model.xml. Кроме этого, мы
указываем симулятору, что вычислять полетную динамику не нужно.
Скопируйте FlightGear/Models/Geometry/tuxcopter.ac ->; /test/Model/test.ac. Это у нас будет сама трехмерная модель.
Теперь опишем визуальную модель. Создайте файл test/Model/test-model.xml и запишите в него следующее:
<PropertyList> <path>test.ac</path> <offsets> <x-m>0.0</x-m> <y-m>0.0</y-m> <z-m>3.5</z-m> <heading-deg>90.0</heading-deg> </offsets> </PropertyList>
Тут мы указываем симулятору, что нужно использовать файл трехмерной
модели test.ac и определяем начальные смещения: нулевые по оси
"вперед-назад" и "влево-вправо", три c половиной метра вверх, и
поворачиваем модель на 90 градусов против часовой стрелки (если
смотреть сверху).
Готово. Теперь если дать команду в консоли fgfs --show-aircraft, то в длинном списке имеющихся самолетов можно увидеть:
test Test FlightGear Model
Запустив симулятор командой fgfs --aircraft=test, и переключившись
на внешний вид, мы получим картинку странно знакомого вертолетика в
торце взлетной полосы KSFO.
Теперь следующий шаг. Закройте
сим, замените в файле test-set.xml строку
<flight-model>null</flight-model> строкой
<flight-model>ufo</flight-model>.
Запустите сим.
Теперь наш вертолетик управляется с помощью особой FDM - динамикой UFO,
и как и положено приличному НЛО, способен на всякие энергичные
эволюции. Можно порулить по сценарию Фриско и окрестностей, и
погоняться за трафиком. Предполагается, что джойстик у вас настроен.
Как видим, все довольно просто.
Property Tree
Мне не нравится, как это принято
переводить. "Дерево свойств"... по-русски как-то не звучит, хотя для
программера привычно. Мне кажется, вместо "свойств" тут более точным
был бы термин "параметры", ну да ладно. Свойства так свойства. В виде
дерева.
Property Tree - совокупность глобальных переменных,
служащих для обмена информацией между различными частями программного
комплекса FlightGear, структурированная наподобие файловой системы.
Можно сказать, это "нервная система" авиасимулятора.
Если
открыть встроенный браузер свойств в меню File->Browse Internal
Properties, то легко можно провести аналогию с фаловой системой.
Переменные выполняют роль "файлов", а древовидная структура точно
соответствует привычным "директориям". В дальнейшем, я буду иногда
использовать эти термины, ставя их в кавычки.
С точки зрения автора модели, обмен с переменными property
tree - единственная возможность чем-то управлять или получать
какую-либо информацию в симе. Свойства можно читать, некоторые - можно
изменять. Можно создавать свои собственные свойства, наподобие того,
как программист может объявлять переменные в своей программе. Свойства
могут быть разных типов - булевые, целые, строковые, с плавающей
точкой. Свойства можно инициализировать, а можно и нет - тогда, до
первого присваивания, свойство имеет особое значение "nil". Свойства
можно устанавливать из различных конфигурационных файлов симулятора, и
даже подгружать таким образом целые "деревья свойств", а можно любое
свойство изменить из командной строки при старте сима, или из
встроенного браузера в процессе полета, или даже с помощью встроенного
HTTP или telnet - сервера, подключившись к ним средствами операционной
системы.
Большая часть свойств служит для внутренних нужд
симулятора, и автору модели никогда не придется читать или
перезаписывать их (как, например, выходные данные FDM - полетной
динамики). С другой стороны, наблюдать некоторые параметры очень
полезно в образовательных целях, например зависимость тяги винта от
оборотов/скорости/угла установки лопастей итд. Некоторые свойства
специально разработаны для взаимодействия с моделями, это практически
все, что находится в ветках /Controls и /Instrumentation. Часть свойств
могут казаться нерабочими, изменение их значения не оказывает влияние
на работу сима - так происходит потому, что различные FDM имеют
собственные управляющие параметры, которые неактивны, когда симулятор
работает с другой динамикой.
Давайте научимся пользоваться
свойствами property tree. Для начала, установим собственное свойство
(параметр) и свяжем его с нажатием на клавишу.
Вообще, на
данном этапе, предполагается что синтаксис xml не представляет
сложностей. Важно следить за тем, чтобы каждый открывающий тэг имел
свой закрывающий... да вобщем-то и все...
Итак. мы хотим
сконфигурировать изменение свойства (параметра) при нажатии клавиши.
Нажимать будем "d", ее код в симуляторе - 100. Коды клавиш можно
посмотреть в FlightGear/Docs/keyboard/map.pdf, или в
FlightGear/keyboard.xml. После просмотра крайнего файла, несложно
понять, как это все конфигурируется.
Работаем с
конфигурационным файлом test-set.xml. На первый раз я напишу подробный
комментарий, но вообще все интуитивно понятно и так. После закрывающего
тега </sim> добавляем:
<input> <!-- òóò â ñèìå õðàíÿòñÿ ïåðåìåííûå äëÿ âñåõ óñòðîéñòâ ââîäà --> <keyboard> <!-- òóò - äëÿ êëàâèàòóðû --> <key n="100"> <!-- ýòî - êîíôèãóðàöèÿ êëàâèøè ñ êîäîì 100 --> <name>d</name> <!-- íà êëàâèàòóðå îíà ïîìå÷åíà êàê d --> <desc>my variable</desc> <!-- ïðîñòî îïèñàíèå --> <binding> <!-- Ñâÿçûâàåì... --> <command>property-toggle</command> <!-- êîìàíäó "èíâåðòèðîâàòü ñîéñòâî"... --> <property>/tuxmodel/test</property> <!-- ñ ñâîéñòâîì (ïåðåìåííîé) /tuxmodel/test --> </binding> </key> </keyboard> </input>
Запускаем сим, не нажимаем пока клавиши.
Открываем File->Browse Internal Properties, и в открывшемся окошке
убеждаемся, что никакого упоминания о нашей переменной нет. Все
правильно - мы не нажимали сконфигурированную клавишу. Нажимаем "d", и
видим внизу списка появившуюся в момент нажатия новую "директорию"
/tuxmodel, а в ней - "файл" test. Нажимая "d", можно убедиться, что при
каждом нажатии булевая переменная инвертируется.
Существует
довольно ограниченный набор встроенных команд для работы со свойствами.
Свойству можно присвоить фиксированное значение или значение,
хранящееся в другом свойстве (команда property-assign), изменить
значение на некоторую величину (property-adjust), при этом можно задать
верхний и нижний пределы. Можно обменять местами значение двух свойств
(property-swap), например, сменив частоты настроек
"operate<->standby". Свойства можно умножить на фиксирванную
величину (property-multiply), и можно связать переменную с осью
джойстика (property-scale). Вот, в принципе, и все.
Следующий
пример чуть сложнее. Он иллюстрирует, как сделать часто требуемую фичу
- обработку отпускания клавиши. Переписываем связывание:
<input> <keyboard> <key n="100"> <name>d</name> <desc>my variable</desc> <binding> <command>property-assign</command> <property>/tuxmodel/test</property> <value>"key d pressed"</value> </binding> <mod-up> <binding> <command>property-assign</command> <property>/tuxmodel/test</property> <value>"key d released"</value> </binding> </mod-up> </key> </keyboard> </input>
Как видим, работать со строками ничуть не сложнее, чем с булевыми переменными.
В
практике работы с моделью, постоянно возникает необходимость
инициализировать переменные при старте симулятора. Иногда (да почти
всегда!) переменная должна иметь определенное значение, даже если код,
который ее модифицирует, ни разу не выполнялся. Это типично для
переменных, выполняющих функции разных флагов, признаков состояния итд.
Давайте добавим такую инициализацию для нашего примера (продолжаем
работать с test-set.xml). Добавляем описание переменной (свойства) test
в "директории" /tuxmodel:
<tuxmodel> <test type="string" archive="y">"Key d has not pressed yet"</test> </tuxmodel>
Модификатор type="string" указывает симу, что
эта переменная - строковая. Это аналог объявления переменной в
привычных языках программирования. Можно и не объявлять, сим достаточно
умный, но в браузере свойств у необъявленных переменных стоит тип
"unspecified", что не так информативно, как строгое описание типа
"bool" или "string". Второй модификатор, archive="y", указывает симу,
что данную переменную необходимо обрабатывать, когда выполняется
сохранение полета. При последующей загрузке сохраненного полета,
переменной будет присвоено нужное значение.
Ну вот. Теперь можно снова запустить сим, открыть браузер свойств, и, нажимая "d", убедиться, что все работает как ожидалось.
Анимация
Анимация - это способ определить "правила
движения" для различных объектов модели. Но вначале давайте разберемся,
что там и куда движется.
Симулятор ( точнее, выбранный модуль
полетной динамики ) рассчитывает движение модели в абсолютных
координатах "широта-долгота-высота". Высота тут - это либо высота над
уровнем моря, либо превышение над препятствием, оба параметра доступны
одновременно. Получить эти цифры можно из переменных property tree,
ветка /position. По большому счету, для симулятора нет никакой разницы
- находитесь вы в воздухе или уже под поверхностью. Недавно в
девел-листе, разработчики FlightGear обсуждали возможность создания FDM
для моделирования движения надводных и подводных объектов - судов,
подводных лодок, и соответствующих сценариев. Подводные экскурсии,
дайвинг и все такое.
Абсолютные координаты
"широта-долгота-высота" пересчитываются графическим движком симулятора
в координаты модели в трехмерном пространстве сцены OpenGL. При этом
используются различные хитрости - например, для избежания джиттера
(дрожания) объектов, расположенных близко к наблюдателю (прежде всего -
объектов в виртуальной кабине - ВК), центр сцены OpenGL смещается
скачком в точку расположения модели, как только модель удалится на 30
метров от этого центра по любой координате. Если так не делать, то на
больших расстояниях ошибка представления числа с плавающей точкой
приведет к заметному дрожанию объектов вблизи наблюдателя. Все эти
тонкости скрыты как от моделлера, так и от симера.
Нам важно
понимать, что модель движется в сцене, и все смещения в анимациях
модели задаются в системе координат, движущейся вместе с моделью.
Заметим тут, что в отличие от анимации модели, возможна также (не
всегда) анимация для статических объектов, например для объектов
сценария, система координат которых неподвижна в абсолютных значениях
"широта-долгота-высота".
Если открыть любую книжку по
трехмерной компьютерной графике, и почитать про программирование
движения объектов, то нам сразу встретится понятие "матрица
преобразования". Матрица преобразования - это матрица чисел с плавающей
точкой, размерностью 4х4. С помощью таких матриц определяется движение
объекта в трехмерном пространстве. В зависимости от того, какие
элементы матрицы заполнены ненулевыми значениями, матрица может
задавать смещение объекта, вращение, масштабирование или все это
одновременно. Матрица преобразования - общепринятый, универсальный
способ программирования движения трехмерных объектов в пространстве
сцены.
Если мы дизассемблируем модель для MSFS (файлы bgl,
mdl) в формат SCASM, то среди различных элементов модели мы обязательно
встретим что-то типа:
Transform_Mat( -0.051 -0.273 -98.292 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 );
Это и есть матрица преобразования. Для MSFS
анимация собрана в единое целое с самой моделью, в единый двоичный
файл. В FlightGear этот механизм реализован по-другому.
В
FlightGear анимация задается с помощью специальных конфигурационных
команд в xml-файле модели. Команды конфигурирования анимации - это
текстовый интерфейс к матрицам преобразования OpenGL. Обычно, анимация
связана с одним или несколькими переменными из property tree. Если
рассмотренный нами в предыдущем разделе пример устанавливал переменную
в зависимости от нажатия клавиши, (т.е. являлся источником информации)
то анимация - это потребитель этой информации.
Для объектов FlightGear доступны следующие виды "настоящей" анимации:
translate - смещение объекта;
rotate - поворот объекта на заданный угол;
spin - вращение объекта с заданной скоростью;
scale - масштабирование, изменение размера;
billboard - поворот объекта к наблюдателю. эта анимация, имхо, используется только для наземных объектов, в основном деревьев.
Кроме этих видов, существуют еще "псевдо-анимации", не меняющие положение объекта, но изменяющие его атрибуты:
none
- нет анимации. none - анимация "по умолчанию", если тип анимации не
указан вообще. Этот тип используется для объединения объектов в группу,
для последующей обработки группы как единого целого, либо для изменения
порядка отрисовки объектов, что важно, если у нас есть прозрачные
объекты.
blend - управление прозрачностью объекта;
select - удаление объекта из сцены или наоборот, его вставка в сцену;
timed - отрисовка объекта в течении заданного интервала времени;
texrotate - сам объект неподвижен, вращается текстура на объекте;
textranslate - сам объект неподвижен, текстура линейно смещается;
texmultiple
- способ комбинирования двух предыдущих текстурных анимаций,
применительно к одному объекту. Поскольку необходимость данной анимации
вызвана ограничениями движка PLIB, эта анимация, возможно, будет
неактуальна в OSG-ветке.
material -
управление всеми возможными свойствами материала объекта, включая путь
к файлу текстуры. Очень широко используемая анимация - она позволяет не
только зажигать лампочки, но и динамически менять текстуры - что
позволяет в полете менять ливреи, использовать подсвеченные ночные
текстуры итд.
range - удаление объекта из
сцены, если расстояние от него до наблюдателя вышло из заданного
диапазона. С помощью этой анимации делается LOD.
alpha-test - способ оптимизации отрисовки группы объектов, имеющих прозрачность. Не могу ничего более подробно написать...
noshadow
- не рисовать тень для объекта. Вообще, просчет и отрисовка тени -
довольно дорогая фича, с точки зрения fps. поэтому для тех объектов,
которые заведомо не могут давать видимую снаружи тень (интерьеры, ВК
етс), следует использовать эту анимацию. Сильно способствует росту fps.
Впрочем, код, отвечающий за отрисовку теней, сейчас переписывается, так
что в osg-devel ветке теней пока нет вообще.
dist-scale
- масштабирование объекта в зависимости от расстояния до точки
наблюдения. Анимация специально разработана для компенсации видимости
огней (полосы, VASI етс) в дымке. Огни слишком плохо было видно, вот и
решили увеличить их размер с помощью этой анимации.
flash
- масштабирование объекта в зависимости от угла его видимости. Казалось
бы - абсолютно бессмысленная вещь, ничего похожего в реальности
представить невозможно. отнюдь:) эта анимация придумана вот для чего.
Представьте, что мы ночью смотрим на направленный источник света -
например, фару. Если смотреть на такой источник сбоку, то размер
светящейся области невелик, но если изменить положение точки наблюдения
таким образом, что наблюдатель окажется в луче направленного света -
размер светящейся области покажется значительно бОльшим. Особенно этот
эффект хорошо заметен, если используется оптика - из-за засветки
объектива. Анимация flash позволяет делать очень симпатичные
проблесковые маячки, всякие мигалки, фары, которые при наблюдении в
луче не выглядят мелкими точками, но превращаются в большие яркие
светящиеся шары итд. Дефолтный beacon - мачта с вертящимся прожектором
- хороший пример использования этой анимации.
pick
- поддержка мышиных кликов. Наведя курсор на объект и нажав кнопку
мыши, мы получим изменение заданного свойства. Имхо, это единственная
анимация, которая изменяет значение переменной - все остальные только
читают. Эта анимация появилась недавно, она еще не документрована и
работает только в ветке OSG-devel симулятора. Я специально не
использовал ее в модели Ан-2, чтобы дать возможность управлять моделью
в текущем релизе.
Для получения полной информации о синтаксисе всех анимаций
FlightGear, обязательно нужно прочитать файл
FlightGear/Docs/model-howto.html. Да, на английском. Может быть,
какой-нибудь доброволец сделает перевод? Только обратите внимание на
дату последней модификации файла! В заголовке howto по-прежнему стоит
2002 год, но это дата создания - реально, изменения вносятся туда
постоянно, последняя редакция этого файла (на момент написания статьи)
- январь 2007 года. Последнюю версию документации можно взять из CVS, и
если вы пользуетесь devel-версией сима (что я вам рекомендую, тем более
есть готовые бинарники для винды) - обязательно обновляйте документацию!
Давайте
попробуем анимировать нашу модель. У нас там сейчас летает простенький
вертолетик, очень схематично сделанный. Для анимации, нам нужно знать
названия объектов модели, которые мы хотим привести в движение, и в
некоторых случаях - координаты. Нам теперь понадобится 3D редактор,
способный понимать формат ac. Я буду пользовать AC3D, но с успехом
можно применять blender.
Итак. Открываем test.ac в редакторе и смотрим, что там и как:
Видно,
что модель неверно ориентирована - ось X смотрит вбок, а не вперед по
ходу модели. Именно поэтому нам пришлось развернуть модель тегом
<heading-deg>90.0</heading-deg> в файле test-model.xml.
Убираем этот тег в исходном файле и разворачиваем модель в редакторе.
Для этого "выделяем все" и поворачиваем на 90 градусов по оси Y. Здесь
же, обнуляем вертикальное смещение - ставим <z-m>0.0</z-m>.
В результате, при старте, в начальной точке модель просядет, но для FDM
UFO это неважно - модель все равно не опирается на землю, а вот нулевое
смещение модели будет важно, когда мы позже будем работать с ВК.
Допустим, мы хотим анимировать шасси. Их в модели есть - хотя и выглядят они своеобразно:
Кроме этого, мы анимируем оба ротора - несущий и хвостовой. Но начнем с шасси.
Мы
запомнили названия объектов, теперь можно графический редактор закрыть
и перейти к работе с анимациями. Вначале, подготовим переменную для
управления анимацией шасси. Перепишем наш пример test-set.xml, чтобы
файл содержал следующее:
<PropertyList> <sim> <description>Test FlightGear Model</description> <model> <path>Aircraft/test/Model/test-model.xml</path> </model> <flight-model>ufo</flight-model> </sim>
<input> <keyboard> <key n="103"> <name>g</name> <binding> <command>property-assign</command> <property>/tuxmodel/gear</property> <value>0.0</value> </binding> </key> <key n="71"> <name>G</name> <binding> <command>property-assign</command> <property>/tuxmodel/gear</property> <value>1.0</value> </binding> </key> </keyboard> </input>
<tuxmodel> <gear type="double" archive="y">1.0</gear> </tuxmodel>
</PropertyList>
Мы связали две клавиши с одной переменной. Одной клавишей мы
устанавливаем переменную в 1.0, второй - сбрасываем в 0.0. Переменную
описываем как число с плавающей точкой и присваиваем ей начальное
значение 1.0, что будет у нас соответствовать выпущенным шасси. На этом
этапе можно снова запустить сим и убедиться, что переменная правильно
управляется.
Открываем файл test-model.xml и пишем туда:
<animation> <type>translate</type> <!-- Òèï àíèìàöèè --> <object-name>landing_gear</object-name> <!-- Èìÿ îáúåêòà èç ôàéëà ìîäåëè --> <property>/tuxmodel/gear</property> <!-- Èìÿ óïðàâëÿþùåé ïåðåìåííîé --> <factor>0.3</factor> <!-- Êîýôôèöèåíò ïðîïîðöèîíàëüíîñòè --> <axis> <!-- Îñü, ïî êîòîðîé áóäåò ïðîèçâîäèòüñÿ ïåðåìåùåíèå --> <x>0.0</x> <y>0.0</y> <z>-1.0</z> </axis> </animation>
Запускаем сим, переключаемся на внешний вид, давим g/G и убеждаемся, что ноги дергаются, как и ожидалось.
Некоторые
пояснения к анимации. В данном примере, мы смещаем объект landing_gear
(это имя должно соответствовать имени объекта в файле test.ac).
Расстояние в метрах, на которое смещается объект, получается из
умножения переменной /tuxmodel/gear на множитель 0.3. Поскольку у нас
переменная принимает значения 0.0 и 1.0, объект будет перемещен на 30
см. Направление перемещения задается вектором <axis> с
координатами X:0.0, Y:0.0, Z:-1.0. Если мы сидим на пилотском кресле,
то направление X будет для нас - назад, Y - вправо, Z - вверх.
Абсолютное значение координат вектора направления особого смысла не
имеет, важны их относительные величины. В данном примере, вектор
смотрит вниз, и именно в этом направлении будет смещаться объект, от
своего начального положения в файле test.ac.
Давайте поработаем с ротором. Для этого создадим еще одну переменную в дереве свойств (ветка /tuxmodel) и назовем ее rotor:
<tuxmodel> <gear type="double" archive="y">1.0</gear> <rotor type="double" archive="y">0.0</rotor> </tuxmodel>
В ветке /input/keyboard сконфигурируем связывание клавиши d/D для этой переменной:
<key n="100"> <name>d</name> <binding> <command>property-adjust</command> <property>/tuxmodel/rotor</property> <step>0.1</step> <max>1.0</max> </binding> </key> <key n="68"> <name>D</name> <binding> <command>property-adjust</command> <property>/tuxmodel/rotor</property> <step>-0.1</step> <min>0.0</min> </binding> </key>
Обратите внимание: команда тут другая, и мы
на каждое нажатие изменяем переменную /tuxmodel/rotor на 0.1, при этом
контролируем диапазон.
Чтобы правильно закрутить ротор, нам
нужно задать ось вращения. Ось можно задать так: указать точку, задав
три ее координаты, и вектор <axis>, как в примере для шасси. Для
данного примера, ось вращения ротора должна быть вертикальна, так что
значения <axis> понятно. Осталось найти координаты. Откроем наш
графический редактор, и курсором укажем на центр вращения в
соответствующей проекции.
Отметим, что центр вращения нужно указывать с максимальной
точностью. Редактор должен давать координаты курсора в метрах, и для
удовлетворительной точности нам нужно не меньше трех знаков после
запятой. Для больших вращающихся объектов (колес шасси, роторов, разных
ручек итд) иногда смещение оси на полсантиметра приводит к заметному
вихлянию объекта. Точность установки осей для мелких деталей
соответственно еще выше.
Заметим также, что модель у нас
смещена влево от продольной оси симметрии, и это тоже нужно устранить.
Чтобы избежать ошибок, я просто выделяю всю модель и даю команду "move
to 0,0,0". Видно, что с симметрией у модели не все в порядке, ну да
ладно.
Подвожу курсор к центру ротора: X:-1.871, Y:0.0,
Z:-0.078. На скриншоте координаты курсора не соответствуют записанным -
ибо пришлось мышой нажать на "сохранить экран".
Обратите
внимание: оси модели не соответствуют осям FlightGear (к сожалению,
особенность AC3D), и у получившихся координат нужно поменять местами Y
и Z. Нулевое значение по Z смущать не должно - ось вращения совпадает с
Z, так что координата по этой оси может быть любая.
Пишем новую анимацию в test-model.xml:
<animation> <type>spin</type> <object-name>rotors</object-name> <property>/tuxmodel/rotor</property> <factor>200.0</factor> <center> <x-m>-1.871</x-m> <y-m>-0.078</y-m> <z-m>0.0</z-m> </center> <axis> <x>0.0</x> <y>0.0</y> <z>1.0</z> </axis> </animation>
>
Обратите внимание: задавая центр, мы поменяли местами Y и Z. Для
анимации spin значение управляющей переменной - это RPM, обороты в
минуту. Множитель 200 дает нам максимальный RPM 200 об/мин, т.к. сама
переменная у нас меняется в диапазоне 0.0 - 1.0. Запустив сим, можно
поиграться с плавным изменением скорости вращения, нажимая d/D. Видно,
что ротор вращается кривовато, и не по центру симметрии модели - но это
результат кривости самого ротора. Это хороший пример, показывающий, что
лишней точности в установке вращающихся объектов модели просто не
бывает.
Давайте освоим еще один способ задания оси вращения анимаций spin,
rotate - указав координаты двух точек, через которые проходит ось.
Такой способ рекомендуют применять в случае, когда ось вращения не
совпадает с осью X, Y или Z. Это характерно, например, для осей
элеронов, когда крыло стреловидное и V-образное. Опять откроем файл
модели в графическом редакторе и запишем координаты двух точек, лежащих
на воображаемой оси вращения хвостового ротора:
<animation> <type>spin</type> <object-name>tail_rotor</object-name> <property>/tuxmodel/rotor</property> <factor>400.0</factor> <axis> <x1-m>9.774</x1-m> <y1-m>-1.0</y1-m> <z1-m>1.469</z1-m> <x2-m>9.774</x2-m> <y2-m>1.0</y2-m> <z2-m>1.469</z2-m> </axis> </animation>
Все координаты тут - в метрах, о чем говорит
<-m> в тегах. Скорость вращения хвостового ротора я увеличил
вдвое. Вроде бы, все наглядно и понятно.
Ну вот, в общем, как конфигурируются основные типы анимации - смещение и вращение.
Да,
чуть не забыл. Любой объект может иметь неограниченное количество
анимаций, в каждую анимацию может входить несколько объектов, но
группировки объектов и последовательности анимаций имеют определенные
тонкости, которые могут взорвать мозг начинающему моделлеру. Часть
таких особенностей я опишу позже.
Виртуальный кокпит
Если есть визуальная модель - значит, есть и виртуальный кокпит. Давайте туда переместимся. Откроем
наш редактор, и выберем координаты точки, где бы мы хотели поместить
точку наблюдения в ВК - другими словами, откуда пилот будет смотреть на
окружающий мир. Я взял точку с координатами X:-4.3, Y:-0.5, Z: 2.6.
Точка наблюдения смещена влево на полметра от продольной оси модели -
считаем, что там у нас "левая чашка":)
Конфигурируем обзор. В файл tes-set.xml, в секцию /sim добавляем:
<virtual-cockpit archive="y">true</virtual-cockpit> <view> <internal archive="y">true</internal> <config> <x-offset-m archive="y">-0.5</x-offset-m> <!--Left-right--> <y-offset-m archive="y">2.6</y-offset-m> <!--Down-Up--> <z-offset-m archive="y">-4.3</z-offset-m> <!--Fwd-Back--> </config> </view>
Мы сконфигурировали нулевой режим обзора.
Режимов обзора по умолчанию шесть: Cockpit View, Helicopter View, Chase
View, Tower View, Tower View Look From, Chase View wo yaw.
Переключаеются виды клавишей V, но очень желательно сдублировать ее на
джойстике.
Вы можете добавлять свои собственные обзоры и
менять дефолтные установки существующим. Кстати, все дефолтные
настройки симулятора живут в файле preferences.xml.
Нулевой
режим обзора - ВК (Cockpit View). Сим стартует именно в нем, но если он
не сконфигурирован (как было у нас раньше) - в этом обзоре модель будет
не видна - только окружающий мир.
Обратите внимание, что для
координат точки наблюдения оси поменяны местами. Почему - лучше
спросить в devel-листе у авторов... имхо, это один из тех случаев,
когда баг объявляется фичей...
Теперь, когда вы запустите
сим, вы можете повертеть головой внутри ВК нашей модели. Конечно, там
сейчас пусто, и для реальных моделей обязательно нужно построить
интерьер (3D, обращая внимание на нормали!), расставить пилотские
кресла, воздвигнуть штурвальные колонки (анимированные, а как же!), но
для освоения принципов пока пусть все будет как есть. Главное - мы
видим перед собой панель, и все готово для того, чтобы расставить на
ней приборы.
Приборы
Приборы
|