Skip to main content
GameDev.net gamedev.net
🔒 Locked

Quake BSP Loader [SOLVED]

Started by bori Jan 24, 2008 at 11:46 AM 8 replies 1.8k views
Original Post
bori
bori
Hi all. I just debugged my engine (rendering was really weird) and found out interesting thing. I am trying to load Quake 3 map (official one) and if I print the position of vertices, sometimes it shows insane values:

Vertex  0 | X:          2552.000000 Y:            24.000000 Z:         -2436.000000
Vertex  1 | X:             2.937500 Y:             0.480469 Z:             0.937500
Vertex  2 | X:             0.003906 Y:            -1.000000 Z:            -0.000000
Vertex  3 | X:             0.000000 Y:          2552.000000 Z: 208876590168752002862353036063671320576.000000
Vertex  4 | X:          2436.000000 Y:             2.937500 Z:           -88.000000
Vertex  5 | X:            -0.937500 Y:             0.066406 Z:            -0.449219
Vertex  6 | X:             0.000000 Y:             0.000000 Z:             1.000000
Vertex  7 | X: -208876590168752002862353036063671320576.000000 Y:          2496.000000 Z:         -2496.000000
Vertex  8 | X:            88.000000 Y:            -0.937500 Z:            -2.937500
Vertex  9 | X:             0.441406 Y:             0.000000 Z:            -0.003906
Vertex 10 | X:             1.000000 Y: -217045371201441920428938639413616836608.000000 Z:            -0.000000
Position like about 2^38 is really insane. i absolutely don't understand it. Here is relevant part of loading code:

numVerts = gLump[LUMPS_VERTICES].length / sizeof(sVertex);
newentity->Geometry->Vertices = new sVertex[numVerts];
newentity->Geometry->numVertices = numVerts;

fseek(f, gLump[LUMPS_VERTICES].offset, SEEK_SET);

for(i = 0; i < numVerts; i++) {

   fread(&newentity->Geometry->Vertices, 1, sizeof(sVertex), f);

   float temp = newentity->Geometry->Vertices.position[1];
   newentity->Geometry->Vertices.position[1] = newentity->Geometry->Vertices.position[2];
   newentity->Geometry->Vertices.position[2] = -temp;

   newentity->Geometry->Vertices.texCoord[1] *= -1;

}
Does anyone know the reason of these values? I would really appreciate your help. Thanks in advance. bori [Edited by - bori on January 25, 2008 8:23:37 AM]
cobru
cobru
i don't see anything wrong with the code you posted... (but maybe i'm just tired)...

try to see if #pragma pack(1) helps.
Q: How many programmers does it take to write a nice piece of software?A: MORE.
bori
bori
Quote:
Original post by cobru
i don't see anything wrong with the code you posted... (but maybe i'm just tired)...

try to see if #pragma pack(1) helps.


I also cannot see anything wrong.

#pragma pack(1) however didn't help. But thanks for reply.
Evil Steve
Evil Steve
Is there any padding in the file? As it is, your code requires that all the vertices be adjacent in the file with no padding. Are the values correct if you look at them in the debugger right after the fread() call? What is the hex value of the invalid floats? (They might look like something sensible as a unsigned int or something).
bori
bori
Quote:
Original post by Evil Steve
Is there any padding in the file? As it is, your code requires that all the vertices be adjacent in the file with no padding. Are the values correct if you look at them in the debugger right after the fread() call? What is the hex value of the invalid floats? (They might look like something sensible as a unsigned int or something).


Well, it is original Quake III map. It works in Quake, so I presume it is correct... I looked at it right after the fread() and it was exactly the same (and wrong). How do I get hex values of the variables? My debugger doesn't offer anything like that.
cobru
cobru
from what I remember (I took a peek at my 6 year old quake2 engine written in delphi) quake3 vertices aren't padded, you can actually load all them with one call to fread so I don't think that's it.

could you post the declaration of sVertex type? that's the only thing that might be wrong...
Q: How many programmers does it take to write a nice piece of software?A: MORE.
bori
bori
Quote:
Original post by cobru
from what I remember (I took a peek at my 6 year old quake2 engine written in delphi) quake3 vertices aren't padded, you can actually load all them with one call to fread so I don't think that's it.

could you post the declaration of sVertex type? that's the only thing that might be wrong...


Yes, it can be done by one call of fread(), however I do it per-one, cause of swapping Y and Z and negating Y.

Here is sVertex struct:

struct sVertex {  	float position[3];  	float texCoord[2];  	float lightmapCoord[2];  	float normal[3];  	unsigned int color[4];};
ReaperSMS
ReaperSMS
Change color from unsigned int[4] to unsigned char[4]. Your vertex structure is too large by 12 bytes. The data in the file:

X, Y, Z, T0, T1, L0, L1, NX, NY, NZ, C, repeat

What you're reading:

X, Y, Z, T0, T1, L0, L1, NX, NY, NZ, C0, C1, C2, C3, repeat

What you're reading for XYZ for the first 4 verts:

Vert 0: v0 X, Y, Z
Vert 1: v1 T0, T1, L0
Vert 2: v2 L1, NX, NY
Vert 3: v3 NZ, Color, v4 X

Give or take.
bori
bori
Quote:
Original post by ReaperSMS
Change color from unsigned int[4] to unsigned char[4]. Your vertex structure is too large by 12 bytes. The data in the file:

X, Y, Z, T0, T1, L0, L1, NX, NY, NZ, C, repeat

What you're reading:

X, Y, Z, T0, T1, L0, L1, NX, NY, NZ, C0, C1, C2, C3, repeat

What you're reading for XYZ for the first 4 verts:

Vert 0: v0 X, Y, Z
Vert 1: v1 T0, T1, L0
Vert 2: v2 L1, NX, NY
Vert 3: v3 NZ, Color, v4 X

Give or take.


Well, I cannot access my project till Sunday evening, but I find it very possible, so I think problem is solved.

Thank you all!
bori
Evil Steve
Evil Steve
Quote:
Original post by bori
Quote:
Original post by Evil Steve
Is there any padding in the file? As it is, your code requires that all the vertices be adjacent in the file with no padding. Are the values correct if you look at them in the debugger right after the fread() call? What is the hex value of the invalid floats? (They might look like something sensible as a unsigned int or something).


Well, it is original Quake III map. It works in Quake, so I presume it is correct... I looked at it right after the fread() and it was exactly the same (and wrong). How do I get hex values of the variables? My debugger doesn't offer anything like that.
Assuming you have the variable in the debug watch window, and assuming some version of Visual Studio, you'd do:
*(unsigned int*)&varname
Where "varname" is the name of the float variable. Then right click in the debug watch window and select "View as Hexadecimal"

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.