-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTangoPointCloudBuffer.cs
More file actions
167 lines (126 loc) · 4.72 KB
/
TangoPointCloudBuffer.cs
File metadata and controls
167 lines (126 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Attach to a TangoPointCloud prefab. It will automatically check for a new point cloud, duplicate it, and add it to a rolling buffer.
// A few useful functions are copied and modified from TangoPointCloud.cs
// A more efficient version of this script would be written directly into TangoPointCloud.cs.
// The reasoning behind making this a separate script, is so that this should be "plug and play" with future updates to the Tango Unity SDK.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Tango;
public class TangoPointCloudBuffer : MonoBehaviour {
public int bufferSize = 6;
private TangoPointCloud tangoPointCloud;
private Vector3[][] pointsBuffer;
private double[] timestampBuffer;
private int[] pointsCountBuffer;
private int[] offsetBuffer;
private int writeFrame = 0;
private double lastPointCloudTimestamp = 0.0;
// This seems like a bad idea for future proofing devices
private const int MAX_POINT_COUNT = 61440;
private Mesh m_mesh;
private Renderer m_renderer;
private double renderedMeshTimestamp = 0.0;
private bool writePointCloud = false;
// Use this for initialization
void Start () {
tangoPointCloud = gameObject.GetComponent<TangoPointCloud> ();
pointsBuffer = new Vector3[bufferSize][];
timestampBuffer = new double[bufferSize];
pointsCountBuffer = new int[bufferSize];
offsetBuffer = new int[bufferSize];
for (int i = 0; i < bufferSize; i++) {
pointsBuffer [i] = new Vector3[MAX_POINT_COUNT];
offsetBuffer [i] = bufferSize - i - 1;
}
m_mesh = GetComponent<MeshFilter>().mesh;
m_mesh.Clear();
m_renderer = GetComponent<Renderer>();
}
// Update is called once per frame
void Update () {
if (writePointCloud) {
System.Array.Copy (tangoPointCloud.m_points, pointsBuffer [writeFrame], tangoPointCloud.m_pointsCount);
timestampBuffer [writeFrame] = tangoPointCloud.m_depthTimestamp;
pointsCountBuffer [writeFrame] = tangoPointCloud.m_pointsCount;
writeFrame++;
if (writeFrame >= bufferSize)
writeFrame = 0;
for (int i = 0; i < bufferSize; i++) {
offsetBuffer [i]++;
if (offsetBuffer [i] >= bufferSize)
offsetBuffer [i] = 0;
}
lastPointCloudTimestamp = tangoPointCloud.m_depthTimestamp;
writePointCloud = false;
}
if (tangoPointCloud.m_depthTimestamp != lastPointCloudTimestamp) {
writePointCloud = true;
}
}
public Vector3 FindClosestPoint(Camera cam, double colorTimestamp, Vector2 pos, int maxDist)
{
int pointsIndex = FindClosestPointCloud(colorTimestamp);
int bestIndex = -1;
if (pointsIndex >= 0) {
float bestDistSqr = 0;
for (int it = 0; it < pointsCountBuffer [pointsIndex]; ++it) {
Vector3 screenPos3 = cam.WorldToScreenPoint (pointsBuffer [pointsIndex] [it]);
Vector2 screenPos = new Vector2 (screenPos3.x, screenPos3.y);
float distSqr = Vector2.SqrMagnitude (screenPos - pos);
if (distSqr > maxDist * maxDist) {
continue;
}
if (bestIndex == -1 || distSqr < bestDistSqr) {
bestIndex = it;
bestDistSqr = distSqr;
}
}
}
if (bestIndex >= 0)
return pointsBuffer [pointsIndex] [bestIndex];
else
return Vector3.zero;
}
// Finds the closest pointcloud given a timestamp
public int FindClosestPointCloud(double timestamp) {
int index = -1;
float time = 1000f;
for (int i = 0; i < bufferSize; i++) {
float timeDifference = Mathf.Abs ((float)(timestampBuffer [i] - timestamp));
if (timeDifference < time) {
index = i;
time = timeDifference;
}
}
return index;
}
// This will overwrite any pointcloud mesh set by TangoPointCloud.cs. If UpdateMesh is true, the next pointcloud will overwrite this mesh.
public void RenderPointCloud(double colorTimestamp){
int pointsIndex = FindClosestPointCloud(colorTimestamp);
if (timestampBuffer [pointsIndex] != renderedMeshTimestamp) {
int[] indices = new int[pointsCountBuffer [pointsIndex]];
for (int i = 0; i < pointsCountBuffer [pointsIndex]; ++i) {
indices [i] = i;
}
m_mesh.Clear ();
m_mesh.vertices = pointsBuffer [pointsIndex];
m_mesh.SetIndices (indices, MeshTopology.Points, 0);
renderedMeshTimestamp = timestampBuffer [pointsIndex];
}
}
// Checks to see if the color time stamp is within 1/30th of a second of the pointcloud timestamp.
public bool isSyncFrame(double colorTimestamp) {
int pointsIndex = FindClosestPointCloud(colorTimestamp);
float difference = (float)(colorTimestamp - timestampBuffer [pointsIndex]);
if (Mathf.Abs (difference) < 1f / 60f)
return true;
else
return false;
}
// Returns the timestamp of the nearest point cloud
public double ClosestPointCloudTimestamp(double colorTimestamp) {
int pointsIndex = FindClosestPointCloud(colorTimestamp);
return timestampBuffer [pointsIndex];
}
}