Final Fantasy 7 *.p format (3d model) description ( by [mirex on the mailserver centrum.sk] ) 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+VS*12) Vertex data A .. T*8 tex coords O .. (V+P)*4 colors A .. E*4 edges O .. P*24 polygons A .. ??? unknown5 A .. 29*4 unknown5.5 O .. (T*3)*4 unknown6 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) VS(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 VS = vertexs count for small model 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==( VS * 3 * float + V * 3 * float ) = (V*12+VS*12) V * ( 3 * float ) {x,y,z} for big model VS * ( 3 * float ) {x,y,z} for small model ==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. This is not allways. ==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 ==unknown5== unknown length !!! 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 ==unknown5.5( 29 longs ) = 29*4 unknown, sometimes not present ==unknown6==( T*3 longs ) =(T*3)*4 unknown ==bbox==( 6 floats ) = 24 bounding box of big model. max( x, y, z ), min( x, y, z ) sometimes just zeroes. ==unknown8==( V longs ) = V * 4 low longs < VS, translation ? some numbers are there more then once, probably when VS < 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 big model first (in format V* {x,y,z:float} ), and after that vertexs for small model (in format VS* {x,y,z:float} ). Small model usually fits into (-1..+1) 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 VS * 12 bytes ( small model ) 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