3D Modelle komprimieren?
lima-city → Forum → Programmiersprachen → C/C++ und D
bit
byte
code
computer
datei
format
koordinate
modell
platz
polygon
programm
punkt
rechenzeit
sagen
sparen
spart
speichern
technik
zahl
ziffer
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Dir hat man irgendein Scheiß gesagt: Binär ist nur eine Umwandlung in 0 und 1, aber nix komprimiert.
-
Wenn du die Zahlen in Hex speicherst, spart das Speicherplatz, in Binär dürfte das aber sehr viel mehr Schpeicherplatz benötigen.
PS: Es gibt auch 3D-Frameworks (ich weiß jetzt nicht den Fachbegriff), d.h. du hast dieses in deiner Anwendung eingebunden und deine 3D-Modelle können mit sehr viel weniger Code beschrieben werden. Ein Beispiel dazu ist Windows Presentation Fundation (is aber nich für C++) -
Wie meinst du das denn mit dem Speichern?
Speicherst du dieZahlen im Moment als Textdatei?
Wenn ja, dann kannst du in der Tat einiges an Speicher und Rechenzeit sparen, wenn du
stattdessen ein eigenes binäres Format entwickelst oder ein schon vorhandenes verwendest. -
sektor schrieb:
Wie meinst du das denn mit dem Speichern?
Speicherst du dieZahlen im Moment als Textdatei?
Wenn ja, dann kannst du in der Tat einiges an Speicher und Rechenzeit sparen, wenn du
stattdessen ein eigenes binäres Format entwickelst oder ein schon vorhandenes verwendest.
Ja genau, das mein ich!
Die Frage ist ja: gibt es eine bekannte (und freie) gute Technik um zahlen in Hex zu speichern? -
Tach ich hoffe ich habe das ganzen posts alle vorher richtig verstanden. ersten hex und binar und dezimal brauchen Prinzipel gleichviel Speicher da alles sowieso im Speicher nur in binar vorliegen z.B. 29 in dezimal ist auch 11101 in binar und in hex 1D. Nur wen eine Zahl in asci vorliegt brauch sie mehr speichere da für jedes zeichnen 8bit geraucht werden z.b. entspricht die 1 in asci 49.
Zur richtiger Datenkompression kann ich nicht richtige was sagen nur fiele Datenkompression ficht den Wiki Artikel empfehlen http://de.wikipedia.org/wiki/Datenkompression
-
Also um das mal klarzustellen die HEX-Schreibweise ist nur eine Form um Binärzahlen kürzer darzustellen.
Beim speichern gewinnst du dadurch nichts .
Also ich kenne keine freie Definition für binäre Dateien zumal da jeder sein eigenes Ding macht. Die meisten erzeugen mit einem Tool ihre Dateien und konvertieren sie dann in ihr benötigtes Binärformat.
Damit will ich sagen, dass du dir am besten dein eigenes Format nach deinen Bedürfnissen überlegst.
Wenn du zum Beispiel der Reihe nach nur X,Y,Z Koordinaten von Eckpunkten speichern möchtest, dann könntest du einfach nacheinander die Eckpunkte in dieser Form speichern.
In deiner Datei würde dann immer stehen:
XYZXYZXYZXYZ...
Beitrag zuletzt geändert: 9.6.2010 21:21:44 von sektor -
Ich hab jetzt eine von mir erfundene "neue" Methode (-; probiert die etwa die hälfte des Speichers spart, ob sie aber Programmiersprachengerecht ist weis ich nicht so genau da ich noch kaum mit Hex/Binär Programmiert hab:
Ich hab die Koordinaten
1.026345 86.2774 2834.263328
normal gespeichert (29 Byte) und die dann in einem Hex editor direkt hintereinander geschrieben mit A's als Punkten (für Nachkommastellen) und B's um die Zahlen zu trennen. Das sieht mit den oben genannten Zahlen in Hex dann so aus (14 Byte):
1A 02 63 45 B8 6A 27 74 B2 83 4A 26 33 28
Wieso ich mir nicht sicher bin ist das die Zahlen sich nicht exakt auf einem String oder Byte (oder wie das heißt) trennen und ich deswegen nicht weis ob es der Computer bzw. dann programm was ich dann schreibe sie dann verarbeiten kann. Wie schon gesagt bin ich mit Binär/Hex in Programmen noch nicht vertraut.
Hab ich es richtig gemacht? -
Also ich glaube dir ist noch nicht klar, dass der Computer ausschließlich binäre Werte speichern kann.
Der Speicher des Computers besteht aus sehr vielen "Schaltern" hintereinander, die entweder auf aktiv oder nicht-aktiv stehen (was meisten dazu führt, dass Strom fließt, oder nicht).
Du kannst mit einem Bit also maximal 2 Aussagen treffen, die sich gegenseitig ausschließen.
Da ein Byte aus 8 Bit besteht, ergeben sich verschiedene Möglichkeiten, wie die Bits im Byte geschaltet sind.
Die Hexadezimale Darstellung ist ausschließlich eine Hilfe für uns Menschen, um mit Binärwerten besser umgehen zu können, denn eine Hex-Ziffer hat den gleichen Informationsgehalt wie 4 Bits. Und 2 Hex-Ziffern so viel Informationsgehalt wie ein Byte. Entsprechend kann man als Mensch sehr schnell zwischen dem Binärsystem und dem Hexadezimalsystem umrechnen, da keine Überträge vorkommen.
Der Computer selber versteht aber kein Hexadezimal!
Und deine Herangehensweise ist sehr verschwenderisch. Du verbrauchst nämlich ein Byte für ein Ziffer und zusätzlich noch ein weiteres Byte für die Begrenzer, denn du scheinst die Ziffern als C-Char abzuspeichern. Das ganze wird dann eh intern in Binär umgerechnet, aber aus eine sehr verschwenderische Weise, da du für eine Hex-Ziffer ja keine 8 Bit bräuchtest, sondern nicht mal 4 ganze Bits.
Lange Rede, kurzer Sinn, hier mal ein Code, der deine Zahlen ausgibt, in eine Datei speichert und sie danach wieder ausliest und erneut ausgibt.
#include <stdio.h> typedef struct { float x, y, z; //alternativ: double } coords; int main( int argc, char ** argv ) { coords foo = { 1.026345, 86.2774, 2834.263328 }; printf( "%f %f %f\n", foo.x, foo.y, foo.z ); FILE * save = fopen( "Koordinaten.txt", "w" ); fwrite( &foo, sizeof( foo ), 1, save ); fclose( save ); coords bar; FILE * open = fopen( "Koordinaten.txt", "r" ); fread( &bar, sizeof( bar ), 1, open ); fclose( open ); printf( "%f %f %f\n", bar.x, bar.y, bar.z ); return 0; }
Wenn die Werte als floats gespeichert werden, verbrauchen sie nur 4*3=12 Byte und falls sie als doubles gespeichert werden, dann brauchen sie 8*3=24 Bytes.
Dein Ansatz benötigt angeblich 14 Bytes, aber du musst beachten, dass dies nur für die Zahlen, die du jetzt gewählt hast, gilt. Außerdem mag der Computer das Dezimalsystem genausowenig wie das Hexadezimalsystem. Der Compiler rechnet das zwar für dich um, aber im laufenden Betrieb kostet es unnötig Rechenzeit Dezimalzahlen (und dann noch in einen so absurden Format wie deinem) umzuwandeln. -
Also wie der werte bladehunter bereits anmerkte, kann man das ganze von wegen "Hexadezimal verbrauchen die Werte weniger Platz" vollkommen vergessen. Du solltest zu allererst wissen, dass jeder Datentyp seinen Speicheraufwand hat. Das Daten lesen und schreiben ist so, wie bladehunter es beschrieben hat, wahrscheinlich am schnellsten und einfachsten gemacht - hat aber noch nicht so wirklich viel mit "Kompression" zutun.
Bei der Kompression sollte an erster Stelle die Überlegung stehen, wie du Informationsgehalt sparen kannst. Beispielsweise brauchst du bei einer 1 oder einer 0 praktisch nur einen bit pro Punkt, bei einer Zahl zwischen 0 und 255 brauchst du schon acht bit (1 Byte), bei einem long-integer bereits 64 Bit (8 Byte) und so weiter. Die ersten Einsparungen lassen sich also schon machen, wenn du immer möglichst kleine Werte hast. Bei 3D-Objekten kann man sowas eventuell erreichen, indem man keine absoluten Positionen verwendet, sondern relative. Nach dem laden kann man diese ja noch immer ohne viel aufwand in absolute positionen umrechnen. Dadurch lassen sich teils schon über 50% einsparen.
Danach lässt sich beispielsweise durch eine geordnete Datenstruktur sehr viel Platz sparen. Wenn du möglichst wenige Marker-Bits und -Bytes benötigst, lässt sich dadurch nochmals Platz sparen. Hauptsache du weisst, wie deine Datei aussieht - einem anderen muss das ganze ja nicht zwingend durchsichtig erscheinen. Also anstelle zu schreiben "An Position x/y/z kommt ein Punkt, an Position a/b/c kommt ein Punkt" schreibst du nur noch "xyzabc" - die Darstellung ist jetzt leicht übertrieben, aber sie soll auch nur grob zeigen was ich meine. Dein Programm weiss dann, dass die ersten 3 byte die x-, y- und z-Koordinate eines Punktes sind, die nächsten 3 Byte die Koordinaten des nächsten Punkts und so weiter.
Diesbezüglich hat bladehunter ja bereits erklärt, dass sich zahlen in einem String von Integer-Zahlen vor allem im Speicherbedarf unterscheiden. Eine "123" zu schreiben benötigt mindestens 3 Byte. Das ganze als integer auszudrücken passt in 1 Byte. (bzw. 7 bit)
In vielen Tutorials wird da ganz falsch heran gegangen, denn die erklären einem, dass man doch einfach "123, 456, 789" in eine Datei schreiben sollte. Dort liegt allerdings eine gigantische Speicher-Falle.
Um dann zur "richtigen" Kompression zu kommen, muss man schon eine ganze Menge lesen. Aber wenn du dann schon mal eine Datei so fertig geschrieben hast, kannst du durchaus mal verschiedene Kompressionsalgorithmen ausprobieren. Diese gibt es häufig in Open-Source-Bibliotheken. Das einfachste wäre dann die Lauflängenkompression, welche allerdings für dein Vorhaben wohl nicht zu empfehlen ist, da es in 3D-Modellen weniger wahrscheinlich ist, dass sich Datenstränge wiederholen. Am sinnvollsten wäre eventuell das Huffmann- oder Shannon-Fano-Verfahren. Musst du dich mal durchs Netz lesen, was du da selbst für das beste hälst und wo du die besten Bibliotheken her bekommst.
Aber am Ende solltest du immer bedenken: Zaubern kann das alles auch nicht ;) Und komplexe 3D-Modelle sind nunmal recht Speicherintensiv. Das sollte aber bei den heutigen Terrabyte-Platten auch weniger das große Problem sein
Nun ja, gar keinen Code gepostet. Aber da man ja auch nichts über deine Datenstrukturen weiss, ist es auch schwierig, dir da was passendes vorzulegen. -
Man sollte sich bei 3D Modellen auch immer überlegen, ob man wirklich hunderte von Polygone brauch. :) Bei riesigen Modellen kann man öfters mal locker 100+ Polygone sparen, was bei ein paar Duzent 3d Modellen schon sparsamer sein kann, und meistens bleibt nicht mal mehr ein sichtbarer Qualitätsverlust.
Viele Render Programme verfügen auch über eine Funktion, Polygone 'zusammen zu fassen'. -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage