这两天简单看了下 java_point_cloud_example 工程的代码,作此笔记,以备日后查阅。
源码基于 Eisa 版本。
第一张图是由 TangoUX 控制的,是一个铺满全屏的 com.google.atap.tango.ux.TangoUxLayout,相当于普通 app 里面的 loading 界面。
第二张图中的棱锥代表设备,不同颜色的点表示离设备不同距离的点云,红色的最近。
晃动设备,棱锥的角度会随着设备变化。
有两个核心点:
既然能在屏幕上用不同的颜色表示不同的坐标,那么 Tango 肯定是获取了点云的坐标和距离信息,然后再映射到屏幕上的坐标系中;棱锥能随着设备而摆动,说明代码里面肯定有获取设备 Pose 数据的地方,通过 Pose 里面的 orientation 信息来控制棱锥的摆动;根据上述两个假设,在代码可中可以找到:
// more code final double averageDepth = getAveragedDepth(pointCloud.points, pointCloud.numPoints); // more code private float getAveragedDepth(FloatBuffer pointCloudBuffer, int numPoints) { float totalZ = 0; float averageZ = 0; if (numPoints != 0) { int numFloats = 4 * numPoints; for (int i = 2; i < numFloats; i = i + 4) { totalZ = totalZ + pointCloudBuffer.get(i); } averageZ = totalZ / numPoints; } return averageZ; }pointCloudBuffer 里面是个四元组,查阅 文档 可以得知,每个四元组都是一个 (x, y, z, c)。
public class TangoPointCloudData implements Parcelable { public double timestamp; public int numPoints; public FloatBuffer points; }3个核心字段:
timestamp,获得4元组的时间戳;numPoints,4元组的数量;points,4元组集合,(x, y, z, c),竖直方向放置设备时,x 为正表示用户的右手方向,y 为正表示屏幕底部方向,z 为正表示摄像头焦距方向且垂直于摄像头平面,近似取 z 为某点距离,c 为置信系数,区间[0, 1],1 表示完全可信;拿到点云的数据之后,在 PointCloud 类里面做映射计算,将点云坐标映射成不同颜色点的坐标。从而显示在屏幕上。
至于第二个假设,同样看代码:
TangoPoseData lastFramePose = TangoSupport.getPoseAtTime(0,TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE, TangoPoseData.COORDINATE_FRAME_DEVICE, TangoSupport.TANGO_SUPPORT_ENGINE_OPENGL, mDisplayRotation); mRenderer.updateCameraPose(lastFramePose);通过这种方式来获取 Pose 数据,然后更新愣头进行实现角度变化。
上面的点就像一条隔板,把 Tango 相关代码和 Rajawali 代码隔离开来。拿到 Tango 数据之后,更新 3D 虚拟图像的操作就完全交由 Rajawali 来做了,与 Tango 无关了。
材质,用来定义 3D 模型的视觉效果,比如光照、颜色、高亮等。
纹理,3D 模型的表面,比如给球体覆盖一个世界地图。
球体。
一种简单的光照模型。
光照
工程自定义网格类,用于第一人称视角展示网格。
工程自定义棱锥类,用于表示设备。
自定义三位点类。
工程自定义类,代表所有的颜色点。Palette:调色板。
Rajawali 工程中继承 RajawaliRenderer,重写 initScene() 和 onRender() 方法。在前者中加入 3D 模型,在后者中加入动画效果。
Rajawali 里面的 Camera 类代表什么,跟 Tango 设备的 Camera 是什么关系?这是一个 virtual camera? camera.setPosition() 和 camera.setOrientation() 又是什么作用?