Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

According to here: http://developer.valvesoftware.com/wiki/The_Source_Engine_BSP_File_Format

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: lightmaps

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.

share|improve this question
    
If you can post a picture link in the comments, someone can edit it in for you. –  The Communist Duck Mar 31 '11 at 15:36
    
Thanks. I got a few vote ups so i can post pictures now. :) –  terryhau Mar 31 '11 at 18:00
    
Why are you dividing by 14? Is your lightmap's size really "14"? Most lightmaps are powers of 2... –  PatrickB Apr 1 '11 at 1:38
add comment

2 Answers

up vote 0 down vote accepted

I eventually figured out, I was reading the data in wrong. All the code above is correct.

share|improve this answer
add comment

You should normalize the vectors before calculating the dot product.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.