void BuildSpatialSurfaceObserver()
        {
            _spatialSurfaceObserver = new SpatialSurfaceObserver();

            var positionFormat = DirectXPixelFormat.R32G32B32A32Float;
            var normalFormat   = DirectXPixelFormat.R32G32B32A32Float;

            _spatialSurfaceMeshOptions = new SpatialSurfaceMeshOptions
            {
                IncludeVertexNormals = true,
                VertexPositionFormat = positionFormat,
                VertexNormalFormat   = normalFormat,
                TriangleIndexFormat  = DirectXPixelFormat.R16UInt
            };

            var boundingBox = new SpatialBoundingBox
            {
                Center  = new Vector3(0f, 0f, 0f),
                Extents = new Vector3(10f, 10f, 10f)
            };
            var bounds = SpatialBoundingVolume.FromBox(_spatialCoordinateSystem, boundingBox);

            _spatialSurfaceObserver.SetBoundingVolume(bounds);

            _spatialSurfaceObserver.ObservedSurfacesChanged += SpatialSurfaceObserverOnObservedSurfacesChanged;
        }
예제 #2
0
        /// <inheritdoc />
        public WindowsMixedRealitySpatialMeshObserver(string name, uint priority, WindowsMixedRealitySpatialMeshObserverProfile profile, IMixedRealitySpatialAwarenessSystem parentService)
            : base(name, priority, profile, parentService)
        {
#if WINDOWS_UWP
            if (profile.MeshLevelOfDetail == SpatialAwarenessMeshLevelOfDetail.Custom)
            {
                trianglesPerCubicMeter = profile.TrianglesPerCubicMeter;
            }

            if (SpatialSurfaceObserver.IsSupported())
            {
                spatialSurfaceObserver    = new SpatialSurfaceObserver();
                spatialSurfaceMeshOptions = new SpatialSurfaceMeshOptions {
                    IncludeVertexNormals = true
                };

                // TODO Determine which formats are the correct ones to use.
                var supportedVertexPositionFormats = SpatialSurfaceMeshOptions.SupportedVertexPositionFormats;
                var supportedVertexNormalFormats   = SpatialSurfaceMeshOptions.SupportedVertexNormalFormats;

                for (int i = 0; i < supportedVertexPositionFormats.Count; i++)
                {
                    if (supportedVertexPositionFormats[i] == Windows.Graphics.DirectX.DirectXPixelFormat.R16G16B16A16IntNormalized)
                    {
                        spatialSurfaceMeshOptions.VertexPositionFormat = Windows.Graphics.DirectX.DirectXPixelFormat.R16G16B16A16IntNormalized;
                        break;
                    }
                }

                for (int i = 0; i < supportedVertexNormalFormats.Count; i++)
                {
                    if (supportedVertexNormalFormats[i] == Windows.Graphics.DirectX.DirectXPixelFormat.R8G8B8A8IntNormalized)
                    {
                        spatialSurfaceMeshOptions.VertexNormalFormat = Windows.Graphics.DirectX.DirectXPixelFormat.R8G8B8A8IntNormalized;
                        break;
                    }
                }

                // If a very high detail setting with spatial mapping is used, it can be beneficial
                // to use a 32-bit unsigned integer format for indices instead of the default 16-bit.
                if (MeshLevelOfDetail == SpatialAwarenessMeshLevelOfDetail.High)
                {
                    var supportedTriangleIndexFormats = SpatialSurfaceMeshOptions.SupportedTriangleIndexFormats;

                    for (int i = 0; i < supportedTriangleIndexFormats.Count; i++)
                    {
                        if (supportedTriangleIndexFormats[i] == Windows.Graphics.DirectX.DirectXPixelFormat.R8G8B8A8IntNormalized)
                        {
                            spatialSurfaceMeshOptions.TriangleIndexFormat = Windows.Graphics.DirectX.DirectXPixelFormat.R32UInt;
                        }
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SpatialMappingManagerUWP"/> class.
        /// </summary>
        public SpatialMappingManagerUWP()
        {
            this.surfaces = new Dictionary <Guid, SpatialMappingSurface>();

            this.extents = Vector3.One * 10.0f;
            this.TrianglesPerCubicMeter = 500;
            this.ObtainNormals          = true;
            this.pendingChanges         = true;

            this.surfaceMeshOptions = new SpatialSurfaceMeshOptions()
            {
                IncludeVertexNormals = this.ObtainNormals,
                VertexPositionFormat = Windows.Graphics.DirectX.DirectXPixelFormat.R32G32B32A32Float,
                VertexNormalFormat   = Windows.Graphics.DirectX.DirectXPixelFormat.R32G32B32A32Float,
                ////TriangleIndexFormat = Windows.Graphics.DirectX.DirectXPixelFormat.R32UInt
            };
        }
예제 #4
0
        public async Task AddOrUpdateAsync(SpatialSurfaceInfo spatialSurfaceInfo, SpatialSurfaceMeshOptions options)
        {
            var mesh = await spatialSurfaceInfo.TryComputeLatestMeshAsync(1000.0d, options);

            if (mesh == null)
            {
                return;
            }

            var tempList = new Dictionary <Guid, SurfaceMesh>(_internalList);

            // See if we already have this one....
            var hasOne = tempList.ContainsKey(mesh.SurfaceInfo.Id);

            if (hasOne)
            {
                // Update
                var surfaceMesh = tempList[mesh.SurfaceInfo.Id];
                if (surfaceMesh.UpdateTime < mesh.SurfaceInfo.UpdateTime)
                {
                    surfaceMesh.CalculateAllVertices(mesh);
                    surfaceMesh.UpdateTime = mesh.SurfaceInfo.UpdateTime;
                }
            }
            else
            {
                // Add new
                var newMesh = new SurfaceMesh
                {
                    Id               = mesh.SurfaceInfo.Id,
                    UpdateTime       = mesh.SurfaceInfo.UpdateTime,
                    CoordinateSystem = CoordinateSystem,
                    DirectXDevice    = DirectXDevice
                };

                newMesh.CalculateAllVertices(mesh);
                tempList[newMesh.Id] = newMesh;
            }

            lock (_lockObject)
                _internalList = tempList;
        }
예제 #5
0
        private void OnSurfaceUpdate(SpatialSurfaceObserver observer, object args)
        {
            var surfaceDict = observer.GetObservedSurfaces();

            foreach (var surface in surfaceDict)
            {
                // Find or add a surface mesh for this surface
                SurfaceMesh mesh = meshes.Find(m => m.id == surface.Key);
                if (mesh == null)
                {
                    mesh = new SurfaceMesh {
                        mesh       = new Mesh(),
                        id         = surface.Key,
                        lastUpdate = new DateTimeOffset()
                    };
                    meshes.Add(mesh);
                }

                // Ask for an update to the mesh data, if it's old
                if (surface.Value.UpdateTime > mesh.lastUpdate)
                {
                    mesh.lastUpdate = surface.Value.UpdateTime;
                    SpatialSurfaceMeshOptions opts = new SpatialSurfaceMeshOptions();
                    opts.IncludeVertexNormals = false;
                    opts.TriangleIndexFormat  = Windows.Graphics.DirectX.DirectXPixelFormat.R32UInt;
                    opts.VertexPositionFormat = Windows.Graphics.DirectX.DirectXPixelFormat.R32G32B32A32Float;
                    surface.Value.TryComputeLatestMeshAsync(trisPerMeter, opts).Completed = (info, state) => {
                        // Send update to the main thread for upload to GPU
                        if (state == Windows.Foundation.AsyncStatus.Completed)
                        {
                            queuedUpdates.Add(info.GetResults());
                        }
                    };
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Update the surface
        /// </summary>
        /// <param name="handler">The handler to receive the surface information</param>
        /// <param name="change">The surface change</param>
        /// <param name="surface">The surface to update</param>
        /// <param name="trianglesPerCubicMeter">The max triangles per cubic meter</param>
        /// <param name="surfaceInfo">The surface info</param>
        /// <param name="surfaceOptions">The mesh options</param>
        private async void UpdateSurface(OnSurfaceChangedHandler handler, SurfaceChange change, SpatialMappingSurfaceInternal surface, float trianglesPerCubicMeter, SpatialSurfaceInfo surfaceInfo, SpatialSurfaceMeshOptions surfaceOptions)
        {
            if (surface.IsProcessing)
            {
                return;
            }

            try
            {
                surface.IsProcessing = true;

                // Generate the mesh from the MixedReality surface info
                SpatialSurfaceMesh surfaceMesh = await surfaceInfo.TryComputeLatestMeshAsync(trianglesPerCubicMeter, surfaceOptions);

                if (surfaceMesh != null && surface.UpdateTime < surfaceMesh.SurfaceInfo.UpdateTime)
                {
                    // Update the surface mesh
                    surface.UpdateSurfaceMesh(surfaceMesh);

                    if (handler != null)
                    {
                        handler(surface.Id, surface, change, surface.UpdateTime);
                    }
                }
            }
            finally
            {
                surface.IsProcessing = false;
            }
        }