ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax | SSL HTTPS://zenhax.com
It is currently Sat Dec 16, 2017 4:54 pm

All times are UTC




Post new topic  Reply to topic  [ 79 posts ]  Go to page Previous 1 2 3 4 Next
Author Message
PostPosted: Fri May 05, 2017 4:13 pm 

Joined: Fri May 05, 2017 1:16 pm
Posts: 9
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...)


Top
   
PostPosted: Fri May 05, 2017 6:15 pm 

Joined: Sun Mar 22, 2015 7:09 pm
Posts: 690
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)


Top
   
PostPosted: Fri May 05, 2017 8:19 pm 

Joined: Fri May 05, 2017 1:16 pm
Posts: 9
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?


Top
   
PostPosted: Sat May 06, 2017 5:12 am 

Joined: Sun Mar 22, 2015 7:09 pm
Posts: 690
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.


Top
   
PostPosted: Sat May 06, 2017 2:51 pm 

Joined: Fri May 05, 2017 1:16 pm
Posts: 9
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?


Top
   
PostPosted: Tue Jun 13, 2017 6:18 am 

Joined: Mon Dec 29, 2014 8:49 pm
Posts: 33
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?


Top
   
PostPosted: Tue Jun 13, 2017 3:35 pm 

Joined: Sun Mar 22, 2015 7:09 pm
Posts: 690
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.


Top
   
PostPosted: Wed Jun 14, 2017 3:22 am 

Joined: Mon Dec 29, 2014 8:49 pm
Posts: 33
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:
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


Top
   
PostPosted: Wed Jun 14, 2017 4:04 pm 

Joined: Sun Mar 22, 2015 7:09 pm
Posts: 690
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


Top
   
PostPosted: Thu Jun 15, 2017 5:55 am 

Joined: Mon Dec 29, 2014 8:49 pm
Posts: 33
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


Top
   
PostPosted: Thu Jun 15, 2017 10:04 am 

Joined: Mon Dec 29, 2014 8:49 pm
Posts: 33
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


Top
   
PostPosted: Thu Jun 15, 2017 3:10 pm 

Joined: Sun Mar 22, 2015 7:09 pm
Posts: 690
JohnHudeski wrote:
are you sure it is

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


yes i am


Top
   
PostPosted: Sat Jun 17, 2017 1:25 pm 

Joined: Mon Dec 29, 2014 8:49 pm
Posts: 33
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.

Top
   
PostPosted: Sat Jun 17, 2017 1:43 pm 

Joined: Sun Mar 22, 2015 7:09 pm
Posts: 690
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.


Top
   
PostPosted: Sat Jun 17, 2017 9:31 pm 

Joined: Mon Dec 29, 2014 8:49 pm
Posts: 33
This is sad and terrifying lol

Code:
//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);



Top
   
PostPosted: Sun Jun 18, 2017 7:46 pm 

Joined: Sun Mar 22, 2015 7:09 pm
Posts: 690
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.


Top
   
PostPosted: Sun Jun 18, 2017 10:59 pm 

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


Top
   
PostPosted: Tue Jun 20, 2017 3:21 pm 

Joined: Mon Dec 29, 2014 8:49 pm
Posts: 33
: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


Top
   
PostPosted: Tue Jun 20, 2017 3:48 pm 

Joined: Sun Mar 22, 2015 7:09 pm
Posts: 690
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.


Top
   
PostPosted: Tue Jun 20, 2017 4:36 pm 

Joined: Mon Dec 29, 2014 8:49 pm
Posts: 33
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


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 79 posts ]  Go to page Previous 1 2 3 4 Next

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Limited