So because we know that weâre getting an ordered list of coordinates from the Kinect, we can create the quad faces directly from the indices. For example, with the topology:
0---1---2---3---4---5---6
| | | | | | |
7---8---9---10--11--12--13
| | | | | | |
14--15--16--17--18--19--20
We could directly do:
AddVertices(<all vertices>)
AddFace(0,1,8,7);
AddFace(1,2,9,8);
AddFace(2,3,10,9);
etc...
And hence knowing the stride (x-resolution) we can come up with the function:
/// <summary>
/// Creates a quad mesh from an ordered grid of points
/// Diagram of structure:
///
/// 2 -- 3
/// | |
/// 1 -- 0
///
/// x-1 , y-1 -- x , y-1
///
/// | |
/// | |
/// | |
///
/// x-1 , y -- x , y
/// </summary>
Mesh CreateQuadMesh(IEnumerable<Point3d> pts, int stride) {
int xd = stride; // The x-dimension of the data
int yd = pts.Count() / stride; // They y-dimension of the data
Mesh m = new Mesh();
m.Vertices.Capacity = pts.Count(); // Don't resize array
m.Vertices.UseDoublePrecisionVertices = false; // Save memory
m.Vertices.AddVertices(pts); // Add all points to vertex list
for (int y = 1;y < yd; y++) // Iterate over y dimension
{
for (int x = 1;x < xd; x++) // Iterate over x dimension
{
// To get the array index of the item at x,y, we use y * xd + x
m.Faces.AddFace(y * xd + x, y * xd + x - 1, (y - 1) * xd + x - 1, (y - 1) * xd + x);
}
}
return m;
}
In practice thereâd be some further optimization you could make by creating the mesh directly from the frames rather than creating additional Point3d list first, and you could also go directly to Point3f to avoid some garbage collection and memory overhead (since a 640x480 Point3d array should be 640x480x3x4 bytes = 3.69kB per frame which we donât need floating around).
And subsequently, because we then know the topology of the mesh ( due to knowing the stride ) the smoothing operation can become faster again, as we donât need to calculate and cache the mesh topology in the beginning.