Estou escrevendo um visualizador de BSP para um projeto universitário. Até agora eu tenho a geometria principal carregada corretamente e o PVS funcionando.
Agora, estou tentando aplicar os mapas de luz, mas não consigo obter as coordenadas de textura dos mapas de luz calculadas corretamente.
De acordo com aqui: 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.
}
A primeira matriz de flutuadores é basicamente dois vetores que representam como a textura é orientada e dimensionada quando renderizada na geometria do mundo. Os dois vetores, s e t, são o mapeamento das direções da esquerda para a direita e de baixo para cima no espaço de coordenadas do pixel de textura para o mundo. Cada vetor possui um componente x, ye z, além de um deslocamento que é a "mudança" da textura nessa direção em relação ao mundo. O comprimento dos vetores representa a escala da textura em cada direção.
As coordenadas 2D (u, v) de um pixel de textura (ou texel) são mapeadas para as coordenadas do mundo (x, y, z) de um ponto em uma face por:
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. O produto escalar dos vetores com o vértice mais o deslocamento nessa direção. Onde tvA, B é textureVecs [A] [B].
Além disso, após calcular (u, v), para convertê-las em coordenadas de textura que você enviaria para sua placa gráfica, divida u e v pela largura e altura da textura, respectivamente.
Então, eu estou fazendo o cálculo da seguinte maneira. Pegue o produto escalar do vértice e o vetor lightmap (lightmapVecs [0] [0], lightmapVecs 0 , lightmapVecs [0] [2]) adicione o deslocamento (lightmapVecs [0] [3]), subtraia os minutos e divida o resultado pela largura / altura.
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);
No entanto, acaba assim:
Aqui está um cálculo de amostra para a textura coord 't' para um vértice.
vertex = 352.0, -144.00027, -224.0
lightmap vector = -4, 0, 0
lightmap offset = 0
lightmap mins = 9
lightmap height = 14
Portanto, o produto escalar é -1408
(-1408 + 0 - 9) / 14
t = -101.21
Isso parece muito distante.
fonte
Respostas:
Acabei descobrindo que estava lendo os dados de maneira errada. Todo o código acima está correto.
fonte
Você deve normalizar os vetores antes de calcular o produto escalar.
fonte