i am trying to read an unknown game file format (ps2 model file). all i know is it's a modified renderware dff file (which has elements of the gta sa dff format). this
particular game uses triangle strips to draw each model. there is duplicate/degenerate vertices present in every model file.
as i understand, the ps2 had serious memory limits. it appears the programmers decided there was significant gains to be had from changing the storage of floating
point data. for example, instead of storing a vertex float in four bytes, they stored it in two bytes. or normal floats in four bytes, they stored it in one byte! my
problem is converting this data to how it is meant to be read. originally i thought there was a fixed scale variable it had to be multiplied by... but now i am just
not sure at all. the total number of vertices for a model file i am looking at currently is 321. coincidently, theres also four different chunks of data that follows
this vertex data i believe is uv, colour vertices and normals. each chunk that follows the vertices chunk is 321 * 4. i believe uv's are stored as two byte floats,
colour vertices are stored as one byte unsigned chars and normals are stored as one byte floats?
eg;
 vertices; 321 * 8 (two byte float * 4) x, y, z, 00  padding?
 uv's; 321 * 4 (two byte float * two?) u, v
 vertex colours; 321 * 4 (one byte unsigned char * four?) r, g, b, a
 normals; 321 * 4 (one byte * four?) x, y, z, 00  padding?
i wrote a small console application to parse the manualy extracted binary data and dump it into floats but get undesirable values...
[source lang="cpp"]int n_vertices;signed short data;float (*normals)[3];float normal_scale = 1 / 126.076126092;fread(&n_vertices, 4, 1, f);normals = new float[n_vertices][3];printf("parsing normals...\n");for (int loop_loop = 0; loop_loop < n_vertices; loop_loop++) { for (int loop_iterator = 0; loop_iterator < 3; loop_iterator++) { fread(&data, 1, 1, f); normal = (float)data * normal_scale; normals[loop_loop][loop_iterator] = normal; } // skip the padding fseek(f, 1, SEEK_CUR);}[/source]
four bytes of binary data i presume is the normals looks like this (in hex);
7F000000
when i parse it and dump the floats in my program, i see;
110.671234 111.678558 111.678558
i was originally dividing my vertex float values by 32768.0f. basically, i just dont know what i am doing. can someone shed light onto how a single or two byte float is
stored, then read correctly? im getting two very different values for one byte floats and two byte floats !
any help at all is appreciated.
thanks for your time.
best regards,
justin
 Home
 » Viewing Profile: Posts: juddo
juddo
Member Since 30 Aug 2010Offline Last Active Dec 05 2012 07:14 AM
Community Stats
 Group Members
 Active Posts 12
 Profile Views 1,543
 Submitted Links 0
 Member Title Member
 Age 32 years old
 Birthday February 25, 1984

Gender
Male

Location
Melbourne, Victoria
Posts I've Made
In Topic: reading a games binary file vertex floating points
21 November 2012  05:42 AM
In Topic: calculating normals for triangle strip model, not terrain
08 November 2012  07:07 PM
thank you Lauris Kaplinski for the great reply!
i did as you mentioned and have a better result, just not the right one. i tried changing odd to even and (k & 1) is the only one that gives near results. i've taken a screenshot to show what i see...
&&
i can see through the mesh which i hope is a result of incorrect normals, or else something in my rendering section is broken!
[source lang="cpp"] float vu[3]; float vv[3]; float cp[3]; float result; for (int k = 0; k < nvertices  2; k++) { vu[0] = vertices[k + 1][0]  vertices[k][0]; vu[1] = vertices[k + 1][1]  vertices[k][1]; vu[2] = vertices[k + 1][2]  vertices[k][2]; vv[0] = vertices[k + 2][0]  vertices[k][0]; vv[1] = vertices[k + 2][1]  vertices[k][1]; vv[2] = vertices[k + 2][2]  vertices[k][2]; cp[0] = (vu[1] * vv[2])  (vu[2] * vv[1]); cp[1] = (vu[2] * vv[0])  (vu[0] * vv[2]); cp[2] = (vu[0] * vv[1])  (vu[1] * vv[0]); result = (float)sqrt((cp[0]*cp[0]) + (cp[1]*cp[1]) + (cp[2]*cp[2])); if (result == 0.0f) result = 1.0f; normals[k][0] = cp[0] / result; normals[k][1] = cp[1] / result; normals[k][2] = cp[2] / result; if (k &amp; 1) { normals[k][0] = normals[k][0]; normals[k][1] = normals[k][1]; normals[k][2] = normals[k][2]; } }[/source]
above i changed the cross product from what i had originally. a few articles i read on calculating normals seem to use the same cross product. i hope its not incorrect. changing it gives me a completely dark shaded model.
*scratches head*
i did as you mentioned and have a better result, just not the right one. i tried changing odd to even and (k & 1) is the only one that gives near results. i've taken a screenshot to show what i see...
&&
i can see through the mesh which i hope is a result of incorrect normals, or else something in my rendering section is broken!
[source lang="cpp"] float vu[3]; float vv[3]; float cp[3]; float result; for (int k = 0; k < nvertices  2; k++) { vu[0] = vertices[k + 1][0]  vertices[k][0]; vu[1] = vertices[k + 1][1]  vertices[k][1]; vu[2] = vertices[k + 1][2]  vertices[k][2]; vv[0] = vertices[k + 2][0]  vertices[k][0]; vv[1] = vertices[k + 2][1]  vertices[k][1]; vv[2] = vertices[k + 2][2]  vertices[k][2]; cp[0] = (vu[1] * vv[2])  (vu[2] * vv[1]); cp[1] = (vu[2] * vv[0])  (vu[0] * vv[2]); cp[2] = (vu[0] * vv[1])  (vu[1] * vv[0]); result = (float)sqrt((cp[0]*cp[0]) + (cp[1]*cp[1]) + (cp[2]*cp[2])); if (result == 0.0f) result = 1.0f; normals[k][0] = cp[0] / result; normals[k][1] = cp[1] / result; normals[k][2] = cp[2] / result; if (k &amp; 1) { normals[k][0] = normals[k][0]; normals[k][1] = normals[k][1]; normals[k][2] = normals[k][2]; } }[/source]
above i changed the cross product from what i had originally. a few articles i read on calculating normals seem to use the same cross product. i hope its not incorrect. changing it gives me a completely dark shaded model.
*scratches head*
In Topic: calculating normals for triangle strip model, not terrain
08 November 2012  06:18 AM
thank you both for the replys. i think i know what i need to do, just not sure what order i need to read my vu and vv variables when alternating?
so to clarify for myself... for the first alternating read, what vertices do i want vu and vv to be? vu is 23? vv is 20? what about the second alternating read? vu is ?? and vv is ?? does the cross product also change on each alternating read? or just the vertices i read into vu and vv? i thought i had this in concrete, but the more sample code on calculating normals i find, the more confused i become. every source code calculating normals i find reads the vertices in a different order... i've now changed my vu vv and cross product dozens of times...!
correct me if i am wrong, going by the diagram the first read is vertex 1, 2 then 3. and the second read is 3, 4 then 2? cw then alternate ccw?
[source lang="cpp"]if (flip > 0) { flip = 0; vu[0] = vertices[1][x]  vertices[2][x]; vu[1] = vertices[1][y]  vertices[2][y]; vu[2] = vertices[1][z]  vertices[2][z]; vv[0] = vertices[1][x]  vertices[0][x]; vv[1] = vertices[1][y]  vertices[0][y]; vv[2] = vertices[1][z]  vertices[0][z];}else { flip = 1; vu[0] = vertices[?][x]  vertices[?][x]; vu[1] = vertices[?][y]  vertices[?][y]; vu[2] = vertices[?][z]  vertices[?][z]; vv[0] = vertices[?][x]  vertices[?][x]; vv[1] = vertices[?][y]  vertices[?][y]; vv[2] = vertices[?][z]  vertices[?][z];}[/source]
so to clarify for myself... for the first alternating read, what vertices do i want vu and vv to be? vu is 23? vv is 20? what about the second alternating read? vu is ?? and vv is ?? does the cross product also change on each alternating read? or just the vertices i read into vu and vv? i thought i had this in concrete, but the more sample code on calculating normals i find, the more confused i become. every source code calculating normals i find reads the vertices in a different order... i've now changed my vu vv and cross product dozens of times...!
correct me if i am wrong, going by the diagram the first read is vertex 1, 2 then 3. and the second read is 3, 4 then 2? cw then alternate ccw?
[source lang="cpp"]if (flip > 0) { flip = 0; vu[0] = vertices[1][x]  vertices[2][x]; vu[1] = vertices[1][y]  vertices[2][y]; vu[2] = vertices[1][z]  vertices[2][z]; vv[0] = vertices[1][x]  vertices[0][x]; vv[1] = vertices[1][y]  vertices[0][y]; vv[2] = vertices[1][z]  vertices[0][z];}else { flip = 1; vu[0] = vertices[?][x]  vertices[?][x]; vu[1] = vertices[?][y]  vertices[?][y]; vu[2] = vertices[?][z]  vertices[?][z]; vv[0] = vertices[?][x]  vertices[?][x]; vv[1] = vertices[?][y]  vertices[?][y]; vv[2] = vertices[?][z]  vertices[?][z];}[/source]
In Topic: reading a games binary file vertex floating points
01 November 2012  04:19 AM
thanks for that fantastic reply hodgman. i really couldnt ask for more help!
[source lang="plain"]With your code, you're only reading a single byte into byte0/byte1, but they're uninitialized, so their upper 3 bytes contain random values  you should initialize those ints to 0 before using fread.[/source]
as soon as i read this, the penny dropped. yesterday i spent almost all day on this and recalled getting completely random results every time i ran the program with a particular line of code i was using.
i went back to how i was trying to convert the integers and set byte0 and byte1 to 0 and wouldnt you know it! it worked!
thank you so much for all the help.
best regards,
justin
[source lang="plain"]With your code, you're only reading a single byte into byte0/byte1, but they're uninitialized, so their upper 3 bytes contain random values  you should initialize those ints to 0 before using fread.[/source]
as soon as i read this, the penny dropped. yesterday i spent almost all day on this and recalled getting completely random results every time i ran the program with a particular line of code i was using.
i went back to how i was trying to convert the integers and set byte0 and byte1 to 0 and wouldnt you know it! it worked!
thank you so much for all the help.
best regards,
justin
In Topic: reading a games binary file vertex floating points
31 October 2012  07:50 PM
i hope this answers your question.
documentation on this file type says "models have vertexes in two byte signed integer format. to convert to float you convert the integer into a float, but you need to divide it by the radix point (some multiple of two  forgot which?)"
in my hex editor, i found the starting point of the vertex data which i have pasted below.
x, y, z, w (always 0?)
A9F3 1101 0EFD 0000
thanks for your time.
documentation on this file type says "models have vertexes in two byte signed integer format. to convert to float you convert the integer into a float, but you need to divide it by the radix point (some multiple of two  forgot which?)"
in my hex editor, i found the starting point of the vertex data which i have pasted below.
x, y, z, w (always 0?)
A9F3 1101 0EFD 0000
thanks for your time.