Talk:M2: Difference between revisions

From wowdev
Jump to navigation Jump to search
No edit summary
No edit summary
Line 2: Line 2:
--[[User:Schlumpf|schlumpf_]] 00:53, 23 August 2008 (CEST)
--[[User:Schlumpf|schlumpf_]] 00:53, 23 August 2008 (CEST)


== Deleted Blocks ==
== On animations ==
 
Maybe you've already figured it out yourself, chuanhsing, but it still might be helpful as I cannot see any anymations in your latest WMV version:
 
Animation in WotLK is actually easy once you've understood what Blizzard has changed. They have essentially gone from one single, long timeline per model (with every single animation covering a slice of this timeline, based on their start and end times) to a multi-timeline approach where each animation has its own timeline, starting at 0 with the length as defined in the animation sequence data structure.
 
Because of this, the basic animation block structure had to be changed. They dumped the interpolation ranges (as those aren't necessary anymore if each animation has its own timeline), and they have added another layer of references for the timestamp and value information. This means instead of the number of timestamps followed by the offset to said timestamps there's now the number of timelines followed by an offset to the timeline data. This offset leads to a structure of 8 bytes per timeline, with the first 4 bytes making up the actual number of timestamps for one specific timeline and the next 4 being an offset to the actual timestamp data. The keyframe values are stored in a similar fashion.
 
All of this of course does not account for the new .anim files which seem to be single animations that aren't stored in the .m2 file itself - I haven't looked at those yet, so I can't give you any hints about their structure. But the changes described above will get all animations stored in the file itself to work fine, which is the vast majority of animations.
 
 
Okay, now I think I've understood how those .anim-files fit into the picture. Blizzard has created them to externalize seldomly-needed animations such as dance animations from the main model file, probably to speed up the loading process by loading them on-demand when they are to be played.
 
Their structure is simple: they don't have any structure on their own. They are just a pile of binary data, which is being referenced from the animation sub-blocks (I just decided to call those sub-structures in the animation blocks that contain the actual keyframe data for a single animation "animation sub-blocks", see my last post for details on this) in the exact same way as data in the main model file is being referenced: by offsets to timestamp/keyframe data. These references just point into the .anim-file corresponding to a specific animation id if an animation is stored externally.
 
The names of the animation data files are composed from the following template: [model file name][animation id]-[animation sub-id].anim
 
However, there's still one thing I don't understand: how someone can decide if an animation sequence is stored internally (in the model file) or externally. Of course it's possible to check if a corresponding .anim file exists, but I don't think that this is how WoW actually does it as that would result in quite some overhead. That information is probably stored somewhere in the main model file, but I haven't found it yet...
 
* Posted by Slartibartfast at the [http://www.wowmodelviewer.org/forum/index.php?topic=3672.40 wowmodelviewer-forums].


== Animation ==
== Animations in some beta-code ==


animated.h  
animated.h  
Line 70: Line 89:
   };
   };


== Block D ==
== Deleted Blocks ==
=== Block D ===


*'''nD records of (int16, int16) starting at ofsD'''
*'''nD records of (int16, int16) starting at ofsD'''
Line 79: Line 99:
Contain indices into the texture animations list, or -1 meaning a static texture.  
Contain indices into the texture animations list, or -1 meaning a static texture.  


== Texture animations ==
=== Texture animations ===


*'''This block contains definitions for texture animations,''' for example, flowing water or lava in some models. The keyframe values are used in the texture transform matrix.
*'''This block contains definitions for texture animations,''' for example, flowing water or lava in some models. The keyframe values are used in the texture transform matrix.

Revision as of 20:46, 29 September 2008

Finished for Build 8820 now. Post changes here first! And please pay attention to the style when you add something.. --schlumpf_ 00:53, 23 August 2008 (CEST)

On animations

Maybe you've already figured it out yourself, chuanhsing, but it still might be helpful as I cannot see any anymations in your latest WMV version:

Animation in WotLK is actually easy once you've understood what Blizzard has changed. They have essentially gone from one single, long timeline per model (with every single animation covering a slice of this timeline, based on their start and end times) to a multi-timeline approach where each animation has its own timeline, starting at 0 with the length as defined in the animation sequence data structure.

Because of this, the basic animation block structure had to be changed. They dumped the interpolation ranges (as those aren't necessary anymore if each animation has its own timeline), and they have added another layer of references for the timestamp and value information. This means instead of the number of timestamps followed by the offset to said timestamps there's now the number of timelines followed by an offset to the timeline data. This offset leads to a structure of 8 bytes per timeline, with the first 4 bytes making up the actual number of timestamps for one specific timeline and the next 4 being an offset to the actual timestamp data. The keyframe values are stored in a similar fashion.

All of this of course does not account for the new .anim files which seem to be single animations that aren't stored in the .m2 file itself - I haven't looked at those yet, so I can't give you any hints about their structure. But the changes described above will get all animations stored in the file itself to work fine, which is the vast majority of animations.


Okay, now I think I've understood how those .anim-files fit into the picture. Blizzard has created them to externalize seldomly-needed animations such as dance animations from the main model file, probably to speed up the loading process by loading them on-demand when they are to be played.

Their structure is simple: they don't have any structure on their own. They are just a pile of binary data, which is being referenced from the animation sub-blocks (I just decided to call those sub-structures in the animation blocks that contain the actual keyframe data for a single animation "animation sub-blocks", see my last post for details on this) in the exact same way as data in the main model file is being referenced: by offsets to timestamp/keyframe data. These references just point into the .anim-file corresponding to a specific animation id if an animation is stored externally.

The names of the animation data files are composed from the following template: [model file name][animation id]-[animation sub-id].anim

However, there's still one thing I don't understand: how someone can decide if an animation sequence is stored internally (in the model file) or externally. Of course it's possible to check if a corresponding .anim file exists, but I don't think that this is how WoW actually does it as that would result in quite some overhead. That information is probably stored somewhere in the main model file, but I haven't found it yet...

Animations in some beta-code

animated.h void init(AnimationBlock &b, MPQFile &f, int *gs)

original code

    uint32 *ptimes = (uint32*)(f.getBuffer() + b.ofsTimes);
    for (size_t i=0; i<b.nTimes; i++) 
      times.push_back(ptimes[i]);
    
    // keyframes
    assert((D*)(f.getBuffer() + b.ofsKeys));
    D *keys = (D*)(f.getBuffer() + b.ofsKeys);
    switch (type) {
      case INTERPOLATION_NONE:
      case INTERPOLATION_LINEAR:
        for (size_t i=0; i<b.nKeys; i++) 
          data.push_back(Conv::conv(keys[i]));
        break;
      case INTERPOLATION_HERMITE:
        for (size_t i=0; i<b.nKeys; i++) {
          data.push_back(Conv::conv(keys[i*3]));
          in.push_back(Conv::conv(keys[i*3+1]));
          out.push_back(Conv::conv(keys[i*3+2]));
        }
        break;
    }

modified code

    AnimationBlockHeader* pHeadTimes = (AnimationBlockHeader*)(f.getBuffer() + b.ofsTimes);
    
    uint32 *ptimes = (uint32*)(f.getBuffer() + pHeadTimes->ofsEntrys);
    for (size_t i=0; i < pHeadTimes->nEntrys; i++)
      times.push_back(ptimes[i]);
    
    // keyframes
    AnimationBlockHeader* pHeadKeys = (AnimationBlockHeader*)(f.getBuffer() + b.ofsKeys);
    D *keys = (D*)(f.getBuffer() + pHeadKeys->ofsEntrys);
    switch (type) {
      case INTERPOLATION_NONE:
      case INTERPOLATION_LINEAR:
        for (size_t i = 0; i < pHeadKeys->nEntrys; i++) 
          data.push_back(Conv::conv(keys[i]));
        break;
      case INTERPOLATION_HERMITE:
        for (size_t i = 0; i < pHeadKeys->nEntrys; i++) {
          data.push_back(Conv::conv(keys[i*3]));
          in.push_back(Conv::conv(keys[i*3+1]));
          out.push_back(Conv::conv(keys[i*3+2]));
        }
        break;
    }

modelheaders.h

 struct AnimationBlockHeader
 {
   uint32 nEntrys;
   uint32 ofsEntrys;
 };

Deleted Blocks

Block D

  • nD records of (int16, int16) starting at ofsD

Maybe a lookup table for animations? Since the numbers happen to be in fixed positions. The first short seems to increase with the position for models with all animations (like characters), the second seems to be flags or a modifier? Or something.


Contain indices into the texture animations list, or -1 meaning a static texture.

Texture animations

  • This block contains definitions for texture animations, for example, flowing water or lava in some models. The keyframe values are used in the texture transform matrix.

nTexAnims records of 0x54 bytes starting at ofsTexAnims, followed by data referenced in these records.

Offset 	Type 						Description
0x00 	AnimationBlock (float, float, float) 		Translation
0x1C 	AnimationBlock (float, float, float ???) 	Rotation?
0x38 	AnimationBlock (float, float, float) 		Scaling?

The three subrecords specify texture transforms. Translation seems to work, producing nice flowing lava and waterfalls.