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);
 }
Example #5
0
    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);
        }
Example #7
0
    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);
Example #14
0
 /// <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;
 }