Page 1 of 2

Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 17, 2009 3:04 am
by DemonicSandwich
Custom Animations Pt.01
(Raw Structures)


This topic is just for reference. I intend on making a topic on animations and explaining the raw structures there would clutter the topic.
But please, post your questions/ideas/whatever.

Things to note:
  • When I am referring to a meta value, this value is always in the Animations reflexive unless otherwise stated.
  • Not all values are mapped out or mapped out correctly. But there is enough to create a functioning animation.
Compression Types: (Mapped out, Unknown)
  • CODEC #0 no_compression_codec AVERAGE KEY RATIOS Rot:1.00, Trs:1.00, Scl:1.00
  • CODEC #1 uncompressed_static_data_codec AVERAGE KEY RATIOS Rot:1.00, Trs:1.00, Scl:1.00
  • CODEC #2 uncompressed_animated_data_codec AVERAGE KEY RATIOS Rot:1.00, Trs:1.00, Scl:1.00
  • CODEC #3 8byte_quantized_rotation_only_codec AVERAGE KEY RATIOS Rot:1.00, Trs:1.00, Scl:1.00
  • CODEC #4 byte_keyframe_lightly_quantized AVERAGE KEY RATIOS Rot:0.22, Trs:0.26, Scl:1.00
  • CODEC #5 word_keyframe_lightly_quantized AVERAGE KEY RATIOS Rot:1.00, Trs:1.00, Scl:1.00
  • CODEC #6 reverse_byte_keyframe_lightly_quantized AVERAGE KEY RATIOS Rot:0.27, Trs:0.64, Scl:0.12
  • CODEC #7 reverse_word_keyframe_lightly_quantized AVERAGE KEY RATIOS Rot:0.07, Trs:0.14, Scl:1.00
  • CODEC #8 blend_screen_codec AVERAGE KEY RATIOS Rot:1.00, Trs:1.00, Scl:1.00
============================================================================================================
-------------------------------------------------------------------------------------------------------------------------------------------------------
============================================================================================================

Image
Format 2 is identical to format 3 with the only difference being that Format 2's Rotation keyframes aren't compressed.
Format 2 also shares the same Pros/Cons of format 3.
See format 3 for more information.

Primary Header:
  • Same in all formats. See format 3.
Codec #2 Header:
  • Data End [unsigned integer]:
    • Defines the where the Keyframe data ends. This value is also in the meta and should be updated as this one is.
      This value is also just user reference as the animation will work without it being updated. However the value in the meta is used.
  • Rotated Keyframe Block Size [unsigned integer]:
    • Defines the total size off the Rotation Keyframe Block in bytes. Size is [Keyframe count * Rotation Node count * 16]
  • Position Keyframe Block Size [unsigned integer]:
    • Defines the total size off the Position Keyframe Block in bytes. Size is [Keyframe count * Position Node count * 12]
  • Scale Keyframe Block Size [unsigned integer]:
    • Defines the total size off the Scale Keyframe Block in bytes. Size is [Keyframe count * Scale Node count * 4]
Rotation Keyframe Block:
  • Keyframe:
    • I rotation [float]
    • J rotation [float]
    • K rotation [float]
    • W scale [float]
Position Keyframe Block:
  • See format 3.
Scale Keyframe Block:
  • See format 3.
Padding:
  • See format 3.
Node List Block:
  • See foramt 3.
============================================================================================================
-------------------------------------------------------------------------------------------------------------------------------------------------------
============================================================================================================

Image
Format 3 is one of 3 simple formats that have the bare minimum information to have a working animation as shown below.

Advantages:
  • This is a simple format, easy to work with for beginners.
Disadvantages:
  • It requires a key frame for every render frame so animating a single node for 1 second requires 30 keyframes.
    Since machines have a play speed modifier, you can create a simple machine animation with few keyframes.
Primary Header:
  • Codec [byte]:
    • Defines what compression format is used on the animation
  • Rotation Node Count [byte]:
    • Defines the number of nodes affected by Rotation. Purely user reference, has no affect on actual node counts.
  • Possition Node Count [byte]:
    • Defines the number of nodes affected by Possition. Purely user reference, has no affect on actual node counts.
  • Scale Node Count [byte]:
    • Defines the number of nodes affected by Scale. Purely user reference, has no affect on actual node counts.
  • Unknown [integer]:
    • Purpose still unknown. Leave it as is or make it zeros.
  • Playback Rate [float]:
    • What the name suggests. Haven't seen any significant affect when changed though. Leave it as is or make it 1.
  • Data Start (usually)[unsigned integer]:
    • It appears to define where the data starts. But will often reference the end of the data before the Node List.
      Not sure what it truly stands for.
Codec #3 Header:
  • Data End [unsigned integer]:
    • Defines the where the Keyframe data ends. This value is also in the meta and should be updated as this one is.
      This value is also just user reference as the animation will work without it being updated. However the value in the meta is used.
  • Rotated Keyframe Block Size [unsigned integer]:
    • Defines the total size off the Rotation Keyframe Block in bytes. Size is [Keyframe count * Rotation Node count * 8]
  • Position Keyframe Block Size [unsigned integer]:
    • Defines the total size off the Position Keyframe Block in bytes. Size is [Keyframe count * Position Node count * 12]
  • Scale Keyframe Block Size [unsigned integer]:
    • Defines the total size off the Scale Keyframe Block in bytes. Size is [Keyframe count * Scale Node count * 4]
Rotation Keyframe Block:
  • Keyframe:
    • I rotation [short]
    • J rotation [short]
    • K rotation [short]
    • W scale [short]

    The rotations in this format are 16-bit quantized. For the common man, you do the following:
    To Compress: (uncompressed float * 32,767 = compressed short)
    To Decompress: (compressed short / 32,767 = uncompressed float)

    An interesting little aspect of the rotations, Animations in Halo 2 actually use the inverse values. So when you're using a quats calculator to get your quaternions, make sure to reverse their signs before inserting them into your raw.
Position Keyframe Block:
  • Keyframe:
    • X position [float]
    • Y position [float]
    • Z position [float]
Scale Keyframe Block:
  • Keyframe:
    • Scale [float]
    I've only seen this used on first person animations, only on the camera node, and always 1.
    When I attempted to use this on an object, it self deleted.
There can be multiple blocks of one type depending on the number of nodes ticked.
Each block of animations will be assigned to the selected nodes in numerical order.
So if you have Rotation Nodes 2, 7, and 9 selected, there will be 3 blocks or Rotation Keyframes and will be applied to the nodes in numerical order with the first block affecting 2, the next affecting 7, and the next 9.

Then the Position animation blocks after those, also in numerical order and so on.

Padding:
  • This is optional. I've seen several animations with in raw padding, yet none of them fucking needed it.
    This padding will always come imediatly before the Node List Block. It's size is determined by the meta value Internal Padding Size [byte, offset: 60].
    Setting this value to 0 makes this padding block disappear so do that.
Node List Block:
  • Just a block of flags. Tick a flag and the respective node will be affected by animation.
    The size of this block should always be a multiple of 12. It's size is determined my the meta value Node List Size [byte, offset: 61]
    When set to 12, the list can handle objects with a node count up to 32 (0-31).
    When set to 24, the object can have 64 nodes and so on.
    The block is split into 3 groups of flags.
    The first group determines what nodes are affected by rotation, the second group for position, and the third group for scale.

    If looking at it in hex, the Node ticks for each group will be in order as follows:
    [7][6][5][4][3][2][1][0] - [15][14][13][12][11][10][9][8] - etc.
    Each flag corresponding to a Node index.
============================================================================================================
-------------------------------------------------------------------------------------------------------------------------------------------------------
============================================================================================================

Image
Format 6 uses Keyframes the way there are supposed to be used. As KEY frames, with the majority of the frames being Tweens.

This format adds two extra blocks of data to it's structure.
One block that determines how many Keyframes each Node will have, and an offset to to where it's Markers start from.

Advantages:
  • This format requires far fewer Keyframes to make a complex animation.
    You do not need a keyframe for each render frame.
Disadvantages:
  • It's a bit more complex to work with.
    Since it's Keyrame Markers are only 1 byte in size, you're animation cannot be longer than 256 frames, or ~8.5 seconds for non-machine objects.
    Machines are still limited to 256 frames but the frames can be stretched out.
--- will add structure later ---

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 17, 2009 6:21 am
by JacksonCougar
tl;dr but I liked the pictures.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 17, 2009 9:03 am
by DemonicSandwich
JacksonCougar wrote:tl;dr but I liked the pictures.
Too long, almost didn't wanna write it.
Now unless you wanna make a 3ds max script and injector, stfu. :lol:

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 17, 2009 11:41 pm
by Eaton
I want to know how you figured this out.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Wed Nov 18, 2009 12:59 am
by DemonicSandwich
Grim already had most of 2 and 3 mapped out. 8 is just a copy of 2, it just plays differently. And 6 I mapped out by fucking around with several machines that used the format.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Wed Nov 18, 2009 1:01 am
by Grimdoomer
I'm trying to find the code for it but I just woke up from my like 6 hour nap.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Mon Nov 23, 2009 11:45 am
by rentreg
well i cant leave a meaningful/helpful comment but, awsome!

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Mon Nov 23, 2009 7:20 pm
by Grimdoomer
I wish someone would fucking help.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Mon Nov 23, 2009 8:17 pm
by Gary
What can we do?

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 24, 2009 12:44 am
by Grimdoomer
Shock120 wrote:
Grimdoomer wrote:I wish someone would fucking help.
maybe I should go around and mass spam for help for Grimdoomie. :D :wink: :cougar
ugh, nevermind. its just there is no one :whogaf: :scared:

Grimdoomer completez this animations, then move onto another thing.
Cougar can't help. I need someone that knows assembly and can reverse code.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 24, 2009 1:57 am
by Twinreaper
I wish I knew how to do those things so I could help. But sadly even if I did, I will probably be done with Halo franchise as a whole after this map pack is released. I'm gettin too old to be learning assembly and shit. I do wish you luck Grimmie. You've been an outstanding teacher and friend!

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 24, 2009 7:41 am
by OwnZ joO
I wish I could help, but I am really fucking busy right now. I'm staying up all night to get a paper done and study for a test :(

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 24, 2009 11:45 am
by rentreg
yeah the reason why i cant help is because im too stupid :) . thats probably not a good thing but mhm yeah. i have a book (you could call it a booklet, 90 pages) that was handed down to me that goes into a little detail on assembly code (intel ASM86) which would probably allow me to assist in these kinds of topics but that would all depend on if i actually bother to read it. lemme know if i should.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 24, 2009 7:52 pm
by Grimdoomer
Knowing assembly is one thing, being able to interpret it is another.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 24, 2009 9:27 pm
by rentreg
very true.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Tue Nov 24, 2009 9:29 pm
by OwnZ joO
Haha if you can learn it grim anyone can :XP:

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Wed Nov 25, 2009 7:13 am
by troymac1ure
Grimdoomer wrote:
Shock120 wrote:
Grimdoomer wrote:I wish someone would fucking help.
maybe I should go around and mass spam for help for Grimdoomie. :D :wink: :cougar
ugh, nevermind. its just there is no one :whogaf: :scared:

Grimdoomer completez this animations, then move onto another thing.
Cougar can't help. I need someone that knows assembly and can reverse code.
Sorry, I have been busy lately. I appreciate all the work you've been doing.
I can maybe help. I know basic x86 assembly, so I would just need to learn the newer syntax. Just looking for documentation now.
Also most of the assembly I used to translate was into pascal and my c++ syntax isn't up to snuff. Anyways, I'll give it a shot if you want. Just throw some this way.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Thu Nov 26, 2009 12:30 am
by [TT]
Why is it every time someone puts up a very good looking explanation of something really really cool, Everyone or at least the ones that don't know much about it end up commenting bad or less helpful remarks. Its like no one wants to say thanks or hey this looks cool i wanna check this out. Hens the reason why halo 2 modding is dieing .

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Thu Nov 26, 2009 1:18 pm
by SpecOp44
[TT] wrote:Why is it every time someone puts up a very good looking explanation of something really really cool, Everyone or at least the ones that don't know much about it end up commenting bad or less helpful remarks. Its like no one wants to say thanks or hey this looks cool i wanna check this out. Hens the reason why halo 2 modding is dieing .
lol irony

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Thu Nov 26, 2009 5:28 pm
by NotZachary82
Lmao I was going to say that. :lol:

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Sun Nov 29, 2009 5:34 pm
by Grimdoomer
Ok I'm finsihing this shit today. I don't really care what happens here on out, because not a god dam thing is gunna change.

Each codec decompression function calls 3 sub functions that get set at runtime. Each of the 3 sub functions are for rotations, translations and scaling. They are all different functions from what I can see. So the code we have now, should only work for rotations. But who the hell knows it might work either way.

Each codec decompression function has the same layout:

Code: Select all

if (RotatedBones)
{
    do
    {
         (void)(AnimationRotationDecompressionPtr)();
    }
    while (i < RotatedBones)     
}

if (TranslatedBones)
{
    do
    {
         (void)(AnimationTranslationDecompressionPtr)();
    }
    while (i < TranslatedBones)}

if (ScaledBones)
{
     do
    {
         (void)(AnimationScaleDecompressionPtr)();
    }
    while (i < ScaledBones)
}

Code: Select all

if ( !*(_BYTE *)(InheritedChunks + 16) )
        {
          if ( *(_WORD *)(*(_DWORD *)(a1 + 4) + 6) )
          {
            CodecPtr = *(_DWORD *)a1;
            CurrentAnimationHeaderPtr = *(_DWORD *)a1;
            DecompressionFunctionBlock = 40 * *(_BYTE *)CodecPtr + 4717348;
            RotationFunctionPtr = *(int (__fastcall **)(_DWORD, _DWORD))DecompressionFunctionBlock;
            TranslationFunctionPtr = *(int (__fastcall **)(_DWORD, _DWORD))(DecompressionFunctionBlock + 4);
            ScaleFunctionPtr = *(int (__fastcall **)(_DWORD, _DWORD))(DecompressionFunctionBlock + 8);
            AnimationTranslationDecompressionPtr = TranslationFunctionPtr;
            AnimationRotationDecompressionPtr = RotationFunctionPtr;
            AnimationScaleDecompressionPtr = ScaleFunctionPtr;
            AnimationHeaderPtr = *(_DWORD *)a1
                               + *(_DWORD *)(*(_DWORD *)(a1 + 4) + 12)
                               + *(_WORD *)(*(_DWORD *)(a1 + 4) + 6);
            dword_504494 = *(_DWORD *)a1
                         + *(_DWORD *)(*(_DWORD *)(a1 + 4) + 12)
                         + *(_WORD *)(*(_DWORD *)(a1 + 4) + 6)
                         + (((*(_BYTE *)(a1 + 8) + 31) >> 3) & 0xFFFFFFFC);
            dword_504498 = *(_DWORD *)a1
                         + *(_DWORD *)(*(_DWORD *)(a1 + 4) + 12)
                         + *(_WORD *)(*(_DWORD *)(a1 + 4) + 6)
                         + 2 * (((*(_BYTE *)(a1 + 8) + 31) >> 3) & 0xFFFFFFFC);
            byte_504458 = 0;
            AnimationDecompressionSwitch();
          }
        }
        if ( *(_DWORD *)(*(_DWORD *)(a1 + 4) + 12) )
        {
          if ( !dword_504450 )
          {
            if ( sub_27A100(TagOffset, v21, a5, a4, v15) )
              dword_504450 = 4;
          }
          v58 = *(_DWORD *)a1 + *(_WORD *)(*(_DWORD *)(a1 + 4) + 6);
          CurrentAnimationHeaderPtr = *(_DWORD *)a1 + *(_WORD *)(*(_DWORD *)(a1 + 4) + 6);
          v59 = (char *)&dword_47FB24[10 * *(_BYTE *)v58] + 12 * (a8 != 0);
          AnimationRotationDecompressionPtr = *(int (__fastcall **)(_DWORD, _DWORD))v59;
          v60 = (int (__fastcall *)(_DWORD, _DWORD))*((_DWORD *)v59 + 1);
          AnimationScaleDecompressionPtr = (int (__fastcall *)(_DWORD, _DWORD))*((_DWORD *)v59 + 2);
          AnimationTranslationDecompressionPtr = v60;
          AnimationHeaderPtr = *(_DWORD *)a1
                             + **(_BYTE **)(a1 + 4)
                             + *(_DWORD *)(*(_DWORD *)(a1 + 4) + 12)
                             + *(_WORD *)(*(_DWORD *)(a1 + 4) + 6);
          dword_504494 = *(_DWORD *)a1
                       + **(_BYTE **)(a1 + 4)
                       + *(_DWORD *)(*(_DWORD *)(a1 + 4) + 12)
                       + *(_WORD *)(*(_DWORD *)(a1 + 4) + 6)
                       + (((*(_BYTE *)(a1 + 8) + 31) >> 3) & 0xFFFFFFFC);
          dword_504498 = *(_DWORD *)a1
                       + **(_BYTE **)(a1 + 4)
                       + *(_DWORD *)(*(_DWORD *)(a1 + 4) + 12)
                       + *(_WORD *)(*(_DWORD *)(a1 + 4) + 6)
                       + 2 * (((*(_BYTE *)(a1 + 8) + 31) >> 3) & 0xFFFFFFFC);
          byte_504458 = a8;
          AnimationDecompressionSwitch();
        }
I have the rotation, translation, and dialation code for codecs: 1, 3, 4, 6 and 8. Codecs 6 and 4 use the same code btw :wink:

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Sun Nov 29, 2009 7:39 pm
by Grimdoomer
Codecs 5 and 7 also use the same code. I just need Codecs 0 and 2 then I have all of them.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Sun Nov 29, 2009 11:53 pm
by Grimdoomer
[speculation removed]

I have Codecs 1, 2, and 3 done. Moving to 4. Also 1 and 2 are identical.

1 & 2
4 & 6
5 & 7

are exactly the same. Well... 4 & 6 reference the same code, so do 5 & 7, I have no found the code for 0 or 2 yet, but from Demonics layout, 1 & 2 should be the same. Infact they might use the same code I don't know yet.

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Mon Nov 30, 2009 2:46 am
by DemonicSandwich
Have you found out what those 4 bytes at offset 4 do?

Re: Custom Animations Pt.01 (Raw Structures)

Posted: Mon Nov 30, 2009 2:51 am
by Grimdoomer
DemonicSandwich wrote:Have you found out what those 4 bytes at offset 4 do?
Haven't really looked. I'll keey an eye out.