gpt4 book ai didi

c++ - 如何访问碰撞的 assimp 模型数据?

转载 作者:行者123 更新时间:2023-11-28 04:48:10 32 4
gpt4 key购买 nike

这似乎是一项简单的任务,但我似乎无法弄清楚如何使用从 assimp 导入的数据来测试三角形碰撞。我已经确定我的三角形碰撞算法工作正常,并且将顶点和索引缓冲到 openGL EBO 和 VBO 中以完美地进行绘图。我被引导相信这是我从 std::vector 的顶点和索引访问数据的方式不正确。目前我正在使用索引作为顶点 vector 的索引。

 void loadModel(std::string path) {
Assimp::Importer importer;
const aiScene * scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_JoinIdenticalVertices);
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
printf_s("Assimp loading error \n%s\n", importer.GetErrorString());
return;
}
directory = path.substr(0, path.find_last_of('/'));
processNode(scene->mRootNode, scene);
}
void processNode(aiNode * node, const aiScene * scene) {
for (unsigned int i = 0; i < node->mNumMeshes; i++) {
//processes all the nodes meshes
aiMesh * mesh = scene->mMeshes[node->mMeshes[i]];
meshes.push_back(processMesh(mesh, scene));
}
for (unsigned int i = 0; i < node->mNumChildren; i++) {
processNode(node->mChildren[i], scene);
}
}
Mesh processMesh(aiMesh * mesh, const aiScene * scene) {
std::vector<Vertex> vertices;
std::vector<unsigned int> indices;
std::vector<Texture> textures;
for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
Vertex vertex;
glm::vec3 vector;
vector.x = mesh->mVertices[i].x;
vector.y = mesh->mVertices[i].y;
vector.z = mesh->mVertices[i].z;
vertex.position = vector;
//get other vertex information
vertices.push_back(vertex);
//for all vertices in the mesh, adds the data to a vector
}
for (unsigned int i = 0; i < mesh->mNumFaces; i++) {
aiFace face = mesh->mFaces[i];
if (face.mNumIndices == 3) {
indices.push_back(face.mIndices[0]);
indices.push_back(face.mIndices[1]);
indices.push_back(face.mIndices[2]);
//for all the indices in each face, add each indice

}
else {
printf("Odd mNumIndices \n");
//added as a just in case - but in my situation this case is never executed -> all faces are triangles
for (unsigned int j = 0; j < face.mNumIndices; j++) {
indices.push_back(face.mIndices[j]);
}
}
}

现在要访问此数据,我只需简单地遍历模型的所有网格,并针对网格的每个索引访问其对应的顶点。

bool collision(glm::mat4 worldSpaceTransform, glm::vec3 testVector) {
for (Mesh mesh : meshes) {
for (int i = 0; i < mesh.indices.size(); i += 3) {
//iterate through all faces of the mesh since each face has 3 vertices
glm::vec3 a = glm::vec3(worldSpaceTransform * glm::vec4(mesh.verticies[mesh.indices[i]].position, 1));
glm::vec3 b = glm::vec3(worldSpaceTransform * glm::vec4(mesh.verticies[mesh.indices[i + 1]].position, 1));
glm::vec3 c = glm::vec3(worldSpaceTransform * glm::vec4(mesh.verticies[mesh.indices[i + 2]].position, 1));
//use vector a, b and c (transformed to world space) for collision test with the test vector
//return true if the test vector collides with the triangle
}
}
return false;
}

所以我使用 print 语句输出应该构成三角形的 vector a b 和 c 的坐标。在一种情况下,我无法在模型的原始 .obj 文件中找到这些确切的 vector ,我找到了它们的 x、y 和 z 坐标,但不是全部都在一个 vector 中(是的,当我检查这个时,我打印了局部空间坐标).在另一个例子中,应该构成三角形的三个 vector 最终形成了一条线(三个 vector 中的两个具有相同的坐标)。另外,我知道用模型的所有原语测试一个 vector 是低效的,但现在我专注于在查看优化之前让某事工作。许多模型对于 AABB 来说太复杂了,所以这是我想出的“最佳”解决方案。所以,我不确定我在这里做错了什么,非常感谢任何提示!

最佳答案

obj 格式只存储每个顶点一次,并将在面中引用它。因此 Assimp 将从这些位置生成渲染本身的顶点。这就是为什么您无法从导入的 obj 文件中找到原始信息的原因,因为 obj 是以这种格式存储它们的。 Obj 针对大小进行了优化,assimp 使用的中间格式针对渲染进行了优化。

存储碰撞信息的好策略在很大程度上取决于您的模型类型。对我来说,它可以为整个模型生成局部边界框,并为存储在节点图中的每个网格生成子框。因此,以下方法可能有效:

  • 检查场景边界框你的三角形是否与这个框碰撞
  • 如果是这种情况:
    • 检查所有节点边界框​​
    • 如果您能够检测到碰撞:检查网格内该节点的所有三角形以找到正确的三角形

关于c++ - 如何访问碰撞的 assimp 模型数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48779620/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com