Hi all,
im loading an FBX file using Assimp and everything is OK including the animation but there is one certain FBX file that seems that the other meshes are not in the proper place.
see attached screenshot (not align mesh.png), the correct ones should be the blades should be on the side of the character and not going thru its center.
i have used assimp viewer and load and view the FBX file can it can be loaded and viewed correctly, which means Assimp can load the FBX format properly.
Assimp Viewer output:
the FBX file has 4 meshes, all the other 3 mesh including the entire body mesh has been positioned correctly except for the second mesh (index 1) which is the blade.
I have been going thru my code again and again and can't find the problem, what could have i missed?
here is my assimp loader code (without the animation and bone processing part as this problem happen with static mesh loading)
bool AssimpMesh::Load(const std::string& Filename)
{
CleanUp();
m_pScene = m_Importer.ReadFile(Filename.c_str(), aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_JoinIdenticalVertices);
bool Ret = false;
if (m_pScene) {
m_GlobalInverseTransform = AiToGLMMat4(m_pScene->mRootNode->mTransformation);
m_GlobalInverseTransform = glm::inverse(m_GlobalInverseTransform);
Ret = InitFromScene(m_pScene, Filename);
}
else {
printf("Error parsing '%s': '%s'\n", Filename.c_str(), m_Importer.GetErrorString());
}
return Ret;
}
bool AssimpMesh::InitFromScene(const aiScene* pScene, const std::string& Filename)
{
m_Entries.resize(pScene->mNumMeshes);
m_Textures.resize(pScene->mNumMaterials);
// Initialize the meshes in the scene one by one
for (unsigned int i = 0; i < pScene->mNumMeshes; i++) {
m_Entries[i].MaterialIndex = pScene->mMeshes[i]->mMaterialIndex;
m_Entries[i].NumIndices = pScene->mMeshes[i]->mNumFaces * 3;
const aiMesh* paiMesh = pScene->mMeshes[i];
std::vector<glm::vec3> Positions;
std::vector<glm::vec3> Normals;
std::vector<glm::vec2> TexCoords;
std::vector<unsigned int> Indices;
std::vector<VertexBoneData> Bones;
Bones.resize(pScene->mMeshes[i]->mNumVertices);
InitMesh(i, paiMesh, Positions, Normals, TexCoords, Bones, Indices);
MeshEntry* entry = &m_Entries[i];
glGenVertexArrays(1, &entry->m_VAO);
glBindVertexArray(entry->m_VAO);
// Create the buffers for the vertices attributes
glGenBuffers(ARRAY_SIZE_IN_ELEMENTS(entry->m_Buffers), entry->m_Buffers);
// Generate and populate the buffers with vertex attributes and the indices
glBindBuffer(GL_ARRAY_BUFFER, entry->m_Buffers[POS_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Positions[0]) * Positions.size(), &Positions[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(POSITION_LOCATION);
glVertexAttribPointer(POSITION_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, entry->m_Buffers[TEXCOORD_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords[0]) * TexCoords.size(), &TexCoords[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(TEX_COORD_LOCATION);
glVertexAttribPointer(TEX_COORD_LOCATION, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, entry->m_Buffers[NORMAL_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Normals[0]) * Normals.size(), &Normals[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(NORMAL_LOCATION);
glVertexAttribPointer(NORMAL_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, entry->m_Buffers[BONE_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Bones[0]) * Bones.size(), &Bones[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(BONE_ID_LOCATION);
glVertexAttribIPointer(BONE_ID_LOCATION, 4, GL_INT, sizeof(VertexBoneData), (const GLvoid*)0);
glEnableVertexAttribArray(BONE_WEIGHT_LOCATION);
glVertexAttribPointer(BONE_WEIGHT_LOCATION, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBoneData), (const GLvoid*)16);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, entry->m_Buffers[INDEX_BUFFER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices[0]) * Indices.size(), &Indices[0], GL_STATIC_DRAW);
glBindVertexArray(0);
}
if (!InitMaterials(pScene, Filename)) {
return false;
}
return true;
}
bool AssimpMesh::InitFromScene(const aiScene* pScene, const std::string& Filename)
{
m_Entries.resize(pScene->mNumMeshes);
m_Textures.resize(pScene->mNumMaterials);
// Initialize the meshes in the scene one by one
for (unsigned int i = 0; i < pScene->mNumMeshes; i++) {
m_Entries[i].MaterialIndex = pScene->mMeshes[i]->mMaterialIndex;
m_Entries[i].NumIndices = pScene->mMeshes[i]->mNumFaces * 3;
const aiMesh* paiMesh = pScene->mMeshes[i];
std::vector<glm::vec3> Positions;
std::vector<glm::vec3> Normals;
std::vector<glm::vec2> TexCoords;
std::vector<unsigned int> Indices;
std::vector<VertexBoneData> Bones;
Bones.resize(pScene->mMeshes[i]->mNumVertices);
InitMesh(i, paiMesh, Positions, Normals, TexCoords, Bones, Indices);
MeshEntry* entry = &m_Entries[i];
glGenVertexArrays(1, &entry->m_VAO);
glBindVertexArray(entry->m_VAO);
// Create the buffers for the vertices attributes
glGenBuffers(ARRAY_SIZE_IN_ELEMENTS(entry->m_Buffers), entry->m_Buffers);
// Generate and populate the buffers with vertex attributes and the indices
glBindBuffer(GL_ARRAY_BUFFER, entry->m_Buffers[POS_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Positions[0]) * Positions.size(), &Positions[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(POSITION_LOCATION);
glVertexAttribPointer(POSITION_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, entry->m_Buffers[TEXCOORD_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords[0]) * TexCoords.size(), &TexCoords[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(TEX_COORD_LOCATION);
glVertexAttribPointer(TEX_COORD_LOCATION, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, entry->m_Buffers[NORMAL_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Normals[0]) * Normals.size(), &Normals[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(NORMAL_LOCATION);
glVertexAttribPointer(NORMAL_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, entry->m_Buffers[BONE_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Bones[0]) * Bones.size(), &Bones[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(BONE_ID_LOCATION);
glVertexAttribIPointer(BONE_ID_LOCATION, 4, GL_INT, sizeof(VertexBoneData), (const GLvoid*)0);
glEnableVertexAttribArray(BONE_WEIGHT_LOCATION);
glVertexAttribPointer(BONE_WEIGHT_LOCATION, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBoneData), (const GLvoid*)16);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, entry->m_Buffers[INDEX_BUFFER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices[0]) * Indices.size(), &Indices[0], GL_STATIC_DRAW);
glBindVertexArray(0);
}
if (!InitMaterials(pScene, Filename)) {
return false;
}
return true;
}
void AssimpMesh::InitMesh(unsigned int MeshIndex,
const aiMesh* paiMesh,
std::vector<glm::vec3>& Positions,
std::vector<glm::vec3>& Normals,
std::vector<glm::vec2>& TexCoords,
std::vector<VertexBoneData>& Bones,
std::vector<unsigned int>& Indices)
{
const aiVector3D Zero3D(0.0f, 0.0f, 0.0f);
// Populate the vertex attribute vectors
for (unsigned int i = 0; i < paiMesh->mNumVertices; i++) {
const aiVector3D* pPos = &(paiMesh->mVertices[i]);
const aiVector3D* pNormal = &(paiMesh->mNormals[i]);
const aiVector3D* pTexCoord = paiMesh->HasTextureCoords(0) ? &(paiMesh->mTextureCoords[0][i]) : &Zero3D;
Positions.push_back(glm::vec3(pPos->x, pPos->y, pPos->z));
Normals.push_back(glm::vec3(pNormal->x, pNormal->y, pNormal->z));
TexCoords.push_back(glm::vec2(pTexCoord->x, pTexCoord->y));
}
LoadBones(MeshIndex, paiMesh, Bones);
// Populate the index buffer
for (unsigned int i = 0; i < paiMesh->mNumFaces; i++) {
const aiFace& Face = paiMesh->mFaces[i];
assert(Face.mNumIndices == 3);
Indices.push_back(Face.mIndices[0]);
Indices.push_back(Face.mIndices[1]);
Indices.push_back(Face.mIndices[2]);
}
}
void AssimpMesh::Render()
{
for (unsigned i = 0; i < m_Entries.size(); i++) {
const unsigned MaterialIndex = m_Entries[i].MaterialIndex;
assert(MaterialIndex < m_Textures.size());
if (m_Textures[MaterialIndex]) {
m_Textures[MaterialIndex]->Bind(/*GL_TEXTURE0*/);
}
MeshEntry* entry = &m_Entries[i];
glBindVertexArray(entry->m_VAO);
glDrawElements(GL_TRIANGLES,
m_Entries[i].NumIndices,
GL_UNSIGNED_INT,
(void*)0);
glBindVertexArray(0);
}
}
I'm stuck on this one for hours already as it is just basic static mesh loading and i cannot find the problem
what could i have missed or overlooked?
(I attached the FBX file as well)
Hellmech_Priest.FBX
↧