使用 assimp 进行边缘折叠
Edge Collapse with assimp
我正在尝试在我的游戏引擎中实现边缘折叠,这是由 Assimp 引起的问题。从 face.mNumIndices
解析出来的索引总是递增顺序索引。
当我检查索引列表时,值应该是 0,1,2,3,4....,999...
。但我知道这是 Assimp 使用的某种 mechanism,对象渲染得很好。但是在 Mesh Simplication 上还有另一个问题,我无法为这个索引生成半边结构。我坚持了几天,没有答案。我应该放弃 Assimp 吗?任何建议表示赞赏。
编辑:
我的顶点在面之间共享,我用来获取数据的代码在这里。
BasicRenderModel* AssimpLoader::ProcessMeshBasicVersion(aiMesh * mesh, const aiScene * scene)
{
//std::vector<Vertex> vertices;
float *vertices = new float[mesh->mNumVertices * 3];
int vertexLength = mesh->mNumVertices * 3;
float *normals = new float[mesh->mNumVertices * 3];
int normalLength = mesh->mNumVertices * 3;
float *texCoords = new float[mesh->mNumVertices * 2];
int texCoordLength = mesh->mNumVertices * 2;
std::vector<int> indicesList;
int *indices;
int indexLength;
//std::vector<Texture> textures;
std::map<TextureType, std::vector<Texture>> textures;
for (GLuint i = 0; i < mesh->mNumVertices; i++)
{
// Process vertex positions, normals and texture coordinates
vertices[i * 3] = mesh->mVertices[i].x;
vertices[i * 3 + 1] = mesh->mVertices[i].y;
vertices[i * 3 + 2] = mesh->mVertices[i].z;
normals[i * 3] = mesh->mNormals[i].x;
normals[i * 3 + 1] = mesh->mNormals[i].y;
normals[i * 3 + 2] = mesh->mNormals[i].z;
if (mesh->mTextureCoords[0]) // Does the mesh contain texture coordinates?
{
texCoords[i * 2] = mesh->mTextureCoords[0][i].x;
texCoords[i * 2 + 1] = mesh->mTextureCoords[0][i].y;
}
else
texCoords[i * 2] = texCoords[i * 2 + 1] = 0.0f;
Debug::Log("vertex: " + std::to_string(vertices[i * 3]) + "," + std::to_string(vertices[i * 3 + 1]) + "," + std::to_string(vertices[i * 3 + 2]));
}
// Process indices
for (GLuint i = 0; i < mesh->mNumFaces; i++)
{
aiFace face = mesh->mFaces[i];
for (GLuint j = 0; j < face.mNumIndices; j++)
indicesList.push_back(face.mIndices[j]);
}
indices = new int[indicesList.size()];
indexLength = indicesList.size();
for (int i = 0; i < (int)indicesList.size(); i++)
indices[i] = indicesList[i];
return this->loader.LoadRenderModel(vertices, vertexLength, indices, indexLength, texCoords, texCoordLength, normals, normalLength);
}
以及this object and indices that generated by the code above is here
的结果顶点
比较结果和obj文件。对于树对象,obj 文件有 624 个顶点,但 Assimp 有 927 个顶点,obj 的索引为 310(lines) * 3 = 930,但从 Assimp 读取的索引为 927 个索引。我以为Assimp处理后面的数据,生成指定的索引和顶点。
如果我需要重新计算索引,这意味着我需要检查每个顶点的所有顶点以找到相同的顶点并构建索引..?无法弄清楚如何解决这个问题..
要使算法与 Assimp Importer 一起工作,有两件重要的事情。
模型应该是共享顶点和面的,如果模型不是,应该在3D模型软件中设置一些选项。我在问题部分提供的树对象,我需要在搅拌机中删除双打(删除重复的顶点),法线应该只有一个。
另外需要注意的是assimp的postprocess选项。查看 Assimp 文档,有一个名为 aiProcess_JoinIdenticalVertices
的标志,如果未启用,Assimp 将为唯一顶点生成完全唯一的索引。 here.
中有更多信息
我正在尝试在我的游戏引擎中实现边缘折叠,这是由 Assimp 引起的问题。从 face.mNumIndices
解析出来的索引总是递增顺序索引。
当我检查索引列表时,值应该是 0,1,2,3,4....,999...
。但我知道这是 Assimp 使用的某种 mechanism,对象渲染得很好。但是在 Mesh Simplication 上还有另一个问题,我无法为这个索引生成半边结构。我坚持了几天,没有答案。我应该放弃 Assimp 吗?任何建议表示赞赏。
编辑: 我的顶点在面之间共享,我用来获取数据的代码在这里。
BasicRenderModel* AssimpLoader::ProcessMeshBasicVersion(aiMesh * mesh, const aiScene * scene)
{
//std::vector<Vertex> vertices;
float *vertices = new float[mesh->mNumVertices * 3];
int vertexLength = mesh->mNumVertices * 3;
float *normals = new float[mesh->mNumVertices * 3];
int normalLength = mesh->mNumVertices * 3;
float *texCoords = new float[mesh->mNumVertices * 2];
int texCoordLength = mesh->mNumVertices * 2;
std::vector<int> indicesList;
int *indices;
int indexLength;
//std::vector<Texture> textures;
std::map<TextureType, std::vector<Texture>> textures;
for (GLuint i = 0; i < mesh->mNumVertices; i++)
{
// Process vertex positions, normals and texture coordinates
vertices[i * 3] = mesh->mVertices[i].x;
vertices[i * 3 + 1] = mesh->mVertices[i].y;
vertices[i * 3 + 2] = mesh->mVertices[i].z;
normals[i * 3] = mesh->mNormals[i].x;
normals[i * 3 + 1] = mesh->mNormals[i].y;
normals[i * 3 + 2] = mesh->mNormals[i].z;
if (mesh->mTextureCoords[0]) // Does the mesh contain texture coordinates?
{
texCoords[i * 2] = mesh->mTextureCoords[0][i].x;
texCoords[i * 2 + 1] = mesh->mTextureCoords[0][i].y;
}
else
texCoords[i * 2] = texCoords[i * 2 + 1] = 0.0f;
Debug::Log("vertex: " + std::to_string(vertices[i * 3]) + "," + std::to_string(vertices[i * 3 + 1]) + "," + std::to_string(vertices[i * 3 + 2]));
}
// Process indices
for (GLuint i = 0; i < mesh->mNumFaces; i++)
{
aiFace face = mesh->mFaces[i];
for (GLuint j = 0; j < face.mNumIndices; j++)
indicesList.push_back(face.mIndices[j]);
}
indices = new int[indicesList.size()];
indexLength = indicesList.size();
for (int i = 0; i < (int)indicesList.size(); i++)
indices[i] = indicesList[i];
return this->loader.LoadRenderModel(vertices, vertexLength, indices, indexLength, texCoords, texCoordLength, normals, normalLength);
}
以及this object and indices that generated by the code above is here
的结果顶点比较结果和obj文件。对于树对象,obj 文件有 624 个顶点,但 Assimp 有 927 个顶点,obj 的索引为 310(lines) * 3 = 930,但从 Assimp 读取的索引为 927 个索引。我以为Assimp处理后面的数据,生成指定的索引和顶点。
如果我需要重新计算索引,这意味着我需要检查每个顶点的所有顶点以找到相同的顶点并构建索引..?无法弄清楚如何解决这个问题..
要使算法与 Assimp Importer 一起工作,有两件重要的事情。
模型应该是共享顶点和面的,如果模型不是,应该在3D模型软件中设置一些选项。我在问题部分提供的树对象,我需要在搅拌机中删除双打(删除重复的顶点),法线应该只有一个。
另外需要注意的是assimp的postprocess选项。查看 Assimp 文档,有一个名为
aiProcess_JoinIdenticalVertices
的标志,如果未启用,Assimp 将为唯一顶点生成完全唯一的索引。 here. 中有更多信息