Metal Gear Solid 5 (MGSV) animations

Skeletons, animations, shaders, texturing, converting, fixing and anything else related to read game models
Zuppermati
Posts: 9
Joined: Fri May 05, 2017 1:16 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by Zuppermati »

Gosh, I'm really a frickin analphabet :oops:

Thanks, really :D .

OT: there were only 2 files of animations, ShGimmick_layers.mtar and ShPlayer_layers.mtar?
Cause the .LUA script files cited some .gani files for the freezer, lamp and fetus which I couldn't find anywhere (the files talks about a folder which doesn't exists. But I might have done some errors while trying to extract the data...)
id-daemon
Posts: 1040
Joined: Sun Mar 22, 2015 7:09 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by id-daemon »

ShGimmick_layers.mtar contains animations for fetus, bag, and 2 more things, which may be your lamp and freezer (those had only 2 or 3 bones, i dont remember exactly)
Zuppermati
Posts: 9
Joined: Fri May 05, 2017 1:16 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by Zuppermati »

Hi

ShGimmick_layers always beheaved strangely.
The only 3 files it ever extracted (no matter how many times i tried) where the ones with lisa when she shakes like crazy and are named ShGimmick_layers_005, 007 and 008.
Does that means that there are more? Should I use another model?
id-daemon
Posts: 1040
Joined: Sun Mar 22, 2015 7:09 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by id-daemon »

The problem is that MGSV animations system is very complex and variable. So you can't actually extract other files from ShGimmick_layers with current tools. I had to made a special test version of .exe to extract them. It was never published.
Zuppermati
Posts: 9
Joined: Fri May 05, 2017 1:16 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by Zuppermati »

Uh Ok.
Still, if you ever consider to publish that special test version let us know (I'm really interested into these animations, expecially the baby).
Tons of thanks anyway for your time.
PS: when you said that after loading the animation you need to attach the arms to palms with IK constraints it's because they stand perfectly still if you don't?
JohnHudeski
Posts: 40
Joined: Mon Dec 29, 2014 8:49 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by JohnHudeski »

Any chance you'd be willing to share the .GAni file format?
How do you know frame count and addresses for data (eg Quaternions) per bone?
id-daemon
Posts: 1040
Joined: Sun Mar 22, 2015 7:09 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by id-daemon »

I don't have any papers describing the format. The table is in the beginning of the file. It has info how many bits used for each track values, and data offsets.

Also important note, in this game animation tracks are NOT per-bone. They are per IK group. And each group has a number of tracks for it, which is not equal to number of bones in it. Some bones may have no tracks at all, some may have many. This is complex format, sorry, its hard to explain.
JohnHudeski
Posts: 40
Joined: Mon Dec 29, 2014 8:49 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by JohnHudeski »

It's ok. I think I am really close.
I found a section of the data (based on a table of addresses/offset) that have a format like this

Code: Select all

struct SubEntry
{
   int offset; //Address = Current Stream.positon + this offset
   short index; //I think this is the index to the bone group you spoke of
   byte a; //ranges from 0 to what ever (sometime odd numbers)
   byte b; //usually 0, 12, 16 i assume this is info how many bits used But what is a
}

struct Entry
{
   int unkn; //seems like a hash
   int count; // number of subentries
   SubEntry sEntry[count];
}


I think there must be some logic to bytes in the sub entry
example one file has
a = 133
and
b = 12

the address of the next sub entry (+ offset) starts exactly 12 bytes from the previous one
but then there is a gap of 130 bytes between it an the next "Main" Entry
id-daemon
Posts: 1040
Joined: Sun Mar 22, 2015 7:09 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by id-daemon »

yes b is bits used
a has 0x80 bit indicating that its not last entry in the set, and other bits is track type,

0 - rotation
3 - position
5 - root rotation
6 - root position

i don't understand what do you mean about 130 bytes
JohnHudeski
Posts: 40
Joined: Mon Dec 29, 2014 8:49 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by JohnHudeski »

omg that makes so much more sense

Values for a i have seen include
0x85 //very first guy (the 133-130 guy i spoke of)
0x6
0x80
0x3
0x0
0x83

It must mean a is a flag that gets Or'd

Thank you so much.
I don't think i could have understood that at all
JohnHudeski
Posts: 40
Joined: Mon Dec 29, 2014 8:49 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by JohnHudeski »

id-daemon wrote:yes b is bits used
a has 0x80 bit indicating that its not last entry in the set, and other bits is track type,

0 - rotation
3 - position
5 - root rotation
6 - root position

i don't understand what do you mean about 130 bytes


are you sure it is

0 - rotation
3 - position
5 - root rotation
6 - root position

and not

0 - position
3 - rotation
5 - root position
6 - root rotation

?

Cos every entry that has a position bit has a b of 16
and every rotation has a 12 bits to read
id-daemon
Posts: 1040
Joined: Sun Mar 22, 2015 7:09 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by id-daemon »

JohnHudeski wrote:are you sure it is

0 - rotation
3 - position
5 - root rotation
6 - root position


yes i am
JohnHudeski
Posts: 40
Joined: Mon Dec 29, 2014 8:49 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by JohnHudeski »

I am 99% there.
I only have 2 questions I think.
it seems each track size is based on the bytes from the addr[n+1] -addr[n]
where addr is the offset address in each sub entry + some magic number
when I divide the size by bits to read it always has a remainder
eg 140 / 12.
some files even have a smaller size than the bits to read.

How do you figure out the animation frame size/ length in seconds?

I can send you a sample file + complete 010 template if interested (so you don't have to keep guessing at what I am describing lol)
Last edited by JohnHudeski on Sat Jun 17, 2017 7:17 pm, edited 1 time in total.
id-daemon
Posts: 1040
Joined: Sun Mar 22, 2015 7:09 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by id-daemon »

I'm not sure what reminder you're talking about, but

JohnHudeski wrote:some files even have a smaller size than the bits to read.

this must NEVER happen.

Also, I never use 010 and have no idea about templates.
JohnHudeski
Posts: 40
Joined: Mon Dec 29, 2014 8:49 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by JohnHudeski »

This is sad and terrifying lol

Code: Select all

//Gobals
local int counter = 0;

local int rootPos = 0;
local int rootRot = 0;
local int boneRot = 0;
local int bonePos = 0;

local int subEntAddr[60];


//Data type declaration

typedef struct(int arraySize)
{
    local int size = arraySize;
    byte array[arraySize];
}ByteArray;


string FlagReader(int flag)
{
    /*
    0 - rotation
    3 - position
    5 - root rotation
    6 - root position
    */
    local string s0;
    local int f = flag & ~0x80; //remove 0x80
    switch(f)
    {
    case 0x0:
        s0 = "rotation";
        boneRot+= 1;
        break;
    case 0x3:
        s0 = "position";
        bonePos+= 1;
        break;
    case 0x5:
        s0 = "Root_rot";
        rootRot = rootRot + 1;
        break;
    case 0x6:
        s0 = "Root_pos";
        rootPos = rootPos + 1;
        break;
    }
    local string s2;
    SPrintf(s2, " (0x%02x)",flag);
    return s0 +s2; 
}

typedef struct
{
    local int currPosition = FTell();
    int addr; //Maybe +248
    short index; //references an index in based on size

    subEntAddr[index] = addr+addrbac;

    ubyte typeFlag<read=FlagReader, bgcolor=cYellow>; //this is an enum flag bit
    ubyte bitSz< bgcolor=cYellow>;
   
    //debug
    Printf("\n    %02d) Addr: %d (+%d: %d)\n    ----------------------------", index, addr,currPosition, addr+currPosition);
   
    Printf("\n    %s", FlagReader(typeFlag));
    Printf("\n    typeFlag: 0x%02x, bitSz: 0x%02x\n", typeFlag, bitSz);
}SubEntry<bgcolor=cLtBlue,optimize=false>;

typedef struct
{
    Printf("\n\nEntryx[%d]:\n{", counter);
    counter += 1;
    uint _hash;
    byte subCount; //int
    short unkn;
    byte pad;
    if(subCount > 4)
    {
        SubEntry sEntry<optimize=false>;
    }
    else
    {
        SubEntry sEntry[subCount]<optimize=false>;
    }
}Entryx<optimize=false,bgcolor=cLtRed>;

//Generic container?
typedef struct
{
    int hash;
    int a; //size a?
    int fileSize;
    // b[2] = number of files?
    int b[5];
    int hash2;

    //c[0] = //size b?
    //c[5] = motion headr size (skip char name)
    int c[11];
    //size of header = size a + size b
}MainHdr;

typedef struct
{
    char sig[16];
    int64 hash_;
    int a,b;
    int size;
    int unkn;
    int __[6];

}MotionHdr;


//Actual entry
MainHdr mHdr;
MotionHdr mothdr;

struct Motion
{
    int entryCount; //defonitley
    int subEntryCount; //subEntryCount is another count (refereneced by entry) Bones?
    int a; //hash
    int b; //header size for this motion struct
    int c; 
    int entryAddr[entryCount]; //definitley
    local int i = 0;
    local int sum = 0;
    for(i =0; i < 60; ++i)
    {
        subEntAddr[i] = -1;
    }
    subEntAddr[subEntryCount] = FileSize();

    int pad[4];

    //byte data[sum+16];
    for(i = 0; i < entryCount; i++)
    {
        Entryx dataX;
        Printf("}\n");
    }

    local int j = 0;
    local int addrOff = FTell() - dataX[0].sEntry[0].addr;
    local int idx =0;
    for(i = 0; i < subEntryCount; i++)
    {
        Printf("\n%d - %d : %d",subEntAddr[i],subEntAddr[i+1], subEntAddr[i+1]-subEntAddr[i]);
        ByteArray bArr(subEntAddr[i+1]-subEntAddr[i])<bgcolor=cLtGreen>;
    }
}motion;

Printf("\n\nTrackStats: %d rootPosition(s), %d rootRotation(s), %d bonePos(s), %d boneRot(s)", rootPos, rootRot, bonePos, boneRot);

id-daemon
Posts: 1040
Joined: Sun Mar 22, 2015 7:09 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by id-daemon »

JohnHudeski wrote:This is sad and terrifying lol


Yes, good luck with this. I never understood why people are doing this. It only complicates things.
JohnHudeski
Posts: 40
Joined: Mon Dec 29, 2014 8:49 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by JohnHudeski »

I moved to c#
JohnHudeski
Posts: 40
Joined: Mon Dec 29, 2014 8:49 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by JohnHudeski »

:D

I think I might have figured out my error
Bits size/Bits to read != bytes
I always thought it was bytes for some reason

so all the 6's i saw were bytes and not bits.
I finally understand what you meant by variable bits
cos 6 bytes = 48 bits
divided by 12 you 4 floating points (typical rotation size)
divide by 14 you get 3 floating points (typical position size)
I am so dumb

i'd just like to know.
Is this animated at 60fps?
How do you know what frame each Vector/quaternion belongs to?
I don't think normalizing and stretching them all to fit the maximum frame length them all is a particularly good idea
Would also wreck animation quality
id-daemon
Posts: 1040
Joined: Sun Mar 22, 2015 7:09 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by id-daemon »

JohnHudeski wrote::D

you are only in the beginning of the way ;)

JohnHudeski wrote:divided by 12 you 4 floating points (typical rotation size)


they are not floating points, they are integers

JohnHudeski wrote:How do you know what frame each Vector/quaternion belongs to?


Between the data there is a frame count for each value. It's always 8 bits.
JohnHudeski
Posts: 40
Joined: Mon Dec 29, 2014 8:49 pm

Re: Metal Gear Solid 5 (MGSV) animations

Post by JohnHudeski »

id-daemon wrote:you are only in the beginning of the way ;)

LMAO

id-daemon wrote:they are not floating points, they are integers

Integers/Bits that you convert to floats?

id-daemon wrote:Between the data there is a frame count for each value. It's always 8 bits.

Between the actual quaternion and vector data?
I knew this was too easy