Title: Re: Model Enhancement/Reconstruction [FFVIII]
Post by: Alkor on 2008-06-22 15:59:17
1) Download: _http://rapidshare.com/files/124242233/FF8_Edit.7z.html
2) unrar it all
Then
1) Open Garden. Open - Decompile data files - name it. Then wait. When it stop go to:
"ur folder with Garden"\ff8\data\eng\FIELD\model\main_chr
There will be files such us .mch this is battle and field models of main chars.
U can open it with Biturn.
#S #S #S #S S1 S1 S1 S1 - S2 S2 S2 S2 S3 S3 S3 S3
S4 S4 S4 S4 S5 S5 S5 S5 - S6 S6 S6 S6 S7 S7 S7 S7
S8 S8 S8 S8 S9 S9 S9 S9 - SA SA SA SA SB SB SB SB
EF EF EF EF
#T #T #T #T T1 T1 T1 T1 - T2 T2 T2 T2 ... ...
EF EF EF EF
Pretty much all of the main characters have their own .mch files which are referenced in the actual field data files (rather than having to include the entire model in each field it's used). Other character models reside in the chara.one files found in the field files. Also, all animation data resides in the chara.one files, even for main character models. The animation data (found in the beginning of each model block in the chara.one files) is pretty much the only part of the model format that still eludes me; I have decoded the vertex data, face data, skeleton data and texture mapping data. Once I've understood the format of the animation data, I might compile a document on it, or write a small program to read the models. (just pleeease don't bug me about it ;) )
Until then, here's a basic layout on the .mch files:Teaser image of a decapitated Squall
- Index block, 64 DWORDs. Contains the offsets of each texture in the file, then a 0xFFFFFFFF, then the offset of the model data.
- Texture data. Standard TIM format.
- Model data header, 8+8 DWORDs. Contains counts and offsets of different types of model data (skeletal joints, vertices, unknown, faces, unknown, vertex-to-bone links, 3 x unknown).
- Skeletal joint data. 64-byte blocks of mostly zeros, contains a 1-based parent index and a bone length value. Probably a bunch of skeletal deformation data used in-game, but whose values are initially stored as zeros.
- Vertices. Blocks of 4 shorts, the first three being x-, y- and z-coordinates and the fourth unused.
- Faces. Huge blocks containing vertex indices, color data (unused), edge data (I think), texture mapping data and texture ID. Faces can be 3-point or 4-point polygons, decided by the first DWORD (actually it's a PSX GPU command ID).
- Vertex groups, or "limbs". These decide which vertices are connected to which skeletal node. Groups of 4 shorts, with the index of the first vertex, the number of vertices and the bone ID (1-based) to which they belong.
[/list]
Side notes: The animation data somehow stores the internal rotations for the model's skeletal nodes using 4 bytes per node. I'm speculating that the format would be one which a PSX could handle, in line with the lazy programmers theorem. Any ideas?
Also, the battle model format is vastly different from the normal field model format. I haven't even been able to find any vertex data in it, I'm almost suspecting it's compressed or something.
This is what I've managed to gather so far:
S1: Skeleton
S2: Geometry
S3: Animation (there's a subheader with no. frames)
S4: Unknown
S5: Unknown
S6: Unknown
S7: Monster Info section (I decoded a lot of this, see below)
S8: Suspected of being some sort of Battle Script (it contains text that's displayed in the battle)
S9: Some sort of sound data
SA: Some sort of sound data
SB: Texture
By the way, I believe that the duplicate pointers are because a section is unused (ie. zero length) so the section after ends up with the same pointer.
struct Item {
BYTE id;
BYTE amount;
};
struct Action {
BYTE type; //??? 0x02 = generic magic
BYTE animscript; //???
BYTE id; //???
BYTE unk;
};
struct MonsterInfo {
char name[24]; //FF8 encoded - length might be less than this
BYTE HP[4]; //HP = (HP[0]*x*x)/20 + (HP[0] + 100*HP[2])*x + 10*HP[1] + 1000*HP[3], where x = monster lvl
BYTE unk0[24];
Action RosterL[16];
Action RosterM[16];
Action RosterH[16];
BYTE Unk1[4];
BYTE Card[3]; //1st Byte = Card Drop, 2nd Byte = Carded into, 3rd Byte = Rarely Carded into, 0xFF = no drop/can't card
BYTE Devour[3]; //Low, Med and High lvl Devour effect id's
BYTE unk2[6];
USHORT LowLvlDraw[4];
USHORT MedLvlDraw[4];
USHORT HighLvlDraw[4];
Item LowLvlMug[2];
Item LowLvlRMug[2];
Item MedLvlMug[2];
Item MedLvlRMug[2];
Item HighLvlMug[2];
Item HighLvlRMug[2];
Item LowLvlDrop[2];
Item LowLvlRDrop[2];
Item MedLvlDrop[2];
Item MedLvlRDrop[2];
Item HighLvlDrop[2];
Item HighLvlRDrop[2];
BYTE unk3[20];
BYTE ElemRes[8]; //These are how resistant the monster is to each element 0 = very weak
//0 - Fire
//1 - Ice
//2 - Thunder
//3 - Earth
//4 - Poison
//5 - Wind
//6 - Water
//7 - Holy
BYTE StatusRes[20]; //Status resistances 0xFF = immune
//0 - Death
//1 - Poison
//2 - Petrify
//3 - Darkness
//4 - Silence
//5 - Beserk
//6 - Zombie
//7 - Sleep
//8 - Haste
//9 - Slow
//10 - Stop
//11 - Regen
//12 - Reflect
//13 - Doom (red timer) - command/doomtrain
//14 - Slow Petrify? (white timer) - cast using doomtrain
//15 - Float
//16 - Confuse
//17 - Drain
//18 - Huh
//19 - Huh
};
0x00: Number of PC and NPC models (32-bit). Might not count for calculating offsets.
0x04: First model's header (detailed below)
PC Model chara.one header:
0x00: Pointer to animation data? (32-bit)
0x04: Size of the animation data or whatever it is. (32-bit)
0x08: Size again.
0x0C: MCH number? (32-bit? Upper 16-bits might determine whether header refers to PC or NPC)
0x10: 4 bytes
0x14: MCH name? Not sure if used. (4 bytes)
0x18: 4 unknown bytes
NPC header:
0x00: Pointer to first TIM (32-bit)
0x04: Size of TIM & Model data (32-bit)
0x08: Size again.
0x10: MCH-type header possibly starts here. Offsets are relative to the TIM image.
After the model data pointer: 8 unknown bytes.
Both types usually end with the hex bytes "EE EE EE EE" after the unknown bytes, though there may be exceptions.
Section Header:
WORD Number of animations
Animation Header:
WORD Number of frames
WORD Number of joints (Koral labeled them bones.)
In that old thread, Qhimm said the animations were stored using 4 bytes per node. By counting I think there might also be an additional 6 bytes per frame, but I'm not absolutely sure.
Well it does look like, from what I'm reading, some lesser form of import/conversion tool could be developed for the time being if the person is willing to do some fiddling with the model after an end result (it's more the beasties I'm hoping to give a rendered animated version, so "some assembly required" is of no consequence for me XD)
Well had some luck. Of sorts.
http://planescape.piiym-net.com/irongiant.rar
What I did was use 3DVia Printscreen (http://www.3dvia.com/pros/3DVIA_PrintScreen/) on CharEdit itself. The result came out as you see up there. Unfortunately giving the thing bones is turning into somewhat of a pain in the...maybe I need a crash course in it.
If anyone's willing, I can go ahead and see if I can get any other models from it for them. They rip pretty well, just no bones, no animations and twisted elements stay, well, twisted.
Byte Numbers refer to bytes of each bone's four bytes in the animation data.
Short Rotation?1 = (Byte1 << 0x02)| ((Byte4 & 0x03) << 0x0A)
short Rotation?2 = (Byte2 << 0x02) | ((Byte4 & 0x0C) << 0x08)
short Rotation?3 = (Byte3 << 0x02) | ((Byte4 & 0x30) << 0x06))
or, more closely following the game's ASM:
Short Rotation?1 = (Byte1 << 0x02)| ((Byte4 << 0x0A) & 0xC00)
short Rotation?2 = (Byte2 << 0x02) | ((Byte4 << 0x08) & 0xC00)
short Rotation?3 = (Byte3 << 0x02) | ((Byte4 << 0x06) & 0xC00)
In case anyone's wondering, I messed with my script too much and didn't keep backups, so I can't reproduce those results from before. :oops:
I've attempted to recreate it, but I don't know how close I've gotten. I've fixed the misplacement of vertices though.
Current results:
However, the first method can only do one frame from one animation.
(I don't know much about 3D.)
Oh how I wish I had he skill at spotting the relevant patterns for data structures like you guys have... Even with well documented headers I can't seem to make my bytes fit right... nonetheless find a vertex pool...For me it's sort of like this, "I'm working on an LED luminary, how far is that half bridge from the OSMC 4.1XX, ok I have this AT91SAM7S dev kit is the JTAG drivers installed, I need to install YAGARTO to develope for the micro why is ECLIPSE CDT wiping out the ZYLIN CDT used with YAGARTO, we have 30cm of snow in the drive way. Ok which to do first" sadly that's just today. That didn't include eating getting up and the myriad of other things I think of in a single day etc.
but regardless, I'm glad to see I'm not the only one still interested in getting a good look at 8's graphics.
So what you're saying, is that once I have a potential vertex pool, I start plotting two of the coords per vertex in paint... If it starts to look like a model shape, I probably have the right stuff. If not I may be looking at something else entirely...
Is that what you're describing?
(And on the subject of busy life stuff... that I can fully understand... it isn't easy being a fulltime student with a part time job and no method of self-transport...)
However, I should note that I'm not simply working on FF8... I'm on FF9, both .hack series' and a number of other games on and off at any given moment, as well as being a 3D modeler for my own games... If I devoted all my time to one format... I'd probably be able to crack it at some point(or have a severe mental break).
However, my previous statement was referring mainly to the fact that I still can't get my headers to read properly even when they are fully documented...
When I read a header that tells me a file should start or end at a certain point in the data... I look at that part and it's either well after the end of the file or it is in some random spot after the file has already started... so instead I look at a relative point to the beginning, or end of that header, or the main header, or the end of the previous file, etc... but for some reason, even though I know the documentation is good, the headers don't seem to point me to where they should... (meaning I'm somehow reading them wrong...)
In any case... none of this helps the FF8 formats so I guess I'll stop.
Synopsis
A triangle strip is a speed- and space-efficient way of storing a set of triangles on a computer, usually for computer graphics.
Detail
Take, for example, a modern graphics processor, capable of drawing millions of polygons per second. One of the major limiting factors is not the triangle-drawing ability of the processor; without triangle strips often the limiting factor is the data bus between the graphics processor and the memory storing the triangles1. Triangle strips reduce the memory bandwidth needed by a graphics processor by not transmitting redundant information. Each triangle is comprised of three separate vertices, but in many cases you can find a set of topologically connected triangles which share common edges. Triangle strips exploit this fact. So what does this mean?
Consider a simple square, which would be stored as two triangles:
0--1
| /|
|/ |
2--3
Thus, the square is made up of the triangles (0, 1, 2) and (1, 2, 3)2. A naive storage format for this square would just store both those triangles, costing 6 (2 x 3) vertices. Notice how in both of those triangles, the edge (1, 2) is specified. A triangle strip simply stores that square as (0, 1, 2, 3), where the two constituent triangles share the middle edge (1, 2). In a triangle strip of length N, there are (N-2) triangles; with each triangle being a vertex and its two previous vertices. This means the square is now stored in 4 vertices, and if we wanted to add another connected triangle (sharing edge (2,3) with triangle (1, 2, 3)) we only need to add an extra vertex:
0--1
| /|
|/ |
2--3
| /
|/
4
This is extremely space efficient; in a perfect strip each extra triangle costs us only another vertex.
If you imagine a typical polygonal mesh, for example a triangulated teapot, you can see that the majority of the triangles share edges with other triangles around them. This makes finding long strips of connected triangles relatively easy, and indeed such shapes can be stored very efficiently using strips.
Given an arbitrary polygon soup, finding the perfect set of triangle strips which represent it is a difficult problem. There is a potentially infinite number of different strips you could choose to represent an object, but for efficiency's sake the strips used must be as long as possible. In fact, this process (known as triangle stripping or sometimes stripification) in an NP complete problem. However, armed with some simple heuristics you can usually come up with a near-perfect solution. There are a number of GPL libraries around for performing stripification, including a particularly good one called Stripe.
As you've seen, strips are space-efficient; it takes less vertices to specify a mesh using strips. However, it is also speed-efficient. In rasterizing a triangle, a graphics processor has to perform a fair degree of calculations, particularly if it supports something like programmable vertex shaders. When rendering a strip, if the previous two vertices are cached, then after the first triangle has been drawn, the next only requires one extra vertex calculation.
There's another trick that can be used; normally there's a set up cost associated with starting a strip on modern graphics hardware. So reducing the total number of triangle strips is beneficial too - this can be achieved using degenerate (zero area) triangles. Given two strips, you can stitch them together by duplicating the last vertex of the first strip, and the first vertex of the second strip, and then concatenating them. Consider two separated squares:
0--1 4--5
| /| | /|
|/ | |/ |
2--3 6--7
These squares can be expressed as a single triangle strip (0, 1, 2, 3, 3, 4, 4, 5, 6, 7) with four degenerate triangles (2, 3, 3), (3, 3, 4), (3, 4, 4), (4, 4, 5). As the triangles have zero area (which is quick to detect), they usually cost very little to process, and in most circumstances these long concatenated strips are more efficient than lots of small strips3.
Any task involving large numbers of triangles can benefit from triangle stripping, for example collision detection, or ray tracing.
1.Indexing vertices and storing vertex data separately to topology information is another common way of reducing the bandwidth, which is compatible with stripping.
2.Usually triangles are stored with a consistant winding order, I ignore winding issues here for clarity. Where winding order is important (e.g. on graphics processors) note that every other triangle's winding order is opposite, and this is taken into account by the hardware.
3.Some specialist applications (e.g. the PlayStation 2's rendering system) store an extra piece of information with each vertex: whether that vertex and its previous two vertices should be considered a valid triangle. This allows an even more efficient way of stitching triangles together; you can simply concatenate strips together and ensure the first two vertices are not marked as valid triangles. For example, using an asterisk to mark valid triangles, the two squares can be expressed as (0, 1, 2*, 3*, 4, 5, 6*, 7*) using such a system.
1. .2 and the next triangle being .1(2)
3. 2(3). .3(4)
(http://i239.photobucket.com/albums/ff83/TtravelrKev/Final%20Fantasy/RinoaParty_GoodRotations_1.png)
:-D
I don't actually know how what I did works, but I'm now very close to proper bone rotations. Still need to fix the other issues though.
Some issues
- Gaps in UV
- Textures don't show up in render (Need to associate it correctly or something.)
Hmmm, I've come a long way since I started, when it had no skeleton at all and was just a clump of parts stuck together. (Those are stages which I didn't show here.)
Edit: Didn't notice that the parts of the body (noticeably the hands) were flipped. I think I've fixed it in the script now.
Edit: Didn't notice that the parts of the body (noticeably the hands) were flipped. I think I've fixed it in the script now.
:-o arg, we still can't get models from FF8?On the contrary, it is quite possible to get the battle models (eventhough they are somewhat twisted, it's easily fixed) It is reportedly possible to also get the field models, but I have yet to do it or see it being done.
I wonder, the PC game is dx8 or dx6 based?
:-o arg, we still can't get models from FF8?On the contrary, it is quite possible to get the battle models (eventhough they are somewhat twisted, it's easily fixed) It is reportedly possible to also get the field models, but I have yet to do it or see it being done.
I wonder, the PC game is dx8 or dx6 based?
Sure, this will be the quick version though because I have a lot of stuff to get done today.On the contrary, it is quite possible to get the battle models (eventhough they are somewhat twisted, it's easily fixed) It is reportedly possible to also get the field models, but I have yet to do it or see it being done.
Beg pardons, but if you can get battle models, could you explain how? I've tried a few programs but most fail miserably to even run at all...
the models are very lowpoly.. I can't imagine it be that too hard to extract.I guess just to show we can. All the information is there (I think) and Qhimm is supposed to be the mecha of 90's FF modding.
I think it's largely due to how old these models are.. they are outdated.. so whats the point cracking a heavily optimised/condensed format..
it just sucks that no reliable viewer has ever been made considering that FF8 is just one of those lagacy gamesWell Vehek was making awesome progress, maybe he'll decide to take it back up.
ohwell guess it's time to start re-modeling so of these characters right ;)
I would love to see progress made on this game, I'm one of it's few fans. :)One necro isn't terribly bad when it brings something new to the table. 2 is bad. Definitely bad. Locked. Warned.
Here is a tool that is capable of ripping 3d data directly from games, maybe it could help you, it offers a different method of getting data. (Ie, it hooks DX, when the model is drawn, it can dump that data directly, rather than bothering with figuring out the file format.. I've used this myself, it's not perfect, but it can get the models out of otherwise undocumented game formats.)
It basically takes a 3d screenshot.
3d Ripper DX
http://www.deep-shadows.com/hax/3DRipperDX.htm