PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Quake BSP (Visibility)


liquid
2003-08-19, 23:59:12
Hi Leute,

ich bin momentan dabei zahlreiche Loader für verschiedene Levelformate zu schreiben (ja, auch wenns schon Loader gibt, mir liegt der Lerneffekt am Herzen) und habe im Bereich der Quake-Engine eigentlich alle Typen von BSP-Formaten abgedeckt.
Sprich können Q1, Q2 und Q3 BSPs vom Programm eingelesen werden und entsprechende Stats über das Levels ausgegeben werden.

Jetzt fehlt eigentlich nur noch das Interpretieren der Daten. Und da hänge ich momentan ein wenig fest. Erstmal ein Link...
Link (http://www.gamers.org/dEngine/quake/spec/quake-spec34/qkspec_4.htm#BL4)

So, die Quake Specs 3.4 lässt sich hier über die Visibility Lists der Quake1 BSPs aus.
Das ist natürlich nur Pseudo-Code, den sie da präsentieren (für lauffähigen Code wäre da noch etwas mehr nötig). Naja, ich hab mir halt das angeguckt was sie dort geschrieben haben, den Code durchgegangen und hab dann eine entsprechende Methode geschrieben.

void CVisiList::isVisible(const leaf& _leaf, bool* _state, ulong numLeaves)
{
long V = _leaf.visList; // get index to visi-bits

if (V < 0)
return; // leaf's index is invalid

for (ulong L = 1; L < numLeaves; ++V)
{
if (visInfo[V] == 0)
{
L += 8 * visInfo[V + 1]; // skip some leaves
++V;
}
else
{
if (visInfo[V] & 0x01) _state[L] = true; ++L; // bit 1
if (visInfo[V] & 0x02) _state[L] = true; ++L; // bit 2
if (visInfo[V] & 0x04) _state[L] = true; ++L; // bit 3
if (visInfo[V] & 0x08) _state[L] = true; ++L; // bit 4
if (visInfo[V] & 0x10) _state[L] = true; ++L; // bit 5
if (visInfo[V] & 0x20) _state[L] = true; ++L; // bit 6
if (visInfo[V] & 0x40) _state[L] = true; ++L; // bit 7
if (visInfo[V] & 0x80) _state[L] = true; ++L; // bit 8
}
}
// end of RLE extraction
}

Wie ihr sehen könnt habe ich den inner-loop ausgerollt. Hielt ich für ganz sinnvoll, da die Anzahl der Durchläufe (8 Stück) ja eigentlich fest steht und der Loop auch recht häufig durchlaufen werden wird (gehört ja zum Hauptculling).

Ich hoffe mal ich habe das Dokument in dieser Hinsicht richtig interpretiert (und es gibt wirklich nur 8 Durchläufe).

Jedenfalls sind mir dann noch ein paar Sachen aufgefallen. In der Originalversion haben wir nach dem inner-loop (for Schleife) keine Inkrementierung von v. Allerdings ist im ersten if-Branch eine Inc von v zu finden. Ist das richtig so (der Coee da muss ja nicht fehlerfrei sein) und wenn ja, kann man das v++ nicht in den Addressoperator reinschreiben (ist ja schließlich kein ++v)?

Dann fiel mir noch auf, dass L am Start 1 ist. Was ist mit der 0 passiert?
Ich meine so wie das ganze jetzt läuft werden numleaves-1 leaves auf ihre Sicherbarkeit getestet. Sollten es nicht alle leaves sein? Also den Counter bei 0 anfangen lassen?

Hmm, Fragen über Fragen. Ich wäre froh wenn mir jemand beistehen würde ;D

cya
liquid

liquid
2003-08-20, 16:02:49
Nach FlipCode arbeitet das Visi-System von Quake2 fast genauso wie das von Q1.

int v = offset;

memset(cluster_visible, 0, num_clusters);

for (int c = 0; c < num_clusters; v++) {

if (pvs_buffer[v] == 0) {
v++;
c += 8 * pvs_buffer[v];
} else {
for (uint8 bit = 1; bit != 0; bit *= 2, c++) {
if (pvs_buffer[v] & bit) {
cluster_visible[c] = 1;
}
}
}

}

Hmm, die fangen dort auch mit Counter=0 an. *sich fragt warum da jeder was anderes schreibt*

cya
liquid