octoawesome icon indicating copy to clipboard operation
octoawesome copied to clipboard

Inkonsistente Block Koordinaten

Open runner78 opened this issue 8 years ago • 19 comments

Ich versuche mich gerade an einer alternativen Chunk Implementation, die die Daten anders abspeichert und theoretisch sehr viel RAM sparen sollte. Allerdings stoße ich auf das Problem, dass beim setzen und abrufen der Blocks ständig andere Koordinatensysteme benutz werden. Mal Global, mal Lokal.

Ich wäre dafür, das zu vereinheitlichen, entweder Global oder Lokal, aber nicht gemischt.

runner78 avatar Sep 30 '16 20:09 runner78

Das hat sehr gute Gründe, dass es Lokal und Global gibt. die Lokalen braucht man um Blöcke für Chunks abzurufen, die Globalen braucht man für alles Spieler und Generatorbezogenes. Und ich glaube die einzigsten Arten zur Komprimierung wären denke ich über etwas mit OctTrees oder sonstigen Komprimierungsalgorithmen. Ansonsten erklär doch vlt. einfach mal was du vorgehabt hättest.

jvbsl avatar Oct 01 '16 12:10 jvbsl

Dass es Globale und Lokale Koordinaten gibt ist ja normal, wenn die aber dann wild durcheinander gewürfelt werden wird es unübersichtlich und ist eine potenzielle Fehlerquelle.

Zum einen mag man argumentieren, dass es ja praktisch ist, wenn man bei Chunk.GetBlock() und Chunk.SetBlock() beide Arten von Koordinaten benutzen kann, motiviert aber dazu, unsauberen Code zu schreiben.

Nach meiner Meinung sollte ein Chunk immer nur mit lokalen Koordinaten arbeiten, ({0,0,0} - {31,31,31})

Ich arbeite derzeit mit Octrees. Bin gerade dabei den von einem meiner experimentalen Unity Projekte zu portieren.

Dort hatte ich Eine statische World, den Chunk und den ChunkNode, (Entspricht bei OctoAwesome in etwa Planet, ChunkColumn, Chunk) und habe überall mit Globalen Koordinaten gearbeitet.

Mein Konzept des Chunks war aber ganz anders, hier ist ein Chunk nur ein Datenspeicher. Bei meinem Konzept hatten sich die Chunks (ChunkColumn) teils selbst "Verwaltet". Das war aber auch alles auf Unity zugeschnitten.

runner78 avatar Oct 01 '16 12:10 runner78

Chunk.SetBlock/GetBlock nehmen doch nur zum Chunk-Relative Koordinaten an?

jvbsl avatar Oct 01 '16 13:10 jvbsl

Nein eben nicht, da kommen auch Globale Koordinaten an. Zumindest bei mir.

z.B in SceneControl Zeile 204 beim selektieren eines Blocks vom Spieler wird dem LocalChunkCache die Globale Koordinate übergeben und dort 1:1 dem Chunk übergeben.

runner78 avatar Oct 01 '16 13:10 runner78

Tatsache, aber dann guck dir doch mal an, was damit passiert, es ist einfach irrelevant, die Globale Position wird einfach abgeschnitten, schließlich haben wir ja Chunkgrößen von 2^N. Für die Positionierung interessieren uns nur die letzten 5 bits, warum dann nicht auf unterster Ebene abschneiden, ist sowieso schlauer als dann ne Exception zu schmeißen. Wir wollen schließlich Geschwindigkeit haben ;)

jvbsl avatar Oct 01 '16 13:10 jvbsl

Bekomme ich da dann die lokale Koordinate raus? Mit dem Octree bin ich auf gleichbleibende Koordinaten angewiesen.

runner78 avatar Oct 01 '16 13:10 runner78

Wir haben folgendes Koordinaten-Konzept: Chunks müssen als Kantenlänge immer eine Zweierpotenz haben - in unserem Falle 32. Dadurch erlangt man die lokale Koordinate eines Blocks, indem man nur die letzten 5 Bit maskiert. Die nächstgrößere Einheit um eine Entität ist der LocalChunkCache. Der soll Chunks in unmittelbarer Nähe der Entität halten. Auch dessen Kantenlänge darf nur eine Zweierpotenz sein. Dieser hält für den schnellen Zugriff alle Chunks in einem 2d-Array - der entsprechende Index im Array ergibt sich aus der Maskierung der kommenden Bits der Koordinate. Nehmen wir auch hier eine Sichtweite von 32 an, dann sind das Bit 6 bis 10.

tomwendel avatar Oct 01 '16 14:10 tomwendel

Octrees arbeiten ja naturgemäß mit Zweierpotenzen. Mir gefällt nur nicht, dass man nicht darauf vertrauen kann, ob man nun mit lokalen oder globalen Koordinaten gefüttert wird und selbst das Umrechnen erledigen muss. Am Ende hat man 20 Stellen pro Block, wo die Koordinaten maskiert werden.

runner78 avatar Oct 02 '16 10:10 runner78

warum sollte man sich darauf verlassen können, wenn es unnötig ist? Was hast du für einen Vorteil, wenn du es an 100 stellen außerhalb machen musst, anstelle von einer innerhalb? Und machen musst du es aufjedenfall. 1D Array ist auch sinnvoll für die Geschwindigkeit und auch einfachere Datenhaltung. Also eigt. ist es so wie es jetzt ist eine zentrale Stelle wo das gemacht wird und eben nicht 20 stellen :D

jvbsl avatar Oct 02 '16 11:10 jvbsl

Man sollte sich darauf verlassen können was in der Dokumentation steht. Und für jemanden, der sich wie ich neu in den Code einarbeitet, bedeutet das durchaus Stunden an Frust, wenn das Teil nicht das macht was man erwartet ;)

Eigentlich braucht man das nicht extern an 200 Stellen machen, bei einer guten Architektur sollte eine globale Stelle reichen.

Die 1D Arrays sind zwar schnell , aber trotzdem Speicherfressend. Bei der aktuellen Standardeinstellungen werden 1800 Chunks im Speicher gehalten, das sieht dann in etwa so aus: Chunks.Blocks = 112,5 MB Chunks.MetaData = 225 MB Chunks.Resources = 450 MB

Mit allem drum und dran kommt man dann ca. auf 0,9-1,1 GB RAM Mit meinem Octree habe ich derzeit eine gesammt RAM verbrauch von 400 - 500MB

Das ist aber ein Anderes Thema.

runner78 avatar Oct 02 '16 13:10 runner78

Wie sieht es hiermit aus, ist das noch relevant?

Gallimathias avatar Dec 29 '17 13:12 Gallimathias

Ich glaube für uns selbst war das nie relevant, das war eine Idee von runner78, um seine Octrees besser / überhaupt erst implementieren zu können. Das ist nie über einen WIP Pull Request herausgekommen, vgl. #172. Ich weiß nicht, ob @runner78 das hier überhaupt nocht braucht für seine neue Implementierung.

ManuelHu avatar Dec 29 '17 14:12 ManuelHu

Ok #172 ist ja closed. Dann würde ich @runner78 bitten sich zu äußern ob er noch an diesem Issue weiter macht.

Gallimathias avatar Dec 29 '17 16:12 Gallimathias

Ich bin immer noch der Meinung, dass es sich hier um einen schlechten Programmierstil handelt, auch weil das Verhalten schlecht dokumentiert ist. Ob das hier noch aktiv bleibt hängt davon ab, ob die derzeit aktiven Entwickler Interesse haben, was zu ändern.

runner78 avatar Dec 29 '17 21:12 runner78

Super! Wird Zeit, dass der Octtree endlich kommt!

tomwendel avatar Dec 29 '17 22:12 tomwendel

OctoAwesome lebt von der Community wenn du was cooles hast dann immer gerne her damit @runner78

Gallimathias avatar Dec 29 '17 23:12 Gallimathias

Ich arbeite derzeit an einem Octree basierten Blockterrain für ein eigenes Project in Unity, den ich danach für OctoAwesome portieren möchte.

runner78 avatar Dec 30 '17 10:12 runner78

Aber wie bereits an anderer Stelle mehrmals angebracht. OctTree schön und gut für Kollision/Speicher sparen etc. aber nichts fürs Rendering...

jvbsl avatar Jan 01 '18 21:01 jvbsl

Wenn man nicht Block für Block sondern Node für Node rendert, dann spart man sich eine Menge Polygone. Und auch das iterieren geht schneller, da man leere Nodes direkt überspringen kann. Bei einem Blockarray musst du immer durch alle Blöcke durch. Es dürfte allerdings etwas komplizierter werden so einen Renderer zu programmieren.

runner78 avatar Jan 02 '18 11:01 runner78