Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] [DirectX] Konwersja z .obj z praworęcznego systemu współrzędnych na leworęczny

Ostatnio zmodyfikowano 2015-09-26 22:47
Autor Wiadomość
TheReclif
Temat założony przez niniejszego użytkownika
[C++] [DirectX] Konwersja z .obj z praworęcznego systemu współrzędnych na leworęczny
» 2015-05-24 22:55:53
Witam!
Tworzę grę, która ma wczytywać modele z plików .obj. Postępuję zgodnie z tym tutorialem: http://rastertek.com/dx11tut08.html. Niestety, ale żeby wczytać .obj trzeba go najpierw przekonwertować na leworęczny system współrzędnych. Robię to tym programem(podaję jego kod):
C/C++
////////////////////////////////////////////////////////////////////////////////
// Filename: main.cpp
////////////////////////////////////////////////////////////////////////////////


//////////////
// INCLUDES //
//////////////
#include <iostream>
#include <fstream>
using namespace std;


//////////////
// TYPEDEFS //
//////////////
typedef struct
{
    float x, y, z;
} VertexType;

typedef struct
{
    int vIndex1, vIndex2, vIndex3;
    int tIndex1, tIndex2, tIndex3;
    int nIndex1, nIndex2, nIndex3;
} FaceType;


/////////////////////////
// FUNCTION PROTOTYPES //
/////////////////////////
void GetModelFilename( char * );
bool ReadFileCounts( char *, int &, int &, int &, int & );
bool LoadDataStructures( char *, int, int, int, int );


//////////////////
// MAIN PROGRAM //
//////////////////
int main()
{
    bool result;
    char filename[ 256 ];
    int vertexCount, textureCount, normalCount, faceCount;
    char garbage;
   
   
    // Read in the name of the model file.
    GetModelFilename( filename );
   
    // Read in the number of vertices, tex coords, normals, and faces so that the data structures can be initialized with the exact sizes needed.
    result = ReadFileCounts( filename, vertexCount, textureCount, normalCount, faceCount );
    if( !result )
    {
        return - 1;
    }
   
    // Display the counts to the screen for information purposes.
    cout << endl;
    cout << "Vertices: " << vertexCount << endl;
    cout << "UVs:      " << textureCount << endl;
    cout << "Normals:  " << normalCount << endl;
    cout << "Faces:    " << faceCount << endl;
   
    // Now read the data from the file into the data structures and then output it in our model format.
    result = LoadDataStructures( filename, vertexCount, textureCount, normalCount, faceCount );
    if( !result )
    {
        return - 1;
    }
   
    // Notify the user the model has been converted.
    cout << "\nFile has been converted." << endl;
    cout << "\nDo you wish to exit (y/n)? ";
    cin >> garbage;
   
    return 0;
}


void GetModelFilename( char * filename )
{
    bool done;
    ifstream fin;
   
   
    // Loop until we have a file name.
    done = false;
    while( !done )
    {
        // Ask the user for the filename.
        cout << "Enter model filename: ";
       
        // Read in the filename.
        cin >> filename;
       
        // Attempt to open the file.
        fin.open( filename );
       
        if( fin.good() )
        {
            // If the file exists and there are no problems then exit since we have the file name.
            done = true;
        }
        else
        {
            // If the file does not exist or there was an issue opening it then notify the user and repeat the process.
            fin.clear();
            cout << endl;
            cout << "File " << filename << " could not be opened." << endl << endl;
        }
    }
   
    return;
}


bool ReadFileCounts( char * filename, int & vertexCount, int & textureCount, int & normalCount, int & faceCount )
{
    ifstream fin;
    char input;
   
   
    // Initialize the counts.
    vertexCount = 0;
    textureCount = 0;
    normalCount = 0;
    faceCount = 0;
   
    // Open the file.
    fin.open( filename );
   
    // Check if it was successful in opening the file.
    if( fin.fail() == true )
    {
        return false;
    }
   
    // Read from the file and continue to read until the end of the file is reached.
    fin.get( input );
    while( !fin.eof() )
    {
        // If the line starts with 'v' then count either the vertex, the texture coordinates, or the normal vector.
        if( input == 'v' )
        {
            fin.get( input );
            if( input == ' ' ) { vertexCount++; }
            if( input == 't' ) { textureCount++; }
            if( input == 'n' ) { normalCount++; }
        }
       
        // If the line starts with 'f' then increment the face count.
        if( input == 'f' )
        {
            fin.get( input );
            if( input == ' ' ) { faceCount++; }
        }
       
        // Otherwise read in the remainder of the line.
        while( input != '\n' )
        {
            fin.get( input );
        }
       
        // Start reading the beginning of the next line.
        fin.get( input );
    }
   
    // Close the file.
    fin.close();
   
    return true;
}


bool LoadDataStructures( char * filename, int vertexCount, int textureCount, int normalCount, int faceCount )
{
    VertexType * vertices, * texcoords, * normals;
    FaceType * faces;
    ifstream fin;
    int vertexIndex, texcoordIndex, normalIndex, faceIndex, vIndex, tIndex, nIndex;
    char input, input2;
    ofstream fout;
   
   
    // Initialize the four data structures.
    vertices = new VertexType[ vertexCount ];
    if( !vertices )
    {
        return false;
    }
   
    texcoords = new VertexType[ textureCount ];
    if( !texcoords )
    {
        return false;
    }
   
    normals = new VertexType[ normalCount ];
    if( !normals )
    {
        return false;
    }
   
    faces = new FaceType[ faceCount ];
    if( !faces )
    {
        return false;
    }
   
    // Initialize the indexes.
    vertexIndex = 0;
    texcoordIndex = 0;
    normalIndex = 0;
    faceIndex = 0;
   
    // Open the file.
    fin.open( filename );
   
    // Check if it was successful in opening the file.
    if( fin.fail() == true )
    {
        return false;
    }
   
    // Read in the vertices, texture coordinates, and normals into the data structures.
    // Important: Also convert to left hand coordinate system since Maya uses right hand coordinate system.
    fin.get( input );
    while( !fin.eof() )
    {
        if( input == 'v' )
        {
            fin.get( input );
           
            // Read in the vertices.
            if( input == ' ' )
            {
                fin >> vertices[ vertexIndex ].x >> vertices[ vertexIndex ].y >> vertices[ vertexIndex ].z;
               
                // Invert the Z vertex to change to left hand system.
                vertices[ vertexIndex ].z = vertices[ vertexIndex ].z * - 1.0f;
                vertexIndex++;
            }
           
            // Read in the texture uv coordinates.
            if( input == 't' )
            {
                fin >> texcoords[ texcoordIndex ].x >> texcoords[ texcoordIndex ].y;
               
                // Invert the V texture coordinates to left hand system.
                texcoords[ texcoordIndex ].y = 1.0f - texcoords[ texcoordIndex ].y;
                texcoordIndex++;
            }
           
            // Read in the normals.
            if( input == 'n' )
            {
                fin >> normals[ normalIndex ].x >> normals[ normalIndex ].y >> normals[ normalIndex ].z;
               
                // Invert the Z normal to change to left hand system.
                normals[ normalIndex ].z = normals[ normalIndex ].z * - 1.0f;
                normalIndex++;
            }
        }
       
        // Read in the faces.
        if( input == 'f' )
        {
            fin.get( input );
            if( input == ' ' )
            {
                // Read the face data in backwards to convert it to a left hand system from right hand system.
                fin >> faces[ faceIndex ].vIndex3 >> input2 >> faces[ faceIndex ].tIndex3 >> input2 >> faces[ faceIndex ].nIndex3
                >> faces[ faceIndex ].vIndex2 >> input2 >> faces[ faceIndex ].tIndex2 >> input2 >> faces[ faceIndex ].nIndex2
                >> faces[ faceIndex ].vIndex1 >> input2 >> faces[ faceIndex ].tIndex1 >> input2 >> faces[ faceIndex ].nIndex1;
                faceIndex++;
            }
        }
       
        // Read in the remainder of the line.
        while( input != '\n' )
        {
            fin.get( input );
        }
       
        // Start reading the beginning of the next line.
        fin.get( input );
    }
   
    // Close the file.
    fin.close();
   
    // Open the output file.
    fout.open( "model.txt" );
   
    // Write out the file header that our model format uses.
    fout << "Vertex Count: " <<( faceCount * 3 ) << endl;
    fout << endl;
    fout << "Data:" << endl;
    fout << endl;
   
    // Now loop through all the faces and output the three vertices for each face.
    for( int i = 0; i < faceIndex; i++ )
    {
        vIndex = faces[ i ].vIndex1 - 1;
        tIndex = faces[ i ].tIndex1 - 1;
        nIndex = faces[ i ].nIndex1 - 1;
       
        fout << vertices[ vIndex ].x << ' ' << vertices[ vIndex ].y << ' ' << vertices[ vIndex ].z << ' '
        << texcoords[ tIndex ].x << ' ' << texcoords[ tIndex ].y << ' '
        << normals[ nIndex ].x << ' ' << normals[ nIndex ].y << ' ' << normals[ nIndex ].z << endl;
       
        vIndex = faces[ i ].vIndex2 - 1;
        tIndex = faces[ i ].tIndex2 - 1;
        nIndex = faces[ i ].nIndex2 - 1;
       
        fout << vertices[ vIndex ].x << ' ' << vertices[ vIndex ].y << ' ' << vertices[ vIndex ].z << ' '
        << texcoords[ tIndex ].x << ' ' << texcoords[ tIndex ].y << ' '
        << normals[ nIndex ].x << ' ' << normals[ nIndex ].y << ' ' << normals[ nIndex ].z << endl;
       
        vIndex = faces[ i ].vIndex3 - 1;
        tIndex = faces[ i ].tIndex3 - 1;
        nIndex = faces[ i ].nIndex3 - 1;
       
        fout << vertices[ vIndex ].x << ' ' << vertices[ vIndex ].y << ' ' << vertices[ vIndex ].z << ' '
        << texcoords[ tIndex ].x << ' ' << texcoords[ tIndex ].y << ' '
        << normals[ nIndex ].x << ' ' << normals[ nIndex ].y << ' ' << normals[ nIndex ].z << endl;
    }
   
    // Close the output file.
    fout.close();
   
    // Release the four data structures.
    if( vertices )
    {
        delete[] vertices;
        vertices = 0;
    }
    if( texcoords )
    {
        delete[] texcoords;
        texcoords = 0;
    }
    if( normals )
    {
        delete[] normals;
        normals = 0;
    }
    if( faces )
    {
        delete[] faces;
        faces = 0;
    }
   
    return true;
}

Konwersja prostych plików(np. sześcian)jest możliwa. Ale kiedy próbuję przekonwertować własny plik(z Blendera, a nie tak jak w tutorialu Mayi 2011), program się zacina, tzn. pokazuje liczbę wierzchołków itp., ale nie tworzy gotowego pliku. Treść pliku:

# Blender v2.74 (sub 0) OBJ File: 'sey.blend'
# www.blender.org
mtllib sey.mtl
o Cube
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
v 6.000000 -1.000000 -2.000000
v -0.999999 -1.000000 -2.000000
v 6.000001 1.000000 -2.000000
v -1.000000 1.000000 -3.000000
v 6.000000 -1.000000 2.000000
v -1.000000 -1.000000 2.000000
v 5.999999 1.000000 2.000000
v -1.000001 1.000000 3.000000
v -5.235246 0.999999 0.999999
v -5.235246 0.999999 -1.000001
v -4.176435 2.430313 0.499999
v -5.235245 1.000000 -4.000001
v -4.176435 2.430313 -0.000001
v -5.235246 0.999999 3.999999
v -1.000000 0.000000 1.000000
v -1.000000 0.000000 -1.000000
v 10.190892 0.000000 -0.999999
v 10.190892 0.000000 1.000001
v 6.000000 0.000000 -4.000000
v -1.000000 0.000000 -4.000000
v 6.000000 -0.000000 4.000000
v -1.000000 -0.000000 4.000000
v -5.235246 -0.000001 0.999999
v -5.235246 -0.000001 -1.000001
v -5.235245 -0.000000 -3.000001
v -5.235246 -0.000001 2.999999
v -3.117623 2.430313 0.999999
v -5.235246 2.430312 -0.000001
v -3.117623 2.430313 -1.000000
v -3.117623 1.000000 0.999999
v -3.117623 1.000000 -1.000000
v -3.117623 2.430313 0.499999
v -4.176435 2.430313 -0.500001
v -4.176435 2.430313 0.499999
v -3.117623 2.430313 -0.500001
v -3.647029 2.430313 -0.000001
v -3.285539 2.181708 -0.000001
vn 0.000000 -0.894400 -0.447200
vn -0.105000 -0.889500 0.444700
vn 0.000000 1.000000 0.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 -0.000000 -1.000000
vn -0.229800 -0.973200 -0.000000
vn -0.000000 0.000000 1.000000
vn -0.105000 -0.889500 -0.444700
vn -0.000000 -0.894400 0.447200
vn 0.232100 0.000000 -0.972700
vn 0.232100 -0.000000 0.972700
vn 0.304900 0.851800 0.425900
vn 0.304900 0.851800 -0.425900
vn -0.000000 -1.000000 -0.000000
vn -0.141400 -0.000000 0.989900
vn -0.141400 0.000000 -0.989900
vn -0.063800 0.892600 0.446300
vn -0.063800 0.892600 -0.446300
vn 0.090000 0.944800 -0.314900
vn 0.090000 0.944800 0.314900
vn 0.075500 0.845400 -0.528800
vn 0.075500 0.845400 0.528800
vn 0.559700 0.828700 0.000000
vn -0.000000 -0.573000 0.819600
vn 0.000000 -0.573000 -0.819600
vn 0.360900 0.534400 0.764300
vn 0.360900 0.534400 -0.764300
vn -0.559700 -0.828700 0.000000
vn 0.459300 0.888300 0.000000
vn 0.560500 0.651000 0.511900
vn 0.560500 0.651000 -0.511900
vn -0.485900 -0.706500 -0.514500
vn -0.304900 0.851800 -0.425900
vn -0.304900 0.851800 0.425900
vn 0.141400 0.989900 0.000000
vn -0.000000 0.707100 0.707100
vn 0.000000 0.707100 -0.707100
vn -0.485900 -0.706500 0.514500
usemtl Material
s off
f 23//1 5//1 6//1 24//1
f 26//2 30//2 10//2
f 37//3 17//3 38//3 40//3
f 28//4 14//4 16//4 29//4
f 1//5 27//5 19//5
f 10//6 30//6 27//6 1//6
f 26//7 12//7 18//7 30//7
f 28//7 2//7 20//7
f 6//8 29//8 24//8
f 13//4 27//4 30//4 18//4
f 2//6 28//6 29//6 6//6
f 8//5 24//5 29//5 16//5
f 9//9 25//9 26//9 10//9
f 1//4 19//4 20//4 2//4
f 5//10 7//10 21//10
f 11//11 9//11 22//11
f 25//12 22//12 11//12
f 23//13 7//13 21//13
f 19//5 3//5 22//5
f 4//7 20//7 21//7
f 3//5 19//5 27//5 13//5
f 6//14 5//14 9//14 10//14 1//14
f 19//15 1//15 9//15
f 2//16 20//16 5//16
f 22//14 25//14 19//14
f 21//14 20//14 23//14
f 25//17 11//17 3//17
f 7//18 23//18 4//18
f 24//19 8//19 4//19 23//19
f 26//20 25//20 3//20 12//20
f 22//21 3//21 11//21
f 7//22 4//22 21//22
f 40//14 36//14 31//14 38//14
f 12//3 3//3 13//3 18//3
f 4//3 8//3 16//3 14//3
f 14//14 35//14 34//14 13//14
f 33//14 39//14 40//14 37//14
f 37//14 40//14 38//14 32//14
f 14//5 35//5 4//5
f 34//23 35//23 32//23
f 4//24 32//24 35//24
f 32//25 3//25 34//25
f 33//26 32//26 4//26
f 32//27 15//27 31//27 3//27
f 31//28 36//28 3//28
f 39//28 33//28 4//28
f 4//29 41//29 3//29
f 3//3 4//3 35//3 34//3
f 39//30 41//30 4//30
f 41//31 36//31 3//31
f 39//32 41//32 40//32
f 22//33 9//33 25//33
f 5//34 21//34 23//34
f 19//35 9//35 5//35 20//35
f 19//36 9//36 22//36
f 20//37 21//37 5//37
f 28//7 20//7 4//7 14//7
f 20//6 19//6 13//6 14//6
f 36//38 40//38 41//38

Czy coś robię źle? Prosiłbym jeszcze o adres jakiegoś kursu, w którym inaczej wczytuje się te pliki.
P-132723
RazzorFlame
» 2015-05-26 17:22:45
Nie podałeś problemu.
P-132813
Gabes
» 2015-05-26 21:41:11
W kursie Pana Janusza Ganczarskiego http://cpp0x.pl/kursy​/Kurs-OpenGL-C++/Podstawy/102 jest napisane że w Open GL jest tak zwany lewoskrętny układ współrzędnych, w DX (brak teraz mi źródła) oś można sobie ustawić zależnie od potrzeb.
Ale może wystarczy twój model wczytać do Blendera i obrócić oś współrzędnych przed wyeksportowaniem do formatu .obj.
Co do programu to nie analizowałem.

 
P-132824
RazzorFlame
» 2015-05-28 16:33:04
Nadal nie podałeś problemu.
P-132897
stevy
» 2015-05-29 09:04:58
Nie rozumiem po co operujesz w fejsach na normalach, łatwiej byłoby na vertexach, przynajmniej mi to oszczędza czas i nerwy przy pisaniu shaderów. Ogólnie skoro Twój problem polega na tym, że masz w "drugą" stronę współrzędną np. x (na jedno wychodzi) to mógłbyś zastosować proste przekształcenie, żeby wykonać sobie lustrzane odbicie atrybutu x każdego wierzchołka.

Chyba że chodzi Ci o to, że w blenderze współrzędna Z jest pionowa, przez co Twoje modele są obrócone. W takim wypadku zostaje wczytywanie współrzędnej y zamiast z i odwrotnie.
P-132918
RazzorFlame
» 2015-05-29 22:19:25
@Up, blender ma opcje w której możesz ustawić która oś jest tą pionową.
P-132951
TheReclif
Temat założony przez niniejszego użytkownika
» 2015-06-08 22:12:41
Może ujmę problem inaczej: gra ma wczytać model z .obj z Blendera(niestety, ale tutorial z którego korzystam jest przepełniony kodem i trudno się w nim połapać, dlatego ostatnio nie koduję dużo). Obecna wersja gry niestety nie wczytuje takich modeli. Moje wymogi są raczej normalne:
1. W DirectX 11.
2. Coś w stylu modelClass z metodami load, draw, changePos i takie tam.
3. Można tworzyć w ten sposób WIELE modeli.
4. Ma się poddawać animacji.
Będę wdzięczny za cokolwiek, ale najlepiej będzie, jak ktoś da adres jakiegoś kursu(w tym jakiś Microsoftowski, byle tylko bez DirectX Tool Kit).

P-133356
RazzorFlame
» 2015-06-09 15:41:26

4. Ma się poddawać animacji.
No to na początek .md5, w www.braynzarsoft.net masz tutorial jak wczytać model i tutorial jak wczytać do niego animacje. Potem, jak już ogarniesz dobrze to, to naucz się importować FBX. W ogóle to i tak dobrym sposobem jest konwertowanie na własny typ. Wczytywanie .obj i .md5 trwa dość długo bo są zapisane w ASCII.
P-133375
« 1 » 2 3
  Strona 1 z 3 Następna strona