Half-Life 2 BSP Lightmaps

I'm writing a BSP viewer for a university project. So far I have the main geometry loaded properly, and the PVS working.

Now I'm trying to apply the lightmaps, but I can't seem to get the texture coordinates for the lightmaps calculated properly.

struct texinfo_t
{
float textureVecs[2][4];  // [s/t][xyz offset]
float lightmapVecs[2][4]; // [s/t][xyz offset] - length is in units of texels/area
int flags;                // miptex flags overrides
int texdata;               // Pointer to texture name, size, etc.
}


The first array of floats is in essence two vectors that represent how the texture is orientated and scaled when rendered on the world geometry. The two vectors, s and t, are the mapping of the left-to-right and down-to-up directions in the texture pixel coordinate space, onto the world. Each vector has an x, y, and z component, plus an offset which is the "shift" of the texture in that direction relative to the world. The length of the vectors represent the scaling of the texture in each direction.

The 2D coordinates (u, v) of a texture pixel (or texel) are mapped to the world coordinates (x, y, z) of a point on a face by:

u = tv0,0 * x + tv0,1 * y + tv0,2 * z + tv0,3

v = tv1,0 * x + tv1,1 * y + tv1,2 * z + tv1,3

(ie. The dot product of the vectors with the vertex plus the offset in that direction. Where tvA,B is textureVecs[A][B].

Furthermore, after calculating (u, v), to convert them to texture coordinates which you would send to your graphics card, divide u and v by the width and height of the texture respectively.

So I am doing the calculation as follows. Take the dot product of the vertex and the lightmap vector(lightmapVecs[0][0], lightmapVecs0, lightmapVecs[0][2]) add the offset (lightmapVecs[0][3]), subtract the mins, and divide the result by the width/height.

float s = Vector3f.dot(v, new Vector3f(lightmapVecs[0][0], lightmapVecs[0][1], lightmapVecs[0][2])) + lightmapVecs[0][3] - f.LightmapTextureMinsInLuxels[0];
float t = Vector3f.dot(v, new Vector3f(lightmapVecs[1][0], lightmapVecs[1][1], lightmapVecs[1][2])) + lightmapVecs[1][3] - f.LightmapTextureMinsInLuxels[1];
s /= (f.LightmapTextureSizeInLuxels[0] + 1);
t /= (f.LightmapTextureSizeInLuxels[1] + 1);


However it ends up looking like this:

Here's a sample calculation for the texture coord 't' for one vertex.

vertex = 352.0, -144.00027, -224.0
lightmap vector = -4, 0, 0
lightmap offset = 0
lightmap mins = 9
lightmap height = 14


So the dot product is -1408

(-1408 + 0 - 9) / 14

t = -101.21


This seems way off.

• If you can post a picture link in the comments, someone can edit it in for you. Mar 31, 2011 at 15:36
• Thanks. I got a few vote ups so i can post pictures now. :) Mar 31, 2011 at 18:00
• Why are you dividing by 14? Is your lightmap's size really "14"? Most lightmaps are powers of 2... Apr 1, 2011 at 1:38