0
\$\begingroup\$

Currently, i am implementing the model loading feature for my game engine using Assimp. But i got an access violation error when loading my FBX model. The problem is that although the mNumVertices is around 100629 vertices, I got this error at i = 50314 in the for loop.

This is my code for loading the mesh.

   #include"Mesh.h"
   #include <assimp/scene.h>
   #include <assimp/postprocess.h>
   #include <assimp/Importer.hpp>
   #include <assimp/DefaultLogger.hpp>
   #include <assimp/LogStream.hpp>
   #include"Core/Log/Logger.h"
   #include"Renderer/Renderer.h"

  namespace {
    const unsigned int ImportFlags =
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_SortByPType |
        aiProcess_PreTransformVertices |
        aiProcess_GenNormals |
        aiProcess_GenUVCoords |
        aiProcess_OptimizeMeshes |
        aiProcess_Debone |
        aiProcess_ValidateDataStructure
    ;
}

struct LogStream : public Assimp::LogStream {
    static void Initialize()
    {
        if (Assimp::DefaultLogger::isNullLogger())
        {
            Assimp::DefaultLogger::create("", Assimp::Logger::VERBOSE);
            Assimp::DefaultLogger::get()->attachStream(new LogStream, Assimp::Logger::Err | Assimp::Logger::Warn);
        }
    }

    void write(const char* message) override
    {
        LIGHT_LOG_ERROR("Assimp error: {0}", message);
    }
};

Mesh::Mesh(const std::string& filePath) : mFilePath(filePath) {
    LogStream::Initialize();

    LIGHT_LOG_INFO("Loading mesh: {0}", filePath.c_str());

    Assimp::Importer importer;
    
    const aiScene* scene = importer.ReadFile(filePath, ImportFlags);
    if (!scene || !scene->HasMeshes()) {
        LIGHT_LOG_ERROR("Failed to load mesh at file path {0}", filePath);
    }

    aiMesh* mesh = scene->mMeshes[0];
    scene->mNumMeshes;
    LIGHT_ASSERT(mesh->HasPositions(), "Meshes require positions.");
    LIGHT_ASSERT(mesh->HasNormals(), "Meshes require normals.");

    mVertices.reserve(mesh->mNumVertices);

    for (size_t i = 0; i < mVertices.capacity(); i++)  {
        Vertex vertex;
        vertex.Position = { mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z };
        vertex.Normal = { mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z };

        if (mesh->HasTangentsAndBitangents()) {
            vertex.Tangent = { mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z };
            vertex.Bitangent = { mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z };
        }

        if (mesh->HasTextureCoords(0)) {
            vertex.TextureCoords = { mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y };
        }
        
        mVertices.push_back(vertex);
    }

    mVertexBuffer.reset(VertexBuffer::Create());
    mVertexBuffer->SetData(mVertices.data(), mVertices.size() * sizeof(Vertex));

    // Extract indices from model
    mFaces.reserve(mesh->mNumFaces);
    for (size_t i = 0; i < mFaces.capacity(); i++)
    {
        LIGHT_ASSERT(mesh->mFaces[i].mNumIndices == 3, "Each face must have 3 indices.");
        mFaces.push_back({ mesh->mFaces[i].mIndices[0], mesh->mFaces[i].mIndices[1], mesh->mFaces[i].mIndices[2] });
    }

    mIndexBuffer.reset(IndexBuffer::Create());
    mIndexBuffer->SetData(mFaces.data(), mFaces.size() * sizeof(MeshFace));
}

I also tried with other models too, but got the same error. I noticed that it always throws this error when the index i is roughly half of the mesh->mNumVertices.

  • My model is totally fine, there is no problem with it.

  • I use Assimp version v.5.25 and build it as a static library.

  • The vertex position is also loaded with weird numbers.

  • I also run a break point in the Assimp to see if model is loaded correctly and it did. But one strange thing here is that the scene pointer seems to be destroyed when returned from the ReadFile() function.

    const aiScene* scene = importer.ReadFile(filePath, ImportFlags);
    
  • I link this assimp-vc143-mtd.lib file after building the Assimp to my engine.

So, can you guys help me fix it? Does it have something to do with the memory allocation?

\$\endgroup\$
0

1 Answer 1

0
\$\begingroup\$

It looks like you're using capacity() instead of mesh->mNumVertices in your loop condition. Note that reserve() can make the capacity of the vector bigger than the capacity that you requested.

Given that it looks like you're iterating over a vector of pointers, that will probably be the cause of the crash because you'll be dereferencing uninitialized ones when you iterate out of bounds.

On top of that your loop condition is checking against the capacity of mVertices, instead of the size of mesh->mVertices.

Try something like this for your loop:

for (size_t i = 0; i < mesh->mNumVertices; i++)  {
    Vertex vertex;
    vertex.Position = { mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z };
    vertex.Normal = { mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z };

    if (mesh->HasTangentsAndBitangents()) {
        vertex.Tangent = { mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z };
        vertex.Bitangent = { mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z };
    }

    if (mesh->HasTextureCoords(0)) {
        vertex.TextureCoords = { mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y };
    }
    
    mVertices.push_back(vertex);
}
\$\endgroup\$
3
  • \$\begingroup\$ No, we can't use a range based for loop like that, because mesh->mVertices is just a pointer without any begin() function implemented. \$\endgroup\$ Sep 4 at 3:28
  • \$\begingroup\$ I use mVertices.capacity() because i already reservered mVertices with the mesh->mNumVertices, so i think it's fine \$\endgroup\$ Sep 4 at 3:53
  • 1
    \$\begingroup\$ Using capacity() is not ok here. You should be using mesh->mNumVertices instead. Check out the documentation at en.cppreference.com/w/cpp/container/vector/reserve and you'll see that calling reserve(100) can actually give you a capacity that's more than 100. \$\endgroup\$
    – Adam
    Sep 6 at 21:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .