Ich schreibe einen BSP-Viewer für ein Universitätsprojekt. Bisher habe ich die Hauptgeometrie richtig geladen und das PVS funktioniert.
Jetzt versuche ich, die Lightmaps anzuwenden, aber ich kann die Texturkoordinaten für die Lightmaps scheinbar nicht richtig berechnen.
Laut hier: 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.
}
Das erste Array von Floats besteht im Wesentlichen aus zwei Vektoren, die darstellen, wie die Textur beim Rendern auf der Weltgeometrie ausgerichtet und skaliert wird. Die beiden Vektoren s und t sind die Abbildung der Richtungen von links nach rechts und von unten nach oben im Koordinatenraum der Texturpixel auf die Welt. Jeder Vektor hat eine x-, y- und z-Komponente sowie einen Versatz, der die "Verschiebung" der Textur in diese Richtung relativ zur Welt darstellt. Die Länge der Vektoren repräsentiert die Skalierung der Textur in jeder Richtung.
Die 2D-Koordinaten (u, v) eines Texturpixels (oder Texels) werden auf die Weltkoordinaten (x, y, z) eines Punktes auf einer Fläche abgebildet, indem:
u = tv0,0 * x + tv0,1 * y + tv0,2 * z + tv0,3
v = tv1,0 * x + tv1,1 * y + tv1,2 * z + tv1,3
(dh das Punktprodukt der Vektoren mit dem Scheitelpunkt plus dem Versatz in dieser Richtung. Wobei tvA, B texturVecs [A] [B] ist.
Teilen Sie nach der Berechnung von (u, v) u und v durch die Breite bzw. Höhe der Textur, um sie in Texturkoordinaten umzuwandeln, die Sie an Ihre Grafikkarte senden würden.
Also mache ich die Berechnung wie folgt. Nehmen Sie das Punktprodukt des Scheitelpunkts und des Lightmap-Vektors (lightmapVecs [0] [0], lightmapVecs 0 , lightmapVecs [0] [2]), addieren Sie den Offset (lightmapVecs [0] [3]), subtrahieren Sie die Minuten und dividieren Sie das Ergebnis durch die Breite / Höhe.
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);
Am Ende sieht es jedoch so aus:
Hier ist eine Beispielberechnung für die Texturkoordinate 't' für einen Scheitelpunkt.
vertex = 352.0, -144.00027, -224.0
lightmap vector = -4, 0, 0
lightmap offset = 0
lightmap mins = 9
lightmap height = 14
Das Punktprodukt ist also -1408
(-1408 + 0 - 9) / 14
t = -101.21
Das scheint weit weg zu sein.