0

当我尝试查看 Assimp 支持的 3D 文件(.3ds .dae 等)时,它们无法正确显示。例如,“Jeep1.3ds”向我展示了一半的车身。信息,网格和法线的所有节点都正确获得,并且顶点和面的数量是正确的(我认为)。纹理不符合正确的坐标,我猜会与上面有关......在图片中你可以“欣赏”我的结果并纠正。感谢您的任何帮助或意见。

在此处输入图像描述

食人魔代码

Ogre::SceneNode *OgreAPP::makeMesh(Ogre::String meshFile,Ogre::String entityName,Ogre::String meshName)
{
    Ogre::MeshPtr Mesh = Ogre::MeshManager::getSingleton().createManual(meshName,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    Ogre::SubMesh *subMesh = Mesh->createSubMesh("subMesh");
    Ogre::VertexDeclaration *vertexDeclaration;
    Ogre::HardwareVertexBufferSharedPtr  vertexBuffer;
    Ogre::HardwareIndexBufferSharedPtr   indexBuffer;
    size_t offset=0;

   // Get file name and extension from the Ogre Resource Manager  
    Ogre::FileInfoListPtr fileInfoListPtr(Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,meshFile,false));
    Ogre::FileInfoList *fileInfoList = fileInfoListPtr.getPointer();
    Ogre::FileInfo &fileInfo = fileInfoList->front();
    stringBuffer << fileInfo.archive->getName().c_str() << meshFile;

   // **************   From Assimp code   ***************************
    ModelManager::loadModel(stringBuffer.str());
    ModelManager::processData();
    std::vector<float>    *vData   = ModelManager::getVertexData();
    std::vector<uint16_t> *iData   = ModelManager::getIndexData();
  // ******************************************************************** 

    Mesh->sharedVertexData = new Ogre::VertexData;

   // Organizo la memoria de video
    vertexDeclaration = Mesh->sharedVertexData->vertexDeclaration;
    vertexDeclaration->addElement(0,offset,Ogre::VET_FLOAT3,Ogre::VES_POSITION);
    offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

    vertexDeclaration->addElement(0,offset,Ogre::VET_FLOAT3,Ogre::VES_NORMAL);
    offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

    vertexDeclaration->addElement(0,offset,Ogre::VET_FLOAT2,Ogre::VES_TEXTURE_COORDINATES);
    offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

    // Make vertex buffer 
    vertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDeclaration->getVertexSize(0),
                                                                                  vData->size()/8,
                                                                                  Ogre::HardwareBuffer::HBU_STATIC);

    // Write the vertex buffer with the target data of vData->data() located in assimp code
    vertexBuffer.getPointer()->writeData(0,vertexBuffer.getPointer()->getSizeInBytes(),vData->data());

    // Make index buffer
    indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT,
                                                                                iData->size(),
                                                                                Ogre::HardwareBuffer::HBU_STATIC);

    indexBuffer.getPointer()->writeData(0,indexBuffer.getPointer()->getSizeInBytes(),iData->data());

    Mesh->sharedVertexData->vertexBufferBinding->setBinding(0,vertexBuffer);
    Mesh->sharedVertexData->vertexCount = vertexBuffer.getPointer()->getNumVertices();
    Mesh->sharedVertexData->vertexStart = 0;

    subMesh->useSharedVertices = true;
    subMesh->indexData->indexBuffer = indexBuffer;
    subMesh->indexData->indexCount = indexBuffer.getPointer()->getNumIndexes();
    subMesh->indexData->indexStart = 0;

    // I don't get real AABB from object, this is ok for probe 
    Mesh->_setBounds(Ogre::AxisAlignedBox(-100,-100,-100,100,100,100));
    Mesh->load();

    stringBuffer.str("");
    stringBuffer << entityName << "_n";
    oSceneManager->createEntity(entityName,meshName);
    oSceneManager->getEntity(entityName)->setMaterialName("material/textura");
    oSceneManager->getRootSceneNode()->createChildSceneNode(stringBuffer.str().c_str())->attachObject(oSceneManager->getEntity(entityName));
    oSceneManager->getSceneNode(stringBuffer.str().c_str())->setPosition(0,0,0);

    std::cout << "total de vertices: " << vData->size()/8 << "\n";
    std::cout << "total de faces: " <<indexBuffer.getPointer()->getNumIndexes()/3 << "\n";
    return oSceneManager->getSceneNode(stringBuffer.str().c_str());
}

Assimp .CPP

   bool ModelManager::loadModel(std::string &file)
    {
        modelScene = importer.ReadFile(file,aiProcess_Triangulate |
                                            aiProcess_GenNormals  |
                                            aiProcess_GenUVCoords);

        if (!modelScene)
        {
            MessageBoxA(NULL,importer.GetErrorString(),"Error: La concha de la lora",MB_ICONERROR);
            return false;
        }

        return true;
    }


    bool ModelManager::assimpGetMeshData(const aiMesh *mesh)
    {
        aiFace *face;

        for (unsigned int v=0;v<mesh->mNumVertices;v++)
         {
            vertexBuff.push_back(mesh->mVertices[v].x);
            vertexBuff.push_back(mesh->mVertices[v].y);
            vertexBuff.push_back(mesh->mVertices[v].z);
            vertexBuff.push_back(mesh->mNormals[v].x);
            vertexBuff.push_back(mesh->mNormals[v].y);
            vertexBuff.push_back(mesh->mNormals[v].z);
            vertexBuff.push_back(mesh->mTextureCoords[0][v].x);
            vertexBuff.push_back(mesh->mTextureCoords[0][v].y);
         }

        for (unsigned int f=0;f<mesh->mNumFaces;f++)
         {
            face = &mesh->mFaces[f];
            indexBuff.push_back(face->mIndices[0]);
            indexBuff.push_back(face->mIndices[1]);
            indexBuff.push_back(face->mIndices[2]);
         }

        return true;
    }
    bool ModelManager::processData()
    {
        bool repeat=true;

        nodeBuff.push_back(modelScene->mRootNode);


       /* if (modelScene->mNumMeshes > 0)
        {
            for (unsigned int m=0;m<modelScene->mNumMeshes;m++)
                this->assimpGetMeshData(modelScene->mMeshes[m]);
        }*/

        // I raise all nodes tree to the root level 
        while (repeat)
        { 
            for (unsigned int a=0;a<nodeBuff.size();a++)
            {
                modelNode = nodeBuff.at(a);
                if (modelNode->mNumChildren > 0)
                    for (unsigned int c=0;c<modelNode->mNumChildren;c++)
                           nodeBuff.push_back(modelNode->mChildren[c]);
                else repeat=false;
            }
        }

        // Get node information from the root level (all nodes)
        for (unsigned int a=0;a<nodeBuff.size();a++)
        {
            modelNode = nodeBuff.at(a);

            if (modelNode->mNumMeshes>0)
                for (unsigned int b=0;b<modelNode->mNumMeshes;b++)
                    assimpGetMeshData(modelScene->mMeshes[modelNode->mMeshes]);
        }
        return true;
    }

    std::vector<float> *ModelManager::getVertexData()
    {
        return &vertexBuff;
    }

    std::vector<uint16_t> *ModelManager::getIndexData()
    {
        return &indexBuff;
    }

假设.H

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <assimp/matrix4x4.h>
#include <assimp/cimport.h>

#include <Windows.h>
#include <iostream>
#include <stdint.h>
#include <vector>

class ModelManager
{
public:
    ModelManager();
    bool loadModel(std::string &);
    bool processData();
    std::vector<float> *getVertexData();
    std::vector<uint16_t> *getIndexData();
private:
    bool assimpGetMeshData(const aiMesh *);
private:
    Assimp::Importer            importer;
    const aiScene               *modelScene;
    const aiNode                *modelNode;
    const aiMesh                *modelMesh;
    const aiFace                *modelFace;
    std::vector<float>          vertexBuff;
    std::vector<uint16_t>       indexBuff;

    std::vector<const aiNode*>  nodeBuff;
    unsigned int                numNodeBuff;
};
4

1 回答 1

0

好的...错误,因为他们花费了大部分时间,实际上是一些小而基本但复杂的背景。“简单地”切换坐标系,当我导入文件时,必须指定 Assimp 标志“aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs”或“aiProcess_ConvertToLeftHanded”。除此之外,我错过了一些转换矩阵(他们没有考虑过),为此我使用了标志“aiProcess_PreTransformVertices”。显然一切正常...

新代码

    bool ModelManager::loadModel(std::string &file)
    {
        modelScene = importer.ReadFile(file,aiProcess_MakeLeftHanded|aiProcess_FlipWindingOrder|aiProcess_FlipUVs|aiProcess_PreTransformVertices|
                                       aiProcess_CalcTangentSpace|
                                       aiProcess_GenSmoothNormals|
                                       aiProcess_Triangulate|
                                       aiProcess_FixInfacingNormals|
                                       aiProcess_FindInvalidData |
                                       aiProcess_ValidateDataStructure | 0
                                       );

        if (!modelScene)
        {
            MessageBoxA(NULL,importer.GetErrorString(),"Error: La concha de la lora...",MB_ICONERROR);
            return false;
        }

        return true;
    }
于 2014-01-19T13:40:23.493 回答