当我尝试查看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;
}
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;
};
答案 0 :(得分: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;
}