如何访问assimp模型数据以进行碰撞?

时间:2018-02-14 04:20:52

标签: c++ opengl assimp

这似乎是一项简单的任务,但我似乎无法弄清楚如何使用来自assimp的导入数据来测试三角形碰撞。我已经确定我的三角形碰撞算法工作正常,并将顶点和索引缓冲到openGL EBO和VBO中以便完美地绘制。我被引导相信它是我访问我的std :: 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语句输出矢量a和b的坐标,这些坐标应该是一个三角形。在一个案例中,我无法在模型的原始.obj文件中找到这些精确的向量,我在一个向量中找到了它们的x,y和z坐标但不是全部(是的,当我检查这个时我打印了局部空间坐标)。在另一个中,应该形成三角形的三个矢量最终形成一条线(三个矢量中的两个具有相同的坐标)。此外,我知道测试一个包含所有模型基元的向量效率很低,但是现在我正专注于在查看优化之前使某些工作。许多模型对于AABB而言过于复杂,所以这是最好的#34;我想出了解决方案。所以,我不确定我在这里做错了什么,非常感谢任何提示!

1 个答案:

答案 0 :(得分:0)

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

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

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