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

前端 未结 1 1850
眼角桃花
眼角桃花 2021-01-25 13:53

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

相关标签:
1条回答
  • 2021-01-25 14:26

    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;
                    }
    
    0 讨论(0)
提交回复
热议问题