Seite 1 von 1

Laden einer 3ds. Datei

Verfasst: Mi Dez 30, 2009 9:00 pm
von cloidnerux
So, ich will für ein kleines Spiel meine 3D Objekte als 3ds-Datei speichern und in mein Spiel laden.
Ich habe auch recht viel dazu gefunden:
http://www.devmaster.net/forums/showthread.php?t=5059
http://www.spacesimulator.net/tut4_3dsloader.html
http://www.the-labs.com/Blender/3DS-details.html
Ich habe das dann nach diesen Quellen eine Funktion gebaut, die es im Grunde schaffen sollte, eine 3DS Datei zu laden.
Aber sie Funktioniert nicht. Zum einen lag es daran das ich die Variablen zu groß Dimensionierte, zum anderen an dem nicht Funktionieren des ">>" Operators.
Doch ich habe jezt die Funktion wieder und wieder Überprüft, und finde den Fehler nicht.
Hier die Funktion:

Code: Alles auswählen

bool MaxModel::LoadModel(std::string pathToFile)
{
	cout << "Lade 3ds-Max Modell" << endl;
	unsigned short identifyer = 0;
	unsigned int length = 0, fileLength;
	unsigned short useless;
	ifstream datei(pathToFile.c_str(), ios::in | ios::binary | ios::_Nocreate);
	if(!datei.is_open())
	{
		cout << "Fehler beim Laden des 3D-Modells: ";
		cout << pathToFile.c_str() << endl;
		return false;
	}
	datei.seekg(0, ios::end);
	fileLength = datei.tellg();
	datei.seekg(0, ios::beg);
	while(datei.eof() == false)
	{
		if(!datei.good())
		{
			continue;
		}
		char nextChar = ' ';
		datei.read((char*)&identifyer, 2);
		datei.read((char*)&length, 4);
		if(length == 0)
		{
			cout << "Kann Objekt nicht laden, kein Inhalt!" << endl;
			return false;
		}
		if(length > fileLength)
		{
			cout << "Chunk ist groesser als Datei!" << endl;
			return false;
		}
		cout << "Chunk-ID: " << hex << identifyer << " Länge: " << dec << length << endl;
		switch(identifyer)
		{
			case MAIN_CHUNK:
				break;
			case EDITOR_CHUNK:
				break;
			case OBJECT_BLOCK: 
				for(int i = 0; i < 20 && (nextChar != '\0'); i++)
				{
					datei.read(&nextChar, sizeof(char));
					name += nextChar;
				}
				cout << name.c_str() << endl;
				break;
			case TRIANGULAR_MESH:
				break;
			case VERTICES_LIST: 
				int count;
				datei.read((char*)&count, sizeof(unsigned short));
				numVertices = count;
				for(int i = 0; i < numVertices; i++)
				{
					datei.read((char*)&(v[i].x), sizeof(float));
					datei.read((char*)&(v[i].y), sizeof(float));
					datei.read((char*)&(v[i].z), sizeof(float));
				}
				cout << "Anzahl Vertices: "  << numVertices << endl;
				break;
			case FACES_DESCRIPTION:
				datei.read((char*)&numPolys, sizeof(short));
                for (int i = 0; i < numPolys; i++)
                {
					datei.read((char*)&(p[i].a), sizeof(short));
					datei.read((char*)&(p[i].b), sizeof(short));
					datei.read((char*)&(p[i].c), sizeof(short));
					datei.read((char*)&useless, sizeof(short));
				}
				cout << "Anzahl Polygone: " << numPolys << endl;
				break;
			case MAPPING_COORDINATES_LIST:
				datei.read((char*)&useless, sizeof(short));
				for (int i = 0; i < numVertices; i++)
				{
					datei.read((char*)&(m[i].u), sizeof(float));
                    datei.read((char*)&(m[i].v), sizeof(float));
				}
                break;
			default:
				datei.seekg(length - 6, ios_base::cur);
		}
	}
	cout << "Modell geladen" << endl;
	datei.close();
	loaded = true;
	return true;
}
DIe Funktion ist aus der Klasse MaxModel, die das ganze ein wenig Abstrahieren soll. Einige Variablen, wie die Anzahl der Polygone und Vertices, sind in dieser Klasse definiert.
Ich danke für Hilfe.

Re: Laden einer 3ds. Datei

Verfasst: Fr Jan 01, 2010 6:46 pm
von cloidnerux
So, ein Problem ist gelöst.
Ifstream hat das eof-Bit nicht gesezt, und hat damit einfach immer weiter gelesen.

Re: Laden einer 3ds. Datei

Verfasst: Fr Jan 01, 2010 7:08 pm
von Kerli
cloidnerux hat geschrieben:So, ein Problem ist gelöst.
Heißt das es funktioniert immer noch nicht?
cloidnerux hat geschrieben:Ifstream hat das eof-Bit nicht gesezt, und hat damit einfach immer weiter gelesen.
Was war denn daran schuld?

Was mir sonst noch problematisch erscheint sind die ganzen read-Aufrufe, da du dabei nie überprüfst ob diese auch funktioniert haben. Eventuell könntest du das mit ios::exceptions versuchen...
cloidnerux hat geschrieben:

Code: Alles auswählen

   while(datei.eof() == false)
   {
      if(!datei.good())
      {
         continue;
      }
Was ist bei einem Fehler? Also nicht eof aber trotzdem ein Fehler?

Re: Laden einer 3ds. Datei

Verfasst: Fr Jan 01, 2010 8:23 pm
von cloidnerux
Heißt das es funktioniert immer noch nicht?
Nein, ich lade zwar die Datei komplett, bekomme aber immer eine out_of_range Exceptions der Vectoren beim Zeichnen.
Was war denn daran schuld?
Erlich gesagt, ich weiß es nicht.
Ich habe nur Probeweise statt des Aufrufes

Code: Alles auswählen

   while(datei.eof() == false)
geprüft ob der Dateizeiger an einer Position hinter der Datei ist und auf einmal kann die Funktion die Datei laden.
Was mir sonst noch problematisch erscheint sind die ganzen read-Aufrufe, da du dabei nie überprüfst ob diese auch funktioniert haben. Eventuell könntest du das mit ios::exceptions versuchen...
Nacher mal einbauen.

Was ich eindeutig als Bug erachte, ist das die Funktion trotz unterschiedicher Dateien immer die selbe Anzahl an Vertices und Polygone hat.