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