Search code examples
c++access-violationassimp

Assimp access violation on existing aiVector3D


I'm using the following code to load in an .obj file using Assimp. Something goes wrong at the TextureCoordinates. The aiVector3D I try to access exists, but as soon as I store the values in a temp variable, it crashes my application.

Here's the code I use:

    Assimp::Importer importer;

    const aiScene* scene = importer.ReadFile(filename,
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType);

    if (!scene)
    {
        printf("[ASSIMP] ");
        printf(importer.GetErrorString());
        printf("\n");
        return nullptr;
    }

    Mesh* newMesh = new Mesh();
    unsigned int vertexCount            = scene->mMeshes[0]->mNumVertices;
    unsigned int triangleCount          = scene->mMeshes[0]->mNumFaces;
    bool hasUv                          = scene->mMeshes[0]->HasTextureCoords(0);
    newMesh->vertexCount                = vertexCount;
    newMesh->triangleCount              = triangleCount;
    newMesh->m_Vertices                 = new Vertex[vertexCount];
    newMesh->m_Triangles                = new Triangle[triangleCount];

    for (unsigned int i = 0; i < vertexCount; i++) {
        aiVector3D vertexPosition       = scene->mMeshes[0]->mVertices[i];
        aiVector3D vertexNormal         = scene->mMeshes[0]->mNormals[i];
        newMesh->m_Vertices[i].pos      = glm::vec3(vertexPosition.x, vertexPosition.y, vertexPosition.z);
        newMesh->m_Vertices[i].normal   = glm::vec3(vertexNormal.x, vertexNormal.y, vertexNormal.z);
        if (hasUv) {
            aiVector3D uvCoordinates    = scene->mMeshes[0]->mTextureCoords[i][0];
            printf("uvCoordinates: %f %f %f\n", uvCoordinates.x, uvCoordinates.y, uvCoordinates.z);
            newMesh->m_Vertices[i].u    = uvCoordinates.x;
            newMesh->m_Vertices[i].v    = uvCoordinates.y;
        }
    }

    for (unsigned int i = 0; i < triangleCount; i++) {
        aiFace face                     = scene->mMeshes[0]->mFaces[i];
        for (int j = 0; j < 3; j++) {
            Triangle* tri               = &newMesh->m_Triangles[i];
            tri->vertex[j]              = &newMesh->m_Vertices[face.mIndices[j]];
            if (tri->vertex[0]->normal.y == 1.0f || tri->vertex[0]->normal.y == -1.0f) {
                tri->color              = glm::vec3(0.2f, 0.2f, 0.2f);
            }
            else
            {
                tri->color              = glm::vec3(1.0f, 0.0f, 0.0f);
            }
        }
    }

It crashes at the line printf("uvCoordinates: %f %f %f\n", uvCoordinates.x, uvCoordinates.y, uvCoordinates.z);, but if I remove this line, it crashes at newMesh->m_Vertices[i].u = uvCoordinates.x;. If I comment out the printf(), set both the u and v of the vertex to 0.0f and not use uvCoordinates at all, it still crashes on the newMesh->m_Vertices[i].u = uvCoordinates.x; line. If I leave the printf() uncommented, it prints the values of the uvCoordinates, but throws an access violation after.

I'm honestly out of ideas here. Here's a screenshot showing what I explained.


Solution

  • scene->mMeshes[0]->mTextureCoords[i][0]; is first texture coordinates for set i. What you wanted is to get first set of texture coordinates - so it should be scene->mMeshes[0]->mTextureCoords[0][i];