<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://stalkerin.gameru.net/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://stalkerin.gameru.net/wiki/index.php?action=history&amp;feed=atom&amp;title=%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D1%82_%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2_%2A.omf</id>
		<title>Формат файлов *.omf - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://stalkerin.gameru.net/wiki/index.php?action=history&amp;feed=atom&amp;title=%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D1%82_%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2_%2A.omf"/>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D1%82_%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2_*.omf&amp;action=history"/>
		<updated>2026-06-09T12:16:39Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.22.6</generator>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D1%82_%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2_*.omf&amp;diff=15154&amp;oldid=prev</id>
		<title>Pavel: Новая страница: «В этой статье описан формат omf из ТЧ, ЧН и ЗП.  OMF файлы содержат скелетные анимации.  Имеют …»</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D1%82_%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2_*.omf&amp;diff=15154&amp;oldid=prev"/>
				<updated>2020-06-10T15:15:39Z</updated>
		
		<summary type="html">&lt;p&gt;Новая страница: «В этой статье описан формат omf из ТЧ, ЧН и ЗП.  OMF файлы содержат скелетные анимации.  Имеют …»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;В этой статье описан формат omf из ТЧ, ЧН и ЗП.&lt;br /&gt;
&lt;br /&gt;
OMF файлы содержат скелетные анимации.&lt;br /&gt;
&lt;br /&gt;
Имеют формат RIFF. То есть файл разбит на чанки.&lt;br /&gt;
&lt;br /&gt;
Файл omf состоит из двух чанков:&lt;br /&gt;
&lt;br /&gt;
0xE - хранит анимации (вращение, перемещение костей)&lt;br /&gt;
&lt;br /&gt;
0xF - хранит Bone Parts и параметры анимаций&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Эти чанки могут встечаться внутри ogf файлов.&lt;br /&gt;
&lt;br /&gt;
То есть omf файл - это кусок ogf файла, который вынесен во внешний файл.&lt;br /&gt;
&lt;br /&gt;
Структура 0xE и 0xF чанков в ogf идентична этим же чанкам в omf.&lt;br /&gt;
&lt;br /&gt;
== Структура чанка 0xE ==&lt;br /&gt;
&lt;br /&gt;
Данный чанк состоит из вложенных чанков.&lt;br /&gt;
&lt;br /&gt;
Первый вложенный чанк - это чанк с идентификатором 0x0.&lt;br /&gt;
&lt;br /&gt;
Нулевой чанк хранит целое беззнаковое 32 битное число.&lt;br /&gt;
&lt;br /&gt;
Это число указывает на количество анимаций в omf файле.&lt;br /&gt;
&lt;br /&gt;
Идентификатор каждого последущего чанка на единицу больше предыдущего.&lt;br /&gt;
&lt;br /&gt;
То есть после вложенного чанка 0x0 идёт чанк 0x1, потом 0x2, 0x3 и т. д.&lt;br /&gt;
&lt;br /&gt;
Все чанки, идущие после 0x0, содержат анимации.&lt;br /&gt;
&lt;br /&gt;
=== Описание вложенного чанка, который хранит анимации ===&lt;br /&gt;
&lt;br /&gt;
В самом начале идёт имя анимации, которое является строкой, оканчивающейся нулевым байтом.&lt;br /&gt;
&lt;br /&gt;
Далее идёт целое беззнаковое 32 битное число, которое указывает количество кадров анимации.&lt;br /&gt;
&lt;br /&gt;
Следующие данные - это трансформации костей. Для каждой кости хранится вращение, перемещение, флаги.&lt;br /&gt;
&lt;br /&gt;
На первом месте идут флаги. Флаги - это целое беззнаковое 8 битное число.&lt;br /&gt;
&lt;br /&gt;
Первый бит этого байта указывает, является ли перемещение изменяемым.&lt;br /&gt;
&lt;br /&gt;
Если бит равен 1, то на протяжении всех кадров перемещение имеет значения.&lt;br /&gt;
&lt;br /&gt;
Если бит равен 0, то перемещение имеет только одно значение для всего промежутка анимации.&lt;br /&gt;
&lt;br /&gt;
Это сделано для оптимизации, чтобы не хранить кучу одинаковых ключей, а вместо этого иметь одно значение.&lt;br /&gt;
&lt;br /&gt;
Второй бит этого байта указывает, является ли вращение статичным (не меняющимся на протяжении всей анимации).&lt;br /&gt;
&lt;br /&gt;
Третий бит - это флаг High Quality. Если равен 0, то позиция имеет 8 битное представление иначе 16 битное.&lt;br /&gt;
&lt;br /&gt;
Далее идёт информация о вращении.&lt;br /&gt;
&lt;br /&gt;
То, что будет записано в файле дальше, зависит от флагов.&lt;br /&gt;
&lt;br /&gt;
Если второй бит флага равен 0, то в файле будет следующее:&lt;br /&gt;
&lt;br /&gt;
одно значение вращения в виде кватерниона с двухбайтовыми знаковыми компонентами.&lt;br /&gt;
&lt;br /&gt;
То есть QXYZ, каждый по 2 байта, в сумме 8 байт.&lt;br /&gt;
&lt;br /&gt;
А если второй бит флага равен 1, то далее идёт следующее:&lt;br /&gt;
&lt;br /&gt;
crc32 сумма в виде 4 байтового целого беззнакового.&lt;br /&gt;
&lt;br /&gt;
А после неё идут значения кватерниона вращения для каждого кадра.&lt;br /&gt;
&lt;br /&gt;
Формат вращения такой же, как описан выше (теже 8 байт).&lt;br /&gt;
&lt;br /&gt;
Теперь идёт информация о перемещении.&lt;br /&gt;
&lt;br /&gt;
Если первый бит флага равен 1, то далее следует 32 битное целое беззнаковое число, которое является crc32 суммой.&lt;br /&gt;
&lt;br /&gt;
После идёт 3 восьмибитных числа, которые указывают позицию кости по осям x, y, z.&lt;br /&gt;
&lt;br /&gt;
Эти позиции записаны для каждого кадра.&lt;br /&gt;
&lt;br /&gt;
То есть считывать позиции нужно в цикле, который повторяется столько раз, сколько кадров содержит анимация.&lt;br /&gt;
&lt;br /&gt;
После всех этих позиций идут данные о начальных условиях перемещения:&lt;br /&gt;
&lt;br /&gt;
Амплитуда или размер перемещения.&lt;br /&gt;
&lt;br /&gt;
Это 3 числа float (4 байта каждое).&lt;br /&gt;
&lt;br /&gt;
А далее идёт начальное значение перемещения. Тоже 3 числа float.&lt;br /&gt;
&lt;br /&gt;
Эти начальные условия хранятся в единственном экземпляре для каждой кости в данной анимации.&lt;br /&gt;
&lt;br /&gt;
То есть эти значения не меняются на протяжении всей анимации.&lt;br /&gt;
&lt;br /&gt;
Если первый бит флага равен 0, то для всех кадров идёт одно значение перемещения.&lt;br /&gt;
&lt;br /&gt;
Это перемещение хранится в 3 числах float (4 байта каждое).&lt;br /&gt;
&lt;br /&gt;
Ниже написан псевдокод, который описывает одну анимацию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
name = string&lt;br /&gt;
length = uint32&lt;br /&gt;
for bone in bones {&lt;br /&gt;
    flags = uint8&lt;br /&gt;
    translate_present = flags(0)    // get bit 0&lt;br /&gt;
    rotate_absent = flags(1)    // get bit 1&lt;br /&gt;
    high_quality = flags(2)    // get bit 2&lt;br /&gt;
    if rotate_absent {&lt;br /&gt;
        quaternion = int16, int16, int16, int16    // Q, X, Y, Z&lt;br /&gt;
    } else {&lt;br /&gt;
        motion_crc32 = int32&lt;br /&gt;
        for (i=0, i&amp;lt;length, i++) {&lt;br /&gt;
            quaternion = int16, int16, int16, int16    // Q, X, Y, Z&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if translate_present {&lt;br /&gt;
        motion_crc32 = int32&lt;br /&gt;
        if high_quality {&lt;br /&gt;
            for (i=0, i&amp;lt;length, i++) {&lt;br /&gt;
                translation = int16, int16, int16    // X, Y, Z&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            for (i=0, i&amp;lt;length, i++) {&lt;br /&gt;
                translation = int8, int8, int8    // X, Y, Z&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        translate_size = float, float, float    // X, Y, Z&lt;br /&gt;
        translate_init = float, float, float    // X, Y, Z&lt;br /&gt;
    } else {&lt;br /&gt;
        translate = float, float, float    // X, Y, Z&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Структура чанка 0xF ==&lt;br /&gt;
&lt;br /&gt;
Хранит bone parts и параметры анимаций.&lt;br /&gt;
&lt;br /&gt;
Ниже показан код, который описывает этот чанк.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
params_version = uint16   // версия формата параметров&lt;br /&gt;
partition_count = uint16    // количество bone parts&lt;br /&gt;
for (i=0, i&amp;lt;partition_count, i++) {&lt;br /&gt;
    partition_name = string    // имя bone part&lt;br /&gt;
    bone_count = uint16    // количество костей в данном bone part&lt;br /&gt;
    for (j=0, j&amp;lt;bone_count, j++) {&lt;br /&gt;
        if params_version == 3 {&lt;br /&gt;
            bone_name = string    // имя кости&lt;br /&gt;
            bone_id = uint32    // идентификатор кости&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    motion_count = uint16    // количество анимаций&lt;br /&gt;
    for (j=0, i&amp;lt;motion_count, j++) {&lt;br /&gt;
        // параметры анимации&lt;br /&gt;
        motion_name = string&lt;br /&gt;
        motion_flags = uint32&lt;br /&gt;
        bone_or_part = uint16&lt;br /&gt;
        motion = uint16    // идентификатор анимации из чанка 0xE&lt;br /&gt;
        speed = float32&lt;br /&gt;
        power = float32&lt;br /&gt;
        accrue = float32&lt;br /&gt;
        falloff = float32&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Участник: Pavel]]&lt;br /&gt;
[[Категория:Форматы файлов]]&lt;/div&gt;</summary>
		<author><name>Pavel</name></author>	</entry>

	</feed>