Demystifying Meshes

In this example, we do not get to reuse any vertex.List<Vector3> vertices = new List<Vector3>();// Right trianglevertices.Add(new Vector3(0.0, 146.7, 0.0));vertices.Add(new Vector3(115.17, 0.0, -115.17));vertices.Add(new Vector3(115.17, 0.0, 115.17));// Front trianglevertices.Add(new Vector3(0.0, 146.7, 0.0));vertices.Add(new Vector3(-115.17, 0.0, -115.17));vertices.Add(new Vector3(115.17, 0.0, -115.17));// Left trianglevertices.Add(new Vector3(0.0, 146.7, 0.0));vertices.Add(new Vector3(-115.17, 0.0, 115.17));vertices.Add(new Vector3(-115.17, 0.0, -115.17));// Back trianglevertices.Add(new Vector3(0.0, 146.7, 0.0));vertices.Add(new Vector3(115.17, 0.0, 115.17));vertices.Add(new Vector3(-115.17, 0.0, 115.17));Vector3[] vertexArray = vertices.ToArray();List<Vector3> normals = new List<Vector3>();// Right trianglenormals.Add(new Vector3(0.703, 0.552, 0.0));normals.Add(new Vector3(0.703, 0.552, 0.0));normals.Add(new Vector3(0.703, 0.552, 0.0));// Front trianglenormals.Add(new Vector3(0.0, 0.552, -0.703));normals.Add(new Vector3(0.0, 0.552, -0.703));normals.Add(new Vector3(0.0, 0.552, -0.703));// Left trianglenormals.Add(new Vector3(-0.703, 0.552, 0.0));normals.Add(new Vector3(-0.703, 0.552, 0.0));normals.Add(new Vector3(-0.703, 0.552, 0.0));// Back trianglenormals.Add(new Vector3(0.0, 0.552, 0.703));normals.Add(new Vector3(0.0, 0.552, 0.703));normals.Add(new Vector3(0.0, 0.552, 0.703));Vector3[] normalArray = normals.ToArray();List<int> triangles = new List<int>();triangles.AddRange(new[]{0, 1, 2});triangles.AddRange(new[]{3, 4, 5});triangles.AddRange(new[]{6, 7, 8});triangles.AddRange(new[]{9, 10, 11});int[] triangleArray = triangles.ToArray();// Create a Mesh object and assign vertices, normals, and triangles// from aboveMesh mesh = new Mesh();mesh.vertices = vertexArray;mesh.normals = normalArray;mesh.triangles = triangleArray;Swift/SceneKit packages normal vectors in a [SCNVector3] array that is then wrapped into a SCNGeometrySource object..Similarly to Unity, you need to duplicate vertices to use them with different normals.var vertices : [SCNVector3] = []// Right trianglevertices.append(SCNVector3(0.0, 146.7, 0.0))vertices.append(SCNVector3(115.17, 0.0, -115.17))vertices.append(SCNVector3(115.17, 0.0, 115.17))// Front trianglevertices.append(SCNVector3(0.0, 146.7, 0.0))vertices.append(SCNVector3(-115.17, 0.0, -115.17))vertices.append(SCNVector3(115.17, 0.0, -115.17))// Left trianglevertices.append(SCNVector3(0.0, 146.7, 0.0))vertices.append(SCNVector3(-115.17, 0.0, 115.17))vertices.append(SCNVector3(-115.17, 0.0, -115.17))// Back trianglevertices.append(SCNVector3(0.0, 146.7, 0.0))vertices.append(SCNVector3(115.17, 0.0, 115.17))vertices.append(SCNVector3(-115.17, 0.0, 115.17))let vertexSource = SCNGeometrySource(vertices: vertices)var normals : [SCNVector3] = []// Right trianglenormals.append(SCNVector3(0.703, 0.552, 0.0))normals.append(SCNVector3(0.703, 0.552, 0.0))normals.append(SCNVector3(0.703, 0.552, 0.0))// Front trianglenormals.append(SCNVector3(0.0, 0.552, -0.703))normals.append(SCNVector3(0.0, 0.552, -0.703))normals.append(SCNVector3(0.0, 0.552, -0.703))// Left trianglenormals.append(SCNVector3(-0.703, 0.552, 0.0))normals.append(SCNVector3(-0.703, 0.552, 0.0))normals.append(SCNVector3(-0.703, 0.552, 0.0))// Back trianglenormals.append(SCNVector3(0.0, 0.552, 0.703))normals.append(SCNVector3(0.0, 0.552, 0.703))normals.append(SCNVector3(0.0, 0.552, 0.703))let normalSource = SCNGeometrySource(normals: normals)var indices : [Int32] = []indices.append(contentsOf: [0, 1, 2])indices.append(contentsOf: [3, 4, 5])indices.append(contentsOf: [6, 7, 8])indices.append(contentsOf: [9, 10, 11])let element = SCNGeometryElement(indices: indices, primitiveType: .triangles)// Create a SCNGeometry object and assign vertices, normals,// and element from abovelet geometry = SCNGeometry(sources: [vertexSource, normalSource], elements: [element])Another common value encoded per vertex is Texture Coordinates or UVs (not to be confused with the UV channels of the YUV color space)..We won't cover those in details, but the high level idea is that textures are sampled with logical floating point coordinates between 0.0 and 1.0 on both axes..This allows artists to paint the different parts of a complex 3D model with a single 2D image.Cow_A texture from the "Cute Pet" Unity asset package by suriyun.comIf you still have your origami creation handy, unfold it: the corners between edges and folds are your UV beta SDK meshing on an iPad.Now that we've covered in details what a mesh is made of, let's tie it all to the beta SDK..If you were to scan the Great Pyramid with our SDK, you wouldn't obtain the four identical triangles from the example..The actual mesh would be millions, if not billions, of small triangles, closely wrapping the imperfect surface of the pyramid.Currently, the beta SDK API calls provide mesh information for up to 10 meters (32 feet) around the user..In order to facilitate mesh manipulation, we organize this "triangle soup" into mesh blocks..We slice the world into cubes of 22.4cm by 22.4cm by 22.4cm (8.82in), and every cube that has at least one triangle of mesh in it is a block.Mesh BlocksEvery block is described by four values:(X, Y, Z) block coordinates(0, 0, 0) is the coordinates of the block containing vertices and triangle between 0.0 and 0.224 on every axis; (-1, -1, -1) is the block containing vertices and triangles between -0.224 and 0.0 on every axis.a vertex counta face counta version numberUpdating mesh objects is expensive, so the version number only increases when its vertices or faces update.The block size was chosen as a compromise between noise and precision..The underlying depth detection models the world in small cubes known as voxels, and estimates for each a probability to be void or solid..The mesh is made from the surface separating solid and empty voxels, block per block, each block containing 512 individual voxels, corresponding to the amount of parallel processing used by our algorithms.In the sample apps of the beta SDK, the mesh is used for rendering and occlusion, but also for physics and collisions..Updating collision meshes is an expensive operation, which grows linearly with the polygon count..We limit the frequency and cost of collision meshes by only updating them when we know they changed (thanks to block versions), and by splitting them into smaller sub-meshes.Unfortunately, each sub-mesh comes with overhead, so we limit their number on the application side by grouping blocks into chunks, which are larger groups of about 1m (4ft) a side.Mesh APIAccessing the beta SDK's mesh data is done through two API functions: SixDegreesSDK_GetMeshBlockInfo() and SixDegreesSDK_GetMeshBlocks().SixDegreesSDK_GetMeshBlockInfo() returns four integer values (the last three are passed as int* parameters):a version numberSimilar to the block version, but applied to the entire mesh.. More details

Leave a Reply