J'écris une visionneuse BSP pour un projet universitaire. Jusqu'à présent, la géométrie principale est correctement chargée et le PVS fonctionne.
Maintenant j'essaie d'appliquer les lightmaps, mais je n'arrive pas à obtenir les coordonnées de texture pour les lightmaps calculées correctement.
Selon ici: 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.
}
Le premier tableau de flottants est essentiellement deux vecteurs qui représentent comment la texture est orientée et mise à l'échelle lorsqu'elle est rendue sur la géométrie du monde. Les deux vecteurs, s et t, sont le mappage des directions de gauche à droite et de bas en haut dans l'espace de coordonnées des pixels de texture, sur le monde. Chaque vecteur a une composante x, y et z, plus un décalage qui est le "décalage" de la texture dans cette direction par rapport au monde. La longueur des vecteurs représente l'échelle de la texture dans chaque direction.
Les coordonnées 2D (u, v) d'un pixel de texture (ou texel) sont mappées aux coordonnées universelles (x, y, z) d'un point sur une face par:
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. Le produit scalaire des vecteurs avec le sommet plus le décalage dans cette direction. Où tvA, B est textureVecs [A] [B].
De plus, après avoir calculé (u, v), pour les convertir en coordonnées de texture que vous enverriez à votre carte graphique, divisez respectivement u et v par la largeur et la hauteur de la texture.
Je fais donc le calcul comme suit. Prenez le produit scalaire du sommet et du vecteur lightmap (lightmapVecs [0] [0], lightmapVecs 0 , lightmapVecs [0] [2]) ajoutez le décalage (lightmapVecs [0] [3]), soustrayez les minutes et divisez le résultat par la largeur / hauteur.
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);
Cependant, cela finit par ressembler à ceci:
Voici un exemple de calcul pour la coordonnée de texture 't' pour un sommet.
vertex = 352.0, -144.00027, -224.0
lightmap vector = -4, 0, 0
lightmap offset = 0
lightmap mins = 9
lightmap height = 14
Donc, le produit scalaire est -1408
(-1408 + 0 - 9) / 14
t = -101.21
Cela semble loin.