Domanda

When I try to view 3D files (.3ds .dae etc ...), supported by Assimp, they are not displayed correctly. For example, "Jeep1.3ds" displayed me half the bodywork. All nodes of information, meshes and normal were obtained correctly, and the number of vertices and faces are correct (I think). Textures not meet the correct coordinates, I guess will be related to the above ... In the picture you can "appreciate" my result and correct. Thanks for any help or opinion.

enter image description here

Ogre code

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;
    }

Assimp .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;
};
È stato utile?

Soluzione

Ok ... errors, as they spend most of the time, in practice something small and basic but complex background. "Simply" switch the coordinate system, when I import the file would have to be specified Assimp flags "aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs" or "aiProcess_ConvertToLeftHanded". Other than that I missed some transformation matrices (they had not considered), for that I use the flag "aiProcess_PreTransformVertices". Apparently everything works fine ...

New code

    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;
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top