Dann hab ich ein View Frustum (bestehend aus 6 Flaechen), mit dem ich den Baum rekursiv durchlaufe. Alle Octree Nodes, deren Bounding Sphere komplett ausserhalb des Octrees liegen, werden ignoriert. Von allen anderen gehts rekursiv an deren Kinderknoten. Das wird bis zum Level 31 gemacht, dort wird dann der Cube gerendert.
Ok, das ist nicht genau das, auf was ich hinaus wollte bzw. es ist schon zu detailliert.
Wenn Deine Welt aus einem XYZ-Koordinatensystem besteht, deren Achsen jeweils 2^31 Einheiten aufweisen, dann sagt das erstmal nur etwas über den möglichen Adressraum aus. Nicht jedoch darüber, wie viele Objekte darin vorkommen und auch nicht, was eine realistische Problemgröße ist.
Beim Speichern von Blöcken in Deiner Welt fallen mir spontan erstmal 3 Möglichkeiten ein (erstmal ohne jegliche zusätzliche Verwaltungsstruktur):
Sei ohne Beschränkung der Allgemeinheit und vollkommen willkürlich die Spielwelt 1 GByte groß und die Nutzinformation jedes Blocks 4 Byte groß (z.B. für die Farbe)
1. Speicherung der Blöcke als direktes Array:
Dann ergibt sich direkt aus der Position des Blocks im Array die Position des Blocks in der Welt. Der Speicherverbrauch eines Blocks ist dann lediglich 4 Byte, sodass (bei 1GByte) insgesamt 268435456 Blöcke vorhanden sein können. Die Speicherung des vollen 2^(3*31) Adressraum würde 4096 Yottabyte benötigen. Bei 1GByte ist die Kantenlänge auf lediglich 645 Einheiten beschränkt.
- Also viel zu klein.
2. Speicherung der Blöcke als jeweilige XYZ-Koordinate:
Jeder Block benötigt nun 16 Byte (XYZ und die Farbe). Es können bei 1GByte also 67108864 Blöcke gespeichert werden.
- 70M + X Blöcke scheint mir eine realistische Problemgröße.
3. Speicherung der Blöcke als Flächen:
Es werden keine einzelnen Blöcke mehr gespeichert, sondern das Ganze ist als Mesh Manipulation aufgebaut. Schlimmster Fall, wenn jemand ein 3D Schachbrett baut, dann können die Flächen nicht zusammengefasst werden bzw. es müssen mindestens die Koordinaten gespeichert werden bei dem sich die Farben ändern. Dann benötigt ein Block ~2*XYZ und die Farbe macht 28 Byte. 1GByte bietet also Platz für ~38347922 Blöcke.
- Aufwendig und ist evtl. schlechter als Version 2.
Alle drei Varianten sind aber ganz weit weg von 2^(3*31), so das die Größe des Adressraums keinen sonderlich großen Einfluss auf das Laufzeitverhalten der Anwendung hat. Ein Occtree mit einer Tiefe von 31 (!) und Berücksichtigung des Frustum erscheint mir übertrieben, selbst wenn die Spielwelt 1TByte umfassen sollte.
Eine aktuelle Mittelklasse-Grafikkarte hat einen (geschönten) Durchsatz an Dreiecken von ~800MTriangles/s. Bei 12 Dreiecken pro Block und 60 FPS würde das ~1M Blöcke bedeuten (halte ich aber für unrealistisch). Nichtsdestotrotz, bei einer Auflösung von jeweils 2^31 Einheiten sind die weiter entfernten Blöcke viel kleiner als ein Pixel. Ein Blick von einem Ende der Welt zum Anderen ist also ohne zusätzliches LOD eh nicht möglich.
Imho, sollte es reichen einfach alle Blöcke die ungefähr in der Nähe der Kamera liegen an die Grafikkarte zu schicken. Die verwirft schon alles, was sie nicht brauchen kann, dafür ist sie schließlich da.
Das Ganze ist auch nur ein kleine Experiment, um einer Antwort auf die Frage naeher zu kommen, wieviele Cubes man mit Java so rendern kann.
Aktuell schreib ich das Berechnen des Morton Codes und den BTree in C neu - und will dann bisschen mit JNI rumspielen ;-)
Ok, wenn Du dann mit C das Maximum bestimmt hast, kannst Du das Beispiel ja mal hier posten. Ggf. poste ich dann mal zum Vergleich ein Beispiel in Java (wenn ich Zeit hab auch evtl. schon vorher).
Lasst mich diesen Thread auch noch etwas zweckentfremden: Wie schwer ist es, von einem C++ Programm aus ein .jar anzusprechen/einzubinden? (Falls ich mal was größeres basteln will und es nützlich sein sollte für was anderes. Dann will ich nich merken, dass ich alles in C++ umschreiben muss^^)
Aber ich glaube, dass du ansich nicht in so eine Situation kommen dürftest. Lass dich hier nicht irre führen, Java ist nicht massivst langsamer als C, wie es hie rmanchmal den Anschein hat. Es komm auf die Art und Weise an, wie du programmierst. Wenn du clever vorgehst, gibt es kaum einen Unterschied.
Volle Zustimmung. Ich würde sogar behaupten, dasselbe Programm, geschrieben einmal in Java und einmal in C, von einem jeweils durchschnittlich begabten Programmieren und mit demselben Zeitaufwand ist in Java schneller. Erst wenn der C-Programmierer ganz viel Zeit und Können reinlegt, wird er ein etwas schnelleres Programm entwickeln können.
Gruß,
Fancy