void Update() { GetPose(out pos, out rot, FrameOffset); TransformValidation.ValidatePose(ref pos, ref rot); // Update local transform with pose data from the network. // Use local transform, so we can child this gameobject to the scene anchor. try { if (gameObject.transform.parent != null && gameObject.transform.parent.lossyScale != Vector3.one) { // If the object we are anchored to has a non-identity scale, // the anchor we get from the pose provider will be off by the scale factor. Vector3 scale = gameObject.transform.parent.lossyScale; gameObject.transform.localPosition = new Vector3( UpdateSVTransformFromParentScale(pos.x, scale.x), UpdateSVTransformFromParentScale(pos.y, scale.y), UpdateSVTransformFromParentScale(pos.z, scale.z) ); } else { // Otherwise, our scale is one and we can set the position as we got it. gameObject.transform.localPosition = pos; } gameObject.transform.localRotation = rot; } catch (Exception ex) { Debug.LogWarning("Error getting position and rotation from SV: " + ex.Message); } if (!frameProviderInitialized) { frameProviderInitialized = InitializeFrameProvider(); } UpdateCompositor(); if (spatialMapping == null) { spatialMapping = new SpatialMapping(); } spatialMapping.UpdateSpatialMapping(transform.parent, SpatialMappingMaterial); }
public void UpdateSpatialMapping(Transform parent, Material SpatialMappingMaterial) { int numSpatialMappingMeshes = 0; if (IsSpatialMappingDataReady(out numSpatialMappingMeshes)) { // Set parent transform and remove previous meshes. spatialMappingParent.transform.SetParent(parent); spatialMappingParent.transform.localPosition = Vector3.zero; spatialMappingParent.transform.localRotation = Quaternion.identity; foreach (GameObject go in spatialMappingMeshes) { GameObject.DestroyImmediate(go); } spatialMappingMeshes.Clear(); // Find largest sizes for index and vertex buffers. int largestNumVertices = int.MinValue; int largestNumIndices = int.MinValue; int numVertices; int numIndices; for (int i = 0; i < numSpatialMappingMeshes; i++) { if (GetSpatialMappingDataBufferLengths(i, out numVertices, out numIndices)) { if (numVertices > largestNumVertices) { largestNumVertices = numVertices; } if (numIndices > largestNumIndices) { largestNumIndices = numIndices; } } } IntPtr nativeVertices = Marshal.AllocHGlobal(largestNumVertices * 3 * sizeof(float)); IntPtr nativeIndices = Marshal.AllocHGlobal(largestNumIndices * sizeof(short)); for (int i = 0; i < numSpatialMappingMeshes; i++) { if (GetSpatialMappingDataBufferLengths(i, out numVertices, out numIndices)) { float[] vertexElements = new float[numVertices * 3]; short[] indices = new short[numIndices]; if (numVertices <= 0 || numIndices <= 0) { return; } Vector3 meshTrans; Quaternion meshRot; Vector3 meshScale; if (GetSpatialMappingData(i, out meshTrans, out meshRot, out meshScale, out nativeVertices, out nativeIndices)) { TransformValidation.ValidateVector(ref meshTrans); TransformValidation.ValidateVector(ref meshScale); meshRot = TransformValidation.GetNormalizedQuaternion(meshRot); Marshal.Copy(nativeVertices, vertexElements, 0, numVertices * 3); Marshal.Copy(nativeIndices, indices, 0, numIndices); List <Vector3> vertices = new List <Vector3>(); for (int v = 0; v < vertexElements.Length; v += 3) { Vector3 vertex = new Vector3( vertexElements[v], vertexElements[v + 1], vertexElements[v + 2] ); vertices.Add(vertex); } int[] int_indices = new int[numIndices]; for (int idx = 0; idx < numIndices; idx++) { int_indices[idx] = (int)indices[idx]; } // Create spatial mapping meshes. GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube); go.name = "SpatialMapping_" + i.ToString(); go.transform.SetParent(spatialMappingParent.transform); go.transform.localPosition = meshTrans; go.transform.localRotation = meshRot; // Scale coming from device is larger by a factor of 5. go.transform.localScale = meshScale / 5.0f; if (SpatialMappingMaterial != null) { go.GetComponent <Renderer>().material = SpatialMappingMaterial; } spatialMappingMeshes.Add(go); GameObject.DestroyImmediate(go.GetComponent <Collider>()); MeshFilter filter = go.GetComponent <MeshFilter>(); filter.mesh = new Mesh(); filter.sharedMesh = filter.mesh; Mesh mesh = filter.sharedMesh; mesh.Clear(); mesh.SetVertices(vertices); mesh.SetIndices(int_indices, MeshTopology.Triangles, 0); mesh.RecalculateNormals(); mesh.RecalculateBounds(); Debug.Log(String.Format("Received spatial mapping mesh {0} with {1} vertices and {2} indices", i, numVertices, numIndices)); } } } //TODO: We should be freeing the memory we allocated for the index and vertex buffers, but this was deadlocking. //Marshal.FreeHGlobal(nativeVertices); //Marshal.FreeHGlobal(nativeIndices); // When receiving spatial mapping data, some amount of time will pass without receiving any pose data. // To ensure our poses remain synced, force a reset of our pose cache. ResetPoseCache(); } }