Final Fantasy 7 *.p format (3d model) description ( by [mirex on the mailserver centrum.sk] ) Version 2. No research was made, i only added here info from alhexx's and NeutopiaW's descriptions, to make it more complete. TODO: find flag 'normals used', 'vertmaterials' First, these are my notes to this format, so they are really messy; if you can't understand something it's my fault. If you want just brief info, jump to end of this text to section -- summary --. If you can tell me something more about this format, or you know about some mistakes in this text, please mail me about them. --File parts-- offset size name Always present/Optional 0h 64 Header1 A 40h 64 Header2 A 80h (V*12) Vertex data A .. (N*12) Normals A .. T*8 tex coords O .. (V+P)*4 colors A .. E*4 edges O .. P*24 polygons A .. H*100 pool100 A .. H*56+4 grp pool A .. 24 bbox A .. V*4 unknown8 A --Parts description, name( size ) -- ==header1== (16 x long) = 64 = 40h 01 00 00 00 01 00 00 00 01 00 00 00 A(long) N(long) 00 00 00 00 T(long) V(long) <-vertex counts ? E(long) P(long) 00 00 00 00 00 00 00 00 <-polygon counts ? H(long) I(long) G(long) 01 00 00 00 V = vertexs count P = polygons count N = normals count E = edges count T = texture points count A = unknown, usually A = V G = sometimes 0 or 1, something with texturing H, I = 1 when non-textured, 2, 4 on some textured. ==header2== (16 x long) = 64 = 40h big longs, unknown looks like positions of parts of file, but in one large file. one(not allways first) long is smallest, and others are little larger ==Vertex data==( V * 3 * float ) = (V*12) V * ( 3 * float ) {x,y,z} for big model ==Normals==( N * 3 * float ) = (N*12) N * ( 3 * float ) {x,y,z} ==tex coords==(T*2 * float) = T*8 texturing info, coordinates T * ( x,y ) float ==colors==(V+P)*4 sequences of 4 bytes (BB GG RR FF) = color in BGR0 format, 0-255, maybe FF has some meaning too, maybe transparentness ? or intensity ? V * 4 bytes = colors of vertexs P * 4 bytes = colors of polygons. There is a mess here sometimes. ==edges==(E * 2 * word) = E * 4 polygon edges. looks like lines (2*word) every word is < V, and they cover big model. Edges are not allways present (never in battle.lgp ?) (Some lines are twice in list. Sometime they dont fit on polygon edges.???) ==polygons==(P * (10*2 + 4) ) = P * 24 records of 10 words and one long. [ 0 | 1 2 3 | 4 5 6 | 7 8 9 | L ] 0 - unknown, always zero ? 1, 2, 3 - polygon points for big model 4, 5, 6 - polygon points for small model - sometimes it's a mess. 7, 8, 9 - polygons completed from edges, numbers < E. three edges (edges of triangle) make one polygon. If edges_count is 0, there are same numbers for all polygons(mess) L(long) - separator ? the same for all polygons in field is this number similar to numbers from 2nd header in battle it is different, also 7, 8, 9 are same for all polygons ==pool100== H * 100 sets of records of (4 x one byte), all four bytes are the same possibilities I have seen so far, and their binary form 00 00 00 00 0000 0000 01 01 01 01 0000 0001 02 02 02 02 0000 0010 04 04 04 04 0000 0100 0E 0E 0E 0E 0000 1110 FF FF FF FF 1111 1111 usually there is one record 10*4 bytes long with FF FF FF FF on end, so length is 44bytes combinations seen so far H I G T records count 1 1 0 0 = 4 1 1 1 0 = 11 4 4 1 14 = 86 4 4 1 12 = 92 Records count change with texture parameters, so it should have something to do with textures Length taken from alhexx's description original NeutopiaW's text: The 100's pool is actually a list of materials that correspond to the poly groups. IE: Use material 0 with group 0. ==grp pool== (H * 56 + 4) taken from alhexx's and NeutopiaW's description H * { 0x00 long Primitive Type, 1 - Triangle, 2 - Triangle Strip long Starting Polygon long How many polygons long Starting Vertex 0x10 long How Many Vertexes long ? long ? long Unknown!! (Something to do with textures probably) 0x20 long ? long ? long ? long Word Starting TextureUV 0x30 long uses textures, 0 - No Texture, 1 - Non Textured Triangles, 2 - Textured Triangles (with vertex normals), 3 - Textured Triangles (No normals used) long Texture Number } 4 bytes ?? original NeutopiaW's text: Ok drawing just the polygons from start to end is not enough, in fact if you do this you will see the model screw ups as stated above. (Hojo's head). Anyways what has been referred to as the 56 pool, is actually the .grp part of the file. (Group) This is very important as it tells you how to draw the model properly. You start at the first group and Each 56 byte group contains the info (listed above), for how to draw it, what texture it uses (if it does use one), starting vertex to use, starting texture UV to use. ==bbox==( 6 floats ) = 24 bounding box of model. max( x, y, z ), min( x, y, z ) sometimes just zeroes. ==unknown8==( V longs ) = V * 4 low longs < N, translation ? some numbers are there more then once, probably when N < v. Looks like translation big model => small model -- some info to data types -- PASCAL C LENGTH IN BYTES byte char 1 word short 2 longint long 4 single float 4 I suggest using unsigned variables (unsigned char, unsigned short, unsigned long) -- summary -- so file consists of two models: big one, and small one, and there are some strange data also. In vertexs data part, there are vertexs for model (in format V* {x,y,z:float} ), In polygon data part, there are records with points, as written above So if you want to rip model, do this: read header1, there you'll get V, P and other values skip 64 bytes ( header2 ) read V * 3 floats (x,y,z) ( vertexs ) skip N * 12 bytes ( normals ) skip T * 8 bytes ( texturing info ) read colors data, vertexs colors V * 4 bytes, or skip them and read polygons colors P * 4 bytes (don't know this for sure) or skip them both, (V + P) * 4 bytes skip E * 4 bytes ( edge info ) read P * polygon struct { unsigned short us[10], long l } and store polygons points us[1], us[2], us[3] and you have polygons, vertexs and colors. 05-07-2001, 22:44:44