Author Topic: Decent FF7 Model Viewer  (Read 116598 times)

Cyberman

  • *
  • Posts: 1572
    • View Profile
Decent FF7 Model Viewer
« Reply #200 on: 2004-09-21 13:51:49 »
Poor Mirex :)

Well I'm working on the PS1 version (using a debugger by Pixel at The Repository.  I've had to do a lot of tweaking though and since it's a debugger things are, entertaining to say the least with making a tool like Spiros.  I'm using XML for the basis to describe structures etc.  This has an additional advantage that isn't obvious at first. I can include prior discovered structures within new structures.  The hard part will be making the structure building interface.  Nothing is easy as they say.  Right now I have something that should work 'OK' for viewing templates in parallel with the data.

Cyb

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Decent FF7 Model Viewer
« Reply #201 on: 2004-09-22 02:36:05 »
I am not sure what you mean by adding priorly discovered structures into new ones.

If my understanding of that is correct, it’s the same as what mine does.
Adding a template inside of a template is the same as adding a structure to a structure.

At least that is my take on your objective.
I could be way misunderstanding, but if that IS what you mean, don’t worry about it.  MemHack.exe allows as many templates added to other templates as is possible (given your hardware, RAM, etc.).  They can be as recursively deep as you need.

One thing that has yet to be added is the ability to import structures from .h files, or any text files that have valid structures.
It will help a lot when you can convert your existing written-out structures automatically with a click of a button.


Also (this has been intended for a long time) I will eventually add a macro editor, so you can assign macros to data items.  It will show the macro, or combination of macros, instead of the number, so it will be easier to decypher values.


L. Spiro

Cyberman

  • *
  • Posts: 1572
    • View Profile
Decent FF7 Model Viewer
« Reply #202 on: 2004-09-22 14:53:55 »
Quote from: L. Spiro
I am not sure what you mean by adding priorly discovered structures into new ones.

If my understanding of that is correct, it’s the same as what mine does.
Adding a template inside of a template is the same as adding a structure to a structure.

That works :lol:
Quote from: L. Spiro
At least that is my take on your objective.
I could be way misunderstanding, but if that IS what you mean, don’t worry about it.  MemHack.exe allows as many templates added to other templates as is possible (given your hardware, RAM, etc.).  They can be as recursively deep as you need.

I think you are misunderstanding this is not a program for dealing with PC programs but playstation programs (IE ones runing on an emulator). I'm just adding a memory viewer is all.
Quote from: L. Spiro
One thing that has yet to be added is the ability to import structures from .h files, or any text files that have valid structures.

Ahh so you have a parser to read that information.
Quote from: L. Spiro
It will help a lot when you can convert your existing written-out structures automatically with a click of a button.

Also (this has been intended for a long time) I will eventually add a macro editor, so you can assign macros to data items.  It will show the macro, or combination of macros, instead of the number, so it will be easier to decypher values.

L. Spiro

Well the target is different, as this has nothing to do with viewing PC memory, put PS1 memory instead.  Same objective however.  I prefer XML for the base description because it's pretty common and interchangable (IE it can be easily used by other people).  The 'MACRO' idea is a bit interesting. Especially if you get into types like those on the playstation  (fixed point values come to mind).

Cyb

Kislinskiy

  • Guest
Decent FF7 Model Viewer
« Reply #203 on: 2004-09-24 06:36:50 »
I am back...  :)

Three quarters after my hard drive crash I finally was motivated enough to rewrite my source code. The only task to do till it is at the same progress as then is to add the TIM converting rountine. This is easy (look at my IOTW at ZFX) but very time intensive due to the amount of code to write (palette handling, image size adjustment, FFVII specific swapping of 8-bit images and so on...).

For this reason I decided to look on animations first. But before I am going to reinvent the wheel, can you guys tell me whether you already figured something out about the PSone animation sequences?

Yes, I know that the first frame of the first animation sequence is the only uncompressed one but do you already find out the data structure of it? The posts on the last pages in this thread are confusing.

Here is a little goody for you: :wink:



From left to right: Buster Sword, Mythril Saber, Hardedge, Butterfly Edge, Enhance Sword, Organics, Crystal Sword, Force Stealer, Rune Blade, Murasame, Nail Bat, Yoshiyuki, Apocalypse, Heaven's Cloud, Ragnarok, Ultima Weapon.

edit: Added link.
edit 2: Added weapon names.

Kislinskiy

  • Guest
Decent FF7 Model Viewer
« Reply #204 on: 2004-09-24 07:54:19 »
This is what I just figured out. I assume that this is nothing new to you.  :z

Animation sequences of CLOUD.LZS (24 bones incl. root bone) with a length of 16, 24, 32 and 36 bytes:

Code: [Select]
01 00 09 00 04 FE 4E FF   E7 FF 50 00 FE 41 00 00

01 00 09 00 04 FF 41 FD   AE FE 84 00 C1 80 00 00



02 00 13 00 04 FF CB FD   D8 FF D2 CE 63 91 FF DB   FF EC E0 21 5A 5E 1B 7E



03 00 19 00 04 00 9B FE   6C FC 0C 15 B8 BE 71 FF   AF 40 43 F2 B5 DC 29 BB   D4 04 AF B9 D3 43 00 00

03 00 1B 00 04 FE A9 FD   42 FB 79 07 1E 4A 80 6A   A5 40 12 6F 75 F9 10 14   58 05 C4 0A 13 BF 8F A8

03 00 19 00 04 00 AC FE   57 FA 95 0F 0B EF 14 FF   CF 40 71 B7 59 99 C0 69   F0 1E BD BE F6 B0 00 00

03 00 19 00 04 00 C9 FE   4C FB DA 0F 0B F1 6B FF   B8 C0 41 F2 B2 70 C3 C1   E0 2C BD FE 46 D8 00 00



05 00 1E 00 04 FF 82 FD   16 FC F7 E3 89 81 01 01   76 44 80 40 9D A2 0F CF   A2 92 A2 02 9A 60 15 56   71 EE E8 00

03 00 1C 00 04 FE D7 FD   69 FC B7 FA 1F 35 80 64   86 7F E8 37 7D 56 FA 02   47 00 4F 80 F7 DF A7 EF   C1 00 00 00


Analyzing this data let me assume the following file structure:

ushort num
ushort length
byte unknown
byte[length + pad bytes] compressed data
Notice on pad bytes: Files in a LZS archive have to be 4 byte aligned.

num is a count of something. I see that you guess this is the frame count. Are you sure?

An empty animation sequence has a length of 4 bytes and consists of num (0x1A30) and length (0x0000) only.

Cyberman

  • *
  • Posts: 1572
    • View Profile
Decent FF7 Model Viewer
« Reply #205 on: 2004-09-24 14:42:50 »
Kislinskiy
Num I believe is the frame count, however 0x1A30 has bothered me for a while, WHAT is it? I've asked myself, on the empty animations.  My Guess is this is an impossibly long length.
The first frame also is NOT UNCOMPRESSED, just to let you know.  The whole sequence is compressed, this is why some of the characters won't look right when you use the first frame of the first animation sequence.  Section1 I am positive has something to do with the animation, I just haven't figured it out.

One of CID's animation sequences is only 11 bytes long this is not enough for a single uncompressed frame even (it is a one frame animation however).  It might be they use the first frame of the first animation sequence to start all of them, however the compression technique used will take a bit to figure out, I believe. If you display the first frame of REDXIII you'll find he's been playing twister.  This first frame is compressed in some way as I said.

It doesn't appear to be LZS I don't think they would use LZW because it has large memory requirements  huffman and shanno fano compression are complicated bitwise compression techniques and slow, unless they found a way to use the MDEC to decode the animations somehow on the playstation.  It might be the LZS compression bytes are somewhere else, but unlikely.  Delta sigma is possible but has a bit too much overhead. Then there is the 3 16bit offset values.

Cyb

sfx1999

  • *
  • Posts: 1142
    • View Profile
Decent FF7 Model Viewer
« Reply #206 on: 2004-09-25 03:08:47 »
Is it gzip/zlib? Or do they not use a 360 degree system?

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Decent FF7 Model Viewer
« Reply #207 on: 2004-09-25 05:19:29 »
What the-

The first frame is not compressed.

I posted this earlier.

That “u1” byte is a “compression code” for the first frame (and may also have meaning on all frames after).
It determines the number of bits in each rotation is 12, 10, or 8.

THAT is why Red XIII’s animation looks twisted.
“u1” can be either 0, 2, or 4, and the formula for the bitcount per rotation is (12 - u1), which means the bitcount for (u1 = 2) is 10.

Red XIII’s animations have only 10 bits per rotation (on his first few, and then some with only 8).
But regardless of the u1 value, the translations are always 2 bytes each, and for some reason they are in reversed byte order and they are also inverted (-466 is actually 466, and 264 is actually -262).



When translating Red XIII’s animations using 10 bits per rotation instead of 12 you get the following table (which I posted already).

Code: [Select]
Bits from 0x1B      * 360 / 1024

0000000000          0.0   RXOffset
0000000000          0.0   RYOffset
0000000000          0.0   RZOffset
0000001001          3.1640625
0000000000          0.0
0000000000          0.0
0000001001          3.1640625
0000000000          0.0
0000000000          0.0
0000000000          0.0
0000000000          0.0
0000000000          0.0
0001000101          24.2578125
1111111101          358.9453125
0000000000          0.0
1111100001          349.1015625
0000000011          1.0546875
0000000001          0.3515625
1101110101          311.1328125
1100011010          279.140625
0100000111          Etc.…
1111111011          Etc.…
1010110100          Etc.…
1001001011          Etc.…
1111101111          Etc.…
0001001101          Etc.…
1111010111          Etc.…
0000111110          Etc.…
1111110101          Etc.…
0000000011          Etc.…
1101110100          Etc.…
0011101011          Etc.…
1011111001          Etc.…
0000000001          Etc.…
0010001101          Etc.…
01 Etc.…



The formula changes from (X * 360 / 4096) to (X * 360 / 1024) because the maximum number for 10 bits is 1024.


You can decode Red XIII’s entire first frame this way and it is not compressed.
It just has a different decoding key (u1).


L. Spiro

Kislinskiy

  • Guest
Decent FF7 Model Viewer
« Reply #208 on: 2004-09-25 09:17:31 »
That sounds more logical. I can not imagine that animation data should be compressed with an algorithm again. The pad bytes in such a stream also indicate length variable values.

Kislinskiy

  • Guest
Decent FF7 Model Viewer
« Reply #209 on: 2004-09-25 10:01:28 »
Here is an example. This is the 3rd file in CLOUD.LZS. The first animation file without that yet unknown header.

The rotation values with a resolution of 12 bits start at offset 0x5FAD.

The first rotation triple is (000; 0FE; 2E0).

Quote from: L. Spiro
Code: [Select]
Bone   0: Name: rtam, Parent:  -1, Children:   3, Rotations:   0.00000000   0.00000000   0.00000000  Translating:  -39.00000000
Bone   1: Name: rtan, Parent:   0, Children:   1, Rotations: 270.00000000 333.10546875   0.00000000  Translating: -163.00000000
...

Related to this post the first rotation value would start at offset 0x5FB3 [(000; 000; 000), (C00, ECE, 000), ...] and ignore the 1st 4 12-bit values. Why? - Could it be that those values are the position/translation of the root bone to handle model movement? PSone coordinates of the battle models are stored in 4 values too. Just a thought.



L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Decent FF7 Model Viewer
« Reply #210 on: 2004-09-25 12:27:39 »
Kislinskiy, I redid the animation structure.
The header of each animation is only 5 bytes long after the block_len and looks like this:

Code: [Select]
struct s_FF7AAanimHdr {
   unsigned long   rec_a;      //0
   unsigned long   frames_1;      //4
   unsigned long   block_len;      //8

   unsigned short   frames_2;      //12
   unsigned short   real_data_len;   //14
   unsigned char   bit_count_key;      //16
} FF7AAanimHdr; //size = 17 bytes



For every animation file, the first animation DATA starts on 0x15.
The next 6 bytes are part of the first animation frame and they are reverse-ordered inverted unsigned shorts (3).
On Cloud it is:
00 00 = 0
FE 2E = 466
00 00 = 0

Then the rotations follow, with the first rotation being the root bone, and it is not counted as part of the total bones of the animation.

Those 6 bytes plus the root bone plus the model bones are all part of the first frame.
After that things are most likely stored in some form of relational offset of the first frame.

Cloud’s certainly seems that way but Barret’s definitely doesn’t.
So it is most likely another bit-length problem.


L. Spiro

Kislinskiy

  • Guest
Decent FF7 Model Viewer
« Reply #211 on: 2004-09-25 12:55:20 »
Quote from: Kislinskiy
Related to this post the first rotation value would start at offset 0x5FB3 [(000; 000; 000), (C00, ECE, 000), ...] and ignore the 1st 4 12-bit values. Why?

Quote from: L. Spiro
The next 6 bytes are part of the first animation frame and they are reverse-ordered inverted unsigned shorts (3).
On Cloud it is:
00 00 = 0
FE 2E = 466
00 00 = 0


Ah, ok. Do you already know what these three values do represent? Perhaps the position/translation of the model as I assumed in my last post?

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Decent FF7 Model Viewer
« Reply #212 on: 2004-09-25 15:31:13 »
They are a translation for each frame.

But they are stored in a strange and illogical way.

00 00 = 0
FE 2E = 466
00 00 = 0

Why?

Well, FE 2E actually equals 12030.
But 2E FE equals -466 (signed).

In order to get the final final result, this number must then be subtracted from 0.
-466 becomes 466.  That is the first translational Y offset of Cloud’s first frame of his first animation.

Also, subtracting the number from 0 only applies to the Y.
The others still need to be reversed (bytewise) but not subtracted from 0.


So, changing these values moves his whole body to whatever position.

The same applies for the first set of rotations (the root bone).
Changing the first rotation will rotate the entire model by the new amount.


L. Spiro

Kislinskiy

  • Guest
Decent FF7 Model Viewer
« Reply #213 on: 2004-09-25 19:30:23 »
I have problems with the correct rotation. Can someone post an image of the first frame of the first animation of ENEMY012.LZS please?

How do you calculate the position of a bone's child? I store the bone length at an identity matrix's z-element (element 43 in DirectX) and multiply that matrix with a matrix containing the bone rotation. Now I store the x-, y- and z-element in a vector and add it to the bone's position. This new vector represents the position of the child.

Due to FFVII uses another coordinate system I have trouble creating the correct rotation matrix.

Cyberman

  • *
  • Posts: 1572
    • View Profile
Decent FF7 Model Viewer
« Reply #214 on: 2004-09-25 21:33:28 »
Here is what I got, Note joints are RED and Bones are blue.
Cyan Magenta and Yellow are the X Y Z axis.



Cyb

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Decent FF7 Model Viewer
« Reply #215 on: 2004-09-26 03:36:05 »
I don’t have that file but when rotating you have to rotate in the exact order: -Y, X, -Z.

DirectX® matrices aren’t like OpenGL®’s and translating along the Z by the length of the bone does not work the same way.
In fact, rotating as I mentioned above won’t work in DirectX® either.

OpenGL® uses degrees while DirectX® uses radians for one.

But if you know the math to transform your matrices then I won’t post beyond that.


L. Spiro

Kislinskiy

  • Guest
Decent FF7 Model Viewer
« Reply #216 on: 2004-09-26 06:30:54 »
Thanks to both of you.  :)

@L. Spiro
I totally forgot that DirectX uses radians.

@Cyberman
Can you post EMENY041 please? The last one, I promise.  :wink: I think it is more suitable to compare...

My models are twisted.

edit: After analyzing ENEMY165 and ENEMY166 I guess I am a victim of Gimbal Lock... I recode my rotations using quaternions now...  -_-

ENEMY041

Kislinskiy

  • Guest
Decent FF7 Model Viewer
« Reply #217 on: 2004-09-26 14:04:31 »
OK, now I use quaternions to prevent Gimbal Locks. But that obviously was not the problem. The problem seems to occur on joint->bone only. There is almost evertime a "90 degree fracture". In addition some model parts are swapped (right arm should actually be left arm etc.).

ENEMY166


ENEMY320

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Decent FF7 Model Viewer
« Reply #218 on: 2004-09-27 03:02:42 »
Concerning your reversed models issue, it isn’t just some models that are on the opposite sides of where they should be, it is ALL.
The only reason SOME of them DON’t appear to be on the wrong side is because they are symmetrical.

This isn’t a problem when loading the models in OpenGL® but in DirectX® you have to load the models with -Z and -Y vertices/normals.
By this, I mean ONLY the 3-D model files.  Not the bones, not anything else.

And be sure to remember to load the normals this way also (which of course does not apply to battle models).


The result of this is that the models will stay on the wrong side, but they will be reversed, so the wrong side becomes the correct side.
This means your models will be perfect mirrors of the originals.


L. Spiro

Kislinskiy

  • Guest
Decent FF7 Model Viewer
« Reply #219 on: 2004-09-27 16:04:38 »
Why +X-Y-Z and not +X+Y-Z? The only difference between a left-handed and a right-handed coordinate system is the direction of the Z-axis. I confusingly get the correct result with +X-Y+Z. Probably only apparently due to wrong rotation. Do you have this "90 degree fractures" too? One more time please, YOU (using OpenGL) convert the rotation values XYZ to ___ and rotate in the order ___.


L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Decent FF7 Model Viewer
« Reply #220 on: 2004-09-27 18:15:42 »
In OpenGL®, the code is as follows:

Code: [Select]
glRotatef( -fY, 0, 1, 0 );
glRotatef( fX, 1, 0, 0 );
glRotatef( -fZ, 0, 0, 1 );

This is for rotations/bones.
Rotated first by -Y, then X, then -Z.




As for the 3-D models, reversing only the Z does not work.
Aside from changing the cull order (a minor problem), the objects become backwards.  Cloud’s head, for example, points back.
But I am sure if you manipulate the bones correctly, you can make the joints go the right directions to make everything dandy.

If you did that, the obect wouldn’t be mirrored horizontally (though it may be mirrored vertically).

I will personally pursue this matter to see if there is a winning combination for the bone rotations to counter the affects of only inverting the Z.


As for 90-degree fractures, I have never had that.


L. Spiro

bomer

  • *
  • Posts: 19
    • View Profile
Decent FF7 Model Viewer
« Reply #221 on: 2004-09-30 05:52:22 »
I sware, Mirex
If you put an option to export models in Leviathon...  :D

Qhimm

  • Founder
  • *
  • Posts: 1996
    • View Profile
    • Qhimm.com
Decent FF7 Model Viewer
« Reply #222 on: 2004-09-30 08:35:18 »
Quote from: Hidden message
Matrix Transformations Are Your Friends

...? :o

mirex

  • *
  • Posts: 1645
    • View Profile
    • http://mirex.mypage.sk
Decent FF7 Model Viewer
« Reply #223 on: 2004-09-30 12:27:16 »
Quote from: bomer
I sware, Mirex
If you put an option to export models in Leviathon...
Its not needed, Unmass & Biturn can export everything you see in Leviathan. Check them out.

bomer

  • *
  • Posts: 19
    • View Profile
Decent FF7 Model Viewer
« Reply #224 on: 2004-10-04 22:44:27 »
Yeah well i spent about 4 hours just trying to export cloud 2 a 3ds max file :x  Yeah not so easy for me... Maybe someone could upload a few of the famous characters?