The first 16 bytes are a header. Bytes 0-3 are type INT and contain the number of animations. Bytes 4-7 are type INT and contain the offset of the first frame. Byte 8 is always 01. Bytes 9-15 are always 00.
This is an example from SHIP_ARG_S_FIGHTER_3_DATA.ANI:
Code: Select all
34 00 00 00 90 20 00 00 01 00 00 00 00 00 00 00
90 20 00 00 is 8336 in decimal. The first frame record starts at offset 8336 (in decimal)
After the header are the animation records
These records are 160 bytes long.
Bytes 0-63 are an ASCII text string for the component to be animated. The first 00 byte terminates the string. Most of the entries have leftover garbage after this.
Bytes 64-127 are an ASCII text string for the animation name. As before the first 00 byte ends the string. The animation names are the same as is in the XML.
Bytes 128-131 are type INT for the number of position frames in the animation.
Bytes 132-135 are type INT for the number of rotation frames in the animation.
Bytes 136-139 are type INT for the number of scaling frames in the animation.
Bytes 140-147 are all 00 in all files that I have inspected.
Bytes 148-151 are type Float and contain a max time for the animation.
Bytes 152-159 are all 00 in all files that I have inspected.
Code: Select all
61 6E 69 6D 5F 6C 61 64 64 65 72 5F 62 6F 61 72 anim_ladder_boar
64 00 63 68 5F 30 32 00 00 00 00 00 00 00 00 00 d.ch_02.........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
63 6F 63 6B 70 69 74 5F 6F 70 65 6E 69 6E 67 00 cockpit_opening.
69 76 65 00 00 00 00 00 00 00 00 00 00 00 00 00 ive.............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
03 00 00 00 03 00 00 00 03 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 80 3F 00 00 00 00 00 00 00 00 ......€?........
it contains three positioning frames, three rotation frames, and three scaling frames.
The max time is 00 00 80 3F which is 1.0 in decimal.
In ship_arg_s_fighter_03.xml, connection_45 with part anim_ladder_board does not have an animations entry. It can be found in the parent connection_44 with part anim_ladder:
Code: Select all
<animations>
<animation name="cockpit_closed" start="1" end="1"/>
<animation name="cockpit_opening" start="1" end="30"/>
<animation name="cockpit_open" start="30" end="30"/>
<animation name="cockpit_closing" start="30" end="60"/>
</animations>
Starting immediately after the last animation definition record is the first frame record.
The offset of the first of these records corresponds with the value from the header.
These records are 128 bytes in length.
Bytes 0-3 are float. This is the X value.
Bytes 4-7 are float. This is the Y value.
Bytes 8-11 are float. This is the Z value.
Bytes 12-15, 16-19, and 20-23 appear to be INT. If this is the last frame in an animation group the value will be 1. If this is not the last frame, the value will be 2, or 5. I haven't determined the difference between 2 and 5. These three values are always the same.
Bytes 24-27 are float. This is the ending time for the frame. The time of the last frame in the group should match the max time value from the animation record.
Bytes 76-127 sometimes have data in them, but I have not been able to determine a meaning for them. In fact, I zeroed out these bytes from all the frame records in a copy of the Pulsar, and not only did it still work, but I could not see a difference in the animations.
Here is a position frame:
Code: Select all
7C A2 42 BF 70 89 1C BE 00 00 00 00 02 00 00 00
02 00 00 00 02 00 00 00 AB AA 2A 3F 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 80 00 00 00 00 00 00 00 80 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
AB AA 2A 3F is 0.666666686534882 in decimal.
So, during this frame, the component will move to a relative position of -0.76, 0.153, 0.0 relative to the position in the XML file. This movement will end at two thirds of the full animation time of 1.0, and then the next frame will start.
This is a rotation frame:
Code: Select all
DB 0F C9 3F 00 00 00 80 00 00 00 00 01 00 00 00
01 00 00 00 01 00 00 00 00 00 00 40 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
The rotations appear to be in a three axis quaternion system. There is no W value in the record, which makes the effect of the value difficult for me to calculate. The component will rotate to a quaternion of 1.57,0,0 with an ending time of 2.0. This is the last rotation frame of this animation due to the 01 00 00 00 values.
The format of the scaling frame is the same:
Code: Select all
56 55 55 40 00 00 80 3F 00 00 80 3F 05 00 00 00
05 00 00 00 05 00 00 00 AB AA 2A 3F 2A 15 47 3F
48 9A AA 40 6C 75 1C 3F B8 65 15 40 2A 15 47 3F
00 00 80 3F 6C 75 1C 3F 00 00 80 3F 2A 15 47 3F
00 00 80 3F 6C 75 1C 3F 00 00 80 3F 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
During this frame, the component will scale to 3.3 times original size in the X axis while maintaining scale in the Y and Z axes. This frame ends at time 0.66 of 1.0
-----------
So far, I have done all my animation editing in a hex editor, using a spreadsheet I put together to calculate the frame offsets for each animation. There is a lot of trial and error, especially for rotation values, but it works.