Assimp .3ds modelle für OpenGL importieren
Assimp .3ds modelle für OpenGL importieren
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 :=)
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 :=)
- 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
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.
Gibst du evtl das ConvertToLeftHanded-Flag an? Sollte prinzipiell fuer OpenGl nicht noetig sein.
- kimmi
- Moderator
- Beiträge: 1412
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Assimp .3ds modelle für OpenGL importieren
Setzt du auch die entsprechende Transformation aus dem Modell? Ich habe das gern immer mal vergessen.
Gruß Kimmi
Gruß Kimmi
Re: Assimp .3ds modelle für OpenGL importieren
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;
}
Was muss ich den noch Transformieren? Wie mache ich das, habe dazu irgendwie nicht viel gefunden.kimmi hat geschrieben:Setzt du auch die entsprechende Transformation aus dem Modell? Ich habe das gern immer mal vergessen.
Gruß Kimmi
Wenn ich die .3ds in Blender betrachte stimmt es. Das genannte ConvertToLeftHanded Flag ist nicht an wie du oben im code sehen kann :)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.
:?:
Re: Assimp .3ds modelle für OpenGL importieren
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.
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.
Re: Assimp .3ds modelle für OpenGL importieren
Wenn ich rausgefunden habe wie ich die Transformationsmatrix bekomme, muss ich dann (in meinen Fall OpenGL) mit glTranslatef( ); und glRotatef( ); in meinem code arbeiten?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.
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.
- Schrompf
- Moderator
- Beiträge: 5162
- 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
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.
Re: Assimp .3ds modelle für OpenGL importieren
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?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.
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();
}
}
meine ich das ich meine Boundingbox nicht manuell mit verschieben muss bei jeder Translation?
Vielen dank für eure schnellen antworten :)
Re: Assimp .3ds modelle für OpenGL importieren
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:
Matrizenmultiplikation:
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.
Es sieht dann also in etwa so aus:
Modell:
Code: Alles auswählen
Node
|-Childnode1
| -ChildChildnode1
|-Childnode2
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.
- kimmi
- Moderator
- Beiträge: 1412
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Assimp .3ds modelle für OpenGL importieren
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
Gruß Kimmi