Как использовать экспериментальный API создания сетки с Project Tango

Заранее извиняюсь за свой длинный пост.

Моя цель — создать приложение для создания сетки для устройства Project Tango Yellowstone для создания 3D-карты интерьеров зданий. Я намерен использовать экспериментальный API создания сетки, добавленный в последние версии кода tango-examples-c.

Я использую point-cloud-jni-example (turing) в качестве отправной точки и до сих пор делал следующее:

  1. Установите параметр конфигурации танго config_experimental_enable_scene_reconstruction в point_cloud_app.cc (см. документы)

    // Enable scene reconstruction
    ret = TangoConfig_setBool(tango_config_, 
            config_experimental_enable_scene_reconstruction", true);
        if (ret != TANGO_SUCCESS) {
            LOGE("PointCloudApp:         config_experimental_enable_scene_reconstruction() failed"
                "with error code: %d", ret);
            return ret;
    }
    
  2. Добавлен собственный метод ExtractMesh в TangoJNINative.java.

    // Extracts the full mesh from the scene reconstruction.
    public static native float extractMesh();
    
  3. Добавлена ​​соответствующая функция extractMesh в файл jni_interface.cc.

    JNIEXPORT void JNICALL
    Java_com_projecttango_experiments_nativepointcloud_TangoJNINative_extractMesh(
    JNIEnv*, jobject) {
        app.ExtractMesh();
    }
    
  4. Добавлен метод ExtractMesh в point_cloud_app.cc.

    void PointCloudApp::ExtractMesh() {
    // see line 1245 of tango_client_api.h
        mesh_ptr = new TangoMesh_Experimental();
        TangoService_Experimental_extractMesh(mesh_ptr);
        mesh = *mesh_ptr;
        LOGE("PointCloudApp: num_vertices: %d", mesh.num_vertices);
    
        float float1, float2, float3;
        float1 = mesh.vertices[1][0];
        float2 = mesh.vertices[1][1];
        float3 = float1 + float2;  // these lines show I can use the vertex data
        LOGE("PointCloudApp: First vertex, x: %f", mesh.vertices[1][0]);  // this line causes app to crash; printing the vertex data seems to be the problem
    }
    
  5. Добавлено объявление TangoMesh_Experimental в point_cloud_app.h.

    // see line 1131 of tango_client_api.h
    TangoMesh_Experimental* mesh_ptr;
    TangoMesh_Experimental mesh;
    
  6. Добавлена ​​дополнительная кнопка для вызова нативного метода extractMesh. (не показывая это, так как это довольно просто)

Для справки, вот экспериментальная структура TangoMesh из API:

    // A mesh, described by vertices and face indices, with optional per-vertex
    // normals and colors.
    typedef struct TangoMesh_Experimental {
    // Index into a three-dimensional fixed grid.
    int32_t index[3];

    // Array of vertices. Each vertex is an {x, y, z} coordinate triplet, in
    // meters.
    float (*vertices)[3];

    // Array of faces. Each face is an index triplet into the vertices array.
    uint32_t (*faces)[3];

    // Array of per-vertex normals. Each normal is a normalized {x, y, z} vector.
    float (*normals)[3];

    // Array of per-vertex colors. Each color is a 4-tuple of 8-bit {R, G, B, A}
    // values.
    uint8_t (*colors)[4];

    // Number of vertices, describing the size of the vertices array.
    uint32_t num_vertices;

    // Number of faces, describing the size of the faces array.
    uint32_t num_faces;

    // If true, each vertex will have an associated normal. In that case, the
    // size of the normals array will be equal to num_vertices. Otherwise, the
    // size of the normals array will be 0.
    bool has_normals;

    // If true, each vertex will have an associated color. In that case, the size
    // of the colors array will be equal to num_vertices. Otherwise, the size of
    // the colors array will be 0.
    bool has_colors;
    } TangoMesh_Experimental;

Мое текущее понимание этой структуры:

  1. Три указателя в float (*vertices)[3]; указывают на адреса в начале трех блоков памяти для координат x, y и z для вершин меша (то же верно для нормалей и цветов цветов). Конкретная вершина состоит из компонентов x, y и z, найденных по определенному индексу в трех массивах.

  2. Точно так же массив uint32_t (*faces)[3] имеет три указателя на начало трех фрагментов памяти, но определенный набор из трех элементов здесь вместо этого содержит порядковые номера, указывающие, какие три вершины (из массива вершин (каждая с тремя координатами)) составляют эту грань. .

Текущее состояние: я могу извлечь сетку и распечатать часть ее в консоли, после чего происходит сбой без ошибок

PointCloudApp: PointCloudApp: num_vertices: 8044 

Если я пропущу последнюю строку, добавленную в point_cloud_app.cc (№ 4 выше), приложение не аварийно завершает работу. Я могу получить доступ к данным вершин и что-то с ними сделать, но печать их с помощью LOGE вызывает сбой в 9 случаях из 10. Иногда он печатает значение правильно без сбоев. Могут ли данные вершины иметь дыры или недопустимые значения?

Я попытался вернуть test_float из JNI обратно в java, но он снова вылетает, когда я пытаюсь это сделать.

Предложения?


person Nate    schedule 13.08.2015    source источник
comment
Предложения? — Правильно инициализируйте аргументы, которые вы передаете функции, т. е. не передавайте ей значение нулевого указателя, оно его не принимает. Исправьте свой код вместо того, чтобы беспокоиться об изменении их кода.   -  person Captain Obvlious    schedule 13.08.2015
comment
Спасибо, @CaptainObvlious. Я заработал, добавив эту строку mesh_ = new TangoMesh_Experimental(); в point_cloud_app.cc перед вызовом TangoService_Experimental_extractMesh(mesh_).   -  person Nate    schedule 14.08.2015
comment
Теперь застрял на получении данных вершин.   -  person Nate    schedule 18.08.2015
comment
Затем напишите еще один вопрос, если вам нужна помощь.   -  person Captain Obvlious    schedule 18.08.2015


Ответы (1)


vertices — это динамический массив точек, где каждая точка представляет собой float[3]. Попробуйте этот пример:

for (int i = 0; i < mesh.num_vertices; ++i) {
  printf("%d: x=%f y=%f z=%f\n", i, mesh.vertices[i][0], 
      mesh.vertices[i][1], mesh.vertices[i][2]);
}

Если вы посмотрите на структуру памяти, это будет x0 y0 z0 x1 y1 z1 и т. д., каждый из которых является числом с плавающей запятой.

person Ivan Dryanovski    schedule 18.08.2015
comment
Спасибо Иван! Я обновил вопрос, чтобы использовать двойные скобки. Я могу получить доступ к данным вершин и что-то с ними сделать (см. изменения в шаге 4), но когда я пытаюсь распечатать значения вершин с помощью LOGE, приложение вылетает. Я могу нормально печатать другие значения с плавающей запятой. Интересно, что он успешно печатает примерно в 1 из 10 раз без сбоев. Могут ли числа с плавающей запятой в данных вершин отличаться от тех, которые ожидает LOGE? Это действительно поставило меня в тупик. - person Nate; 18.08.2015
comment
Я бы предложил проверить возвращаемое значение вызова TangoService_Experimental_extractMesh - person Ivan Dryanovski; 20.08.2015
comment
Я пытаюсь просмотреть переменные, но мне нужно получить работает отладка ndk (непростая задача!). Как только я смогу посмотреть содержимое и тип mesh.vertices[1][0] в отладчике, я думаю, что все будет иметь больше смысла. - person Nate; 26.08.2015
comment
@IvanDryanovski Я получаю сообщение об ошибке в строке mesh.vertices : Array type expected , found 'java.nio.FloatBuffer' . Любое руководство, как это исправить? - person Vikrant; 01.08.2017