Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

132 Neutral

About juddo

  • Rank
  1. 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
  2. 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;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*
  3. 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 2-3? vv is 2-0? 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]
  4. hello all, i am reading vertex data from a game file that stores a character model in triangle strips (ps2 game, hence why triangle strips are used). i did concider converting the triangle strips into vertex indexing to help ease the pain of calculating my normals at runtime, but still would like some help calculating normals for triangle strips. i recently read on here that triangle strips flip cw/ccw culling every triangle if backface culling is on. below is my code for calculating normals at the moment; [source lang="cpp"] float vu[3]; float vv[3]; float cp[3]; float result; for (int k = 0; k < nvertices; 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 + 1][0] - vertices[k + 2][0]; vv[1] = vertices[k + 1][1] - vertices[k + 2][1]; vv[2] = vertices[k + 1][2] - vertices[k + 2][2]; cp[0] = (vu[2] * vv[1]) - (vu[1] * vv[2]); cp[1] = (vu[0] * vv[2]) - (vu[2] * vv[0]); cp[2] = (vu[1] * vv[0]) - (vu[0] * vv[1]); 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; } [/source] when i run my program with the above code, i see the following; && you can see on this side shot that i can see through the model (less than desireable.) at the moment i am iterating through every vertex, do i need an offset in my loop to calculate the next triangle or next vertex? it looks like the normals are facing away from each other... and this is the drawing code... [source lang="cpp"] glPushMatrix(); glTranslatef(posx_, posy_, posz_); glRotatef(90.0f, 0, 0, 1); glRotatef(turnrate_, 1, 0, 0); glBegin(GL_TRIANGLE_STRIP); for (int i = 0; i < model_.nvertices; i++) { glNormal3f(model_.normals[0], model_.normals[1], model_.normals[2]); glVertex3f(model_.vertices[0], model_.vertices[1], model_.vertices[2]); } glEnd(); glPopMatrix(); [/source] thanks for your time, best regards, justin
  5. 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
  6. 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.
  7. thanks for the reply ultramailman. i am only trying to read the binary data, not store it. i am trying to port a game reading original game content (ps2 game files.) i was reading the two bytes seperately because i believe they need to be the other way around for pc. a script i have that converts the data into a 3ds file, looks like this; [source lang="plain"] <loop one - read the data (x,y,z,w)> Get type1 Short 0 ; Get type2 Short 0 ; Get type3 Short 0 ; Get type4 Short 0 ; Put type1 Short MEMORY_FILE1 ; Put type2 Short MEMORY_FILE1 ; Put type3 Short MEMORY_FILE1 ; <loop two - convert data to floats> Get first Byte MEMORY_FILE1 ; Get second Byte MEMORY_FILE1 ; If second > 127 ; Math second -= 256 ; Endif ; Math nb = second ; Math nb *= 256 ; Math nb += first ; Put nb float MEMORY_FILE2 ; [/source]
  8. hodgman, the data is stored as two byte signed integers. thanks for the clarification. i have included some code i've been toying with all day. it's giving me normal looking floats, but im almost certain it's not correct (very similar numbers.) [source lang="cpp"] signed int byte0; signed int byte1; float temp; fread(&byte0, 1, 1, f); fread(&byte1, 1, 1, f); temp = ((byte0 & 0xFF) / 256.f) + byte1; [/source] i've got a script (quickbms script, but i want to do this in c++) that deals with this issue (converting two byte signed int to float) and by looking at it, suggests i am doing this wrong. this is the scripts pseudo code. [source lang="plain"] byte0 byte1 float temp if byte1 > 127 byte1 -= 256 temp = byte1 temp *= 256 temp += byte0 [/source] i tried the above in a small console program i wrote just for this and get weird results.
  9. hello, i have spent an hour or so googleing how to do the following but didnt find anything that covered this specifically. (may have been how i phrased my words, not sure?) i want to read (c++ - fread()) a binary file from a game that contains floating point vertex data stored in two byte signed integer format (x,y,z,w - w is always 0). then i want to convert that into floats that i can use with opengl to draw the vertex data. apparently i also need to divide this by the radix point (which is some multiple of two?)? i would appreciate any help as i've hit a wall here... thanks for your time, best regards, justin
  10. hey there... just following up on this; i did as you said karwosts and grabbed a mesh with a texture and kept at it. im glad to say i finally got it to work :) just to clarify, milkshape does appear to store unique uv data... as i had suspected? thankyou 0xffffffff and karwosts for all your help! what a great community ;) regards, justin
  11. hello again, thanks for your excellent replys 0xffffffff and karwosts! you both helped me simplify things alot (i appear to have overly complicated things on this one?). i've spent the last day thinking about this and still have a few questions. i want to run my new understandings past you if thats ok? i dont quite understand where this uv coord you check against exists? because milkshape stores each uv coord with each vertex? please correct me on my new understandings if i am wrong; if a shared vertice appears anywhere in the triangle index list more than once, i need to duplicate that vertice? each entry in a vertex array made up of (verx, very, verz, norx, nory, norz, u, v) is one vertex? if a shared vertice gets duplicated, the triangle index that was pointing to that vertice gets updated to the location of that newly duplicated vertice? ... the milkshape ascii format stores a u/v coord with each vertex. this confuses me. when i duplicate a vertex, what uv coords am i checking against? i've seen a few examples of vertice duplication and cant work out where this uv coord you check against is coming from? when i read a milkshape ascii model i would store data somethingl like this; vertex[numvertices][3] normal[numnormals][3] < less than numvertices uv[numvertices][2] < same as numvertices vertextriangle[numtriangles][3] < this points to the vertex[] array normaltriangle[numtriangles][3] < this points to the normal[] array ... i assume i fill the vertex array like this; for (verx = 0; verx < nvertices; verx++) { nt = 0; for (trix = 0; trix < ntriangles; trix++) { for (indx = 0; indx < 3; indx++) { if (triangles[trix][indx] == verx) { // this triangle index is pointing to our vertex in question! nt++; if (nt == 1) { // this is the first time we find this vertex in any triangle indexes... // add this vertex to the new vertex array? } else { // this vertex is being used again... // do i just duplicate this vertex, add it to the new vertex array and update the triangle list to point to this duplicated vertex? // i dont need to check for uv coords because milkshape stores each uv with each vertex, therefore it is already a unique coord? } } } } } ... i feel silly for not understanding this. i have hand drawn pictures and everything! just a few unsure details left... thanks for your effort, time and your patience! :) best regards, justin
  12. hello! i've stopped myself several times from posting a thread here regarding my unclear and miss understanding of model vertex sharing, hoping i'd find the answer i was after sooner or later... but i simply can't find a clear answer for what im having trouble understanding anywhere. the thick of it is; i'm trying to draw my model (exported from milkshape - that has many shared vertices) with the gldrawelements function. i understand milkshape is short changing me on vertex, normal and uv data (because of shared vertices). i also understand i need to make an array for gldrawelements made up of; verx very verz norx nory norz (this vertex normal) u v (this vertex uv) this is where i get a little frazzled. i know gldrawelements uses _one_ index (the triangles list) to draw the three vertex, normal and uv data arrays. what i cant wrap my head around is, when i unshare a vertex, where does this new vertex go in the new vertex array? after the vertex in question? at the end? what im super unclear on is what happens with the ordering of the triangles? do i make a new triangle? or do i just update the triangle? does the number of triangles stay the same? im so confused! :( i wrote a few test programs to duplicate data on what i though was the right way and ended up with some silly high numbers of vertices? i've even tried writing a plugin with the milkshape sdk. the entire program seems to run on this shared vertices idea. i cant find a way to get the real vertex count (always the shared vertex count). anyway, i figure the following with the exported ascii format; if the vertex exists > check for same uv coords if same uv coords > disregard? if not the same uv coords > add vertex, normal, uv and bone data to the end of their new arrays now what would i do? i surely need todo something with the triangle data? i'd have all these extra vertices and the triangle list wouldnt point to any of them? the maximum number of vertices would be (number of vertices * 3) right? what about the triangles? does the number of triangles ever increase? so unsure... thanks alot for your time! regards, justin
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!