Как получить доступ к данным модели 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;
    }

Поэтому я использовал операторы печати для вывода координат векторов a b и c, которые должны образовывать треугольник. В одном случае мне не удалось найти эти точные векторы в необработанном файле .obj модели, я нашел их координаты x, y и z, но не все вместе в одном векторе (да, когда я проверил это, я распечатал координаты локального пространства ). В другом случае три вектора, которые должны образовывать треугольник, в итоге образовали линию (два из трех векторов имели одинаковые координаты). Кроме того, я знаю, что тестирование вектора со всеми примитивами модели неэффективно, но сейчас я сосредотачиваюсь на том, чтобы что-нибудь заработало, прежде чем я посмотрю на оптимизацию. Многие модели слишком сложны для AABB, поэтому это «лучшее» решение, которое я придумал. Итак, я не уверен, что я здесь делаю неправильно, любые советы очень ценятся!


person Salamosaurus    schedule 14.02.2018    source источник
comment
Вы проверили, что максимальный используемый индекс равен vertices.size? Просто чтобы проверить, нет ли подмеша.   -  person Jay    schedule 14.02.2018
comment
@Jay да, нет никаких подсетей. Индексов также больше, чем вершин, что, конечно, ожидается, однако это не ожидаемое соотношение 3 к 1, даже когда я не использовал aiProcess_JoinIdenticalVertices   -  person Salamosaurus    schedule 17.02.2018


Ответы (1)


Формат obj просто сохраняет каждую вершину один раз и будет ссылаться на нее в гранях. Таким образом, Assimp будет генерировать из этих позиций вершины для самого рендеринга. И это причина того, что вы не можете найти исходную информацию из импортированного obj-файла в том виде, в котором obj хранит их в этом формате. Obj оптимизирован по размеру, промежуточный формат, используемый assimp, оптимизирован для рендеринга.

Хорошая стратегия хранения информации о столкновениях сильно зависит от вашей модели. Для меня это сработало, чтобы сгенерировать локальную ограничивающую рамку для всей модели и дочерние блоки для каждой сетки, хранящейся в графе узлов. ТАК может работать следующий подход:

  • Проверьте рамку, ограничивающую сцену, сталкивается ли ваш треугольник с этим прямоугольником.
  • If this is the case:
    • Check against all node bounding boxes
    • Если вы можете обнаружить столкновение: проверьте весь треугольник этого узла в сетках, чтобы найти правильный
person KimKulling    schedule 21.02.2018
comment
Это то место, где я в конечном итоге пытался пойти с столкновениями, но сейчас я не могу получить доступ к правильным данным вершин из assimp. Теперь я знаю, что мне не следует искать точно такие же вершины в файле obj для проверки своих данных, но я должен иметь возможность получить доступ к данным вершин из assimp и выполнить тест обнаружения столкновений методом грубой силы с каждым треугольником в модели. . Возможно, я не совсем понимаю? Еще раз спасибо - person Salamosaurus; 01.03.2018