0
\$\begingroup\$

I am a newbie trying to learn DX11.

I successfully put my obj model into the program by using assimp.

Unfortunately, I cannot load the same model in fbx format correctly (both of them were exported from my 3DS Max 2014).

OBJ:

Screenshot of 3D model FBX:

Screenshot of 3D model - all parts overlapping near the origin

It seems like that all the meshes in the file have been moved to (0, 0, 0) instead of their correct offset positions, and the rotations of these objects are also incorrect.

Here is the code I use:

bool Model::LoadModel(const std::string& filePath)
{
    Assimp::Importer importer;

    const aiScene* pScene = importer.ReadFile(filePath, aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_ConvertToLeftHanded);
    //aiProcess_CalcTangentSpace | aiProcess_JoinIdenticalVertices |iProcess_SortByPType | aiProcess_Triangulate | aiProcess_ConvertToLeftHanded);
    if (pScene == nullptr)
        return false;

    ProcessNode(pScene->mRootNode, pScene);
    return true;
}

void Model::ProcessNode(aiNode* node, const aiScene* scene)
{
    for (UINT i = 0; i < node->mNumMeshes; i++) {
        aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
        meshes.push_back(this->ProcessMesh(mesh, scene));
    }
    for (UINT i = 0; i < node->mNumChildren; i++) {
        ProcessNode(node->mChildren[i], scene);
    }
}

Mesh Model::ProcessMesh(aiMesh* mesh, const aiScene* scene)
{
    //Data to fill
    std::vector<Vertex>vertices;
    std::vector<DWORD>indices;

    for (UINT i = 0; i < mesh->mNumVertices; i++) {
        Vertex vertex;
        vertex.pos.x = mesh->mVertices[i].x;
        vertex.pos.y = mesh->mVertices[i].y;
        vertex.pos.z = mesh->mVertices[i].z;

        if (mesh->mTextureCoords[0]) {
            vertex.texCoord.x = (float)mesh->mTextureCoords[0][i].x;
            vertex.texCoord.y = (float)mesh->mTextureCoords[0][i].y;
        }
        vertices.push_back(vertex);
    }

    for (UINT i = 0; i < mesh->mNumFaces; i++) {
        aiFace face = mesh->mFaces[i];

        for (UINT j = 0; j < face.mNumIndices; j++)
            indices.push_back(face.mIndices[j]);
    }

    return Mesh(device, deviceContext, vertices, indices);
}
\$\endgroup\$
5
  • 1
    \$\begingroup\$ If you add aiProcess_PreTransformVertices to your post processing flags, do you observe a difference? (I don't recommend this as a solution, but it might help identify the cause) \$\endgroup\$
    – DMGregory
    Jul 23 '21 at 15:28
  • \$\begingroup\$ yes!!!!!!!!!!!!!!!!!!!!!it works!!!!!like a magic!!!!!! \$\endgroup\$ Jul 23 '21 at 16:09
  • \$\begingroup\$ Okay, this isn't a fix exactly. This tells you the problem. Your FBX file has multiple separate mesh objects in it, each one positioned and rotated in a particular way to make your scene. By default, Assimp is importing each of these objects as a separate node in your scene graph, with its own position and rotation information. If they're all getting drawn at (0, 0, 0) with the wrong rotations, then that means your rendering code is ignoring the position and rotation of these scene graph nodes. That's the bug you probably want to fix. \$\endgroup\$
    – DMGregory
    Jul 23 '21 at 16:21
  • \$\begingroup\$ Thank you so much!!!! I will probably learn and fix it later(it seems like something about hierarchy transformation matrix?),but I am using static mesh so I do not need to have skeleton or animation right now.And how to "confirm/accept" your answer? \$\endgroup\$ Jul 23 '21 at 16:35
  • \$\begingroup\$ Post an answer in the box at the bottom of this page, showing how you changed your code to fix the issue to your satisfaction. You'll be able to click the checkmark button to accept your own answer after about a day's delay - in case other folks want to submit their own suggested answers in that time. \$\endgroup\$
    – DMGregory
    Jul 23 '21 at 16:37
0
\$\begingroup\$

Thank DMGregory for the magic of aiProcess_PreTransformVertices!!!!!!!

bool Model::LoadModel(const std::string& filePath)
{
    Assimp::Importer importer;

    const aiScene* pScene = importer.ReadFile(filePath, aiProcess_Triangulate | aiProcess_JoinIdenticalVertices |
        aiProcess_ConvertToLeftHanded | aiProcess_PreTransformVertices);

    if (pScene == nullptr)
        return false;

    ProcessNode(pScene->mRootNode, pScene);
    return true;
}

void Model::ProcessNode(aiNode* node, const aiScene* scene)
{
    for (UINT i = 0; i < node->mNumMeshes; i++) {
        aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
        meshes.push_back(this->ProcessMesh(mesh, scene));
    }
    for (UINT i = 0; i < node->mNumChildren; i++) {
        ProcessNode(node->mChildren[i], scene);
    }
}

Mesh Model::ProcessMesh(aiMesh* mesh, const aiScene* scene)
{
    //Data to fill
    std::vector<Vertex>vertices;
    std::vector<DWORD>indices;

    for (UINT i = 0; i < mesh->mNumVertices; i++) {
        Vertex vertex;
        vertex.pos.x = mesh->mVertices[i].x / 2;
        vertex.pos.y = mesh->mVertices[i].y / 2;
        vertex.pos.z = mesh->mVertices[i].z / 2;//  ÷2 to make model smaller

        if (mesh->mTextureCoords[0]) {
            vertex.texCoord.x = (float)mesh->mTextureCoords[0][i].x;
            vertex.texCoord.y = (float)mesh->mTextureCoords[0][i].y;
        }
        vertices.push_back(vertex);
    }

    for (UINT i = 0; i < mesh->mNumFaces; i++) {
        aiFace face = mesh->mFaces[i];

        for (UINT j = 0; j < face.mNumIndices; j++)
            indices.push_back(face.mIndices[j]);
    }

    return Mesh(device, deviceContext, vertices, indices);

}
\$\endgroup\$
1
  • \$\begingroup\$ Don't forget to mark this answer as "Accepted" by clicking on the checkmark icon, if this solved your problem. \$\endgroup\$
    – DMGregory
    Aug 22 '21 at 21:52

You must log in to answer this question.

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