Assimp and D3D model loading: Mesh not being displayed in D3D

限于喜欢 提交于 2019-12-02 09:01:44

问题


I would like to load models into D3D using Assimp. I would like to understand more how Assimp handles indices as I am having trouble getting it to work with obj models in a form i understand. For instance, for an obj model with faces as int/int/int, as I iterate through the number of faces:

for (unsigned int x = 0 ; x < paiMesh->mNumFaces ; ++x) {
    const aiFace& Face = paiMesh->mFaces[x];
    assert(Face.mNumIndices == 3);
    for (unsigned int k = 0; k< nidx;k++)//triangle list
    {
    i1 = Face.mIndices[k];
    Indices.push_back(i1);
    }
}

i notice that my Indices vector seems to only contain numbers in an increasing order, i.e., Indices = [0,1,2,3,4,5,6,7,8...]. This looks nothing like the actual obj file. So, can anyone tell me what Assimp is doing here. It would help me understand where my loading code is going wrong


回答1:


I figured it out. While the above code is correct, I do not correct for the different subsets in a model. Here is my code to load up vertices from Assimp. If you want the full set of classes I use, please leave a note.

                /****************************************************
                **********File name: MeshLoader03.cpp****************
                ******************************************************/

                /*************Includes*****************************/
                #include "stdafx.h"
                #include "MeshLoader03.h"

                /******************Class**************************/
                bool MeshLoader03::LoadModel(const std::string& a_file, float a_scale,
                    std::vector<Vertex::Basic28>& vertices,
                    std::vector<USHORT>& indices,
                    std::vector<MeshGeometry::Subset>& subsets,
                    std::vector<ModelMaterial>& mats)
                {

                    //check if file exists
                    std::ifstream fin(a_file.c_str());
                    if(!fin.fail())
                    {
                        fin.close();
                    }
                    else
                    {
                        MessageBox(NULL,  TEXT("Couldn't open file: ") , TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
                        return false;
                    }

                    //Assign scale
                    m_scale = a_scale;

                    //Assign mesh properties
                    numVertices = 0;
                    numSubsets = 0;
                    numMaterials = 0;
                    numTriangles = 0;

                    //initialize success variable
                    bool Ret = false;

                    //Load mesh
                    Ret = loadMesh(a_file,a_scale, vertices,indices,subsets,mats);

                    //Return
                    return Ret;
                }




                //Load mesh with Assimp
                bool MeshLoader03::loadMesh(const std::string& a_file, float a_scale, 
                    std::vector<Vertex::Basic28>& vertices,
                    std::vector<USHORT>& indices,
                    std::vector<MeshGeometry::Subset>& subsets,
                    std::vector<ModelMaterial>& mats)
                {
                    //Assimp importer we are using
                    Assimp::Importer importer;      
                    const aiScene* loadedScene = importer.ReadFile( a_file,
                        aiProcessPreset_TargetRealtime_Quality |
                        aiProcess_ConvertToLeftHanded   
                        );
                    //we have NO assimp object
                    if(!loadedScene)
                    {
                        OutputDebugString(L"Model failed to load \n");
                        //OutputDebugString( (importer.GetErrorString()).c_str() );
                        return false;
                    }
                    else
                    {   //we have an assimp object with meshes
                        if(loadedScene->HasMeshes())
                        {
                        //Get mesh properties
                        GetMeshProperties(loadedScene);
                        //Extract Faces,Vertices,Subsets,Materials
                        InitMaterials(a_file,loadedScene, numMaterials,  mats);
                        InitSubsetTable(a_file,loadedScene,numSubsets,subsets);
                        InitVertices(a_file,loadedScene, numVertices,  vertices);
                        InitTriangles(a_file,loadedScene, numTriangles,  indices);
                        ScaleAsset(loadedScene);
                        return true;
                        }
                        else //an assimp object with NO meshes
                            return false;
                    }

                }


                //Get mesh properties
                void MeshLoader03::GetMeshProperties(const aiScene* loadedScene)
                {
                    //Get rootNode
                    aiNode* rootNode = loadedScene->mRootNode;

                    //Attributes
                    numSubsets = loadedScene->mNumMeshes;
                    numMaterials = loadedScene->mNumMaterials;

                    //If only one node
                    if(rootNode->mNumChildren == 0)
                    {
                        numVertices = loadedScene->mMeshes[0]->mNumVertices;
                        numTriangles = loadedScene->mMeshes[0]->mNumFaces;
                    }
                    else
                    {
                        //For all the children
                        for (size_t i =0 ;i<rootNode->mNumChildren; ++i)
                        {

                            //Get child node
                            aiNode* childNode = rootNode->mChildren[i];

                            // Initialize the meshes in the scene one by one
                            for (size_t n=0; n < childNode->mNumMeshes; ++n)
                            {
                                //get the mesh
                                const aiMesh* paiMesh = loadedScene->mMeshes[childNode->mMeshes[n]];

                                //Update total vertices and faces
                                numVertices+= paiMesh->mNumVertices;
                                numTriangles+= paiMesh->mNumFaces;
                            }
                        }
                    }

                }




                //Extract subsets
                void MeshLoader03::InitSubsetTable(const std::string& a_file,const aiScene* pScene, UINT numSubsets, std::vector<MeshGeometry::Subset>& subsets)
                {
                    subsets.resize(numSubsets);

                    //Get rootNode
                    aiNode* rootNode = pScene->mRootNode;


                    //Counter for vertices and indices
                    unsigned int vertexCounter, faceCounter;

                    //If only one node
                    if(rootNode->mNumChildren == 0)
                    {
                        subsets[0].Id = pScene->mMeshes[0]->mMaterialIndex;
                        subsets[0].VertexStart = 0;
                        subsets[0].VertexCount = pScene->mMeshes[0]->mNumVertices;
                        subsets[0].FaceStart = 0;
                        subsets[0].FaceCount = pScene->mMeshes[0]->mNumFaces;
                    }
                    else
                    {
                        //Counter
                        unsigned int subsetCounter = 0;
                        vertexCounter = 0; faceCounter = 0;
                        //For all the children
                        for (size_t i =0 ;i<rootNode->mNumChildren; ++i)
                        {

                            //Get child node
                            aiNode* childNode = rootNode->mChildren[i];

                            // Initialize the meshes in the scene one by one
                            for (size_t n=0; n < childNode->mNumMeshes; ++n)
                            {
                                //get the mesh
                                const aiMesh* paiMesh = pScene->mMeshes[childNode->mMeshes[n]];

                                subsets[subsetCounter].Id = pScene->mMeshes[childNode->mMeshes[n]]->mMaterialIndex;
                                subsets[subsetCounter].VertexStart = vertexCounter;
                                subsets[subsetCounter].VertexCount = paiMesh->mNumVertices;
                                subsets[subsetCounter].FaceStart = faceCounter;
                                subsets[subsetCounter].FaceCount = paiMesh->mNumFaces;
                                //Update total vertices and faces
                                vertexCounter+= paiMesh->mNumVertices;
                                faceCounter+= paiMesh->mNumFaces;
                                //Update counter
                                subsetCounter++;
                            }
                        }
                    }


                }



                //Extract Vertices
                void MeshLoader03::InitVertices(const std::string& a_file,const aiScene* pScene, UINT numVertices, std::vector<Vertex::Basic28>& vertices)
                {
                    vertices.resize(numVertices);
                    //Get rootNode
                    aiNode* rootNode = pScene->mRootNode;


                    //Counter for vertices and indices
                    unsigned int vertexCounter;

                    //If only one node
                    if(rootNode->mNumChildren == 0)
                    {
                        const aiMesh* mesh = pScene->mMeshes[0];
                        for(size_t b = 0;b<mesh->mNumVertices;b++)
                        {
                            vertices[b].Pos.x = mesh->mVertices[b].x;
                            vertices[b].Pos.y = mesh->mVertices[b].y;
                            vertices[b].Pos.z = mesh->mVertices[b].z;

                            if(mesh->HasVertexColors(0))
                            {
                                const aiColor4D pColr = mesh->mColors[0][b];
                                vertices[b].Color.x = pColr.r;
                                vertices[b].Color.y = pColr.g;
                                vertices[b].Color.z = pColr.b;
                                vertices[b].Color.w = pColr.a;
                            }
                            else
                                vertices[b].Color = XMFLOAT4(1.0f,1.0f,0.0f,0.0f);
                        }

                    }
                    else
                    {
                        //Counter
                        vertexCounter = 0; 

                        //For all the children
                        for (size_t i =0 ;i<rootNode->mNumChildren; ++i)
                        {

                            //Get child node
                            aiNode* childNode = rootNode->mChildren[i];

                            // Initialize the meshes in the scene one by one
                            for (size_t n=0; n < childNode->mNumMeshes; ++n)
                            {
                                //get the mesh
                                const aiMesh* paiMesh = pScene->mMeshes[childNode->mMeshes[n]];

                                for(size_t b = 0;b<paiMesh->mNumVertices;b++)
                                {
                                    vertices[vertexCounter].Pos.x = paiMesh->mVertices[b].x;
                                    vertices[vertexCounter].Pos.y = paiMesh->mVertices[b].y;
                                    vertices[vertexCounter].Pos.z = paiMesh->mVertices[b].z;

                                    if(paiMesh->HasVertexColors(0))
                                    {
                                        const aiColor4D pColr = paiMesh->mColors[0][i];
                                        vertices[vertexCounter].Color.x = pColr.r;
                                        vertices[vertexCounter].Color.y = pColr.g;
                                        vertices[vertexCounter].Color.z = pColr.b;
                                        vertices[vertexCounter].Color.w = pColr.a;
                                    }
                                    else
                                        vertices[vertexCounter].Color = XMFLOAT4(1.0f,1.0f,0.0f,0.0f);

                                    vertexCounter++;
                                }
                            }
                        }
                    }


                }

                //Extract Triangles
                void MeshLoader03::InitTriangles(const std::string& a_file,const aiScene* pScene, UINT numTriangles, std::vector<USHORT>& indices)
                {
                    //indices.resize(numTriangles*3);

                    //Get rootNode
                    aiNode* rootNode = pScene->mRootNode;


                    //Counter for vertices and indices
                    unsigned int indexCounter, indexStart;
                    indexCounter = 0;
                    indexStart = indexCounter;
                    //If only one node
                    if(rootNode->mNumChildren == 0)
                    {
                        const aiMesh* mesh = pScene->mMeshes[0];
                        for(size_t b = 0;b<mesh->mNumFaces;b++)
                        {
                            indices[indexCounter++] = mesh->mFaces[b].mIndices[0] + indexStart;
                            indices[indexCounter++] = mesh->mFaces[b].mIndices[1] + indexStart;
                            indices[indexCounter++] = mesh->mFaces[b].mIndices[2] + indexStart;
                        }

                    }
                    else
                    {
                        //Counter
                        indexStart = 0; 
                        indexCounter = 0;

                        //For all the children
                        for (size_t i =0 ;i<rootNode->mNumChildren; ++i)
                        {

                            //Get child node
                            aiNode* childNode = rootNode->mChildren[i];

                            // Initialize the meshes in the scene one by one
                            for (size_t n=0; n < childNode->mNumMeshes; ++n)
                            {
                                //get the mesh
                                const aiMesh* mesh = pScene->mMeshes[childNode->mMeshes[n]];

                                for(size_t b = 0;b<mesh->mNumFaces;b++)
                                {
                                    //indices[indexCounter++] = mesh->mFaces[b].mIndices[0] + indexStart;
                                    //indices[indexCounter++] = mesh->mFaces[b].mIndices[1] + indexStart;
                                    //indices[indexCounter++] = mesh->mFaces[b].mIndices[2] + indexStart;

                                    indices.push_back(mesh->mFaces[b].mIndices[0] + indexStart);
                                    indices.push_back(mesh->mFaces[b].mIndices[1] + indexStart);
                                    indices.push_back(mesh->mFaces[b].mIndices[2] + indexStart);
                                }
                                indexStart += mesh->mNumVertices;
                            }
                        }
                    }


                }

                /*********************Conversion functions**********************************/
                //AiVector3 to XMFLOAT3
                XMFLOAT3 MeshLoader03::aiVec3ToXMFloat3(const aiVector3D* vector)
                {
                    //Ooutput
                    XMFLOAT3 output;

                    //Assignmetns
                    output.x = vector->x;
                    output.y = vector->y;
                    output.z = vector->z;

                    //Send back result
                    return output;
                }

                //AiColor to XMFLOAT4
                    XMFLOAT4 MeshLoader03::aiColorToXMFLOAT4(const aiColor4D* color)
                    {
                    //Ooutput
                    XMFLOAT4 output;

                    //Assignmetns
                    output.x = color->r;
                    output.y = color->g;
                    output.z = color->b;
                    output.w = color->a;

                    //Send back result
                    return output;

                    }

                //AiMatrix to XMFLOAT4X4
                XMFLOAT4X4 MeshLoader03::aiMatrixToXMFloat4x4(const aiMatrix4x4* aiMe)
                {
                    XMFLOAT4X4 output;
                    output._11 = aiMe->a1;
                    output._12 = aiMe->a2;
                    output._13 = aiMe->a3;
                    output._14 = aiMe->a4;

                    output._21 = aiMe->b1;
                    output._22 = aiMe->b2;
                    output._23 = aiMe->b3;
                    output._24 = aiMe->b4;

                    output._31 = aiMe->c1;
                    output._32 = aiMe->c2;
                    output._33 = aiMe->c3;
                    output._34 = aiMe->c4;

                    output._41 = aiMe->d1;
                    output._42 = aiMe->d2;
                    output._43 = aiMe->d3;
                    output._44 = aiMe->d4;

                    return output;
                }



                /****************Scaling Functions: Taken from Assimp**********************/
                //-------------------------------------------------------------------------------
                // Calculate the boundaries of a given node and all of its children
                // The boundaries are in Worldspace (AABB)
                // piNode Input node
                // p_avOut Receives the min/max boundaries. Must point to 2 vec3s
                // piMatrix Transformation matrix of the graph at this position
                //-------------------------------------------------------------------------------
                int MeshLoader03::CalculateBounds(aiNode* piNode, aiVector3D* p_avOut, 
                    const aiMatrix4x4& piMatrix, const aiScene* pcScene)
                {
                    assert(NULL != piNode);
                    assert(NULL != p_avOut);

                    aiMatrix4x4 mTemp = piNode->mTransformation;
                    mTemp.Transpose();
                    const aiMatrix4x4 aiMe = mTemp * piMatrix;

                    for (unsigned int i = 0; i < piNode->mNumMeshes;++i)
                    {
                        for( unsigned int a = 0; a < pcScene->mMeshes[piNode->mMeshes[i]]->mNumVertices;++a)
                        {

                            const aiVector3D pc = pcScene->mMeshes[piNode->mMeshes[i]]->mVertices[a];
                            XMFLOAT3 pc11 = aiVec3ToXMFloat3(&pc);
                            XMFLOAT4X4 aiMe1 = aiMatrixToXMFloat4x4(&aiMe);

                            XMVECTOR pc1 = XMVector3TransformCoord(XMLoadFloat3(&pc11),XMLoadFloat4x4(&aiMe1));

                            p_avOut[0].x = min( p_avOut[0].x, pc1.m128_f32[0]);
                            p_avOut[0].y = min( p_avOut[0].y, pc1.m128_f32[1]);
                            p_avOut[0].z = min( p_avOut[0].z, pc1.m128_f32[2]);
                            p_avOut[1].x = max( p_avOut[1].x, pc1.m128_f32[0]);
                            p_avOut[1].y = max( p_avOut[1].y, pc1.m128_f32[1]);
                            p_avOut[1].z = max( p_avOut[1].z, pc1.m128_f32[2]);
                        }
                    }
                    for (unsigned int i = 0; i < piNode->mNumChildren;++i)
                    {
                        CalculateBounds( piNode->mChildren[i], p_avOut, aiMe, pcScene);
                    }
                    return 1;
                }


                //-------------------------------------------------------------------------------
                // Scale the asset that it fits perfectly into the viewer window
                // The function calculates the boundaries of the mesh and modifies the
                // global world transformation matrix according to the aset AABB
                //-------------------------------------------------------------------------------
                int MeshLoader03::ScaleAsset(const aiScene* pcScene)
                {
                    aiVector3D aiVecs[2] = {
                        aiVector3D( 1e10f, 1e10f, 1e10f),
                        aiVector3D( -1e10f, -1e10f, -1e10f) };

                    if (pcScene->mRootNode)
                    {
                        aiMatrix4x4 m;
                        CalculateBounds(pcScene->mRootNode,aiVecs,m, pcScene);
                    }

                    aiVector3D vDelta = aiVecs[1] -  aiVecs[0];
                    aiVector3D vHalf =  aiVecs[0] + (vDelta / 2.0f);
                    float fScale = 10.0f / vDelta.Length();

                    aiMatrix4x4 g_mWorld =  aiMatrix4x4(
                                            1.0f,0.0f,0.0f,0.0f,
                                            0.0f,1.0f,0.0f,0.0f,
                                            0.0f,0.0f,1.0f,0.0f,
                                            -vHalf.x,-vHalf.y,-vHalf.z,1.0f) *
                        aiMatrix4x4(
                                    fScale*m_scale,0.0f,0.0f,0.0f,
                                    0.0f,fScale*m_scale,0.0f,0.0f,
                                    0.0f,0.0f,fScale*m_scale,0.0f,
                                    0.0f,0.0f,0.0f,1.0f);

                    m_World = aiMatrixToXMFloat4x4(&g_mWorld);
                    return 1;
                }


来源:https://stackoverflow.com/questions/15820973/assimp-and-d3d-model-loading-mesh-not-being-displayed-in-d3d

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!