Assimp .3ds modelle für OpenGL importieren

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
madmoses
Beiträge: 4
Registriert: 13.01.2012, 18:32

Assimp .3ds modelle für OpenGL importieren

Beitrag von madmoses »

Hi,

ich habe es geschaft mit wenig aufwand eine .3ds Datei in mein Programm zu laden. Leider habe ich das Problem
das meine Objekte alle um die x oder z achse (OpenGL Koordinaten System) um 90 grad gedreht sind. Kann ich Assimp irgendwie
sagen das ich die Objekte anders haben möchte? Also in OpenGL Style oder muss ich das manuell wieder in meinem Code zu recht drehen?

Danke :=)
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Assimp .3ds modelle für OpenGL importieren

Beitrag von Aramis »

Prinzipiell sollte die Ausrichtung von 3DS-Modellen richtig sein, vorausgesetzt, die Modelle waren in der Quelldatei richtig herum :-)

Gibst du evtl das ConvertToLeftHanded-Flag an? Sollte prinzipiell fuer OpenGl nicht noetig sein.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Assimp .3ds modelle für OpenGL importieren

Beitrag von kimmi »

Setzt du auch die entsprechende Transformation aus dem Modell? Ich habe das gern immer mal vergessen.

Gruß Kimmi
madmoses
Beiträge: 4
Registriert: 13.01.2012, 18:32

Re: Assimp .3ds modelle für OpenGL importieren

Beitrag von madmoses »

Also meine Import Funktion sieht so aus:

Code: Alles auswählen

void AllRoundObject::DoTheImportThing()
{
  // Create an instance of the Importer class
  Assimp::Importer importer;

  // And have it read the given file with some example postprocessing
  // Usually - if speed is not the most important aspect for you - you'll
  // propably to request more postprocessing than we do in this example.
  scene = importer.ReadFile( this->pFile,
        aiProcess_CalcTangentSpace       |
        aiProcess_Triangulate            |
        aiProcess_JoinIdenticalVertices  | aiProcess_FlipWindingOrder |
        aiProcess_SortByPType);

  cout << "Load " << this->pFile << " ";
  // If the import failed, report it
  if( !scene)
  {
    cout << ( importer.GetErrorString())<< endl;
  }
  else
  {
	  cout << "SUCCESSFUL" << endl;
  }


  	  aiMesh** meshes = scene->mMeshes;

  	  numVertices = 0;
  	  numFaces = 0;
  	  unsigned int start_index = 0;
  	  unsigned int start_index_faces = 0;
  	  unsigned int old_faces = 0;
  	  cout << "Anzahl Meshes: " << scene->mNumMeshes << endl;


  	  for(unsigned int nMeshes = 0; nMeshes < scene->mNumMeshes; nMeshes++)
  	  {
  		  numVertices +=meshes[nMeshes]->mNumVertices;
  		  numFaces += meshes[nMeshes]->mNumFaces;

  	  }
  	  cout << numFaces << " " << numVertices << endl;
  	  //Für jedes Mesh die Vertices und Faces kopieren
  	  this->vertices = new Vertices[numVertices];
  	  this->normales = new Vertices[numVertices];
  	  this->faces = new Faces[numFaces];
  	  GLfloat min_x = 0, max_x = 0,
  	  	  	  min_y = 0, max_y = 0,
  	  	  	  min_z = 0, max_z = 0;

  	  for(unsigned int nMeshes = 0; nMeshes < scene->mNumMeshes; nMeshes++)
  	  {
  		  cout << "Mesh: " << nMeshes << endl;
  		  //Alles Vertices Kopieren in meine Struktur
  		  for(unsigned int nVertex = 0; nVertex < meshes[nMeshes]->mNumVertices; nVertex++)
  		  {
  			vertices[start_index].X = meshes[nMeshes]->mVertices[nVertex].x;
  			vertices[start_index].Y = meshes[nMeshes]->mVertices[nVertex].y;
  			vertices[start_index].Z = meshes[nMeshes]->mVertices[nVertex].z;
  			if(meshes[nMeshes]->mVertices[nVertex].x< min_x) min_x = meshes[nMeshes]->mVertices[nVertex].x;
  			if(meshes[nMeshes]->mVertices[nVertex].y< min_y) min_y = meshes[nMeshes]->mVertices[nVertex].y;
  			if(meshes[nMeshes]->mVertices[nVertex].z< min_z) min_z = meshes[nMeshes]->mVertices[nVertex].z;

  			if(meshes[nMeshes]->mVertices[nVertex].x > max_x) max_x = meshes[nMeshes]->mVertices[nVertex].x;
  			if(meshes[nMeshes]->mVertices[nVertex].y > max_y) max_y = meshes[nMeshes]->mVertices[nVertex].y;
  			if(meshes[nMeshes]->mVertices[nVertex].z > max_z) max_z = meshes[nMeshes]->mVertices[nVertex].z;

  			normales[start_index].X = meshes[nMeshes]->mNormals[nVertex].x;
  			normales[start_index].Y = meshes[nMeshes]->mNormals[nVertex].y;
  			normales[start_index].Z = meshes[nMeshes]->mNormals[nVertex].z;
  			start_index++;
  		  }
  		  //cout << "############## FACES ################" << endl;
  		  for(unsigned int nFaces = 0;  nFaces < meshes[nMeshes]->mNumFaces; nFaces++)
  		  {
  			  //cout << meshes[nMeshes]->mFaces[nFaces].mIndices[0] << " " <<  endl;
  			  faces[start_index_faces].X = meshes[nMeshes]->mFaces[nFaces].mIndices[0] + old_faces;
  			  faces[start_index_faces].Y = meshes[nMeshes]->mFaces[nFaces].mIndices[1] + old_faces;
  			  faces[start_index_faces].Z = meshes[nMeshes]->mFaces[nFaces].mIndices[2] + old_faces;
  			  start_index_faces++;
  		  }
  		  old_faces = start_index;
  	  }
kimmi hat geschrieben:Setzt du auch die entsprechende Transformation aus dem Modell? Ich habe das gern immer mal vergessen.

Gruß Kimmi
Was muss ich den noch Transformieren? Wie mache ich das, habe dazu irgendwie nicht viel gefunden.
Aramis hat geschrieben:Prinzipiell sollte die Ausrichtung von 3DS-Modellen richtig sein, vorausgesetzt, die Modelle waren in der Quelldatei richtig herum :-)

Gibst du evtl das ConvertToLeftHanded-Flag an? Sollte prinzipiell fuer OpenGl nicht noetig sein.
Wenn ich die .3ds in Blender betrachte stimmt es. Das genannte ConvertToLeftHanded Flag ist nicht an wie du oben im code sehen kann :)

:?:
Grinch
Beiträge: 25
Registriert: 16.04.2004, 22:42

Re: Assimp .3ds modelle für OpenGL importieren

Beitrag von Grinch »

Nach deinem Code liest du zwar alle Meshes aus, aber nicht den Nodetree.
Die Nodes bilden den Modellbaum ab. Jeder Node hat eine Liste(1-n) von Meshes und eine Transformationsmatrix sowie 0-m Childnodes. Durch die Transformationsmatrix werden die Meshes richtig positioniert und du kannst ein Mesh auch an mehreren Stellen verwenden (z.B. ein Fenster an mehreren Stellen im Haus).
Die Transformationsmatrix für einen Node ist auch jeweils relativ zu seinem Parent. Dies muss beim Rendern durch Multiplikation der Matrizen beachtet werden.
madmoses
Beiträge: 4
Registriert: 13.01.2012, 18:32

Re: Assimp .3ds modelle für OpenGL importieren

Beitrag von madmoses »

Grinch hat geschrieben:Nach deinem Code liest du zwar alle Meshes aus, aber nicht den Nodetree.
Die Nodes bilden den Modellbaum ab. Jeder Node hat eine Liste(1-n) von Meshes und eine Transformationsmatrix sowie 0-m Childnodes. Durch die Transformationsmatrix werden die Meshes richtig positioniert und du kannst ein Mesh auch an mehreren Stellen verwenden (z.B. ein Fenster an mehreren Stellen im Haus).
Die Transformationsmatrix für einen Node ist auch jeweils relativ zu seinem Parent. Dies muss beim Rendern durch Multiplikation der Matrizen beachtet werden.
Wenn ich rausgefunden habe wie ich die Transformationsmatrix bekomme, muss ich dann (in meinen Fall OpenGL) mit glTranslatef( ); und glRotatef( ); in meinem code arbeiten?

ich mein wenn ich ein 3d objekt aus mehreren Meshes laden will, ist alles richtig an seiner position wo es sein soll und sieht auch so aus wie im assimp view. Der Spaß ist dann eben nur um 90grad gekippt. Und ich kippe
es jedes mal wenn ich es zeichne um 90grad zurück und das fast 1000mal pro Frame, das will ich verhindern in dem ich das Ganze direkt an in der richtigen form vorliegen habe.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4886
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Assimp .3ds modelle für OpenGL importieren

Beitrag von Schrompf »

Wo bei 3D-Modellen oben ist, dazu existiert leider kein verpflichtender Standard. Einige Modelle musst Du drehen, andere nicht. Die Rechenzeit dafür kannst Du aber ignorieren... ein glRotate() verursacht nur eine Matrix-Multiplikation, davon kannst Du einige hundert Millionen pro Sekunde machen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
madmoses
Beiträge: 4
Registriert: 13.01.2012, 18:32

Re: Assimp .3ds modelle für OpenGL importieren

Beitrag von madmoses »

Schrompf hat geschrieben:Wo bei 3D-Modellen oben ist, dazu existiert leider kein verpflichtender Standard. Einige Modelle musst Du drehen, andere nicht. Die Rechenzeit dafür kannst Du aber ignorieren... ein glRotate() verursacht nur eine Matrix-Multiplikation, davon kannst Du einige hundert Millionen pro Sekunde machen.
Aber alle die ich bis jetzt runtergeladen sind auf der selben art und weiße falsch geneigt. In Blender aber immer richtig ausgerichtet. Da mache ich doch was falsch?


Ich berechne anhand der Mashes eine Bounding Box für meine Culling implementierung. Ich müsste dann halt per hand die Bounding Box auch ensprechend drehen, aber wollte das eigentlich verhindern und das kostet ja auch rechenzeit. Habe gehoft das ich das mit assimp machen lässt.

Momentan sieht meine zeichen Funktion so aus:

Code: Alles auswählen

void AllRoundObject::render(float x, float y, float z)
{
	if(sowi::Frustum::OUTSIDE == ((frustum->pointInFrustum(boundingBox.A.X + x,boundingBox.A.Y + y, boundingBox.A.Z + z)) |
								  (frustum->pointInFrustum(boundingBox.G.X + x,boundingBox.G.Y + y, boundingBox.G.Z + z))))
		outside++;
	else
	{
		inside++;
		glPushMatrix();
		glTranslatef(x, y, z);

	    glEnableClientState(GL_NORMAL_ARRAY);
	    glEnableClientState(GL_VERTEX_ARRAY);

	    glBindBuffer(GL_ARRAY_BUFFER, VBOnormalsID);
	    glNormalPointer(GL_FLOAT, 0, 0);

	    glBindBuffer(GL_ARRAY_BUFFER, VBOverticesID);
	    glVertexPointer(3, GL_FLOAT, 0, 0);

	    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBOindicesID);
		glDrawElements(GL_TRIANGLES, this->numFaces*3, GL_UNSIGNED_INT, 0);

	    glDisableClientState(GL_VERTEX_ARRAY);
	    glDisableClientState(GL_NORMAL_ARRAY);
		glPopMatrix();
	}
}
Ich merke mir sozusagen jede transaltion, damit ich meine Boundinbox manuell verschiebe. Muss man das so machen oder kann ich das auch schöner machen? Mit schöner
meine ich das ich meine Boundingbox nicht manuell mit verschieben muss bei jeder Translation?

Vielen dank für eure schnellen antworten :)
Grinch
Beiträge: 25
Registriert: 16.04.2004, 22:42

Re: Assimp .3ds modelle für OpenGL importieren

Beitrag von Grinch »

Die Transformationsmatrix eines Nodes des Modells enthält alle 3 Faktoren, also Skalierung, Rotation und Translation. Du musst also quasi einen Matrixstack aufbauen, mit dem du das Modell zeichnest. Am Anfang steht die Identmatrix, also Nullpunkt ohne Veränderung. Diese wird dann mit der Transformationsmatrix des ersten Nodes multipliziert. Damit sind die Meshes dieses Knotens an der richtigen Stelle, rotiert und skaliert. Wenn der Node Childs hat, wird die jeweils aktuelle Worldmatrix genommen und mit der eigenen Transformationsmatrix multipliziert, wodurch sich der Child relativ zu seinem Parent verschiebt.
Es sieht dann also in etwa so aus:
Modell:

Code: Alles auswählen

Node
|-Childnode1
|    -ChildChildnode1
|-Childnode2
Matrizenmultiplikation:

Code: Alles auswählen

matN1*1
matC1*matN1*1
matCC1*matC1*matN1*1
matC2*matN1*1

1 ist die Identmatrix. Diese Multiplikation kann man aber auch wegoptimieren.
Ich kenne mich leider bei OpenGL nicht so aus, aber es wird hier auch sicher eine Funktion geben, in der man die Worldmatrix direkt setzen kann ohne glTranslatef oder glRotatef etc.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Assimp .3ds modelle für OpenGL importieren

Beitrag von kimmi »

Schau dir einfach mal das Beispiel assimp_simpleogl an, dort werden die Matrizen korrekt gesetzt. Das Beispiel findest du unter <assimp_root>/samples/simpleopengl .

Gruß Kimmi
Antworten