如何在Project Tango中使用实验网格API

How to use experimental meshing API with Project Tango

本文关键字:实验 网格 API Project Tango      更新时间:2023-10-16

我提前为我的长帖子道歉。

我的目的是为Project Tango Yellowstone设备创建一个网格应用程序,以创建建筑内部的3D地图。我打算利用最近版本的tango-examples-c代码中添加的实验网格API。

我使用point-cloud-jni-example (turing)作为起点,到目前为止已经完成了以下操作:

  1. 在point_cloud_app中设置config_experimental_enable_scene_reconstruction tango config参数。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. 在TangoJNINative.java中添加extractMesh native方法

    // Extracts the full mesh from the scene reconstruction.
    public static native float extractMesh();
    
  3. 在jni_interface中增加了匹配extractMesh功能。cc

    JNIEXPORT void JNICALL
    Java_com_projecttango_experiments_nativepointcloud_TangoJNINative_extractMesh(
    JNIEnv*, jobject) {
        app.ExtractMesh();
    }
    
  4. 在point_cloud_app.cc中添加ExtractMesh方法

    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 native方法。(没有显示这个,因为它很简单)

作为参考,下面是来自API的TangoMesh_Experimental结构体:

    // 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打印它会导致10次中的9次崩溃。偶尔,它会正确打印值而不会崩溃。顶点数据是否有漏洞或无效值?

我已经尝试从JNI返回test_float到java,但是当我尝试这样做时它又崩溃了。

建议吗?

vertices是一个动态点数组,其中每个点都是一个float[3]。试试这个例子:

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

如果你看一下内存布局,它将是x0 y0 z0 x1 y1 z1等,每个都是浮点数