What's new

PM:TTYD model file format, pet project

R-II

New member
This is somewhat of a first for me in a lot of regards - hacking game formats, reverse engineering file formats, and using 3D programming outside of a tutorial.

I've spent a fair ammount of time breaking down the structure of the model files (I assume proprietary) for Paper Mario 2: The Thousand Year Door, and I thought I'd share my progress. If this has allready been done or it's a common format I just don't know about, please tell me and point out the documentation I missed :)

Currently I've pieced together the following specs for the file format at:
http://hocuspocus.penguinia.net/rii/tplvtx.txt
(forgive my probably incorrect use of terms)
[Updated 5/30/05]
Almost all blocks now defined.

I've also got some pictures to document my testing and progress:
http://hocuspocus.penguinia.net/rii/pmviewer1.gif
http://hocuspocus.penguinia.net/rii/pmviewer2.gif
http://hocuspocus.penguinia.net/rii/pmviewer7b.gif
http://hocuspocus.penguinia.net/rii/pmviewer8.gif
http://hocuspocus.penguinia.net/rii/pmviewer10.gif
http://hocuspocus.penguinia.net/rii/pmviewer11.gif
pmviewer15.gif

pmviewer16.gif

I'd like to blend the planes without making them translucent, but I havn't found a good way around that limitation yet.

I hope if anyone wants to play with PM:TTYD, they'll find the document I've pieced together useful, allthough it's still a work in progress and isn't gaurenteed accurate, but if anyone else notices some things I missed that I just don't know how to see, I'd greatly appreciate knowing about it. There's a lot I don't know, especially with 3D. I'll also post my little proggy later after I've cleaned it up and if anyone's interested.

Anyway, maybe this was an easy format to break down, but it's a big accomplishment for me :)
 
Last edited:

thakis

New member
*Very* nice :)

I don't understand what you want to say with 'blend the planes without making them translucent', though. Have you tried glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND) (or the direct3d equivalent if you're using dx) or glAlphaFunc(GL_GREATER, .5f); glEnable(GL_ALPHA_TEST); instead of glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_BLEND) (at least the image looks as if you were using this last method)?
 
OP
R-II

R-II

New member
That's the method I used (GL_SRC_ALPHA/GL_SRC_ALPHA_MINUS_ONE). Unforteunately it doesn't look nearly as pretty if I have white textures. But I need a good way of determining the order to draw the planes in, or order-independent rendering which OpenGL does not lend itself to as far as I can see.
 

thakis

New member
There's a paper over at developer.nvidia.com (http://developer.nvidia.com/object/Interactive_Order_Transparency.html) about order independent transparency, but that's probably overkill for this purpose. The z order has to be stored in the file somewhere, because the original program has to know it too. Perhaps the scene graph stores the planes already in the right order (if there is a scenegraph stored) or there is an array which stores the order in which the planes have to be drawn.
 
OP
R-II

R-II

New member
waha, thank you so much, when I first read your post this morning I didn't notice your mention of glAlphaFunc, which did exactly what I wanted it to do. And in all my hours of searching, I kept seeing blending blending blending but not a single mention of an alpha test. So render order is irrelevant to me at this point in the game, which I couldn't find in the format anyway.

pmviewer19.gif


Now I can get back to researching other parts of the file, which are getting a lot harder :)
 
Last edited:
OP
R-II

R-II

New member
post-2-1115788127.gif


I'm taking a rather blind stab at color and lightning normal blocks. The way this lock model colored and shined under a front-shining light makes me think my guess is correct, but I'm not sure yet if I've implemented it correctly. But I don't even know if all this data handles the same way under openGL as it does on the gamecube.

After this, I'll be looking into 'block 27', which I think is various poses and animation. That should be a real treat to break apart.

While I'm at it, does anyone know why there might be two blocks of incrementing integers? 0x00000000 0x00000001 0x00000002 .... 0x000005DE if there's 0x5DE polygon points. I can't even make a guess as to what they mean.
 
OP
R-II

R-II

New member
Figure I'll post my viewer since it's allready uploaded, for anyone who has PMTTYD files to play around wtih. The model files are stored in the "a" directory of the GCM. It should display most models, but since I've tested only a portion, some might crash it. I've allready fixed many a glaring error in that regard. Make sure the models you try to open are in the same directory. Also make sure the TPL file is present (same filename but followed with a dash), otherwise you'll only get colored models. Also be warned there might be memory leaks or other things since the code is messy, but I havn't seen it do terrible things to my computer yet. Includes a data viewer to examine the model file contents, minus block 27 (see specs).

Download: http://hocuspocus.penguinia.net/rii/pmviewer.zip
If you find a model that crashes the app, please tell me

Currently I'm trying to figure out different poses and how to hide the appropriate planes. And animation, but I don't know anything about model animation, so maybe not.
 
OP
R-II

R-II

New member
I've spent the last few days battling with assembling the models correctly. I've arranged the blocks in the file into a form of a hierarchy. I also think I've figured out a hierarchy for the various planes, in which there's also entries labled as locators, joints, and groups. Every element of the hierarchy has an assoicated set of 24 floats from Block 24, which I think are broken into 8 sets of 3, and are used for translating, scaling, and rotating the different parts of the model. Each child in the hierarchy should inherit the transformation values from their parents as well I think, which makes sense. I'm applying the transformations to the modelview matrix before transforming a child, and then drawing the vertices from the point after all the transformations needed for that child are applied, which seems to work, but I don't know if it's a good method.

This is where I'm having a lot of trouble though, because the way I'm applying the transformations, some of the previously complicated and unrecognizeable models show up almost perfectly, but might have small errors (example: the ears in the pig model from twilight town are out of rotation and aren't symmetrical). Other models that allready displayed perfectly without any transformation are broken (or should I say their assembly shattered) after the transformation is applied. And a good chunk of models don't care or are slightly improved. I've updated the spec with some of my latest guesses and corrections, allthough I need to take the time to add better description.

Here's a picture of Hooktail the Dragon after transformations, looks pretty good, but I think there's some slight errors.
pmviewer42.gif
 

thakis

New member
What you are describing is the standard hierarchical scene graph, so it's probably The Right Thing (TM) to do. In bmd files, sometimes a vertex has to be transformed by more than one matrix (that's called skinning and is used for skeletal animation), perhaps you have to do this as well?

Oh, and did you try to glEnable(GL_CULL_FACE)? That might fix the dragons face...
 
OP
R-II

R-II

New member
Thanks for the tip on culling polygons. That just cleared up every lighting and color problem I had.

Do you have any more information about scene graphs, or more importantly, "skinning"? You're probably right, and I'm sure part of it does have to do with animation, but I don't understand really what you mean by multiplying by a second matrix, or where it comes from. I've literally taken a crash course in OpenGL four weeks ago and have no prior experience in game files or hacking, so I don't know any of the terminology, everything's named and identified from relationships I see.
 
Last edited:

thakis

New member
Here's a pretty good overview on skinning:

http://www.darwin3d.com/gamedev/articles/col0598.pdf
http://www.darwin3d.com/conf/igdn0398/index.htm

Basically, there are two methods to animate meshes:
1.) Keyframes - simply store the mesh in different poses and display them on after the other (like 2d animation), quake2 does this for example. Looks good, but need much memory. And animation has to be "canned".
2.) Hierarchical animation: You have a matrix transform hierarchy and every vertex belongs to one of the matrices. To animate a model, you only animate the matrices ("joints"), and the vertices follow. Problems and solutions to this approach are outlined in the above links.

HTH.
 
OP
R-II

R-II

New member
Thanks for the links, I'm not entirely sure about the whole weighted vertices part, unless it just means inhereting the parent bone's transformations. I guess I need to do more exploring there, and I'll probably have to figure out more of the mysterious "Block 27". Aside from Block 19 which I've never seen change, I've figured out what all the other blocks do, and that just leaves animation.

The PDF actually pointed out something a little unrelated to skinning that just corrected all the minor errors in my 3D models - I was rotating my axes in the order XYZ instead of ZYX. Also discovered that the 4th transformation set is another rotation, so even the broken planar models appear correctly now.
 

thakis

New member
At least in Mario and Zelda, animations are stored in a separate file, not with the model (which makes sense imo). Perhaps Block 27 contains materials stuff (shaders, texgen, texture matrices etc)? I don't know how Paper Mario looks, it might be that it doesn't need materials stored with the models, but... ;)
 
OP
R-II

R-II

New member
I don't know exactly what defines a material, but there's texture vertices, color, lighting normals, and such stored in the other 26 blocks. There's no obvious complementry files that go with the models in the PM rom, so I'm fairly certain everything that pertains to the model apart from their NPC data which is stored in an XML-like file elsewhere, is stored in that file, with textures in an accompanying TPL. I've actually started some work on Block 27 now, and one of the sub-blocks is responsible for animating the textures (or changing them, I don't know if texture animation is the right term), so fuses flash and little fire balls flicker.

From what I can see, there's 4 other types of animation in 4 other blocks, I think one of those is for displaying and hiding planes. The others are probably responsible for physically moving the planes, but I havn't gleaned anything from them yet. All these blocks are indexed by another list with timer offsets, perhaps in milliseconds, and either the animation loops or plays once.

And here's a screenshot from the game itself, and what I'm rendering below it.
14_1.jpg

pmviewer47.gif
 

ShizZy

Emulator Developer
R-II said:
I don't know exactly what defines a material,
A material defines how a mesh is rendered. It can include lighting type (ambient, specular, diffuse, etc..) as well as vertex coloring, mip mapping, bump and env mapping, multi-texturing, etc. What's stored varies based on the format...
 

thakis

New member
Hi, I just tried the viewer, works nicely. the file /a/a_mario looks kinda broken, though, and if I choose util->data view, it hangs. :saint:
 
OP
R-II

R-II

New member
I actually have a grossly updated viewer which displays most things perfectly, which I'll attach for you. Meant to get it up earlier, but...

Anyway, I got some of the animation implemented, but what I have working doesn't work for everything. The bits that control what planes are displayed and which are hidden seems to be working more completely.

I'm a bit down about the project right now because I simply cannot figure out the last couple blocks that actually move the planes around in animation, which would be rotation scaling and translation. I'm dealing with floating point values from the scenegraph, but I can't find any way to derive a floating point value from these animation blocks, and I can't figure out how to derive any kind of index either. I've had some guesses based on how the others worked (an inital index, with each index following actually being a bias to the index), but it hasn't really gotten me anywhere. Blocks in question are 27.4, 27.5, and 27.8 if you or anyone else is interested in looking (you can easily view the raw data with the data viewer inside the tool itself. I've also converted the hex to floating point and signed bytes too I think).
 
Last edited:
OP
R-II

R-II

New member
Actually, never mind that download if you followed the link, I forgot I linked the file to webspace, and that one would have been up to date.

Yeah, I don't know what's up with the Mario models. There might be some special treatment with that one because he's the controllable character and such.
 
OP
R-II

R-II

New member
Second note on that Util->Data View (Gee, I should really be reading your posts more carefully), it hangs for a while, especially on larger model files (most of which is due to animations, not the complexity of the model), but I think in every case I tried, it did eventually come up.
 

Top