protected virtual void UpdateSurfaceData(Surface surface) { SurfaceData tempSurfaceData = surface.surfaceData; tempSurfaceData.id = surface.surfaceId; tempSurfaceData.trianglesPerCubicMeter = lodToPcm[(int)lodType]; tempSurfaceData.bakeCollider = false; tempSurfaceData.outputMesh = surface.meshFilter; surface.surfaceData = tempSurfaceData; }
protected void CloneBakedComponents(SurfaceData bakedData, Surface target) { if (target == null) { return; } if (bakedData.outputMesh != null && target.meshFilter != null) { Destroy(target.meshFilter.mesh); target.meshFilter.mesh = bakedData.outputMesh.sharedMesh; } }
protected override void AddRequiredComponentsForBaking(Surface surface) { base.AddRequiredComponentsForBaking(surface); if (surface.meshCollider == null) { surface.meshCollider = surface.gameObject.AddComponent <MeshCollider>() as MeshCollider; } SurfaceData tempSurfaceData = surface.surfaceData; tempSurfaceData.outputCollider = surface.meshCollider; surface.surfaceData = tempSurfaceData; }
// From the SurfaceData specified, return the index of the in flight // requests that matches or -1 if not found. private int GetInFlightIndexFromSD(SurfaceData sd) { for (int inFlightIndex = 0; inFlightIndex < m_InFlightRequests.Length; ++inFlightIndex) { SMBakeRequest rq = m_InFlightRequests[inFlightIndex]; // this == might be sketchy if (rq.m_RequestData.id.handle == sd.id.handle && rq.m_RequestData.trianglesPerCubicMeter == sd.trianglesPerCubicMeter && rq.m_RequestData.bakeCollider == sd.bakeCollider) { return(inFlightIndex); } } return(-1); }
void Update() { if (mappingEnabled) { foreach (GameObject surface in surfaces.Values) { surface.GetComponent <MeshRenderer>().enabled = DrawVisualMeshes; } if (surfaceWorkOutstanding == false && surfaceDataQueue.Count > 0) { UnityEngine.XR.WSA.SurfaceData smsd = surfaceDataQueue.Dequeue(); surfaceWorkOutstanding = Observer.RequestMeshAsync(smsd, Observer_OnDataReady); } } }
protected override void OnSurfaceDataReady(SpatialMappingBase requester, SurfaceData bakedData, bool outputWritten, float elapsedBakeTimeSeconds) { SpatialMappingBase.Surface surface; if (!surfaceObjects.TryGetValue(bakedData.id.handle, out surface)) { // If we don't have the surface, ignore it because we may never // receive a removal for it. And then it will be a zombie. return; } //Debug.Log(string.Format("Baked \"{0}\" : \"{1}\"", surfaceData.m_GameObject.name, bakedData.id.handle)); // Let the component know that the current surface does not // need to be baked again until the system says the surface // has been updated. surface.awaitingBake = false; if (!outputWritten) { return; } if (surface.gameObject == null) { Debug.LogError(string.Format("A SpatialMappingRenderer component can not apply baked data to a surface with id \"{0}\" because its GameObject is null.", bakedData.id.handle)); return; } if (requester != this) { CloneBakedComponents(bakedData, surface); } if (surface.meshRenderer == null) { surface.meshRenderer = surface.gameObject.GetComponent <MeshRenderer>(); if (surface.meshRenderer == null) { surface.meshRenderer = surface.gameObject.AddComponent <MeshRenderer>(); } surface.meshRenderer.receiveShadows = false; surface.meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; } ApplyRenderSettings(surface.meshRenderer); }
private void Observer_OnSurfaceChanged(UnityEngine.XR.WSA.SurfaceId surfaceId, UnityEngine.XR.WSA.SurfaceChange changeType, Bounds bounds, System.DateTime updateTime) { GameObject surface; switch (changeType) { case UnityEngine.XR.WSA.SurfaceChange.Updated: case UnityEngine.XR.WSA.SurfaceChange.Added: if (!surfaces.TryGetValue(surfaceId.handle, out surface)) { // If we are adding a new surface, construct a GameObject // to represent its state and attach some Mesh-related // components to it. surface = new GameObject(string.Format("Surface-{0}", surfaceId)); surface.AddComponent <MeshFilter>(); surface.AddComponent <MeshRenderer>().sharedMaterial = DrawMaterial; surface.AddComponent <MeshCollider>(); surface.AddComponent <UnityEngine.XR.WSA.WorldAnchor>(); // Set the layer that this SpatialMapping surface is a part of surface.layer = PhysicsLayer; // Add the surface to our dictionary of known surfaces so // we can interact with it later. surfaces[surfaceId.handle] = surface; } UnityEngine.XR.WSA.SurfaceData smsd = new UnityEngine.XR.WSA.SurfaceData( surfaceId, surface.GetComponent <MeshFilter>(), surface.GetComponent <UnityEngine.XR.WSA.WorldAnchor>(), surface.GetComponent <MeshCollider>(), TrianglesPerCubicMeter, true); surfaceDataQueue.Enqueue(smsd); break; case UnityEngine.XR.WSA.SurfaceChange.Removed: if (surfaces.TryGetValue(surfaceId.handle, out surface)) { surfaces.Remove(surfaceId.handle); Destroy(surface); } break; } }
protected override void OnSurfaceDataReady(SpatialMappingBase requester, SurfaceData bakedData, bool outputWritten, float elapsedBakeTimeSeconds) { SpatialMappingBase.Surface surfaceData; if (!surfaceObjects.TryGetValue(bakedData.id.handle, out surfaceData)) { // If we don't have the surface, ignore it because we may never // receive a removal for it. And then it will be a zombie. return; } // Let the component know that the current surface does not // need to be baked again until the system says the surface // has been updated. surfaceData.awaitingBake = false; if (!outputWritten) { return; } if (surfaceData.gameObject == null) { Debug.LogError(string.Format("A SpatialMappingCollider component can not apply baked data to the surface with id \"{0}\" because its GameObject is null.", bakedData.id.handle)); return; } if (bakedData.outputCollider == null) { return; } if (requester != this) { CloneBakedComponents(bakedData, surfaceData); } bakedData.outputCollider.gameObject.layer = layer; if (material != null) { bakedData.outputCollider.material = material; } }
protected virtual bool TryGetHighestPriorityRequest(out SurfaceData bestSurfaceData) { bestSurfaceData = bestSurfaceDataNull; if (surfaceObjects == null || surfaceObjects.Count == 0) { return(false); } Surface bestSurface = null; foreach (KeyValuePair <int, Surface> kvp in surfaceObjects) { if (!kvp.Value.awaitingBake) { // ignore surfaces that have already been baked continue; } if (bestSurface == null) { bestSurface = kvp.Value; continue; } if (kvp.Value.updateTime < bestSurface.updateTime) { bestSurface = kvp.Value; } } if (bestSurface == null) { // nothing to do return(false); } AddRequiredComponentsForBaking(bestSurface); UpdateSurfaceData(bestSurface); bestSurfaceData = bestSurface.surfaceData; return(true); }
public bool RequestMeshAsync(SurfaceData dataRequest, SurfaceDataReadyDelegate onDataReady) { if (onDataReady == null) { throw new ArgumentNullException("onDataReady"); } if (dataRequest.outputMesh == null) { throw new ArgumentNullException("dataRequest.outputMesh"); } if (dataRequest.outputAnchor == null) { throw new ArgumentNullException("dataRequest.outputAnchor"); } if (dataRequest.outputCollider == null && dataRequest.bakeCollider) { throw new ArgumentException("dataRequest.outputCollider must be non-NULL if dataRequest.bakeCollider is true", "dataRequest.outputCollider"); } if (dataRequest.trianglesPerCubicMeter < 0.0) { throw new ArgumentException("dataRequest.trianglesPerCubicMeter must be greater than zero", "dataRequest.trianglesPerCubicMeter"); } bool ret = Internal_AddToWorkQueue( m_Observer, onDataReady, dataRequest.id.handle, dataRequest.outputMesh, dataRequest.outputAnchor, dataRequest.outputCollider, dataRequest.trianglesPerCubicMeter, dataRequest.bakeCollider); if (!ret) { // The only real failure is if the ID is unknown. Debug.LogError("RequestMeshAsync has failed. Is your surface ID valid?"); } return(ret); }
protected virtual void AddRequiredComponentsForBaking(Surface surface) { if (surfaceParent == null) { surfaceParent = new GameObject(string.Format("Surface Parent{0}", observerId)); surfaceParentWasDynamicallyCreated = true; } if (surface.gameObject == null) { // be resilient in the face of users manually destroying spatial mapping sub-objects. surface.gameObject = new GameObject(string.Format("spatial-mapping-surface{0}_{1}", observerId, surface.surfaceId.handle)); surface.gameObject.transform.parent = surfaceParent.transform; } if (surface.meshFilter == null) { surface.meshFilter = surface.gameObject.GetComponent <MeshFilter>(); if (surface.meshFilter == null) { surface.meshFilter = surface.gameObject.AddComponent <MeshFilter>(); } } SurfaceData tempSurfaceData = surface.surfaceData; tempSurfaceData.outputMesh = surface.meshFilter; if (surface.worldAnchor == null) { surface.worldAnchor = surface.gameObject.GetComponent <WorldAnchor>(); if (surface.worldAnchor == null) { surface.worldAnchor = surface.gameObject.AddComponent <WorldAnchor>(); } } tempSurfaceData.outputAnchor = surface.worldAnchor; surface.surfaceData = tempSurfaceData; }
// create new surface records as needed and add the specified surface to the dictionary private void OnAddOrUpdateSurface(SurfaceId surfaceId, System.DateTime updateTime, bool bakePhysics) { Surface surface = null; // If the surface is pending for removal, we should remove it // from the removal list and place it back in the active surface list. if (pendingSurfacesForEviction.ContainsKey(surfaceId.handle)) { surfaceObjects[surfaceId.handle] = pendingSurfacesForEviction[surfaceId.handle]; pendingSurfacesForEviction.Remove(surfaceId.handle); } else if (!surfaceObjects.ContainsKey(surfaceId.handle)) { surface = CreateSurface(surfaceId); surface.surfaceData = new SurfaceData(); surfaceObjects.Add(surfaceId.handle, surface); } if (surface == null) { surface = surfaceObjects[surfaceId.handle]; } SurfaceData tempSurfaceData = surface.surfaceData; tempSurfaceData.id = surfaceId; tempSurfaceData.bakeCollider = bakePhysics; tempSurfaceData.trianglesPerCubicMeter = lodToPcm[(int)lodType]; surface.surfaceData = tempSurfaceData; surface.awaitingBake = true; surface.updateTime = updateTime; AddRequiredComponentsForBaking(surface); }
// data ready event called by the context to inform the component that data is available from the request queue // This method should be implemented by derived components. protected abstract void OnSurfaceDataReady(SpatialMappingBase requester, SurfaceData bakedData, bool outputWritten, float elapsedBakeTimeSeconds);
/// <summary> /// Handles the SurfaceObserver's OnDataReady event. /// </summary> /// <param name="cookedData">Struct containing output data.</param> /// <param name="outputWritten">Set to true if output has been written.</param> /// <param name="elapsedCookTimeSeconds">Seconds between mesh cook request and propagation of this event.</param> private void Observer_OnDataReady(UnityEngine.XR.WSA.SurfaceData bakedData, bool outputWritten, float elapsedBakeTimeSeconds) { surfaceWorkOutstanding = false; }