Suzukaze

MrDev's note about mtar

Jan 1st, 2024
24
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.30 KB | None | 0 0
  1. I will explain what i know about the animation system
  2. mtar - motion archive
  3. gani - game animation
  4. frig - fox rig
  5. ask - Pes skeleton ( I dont know where MGS skeleton is stored)
  6. mogs - motion graph??
  7.  
  8. most of these are straight forward so i will focus on how the frig skeleton and gani are connected.
  9. Note the mgs gani is not full known to me. It contains extra data I have not been able to decipher
  10.  
  11. The structure of the gani file is pretty simple
  12. There is a general header with a hash for the animation name. This header has proved to be largely ignorable containing no real data of interest
  13.  
  14. typedef struct
  15. {
  16. int sig;
  17. int a;
  18. int fileSize;
  19. int b[5];
  20. uint hash2;
  21. int c[11];
  22. }MainHdr;
  23.  
  24.  
  25. then there is a motion header with another hash whose purpose i forgot to investigate.
  26. The second header contains the list of track offsets number of animation curves and number of chains.
  27.  
  28. typedef struct
  29. {
  30. char sig[16];
  31. int64 hash_;
  32. int a,b;
  33. int size;
  34. int unkn;
  35. int __[6];
  36.  
  37. }MotionHdr;
  38.  
  39.  
  40. The motion header was already getting too big so i put this in a seperate struct call Motion
  41.  
  42. struct Motion
  43. {
  44. int entryCount; //number of chains
  45. int subEntryCount; //number of curves
  46. int _fpsInterval; //time between frames. It is actually represented as an int
  47. int _frameCount; //frame count?
  48. int c;
  49. int entryOffsets[entryCount]; //I misnamed this as an address
  50. }
  51.  
  52.  
  53. This section is the daddy of the gani files but before we can go any further I need to explain the concept of tracks and curves.
  54. I first named these as entry as sub entry, so forgive me if i relapse.
  55. Simply put a track is a list of curves. curves can contain positional or rotation data. For the most part we will be dealing with a lot of rotation data.
  56. We only use position data on the root, hip and sometimes shoulder bones.(edited)
  57. The bones in the ask files come with integer ids. This ids are used in the frig to identify what bones belong to a chain
  58. Chains are simple bone links (Think of your arm: shoulder, elbow, wrist).
  59.  
  60. Due to the need of things like partial animations aka the need to play different animations on different body parts ( running + weapon carry)
  61. it is a time saving scheme for devs so we need to let the engine know what body parts we want to keep and which to ignore/mask out.
  62. The frig files defines which bones are are part of a chains.
  63. Chains are pretty much analogous to tracks but i did not want to use the same name so you can understand what file i am talking about.
  64. Basically the animation has the same number of tracks as the rig has the same number of chains so the match easily without search
  65. chain[0] = players(track[0])
  66.  
  67. It seemed a bit convoluted at first but the frgi files also has a way of using these chains to define how animations are mirrored
  68. But you wont need to know this for your modding purposes as it is pretty well defined. So you can swap what hand you use to carry weapons if you want (thorugh the code)
  69. the rig chains also makes it easy to set up ik chains. So I would suggest any file reader to read the skeleton then the rig before tryign to apply animation
  70.  
  71. Back to Motion
  72. When we read an entry(track), it tells us how many sub-entries(curves) we have, and they also have hashes (Track name? maybe running-legs).
  73. The sub entry tells us if it is a position or rotation as well as the size of bits for each frame and the offset for our data, root position and animations have special flags
  74.  
  75.  
  76. typedef struct
  77. {
  78. uint _hash; //constant across all animations (bone group? aka chain?)
  79. byte subCount; //cure count
  80. short unkn; // 1 or 5 (5 means there is a position curve in there i think)
  81. byte pad; // 0
  82. SubEntry sEntry[subCount];
  83. }Entryx;
  84. typedef struct
  85. {
  86. int addr; //OFFSET
  87. short index; //aka this is the nth subEntry in the whole file
  88.  
  89. ubyte typeFlag; //this is an enum flag bit use FlagReader(typeFlag)
  90. ubyte bitSz; // 12 - for quats konami custom, 16 - for position konami custom, 32 - ieee float
  91. }
  92.  
  93.  
  94. Simple function for identifying flags
  95. string FlagReader(int flag)
  96. {
  97. /*
  98. 0x80 bit indicating that its not last entry in the set
  99. other bits are track type,
  100. 0 - rotation
  101. 3 - position
  102. 5 - root rotation
  103. 6 - root position
  104. */
  105. local string s0;
  106. local int f = flag & ~0x80; //remove 0x80
  107. switch(f)
  108. {
  109. case 0x0:
  110. s0 = "rotation";
  111. boneRot+= 1;
  112. break;
  113. case 0x3:
  114. s0 = "position";
  115. bonePos+= 1;
  116. break;
  117. case 0x5:
  118. s0 = "Root_rot";
  119. rootRot = rootRot + 1;
  120. break;
  121. case 0x6:
  122. s0 = "Root_pos";
  123. rootPos = rootPos + 1;
  124. break;
  125. }
  126. local string s2;
  127. SPrintf(s2, " (0x%02x)",flag);
  128. return s0 +s2;
  129. }
  130.  
  131.  
  132. Reading the frame
  133. This is a royal pain in the ass. We have to thank Id-Daemon for figuring this part out
  134. Cos I got everything else except this on my own and I was pretty dejected when I got here.
  135. I am suddenly tired
  136. Before I forget the BoneInfo section in the frig is uber important
  137. It contains a paring of the chain ID referenced earlier and the hash for member names
  138. It ignores the chain/track [0] - which is the root (Get Fucked)(edited)
  139.  
  140.  
  141.  
  142. //in Frig
  143. struct TrackInfo
  144. {
  145. // 0 -
  146. // 1 - always 0
  147. // 2 - number of curves in the track Max 4
  148. // 3 - number of bones in chain
  149. //--------- Parent section
  150. // 4 - parent ID of first bone
  151. // 5 - parent id of second bone
  152. // 6 -
  153. // 7 -
  154. //---------- Bone Section (max 8 curves?) if there is only one bone it doesnt bother with this section just 0s
  155. // 8 - boneID for curve/subEntry 0
  156. // 9 - boneID for curve/subEntry 1
  157. // 10 -
  158. // 11 -
  159. // 12 -
  160. // 13 -
  161. // 14 -
  162. //---------------
  163. // 15 -
  164. short a[16];
  165.  
  166.  
  167. //a[3] tells us number of bones in chain and fills out the bottom gaps
  168. if(a[3] > 1)
  169. {
  170. float f[4]; // No idea what it does
  171. ChannelInfo channelInfo[a[2]/a[3]]; //dont remember why/how this works
  172. }
  173. }
  174.  
  175. struct ChannelInfo
  176. {
  177. //bones[2-3 seq in id] + tracks[2-3 seq in id] + padding
  178. short a[8]<hidden=true>;
  179. }
  180. I dont remember much of this as it has been 6 months since I made this. but basically it is a mapping from curve to bone between both files(edited)
Comments
Add Comment
Please, Sign In to add comment