public string CreateAnchor(Vec3 at, string id = null)
    {
        string anchorID = id == null
                        ? Guid.NewGuid().ToString()
                        : id;

        SpatialLocator locator = SpatialLocator.GetDefault();
        SpatialStationaryFrameOfReference stationary = locator.CreateStationaryFrameOfReferenceAtCurrentLocation();
        SpatialAnchor anchor = SpatialAnchor.TryCreateRelativeTo(stationary.CoordinateSystem);
        Pose          pose   = World.FromPerceptionAnchor(anchor);

        Pose newAnchor = pose.ToMatrix().Inverse.Transform(new Pose(at, Quat.Identity));

        anchor = SpatialAnchor.TryCreateRelativeTo(stationary.CoordinateSystem, newAnchor.position, newAnchor.orientation);
        pose   = World.FromPerceptionAnchor(anchor);

        if (anchor != null)
        {
            anchorPoses.Add(anchorID, pose);
        }

        return(anchorStore.TrySave(anchorID, anchor)
                        ? anchorID
                        : null);
    }
        void OnLocatabilityChanged(SpatialLocator sender, Object args)
        {
            switch (sender.Locatability)
            {
                case SpatialLocatability.Unavailable:
                    // Holograms cannot be rendered.
                    {
                        String message = "Warning! Positional tracking is " + sender.Locatability + ".";
                        Debug.WriteLine(message);
                    }
                    break;

                // In the following three cases, it is still possible to place holograms using a
                // SpatialLocatorAttachedFrameOfReference.
                case SpatialLocatability.PositionalTrackingActivating:
                // The system is preparing to use positional tracking.

                case SpatialLocatability.OrientationOnly:
                // Positional tracking has not been activated.

                case SpatialLocatability.PositionalTrackingInhibited:
                    // Positional tracking is temporarily inhibited. User action may be required
                    // in order to restore positional tracking.
                    break;

                case SpatialLocatability.PositionalTrackingActive:
                    // Positional tracking is active. World-locked content can be rendered.
                    break;
            }
        }
Exemple #3
0
        public void SetHolographicSpace(HolographicSpace holographicSpace)
        {
            this.holographicSpace = holographicSpace;

            //
            // TODO: Add code here to initialize your content.
            //
            // <<NEW>> Set up Event Sub Send
            this.eventHubSend = new EventHubSend();
            // try to send message as test
            Debug.WriteLine("EventHubSendStart:call");
            this.eventHubSend.EventHubSendStart();

#if DRAW_SAMPLE_CONTENT
            // Initialize the sample hologram.
            spinningCubeRenderer = new SpinningCubeRenderer(deviceResources);

            spatialInputHandler = new SpatialInputHandler();
#endif

            // Use the default SpatialLocator to track the motion of the device.
            locator = SpatialLocator.GetDefault();

            // Be able to respond to changes in the positional tracking state.
            locator.LocatabilityChanged += this.OnLocatabilityChanged;

            // Respond to camera added events by creating any resources that are specific
            // to that camera, such as the back buffer render target view.
            // When we add an event handler for CameraAdded, the API layer will avoid putting
            // the new camera in new HolographicFrames until we complete the deferral we created
            // for that handler, or return from the handler without creating a deferral. This
            // allows the app to take more than one frame to finish creating resources and
            // loading assets for the new holographic camera.
            // This function should be registered before the app creates any HolographicFrames.
            holographicSpace.CameraAdded += this.OnCameraAdded;

            // Respond to camera removed events by releasing resources that were created for that
            // camera.
            // When the app receives a CameraRemoved event, it releases all references to the back
            // buffer right away. This includes render target views, Direct2D target bitmaps, and so on.
            // The app must also ensure that the back buffer is not attached as a render target, as
            // shown in DeviceResources.ReleaseResourcesForBackBuffer.
            holographicSpace.CameraRemoved += this.OnCameraRemoved;

            // The simplest way to render world-locked holograms is to create a stationary reference frame
            // when the app is launched. This is roughly analogous to creating a "world" coordinate system
            // with the origin placed at the device's position as the app is launched.
            referenceFrame = locator.CreateStationaryFrameOfReferenceAtCurrentLocation();

            // Notes on spatial tracking APIs:
            // * Stationary reference frames are designed to provide a best-fit position relative to the
            //   overall space. Individual positions within that reference frame are allowed to drift slightly
            //   as the device learns more about the environment.
            // * When precise placement of individual holograms is required, a SpatialAnchor should be used to
            //   anchor the individual hologram to a position in the real world - for example, a point the user
            //   indicates to be of special interest. Anchor positions do not drift, but can be corrected; the
            //   anchor will use the corrected position starting in the next frame after the correction has
            //   occurred.
        }
Exemple #4
0
        public void SetHolographicSpace(HolographicSpace holographicSpace)
        {
            this.holographicSpace = holographicSpace;

            //Task.Factory.StartNew(RunAppScript).Wait();
            try
            {
                host      = new ChakraHost();
                appScript = System.IO.File.ReadAllText(@"Assets/js/app.js");
                host.SetHolographicSpace(this.holographicSpace);
                host.RunScript(appScript);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            };

            // Use the default SpatialLocator to track the motion of the device.
            locator = SpatialLocator.GetDefault();

            // Be able to respond to changes in the positional tracking state.
            locator.LocatabilityChanged += this.OnLocatabilityChanged;

            // Respond to camera added events by creating any resources that are specific
            // to that camera, such as the back buffer render target view.
            // When we add an event handler for CameraAdded, the API layer will avoid putting
            // the new camera in new HolographicFrames until we complete the deferral we created
            // for that handler, or return from the handler without creating a deferral. This
            // allows the app to take more than one frame to finish creating resources and
            // loading assets for the new holographic camera.
            // This function should be registered before the app creates any HolographicFrames.
            holographicSpace.CameraAdded += this.OnCameraAdded;

            // Respond to camera removed events by releasing resources that were created for that
            // camera.
            // When the app receives a CameraRemoved event, it releases all references to the back
            // buffer right away. This includes render target views, Direct2D target bitmaps, and so on.
            // The app must also ensure that the back buffer is not attached as a render target, as
            // shown in DeviceResources.ReleaseResourcesForBackBuffer.
            holographicSpace.CameraRemoved += this.OnCameraRemoved;

            // The simplest way to render world-locked holograms is to create a stationary reference frame
            // when the app is launched. This is roughly analogous to creating a "world" coordinate system
            // with the origin placed at the device's position as the app is launched.
            referenceFrame = locator.CreateStationaryFrameOfReferenceAtCurrentLocation();

            // Notes on spatial tracking APIs:
            // * Stationary reference frames are designed to provide a best-fit position relative to the
            //   overall space. Individual positions within that reference frame are allowed to drift slightly
            //   as the device learns more about the environment.
            // * When precise placement of individual holograms is required, a SpatialAnchor should be used to
            //   anchor the individual hologram to a position in the real world - for example, a point the user
            //   indicates to be of special interest. Anchor positions do not drift, but can be corrected; the
            //   anchor will use the corrected position starting in the next frame after the correction has
            //   occurred.
        }
        private bool GetHistoricalPose(out Vector3 cameraPosition, out Quaternion cameraRotation)
        {
#if !UNITY_EDITOR && UNITY_WSA
            SpatialCoordinateSystem unityCoordinateSystem = Marshal.GetObjectForIUnknown(WorldManager.GetNativeISpatialCoordinateSystemPtr()) as SpatialCoordinateSystem;
            if (unityCoordinateSystem == null)
            {
                Debug.LogError("Failed to get the native SpatialCoordinateSystem");
                cameraPosition = default(Vector3);
                cameraRotation = default(Quaternion);
                return(false);
            }

            if (timeConversionCalendar == null)
            {
                timeConversionCalendar = new Calendar();
            }

            timeConversionCalendar.SetToNow();

            PerceptionTimestamp perceptionTimestamp = PerceptionTimestampHelper.FromHistoricalTargetTime(timeConversionCalendar.GetDateTime());

            if (perceptionTimestamp != null)
            {
                SpatialLocator locator = SpatialLocator.GetDefault();
                if (locator != null)
                {
                    SpatialLocation headPose = locator.TryLocateAtTimestamp(perceptionTimestamp, unityCoordinateSystem);
                    if (headPose != null)
                    {
                        var systemOrientation = headPose.Orientation;
                        var systemPostion     = headPose.Position;

                        // Convert the orientation and position from Windows to Unity coordinate spaces
                        cameraRotation.x = -systemOrientation.X;
                        cameraRotation.y = -systemOrientation.Y;
                        cameraRotation.z = systemOrientation.Z;
                        cameraRotation.w = systemOrientation.W;

                        cameraPosition.x = systemPostion.X;
                        cameraPosition.y = systemPostion.Y;
                        cameraPosition.z = -systemPostion.Z;
                        return(true);
                    }
                }
            }

            cameraPosition = default(Vector3);
            cameraRotation = default(Quaternion);
            return(false);
#else
            cameraPosition = Camera.main.transform.position;
            cameraRotation = Camera.main.transform.rotation;
            return(true);
#endif
        }
    private void SetHolographicSpace()
    {
        // from Holographic Face Tracking Example
        // Use the default SpatialLocator to track the motion of the device.
        m_locator = SpatialLocator.GetDefault();

        // The simplest way to render world-locked holograms is to create a stationary reference frame
        // when the app is launched. This is roughly analogous to creating a "world" coordinate system
        // with the origin placed at the device's position as the app is launched.
        m_referenceFrame = m_locator.CreateStationaryFrameOfReferenceAtCurrentLocation();
    }
Exemple #7
0
 private void OnLocated(SpatialLocator loc, object args)
 {
     if (frame != null || loc.Locatability != SpatialLocatability.PositionalTrackingActive)
     {
         return;
     }
     frame  = loc.CreateStationaryFrameOfReferenceAtCurrentLocation();
     anchor = SpatialAnchor.TryCreateRelativeTo(frame.CoordinateSystem);
     root   = World.FromPerceptionAnchor(anchor).ToMatrix();
     UpdateBounds(center, radius);
 }
Exemple #8
0
        async void LoadAssets(string[] pakFiles)
        {
            ReferenceFrame = SpatialLocator.GetDefault().CreateStationaryFrameOfReferenceAtCurrentLocation();
            foreach (var assetName in pakFiles)
            {
                if (!string.IsNullOrEmpty(assetName) && await ApplicationData.Current.LocalFolder.TryGetItemAsync(assetName) == null)
                {
                    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///" + assetName));

                    var folder = ApplicationData.Current.LocalFolder;
                    await file.CopyAsync(folder);
                }
            }
            await CopyEmbeddedResourceToLocalFolder("Urho.CoreData.pak", "CoreData.pak");

            assetsLoaded = true;
        }
        public GestureController()
        {
            spatialLocator = SpatialLocator.GetDefault();

            gestureRecognizer = new SpatialGestureRecognizer(
                SpatialGestureSettings.Tap |
                SpatialGestureSettings.ManipulationTranslate);

            gestureRecognizer.ManipulationCanceled  += OnManipulationCanceled;
            gestureRecognizer.ManipulationCompleted += OnManipulationCompleted;
            gestureRecognizer.ManipulationStarted   += OnManipulationStarted;
            gestureRecognizer.ManipulationUpdated   += OnManipulationUpdated;
            gestureRecognizer.Tapped += OnTapped;

            interactionManager = SpatialInteractionManager.GetForCurrentView();
            interactionManager.InteractionDetected += OnInteractionDetected;
        }
        void OnHolographicDisplayIsAvailableChanged(Object o, Object args)
        {
            // Get the spatial locator for the default HolographicDisplay, if one is available.
            SpatialLocator spatialLocator = null;

            if (canGetDefaultHolographicDisplay)
            {
                HolographicDisplay defaultHolographicDisplay = HolographicDisplay.GetDefault();
                if (defaultHolographicDisplay != null)
                {
                    spatialLocator = defaultHolographicDisplay.SpatialLocator;
                }
            }
            else
            {
                spatialLocator = SpatialLocator.GetDefault();
            }

            if (this.spatialLocator != spatialLocator)
            {
                // If the spatial locator is disconnected or replaced, we should discard any state that was
                // based on it.
                if (this.spatialLocator != null)
                {
                    this.spatialLocator.LocatabilityChanged -= this.OnLocatabilityChanged;
                    this.spatialLocator = null;
                }

                this.stationaryReferenceFrame = null;

                if (spatialLocator != null)
                {
                    // Use the SpatialLocator from the default HolographicDisplay to track the motion of the device.
                    this.spatialLocator = spatialLocator;

                    // Respond to changes in the positional tracking state.
                    this.spatialLocator.LocatabilityChanged += this.OnLocatabilityChanged;

                    // The simplest way to render world-locked holograms is to create a stationary reference frame
                    // based on a SpatialLocator. This is roughly analogous to creating a "world" coordinate system
                    // with the origin placed at the device's position as the app is launched.
                    this.stationaryReferenceFrame = this.spatialLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();
                }
            }
        }
Exemple #11
0
    //   int reconstructionID = 0;

    // initialization
    void Start()
    {
        locator = SpatialLocator.GetDefault();
        originFrameOfReference = locator.CreateStationaryFrameOfReferenceAtCurrentLocation();
        audioData         = GetComponent <AudioSource>();
        startHeadPosition = Camera.main.transform.position;
        newHeadPosition   = startHeadPosition;
        textMesh.text     = photoCount.ToString();

        Debug.Log("Airtap to start/stop capture");

        //CreateScene("Test");

        CreateFolder();

        gr              = new GestureRecognizer();
        gr.TappedEvent += Tap;
        gr.StartCapturingGestures();
    }
Exemple #12
0
        private bool InitializeUWP()
        {
            // Ask or check for Spatial permissions
            SpatialSurfaceObserver.RequestAccessAsync().Completed = (i, s) => {
                if (s == AsyncStatus.Completed && i.GetResults() == SpatialPerceptionAccessStatus.Allowed)
                {
                    observer = new SpatialSurfaceObserver();
                    observer.ObservedSurfacesChanged += OnSurfaceUpdate;
                    UpdateBounds(center, radius);
                }
            };

            // Establish the coordinate frame of reference
            var locator = SpatialLocator.GetDefault();

            if (locator != null)
            {
                locator.LocatabilityChanged += OnLocated;
                OnLocated(locator, null);
            }
            return(true);
        }
Exemple #13
0
        /// <summary>
        /// Set holographic space
        /// </summary>
        /// <param name="holographicSpace">The holographic space</param>
        public void SetHolographicSpace(HolographicSpace holographicSpace)
        {
            // The DeviceResources class uses the preferred DXGI adapter ID from the holographic
            // space (when available) to create a Direct3D device. The HolographicSpace
            // uses this ID3D11Device to create and manage device-based resources such as
            // swap chains.
            this.deviceResources.SetHolographicSpace(holographicSpace);

            this.holographicSpace = holographicSpace;

            // Use the default SpatialLocator to track the motion of the device.
            this.locator = SpatialLocator.GetDefault();

            // Be able to respond to changes in the positional tracking state.
            this.locator.LocatabilityChanged += this.OnLocatabilityChanged;

            // Respond to camera added events by creating any resources that are specific
            // to that camera, such as the back buffer render target view.
            // When we add an event handler for CameraAdded, the API layer will avoid putting
            // the new camera in new HolographicFrames until we complete the deferral we created
            // for that handler, or return from the handler without creating a deferral. This
            // allows the app to take more than one frame to finish creating resources and
            // loading assets for the new holographic camera.
            // This function should be registered before the app creates any HolographicFrames.
            holographicSpace.CameraAdded += this.OnCameraAdded;

            // Respond to camera removed events by releasing resources that were created for that
            // camera.
            // When the app receives a CameraRemoved event, it releases all references to the back
            // buffer right away. This includes render target views, Direct2D target bitmaps, and so on.
            // The app must also ensure that the back buffer is not attached as a render target, as
            // shown in DeviceResources.ReleaseResourcesForBackBuffer.
            holographicSpace.CameraRemoved += this.OnCameraRemoved;

            // The simplest way to render world-locked holograms is to create a stationary reference frame
            // when the app is launched. This is roughly analogous to creating a "world" coordinate system
            // with the origin placed at the device's position as the app is launched.
            this.ReferenceFrame = this.locator.CreateStationaryFrameOfReferenceAtCurrentLocation();
        }
Exemple #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SeeingSharpHolographicsSpacePainter"/> class.
        /// </summary>
        /// <param name="targetWindow">The target window into which to render.</param>
        public SeeingSharpHolographicsSpacePainter(CoreWindow targetWindow)
        {
            m_targetWindow = targetWindow;

            // Call generic initialization
            //  (choose device, create holographic space)
            InitializeHolographicSpace(targetWindow);

            // Use the default SpatialLocator to track the motion of the device.
            m_spatialLocator = SpatialLocator.GetDefault();

            // Be able to respond to changes in the positional tracking state.
            m_spatialLocator.LocatabilityChanged += this.OnSpatialLocator_LocatabilityChanged;

            // Respond to camera added events by creating any resources that are specific
            // to that camera, such as the back buffer render target view.
            // When we add an event handler for CameraAdded, the API layer will avoid putting
            // the new camera in new HolographicFrames until we complete the deferral we created
            // for that handler, or return from the handler without creating a deferral. This
            // allows the app to take more than one frame to finish creating resources and
            // loading assets for the new holographic camera.
            // This function should be registered before the app creates any HolographicFrames.
            m_holoSpace.CameraAdded += this.OnHoloSpace_CameraAdded;

            // Respond to camera removed events by releasing resources that were created for that
            // camera.
            // When the app receives a CameraRemoved event, it releases all references to the back
            // buffer right away. This includes render target views, Direct2D target bitmaps, and so on.
            // The app must also ensure that the back buffer is not attached as a render target, as
            // shown in DeviceResources.ReleaseResourcesForBackBuffer.
            m_holoSpace.CameraRemoved += this.OnHoloSpace_CameraRemoved;

            // The simplest way to render world-locked holograms is to create a stationary reference frame
            // when the app is launched. This is roughly analogous to creating a "world" coordinate system
            // with the origin placed at the device's position as the app is launched.
            m_referenceFrame = m_spatialLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();
        }
Exemple #15
0
        public unsafe void Run()
        {
            AppStarting?.Invoke();
            ReferenceFrame = SpatialLocator.GetDefault().CreateStationaryFrameOfReferenceAtCurrentLocation();

            var coreWindow = CoreWindow.GetForCurrentThread();

            coreWindow.CustomProperties.Add(nameof(HolographicSpace), HolographicSpace);

            InitializeSpace();
            InteractionManager = SpatialInteractionManager.GetForCurrentView();
            InteractionManager.InteractionDetected += (s, e) => GesturesManager?.HandleInteraction(e.Interaction);

            while (!windowClosed)
            {
                if (!appInited)
                {
                    SpatialMappingManager = new SpatialMappingManager();
                    VoiceManager          = new VoiceManager();
                    appInited             = true;

                    if (options == null)
                    {
                        options = new ApplicationOptions();
                    }

                    //override some options:
                    options.LimitFps = false;
                    options.Width    = 1268;                  //TODO: find system
                    options.Height   = 720;

                    Game = (HoloApplication)Activator.CreateInstance(holoAppType, options);
                    Game.Run();
                    GesturesManager = new GesturesManager(Game, ReferenceFrame);
                    AppStarted?.Invoke(Game);
                }

                if (windowVisible && (null != HolographicSpace))
                {
                    if (Game != null)
                    {
                        CurrentFrame = HolographicSpace.CreateNextFrame();
                        CurrentFrame.UpdateCurrentPrediction();
                        var prediction = CurrentFrame.CurrentPrediction;
                        if (prediction.CameraPoses.Count < 1)
                        {
                            continue;
                        }
                        var cameraPose = prediction.CameraPoses[0];

                        var viewBox = cameraPose.TryGetViewTransform(ReferenceFrame.CoordinateSystem);
                        if (viewBox != null)
                        {
                            Matrix4x4 leftViewMatrixDx  = viewBox.Value.Left;
                            Matrix4x4 rightViewMatrixDx = viewBox.Value.Right;
                            Matrix4x4 leftProjMatrixDx  = cameraPose.ProjectionTransform.Left;
                            Matrix4x4 rightProjMatrixDx = cameraPose.ProjectionTransform.Right;

                            Matrix4 leftViewMatrixUrho  = *(Matrix4 *)(void *)&leftViewMatrixDx;
                            Matrix4 rightViewMatrixUrho = *(Matrix4 *)(void *)&rightViewMatrixDx;
                            Matrix4 leftProjMatrixUrho  = *(Matrix4 *)(void *)&leftProjMatrixDx;
                            Matrix4 rightProjMatrixUrho = *(Matrix4 *)(void *)&rightProjMatrixDx;
                            Game.UpdateStereoView(leftViewMatrixUrho, rightViewMatrixUrho, leftProjMatrixUrho, rightProjMatrixUrho);
                        }

                        var parameters = CurrentFrame.GetRenderingParameters(cameraPose);
                        if (Game.FocusWorldPoint != Vector3.Zero)
                        {
                            parameters.SetFocusPoint(ReferenceFrame.CoordinateSystem,
                                                     new System.Numerics.Vector3(
                                                         Game.FocusWorldPoint.X,
                                                         Game.FocusWorldPoint.Y,
                                                         -Game.FocusWorldPoint.Z));                //LH->RH
                        }
                        Game.Engine.RunFrame();
                        CurrentFrame.PresentUsingCurrentPrediction(HolographicFramePresentWaitBehavior.WaitForFrameToFinish);
                    }
                    CoreWindow.GetForCurrentThread().Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);
                }
                else
                {
                    CoreWindow.GetForCurrentThread().Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessOneAndAllPending);
                }
            }
        }
Exemple #16
0
 public HoloLensCamera()
 {
     locator = SpatialLocator.GetDefault();
     originalFrameOfReference = locator.CreateStationaryFrameOfReferenceAtCurrentLocation();
 }
        private void OnLocatabilityChanged(SpatialLocator sender, Object args)
        {
            switch (sender.Locatability)
            {
                case SpatialLocatability.Unavailable:
                    // Holograms cannot be rendered.
                    {
                        String message = "Warning! Positional tracking is " + sender.Locatability + ".";
                        Debug.WriteLine(message);
                    }
                    break;

                // In the following three cases, it is still possible to place holograms using a
                // SpatialLocatorAttachedFrameOfReference.
                case SpatialLocatability.PositionalTrackingActivating:
                // The system is preparing to use positional tracking.

                case SpatialLocatability.OrientationOnly:
                // Positional tracking has not been activated.

                case SpatialLocatability.PositionalTrackingInhibited:
                    // Positional tracking is temporarily inhibited. User action may be required
                    // in order to restore positional tracking.
                    break;

                case SpatialLocatability.PositionalTrackingActive:
                    // Positional tracking is active. World-locked content can be rendered.
                    break;
            }
        }
        /// <summary>
        /// Set holographic space
        /// </summary>
        /// <param name="holographicSpace">The holographic space</param>
        public void SetHolographicSpace(HolographicSpace holographicSpace)
        {
            // The DeviceResources class uses the preferred DXGI adapter ID from the holographic
            // space (when available) to create a Direct3D device. The HolographicSpace
            // uses this ID3D11Device to create and manage device-based resources such as
            // swap chains.
            this.deviceResources.SetHolographicSpace(holographicSpace);

            this.holographicSpace = holographicSpace;

            // Use the default SpatialLocator to track the motion of the device.
            this.locator = SpatialLocator.GetDefault();

            // Be able to respond to changes in the positional tracking state.
            this.locator.LocatabilityChanged += this.OnLocatabilityChanged;

            // Respond to camera added events by creating any resources that are specific
            // to that camera, such as the back buffer render target view.
            // When we add an event handler for CameraAdded, the API layer will avoid putting
            // the new camera in new HolographicFrames until we complete the deferral we created
            // for that handler, or return from the handler without creating a deferral. This
            // allows the app to take more than one frame to finish creating resources and
            // loading assets for the new holographic camera.
            // This function should be registered before the app creates any HolographicFrames.
            holographicSpace.CameraAdded += this.OnCameraAdded;

            // Respond to camera removed events by releasing resources that were created for that
            // camera.
            // When the app receives a CameraRemoved event, it releases all references to the back
            // buffer right away. This includes render target views, Direct2D target bitmaps, and so on.
            // The app must also ensure that the back buffer is not attached as a render target, as
            // shown in DeviceResources.ReleaseResourcesForBackBuffer.
            holographicSpace.CameraRemoved += this.OnCameraRemoved;

            // The simplest way to render world-locked holograms is to create a stationary reference frame
            // when the app is launched. This is roughly analogous to creating a "world" coordinate system
            // with the origin placed at the device's position as the app is launched.
            this.ReferenceFrame = this.locator.CreateStationaryFrameOfReferenceAtCurrentLocation();
        }
Exemple #19
0
        /// <summary>
        /// Initializes the world coordinate system for the application using a pre-defined spatial anchor,
        /// or creates it at a stationary frame of reference if it does not exist. Once initialized, the
        /// world coordinate system will be consistent across application sessions, unless the associated
        /// spatial anchor is modified or deleted.
        /// <param name="worldSpatialAnchor">A spatial anchor to use for the world (may be null).</param>
        /// <param name="regenerateDefaultWorldSpatialAnchorIfNeeded">Flag indicating whether to regenerate and persist default world spatial anchor if currently persisted anchor fails to localize in the current environment (default: false).</param>
        /// </summary>
        private static void InitializeWorldCoordinateSystem(SpatialAnchor worldSpatialAnchor, bool regenerateDefaultWorldSpatialAnchorIfNeeded)
        {
            SpatialAnchor TryCreateDefaultWorldSpatialAnchor(SpatialStationaryFrameOfReference world)
            {
                // Save the world spatial coordinate system
                WorldSpatialCoordinateSystem = world.CoordinateSystem;

                // Create a spatial anchor to represent the world origin and persist it to the spatial
                // anchor store to ensure that the origin remains coherent between sessions.
                return(SpatialAnchorHelper.TryCreateSpatialAnchor(DefaultWorldSpatialAnchorId, WorldSpatialCoordinateSystem));
            }

            // If no world anchor was given, try to load the default world spatial anchor if it was previously persisted
            worldSpatialAnchor ??= SpatialAnchorHelper.TryGetSpatialAnchor(DefaultWorldSpatialAnchorId);

            if (worldSpatialAnchor != null)
            {
                // Set the world spatial coordinate system using the spatial anchor
                WorldSpatialCoordinateSystem = worldSpatialAnchor.CoordinateSystem;
                if (regenerateDefaultWorldSpatialAnchorIfNeeded)
                {
                    var locator = SpatialLocator.GetDefault();
                    if (locator == null)
                    {
                        throw new Exception($"Could not get spatial locator.");
                    }

                    // determine whether we can localize in the current environment
                    var world   = locator.CreateStationaryFrameOfReferenceAtCurrentLocation();
                    var success = world.CoordinateSystem.TryGetTransformTo(WorldSpatialCoordinateSystem) != null;
                    if (!success)
                    {
                        SpatialAnchorHelper.RemoveSpatialAnchor(DefaultWorldSpatialAnchorId);
                        worldSpatialAnchor = TryCreateDefaultWorldSpatialAnchor(world);
                        if (worldSpatialAnchor == null)
                        {
                            throw new Exception("Could not create the persistent world spatial anchor.");
                        }
                    }
                }
            }
            else
            {
                // Generate and persist the default world spatial anchor
                var locator = SpatialLocator.GetDefault();

                if (locator != null)
                {
                    // This creates a stationary frame of reference which we will use as our world origin
                    var world = locator.CreateStationaryFrameOfReferenceAtCurrentLocation();
                    worldSpatialAnchor = TryCreateDefaultWorldSpatialAnchor(world);

                    if (worldSpatialAnchor == null)
                    {
                        System.Diagnostics.Trace.WriteLine($"WARNING: Could not create the persistent world spatial anchor.");
                    }
                }
                else
                {
                    System.Diagnostics.Trace.WriteLine($"WARNING: Could not get spatial locator (expected in StereoKit on desktop).");
                }
            }

            if (worldSpatialAnchor != null)
            {
                // At startup, we need to capture the pose of StereoKit with respect to the world anchor, and vice versa.
                // These transforms will allow us to convert world coordinates to/from StereoKit coordinates where needed:
                // on input from StereoKit -> \psi, and on output (rendering) \psi -> StereoKit

                // Query the pose of the world anchor. We use this pose for rendering correctly in the world,
                // and for transforming from world coordinates to StereoKit coordinates.
                StereoKitTransforms.WorldHierarchy   = World.FromPerceptionAnchor(worldSpatialAnchor).ToMatrix();
                StereoKitTransforms.WorldToStereoKit = StereoKitTransforms.WorldHierarchy.ToCoordinateSystem();

                // Inverting gives us a coordinate system that can be used for transforming from StereoKit to world coordinates.
                StereoKitTransforms.StereoKitToWorld = StereoKitTransforms.WorldToStereoKit.Invert();

                System.Diagnostics.Trace.WriteLine($"StereoKit origin: {StereoKitTransforms.StereoKitToWorld.Origin.X},{StereoKitTransforms.StereoKitToWorld.Origin.Y},{StereoKitTransforms.StereoKitToWorld.Origin.Z}");

                // TODO: It would be nice if we could actually just shift the origin coordinate system in StereoKit
                // to the pose currently defined in StereoKitTransforms.WorldPose.
                // There's currently an open issue for this: https://github.com/maluoi/StereoKit/issues/189

                // Simply setting the renderer camera root does not work, as its transform appears to be applied in the wrong order.
                // E.g., if the starting StereoKit pose is at a yaw rotation of 180 degrees, we would want to apply that transform
                // first, then apply the transform of the headset pose (perhaps pitching up). Instead, it appears that the headset
                // pose is applied first (e.g., pitching up), and *then* the Renderer.CameraRoot transform is applied (yaw of 180 degrees)
                // which in this example manifests as the pitch going down, opposite of what we desired.
                ////Renderer.CameraRoot = stereoKitTransform.Inverse;
            }
        }
Exemple #20
0
        public unsafe void Run()
        {
            AppStarting?.Invoke();
            ReferenceFrame = SpatialLocator.GetDefault().CreateStationaryFrameOfReferenceAtCurrentLocation();

            var coreWindow = CoreWindow.GetForCurrentThread();

            coreWindow.CustomProperties.Add(nameof(HolographicSpace), HolographicSpace);

            InitializeSpace();
            HolographicSpace.CameraAdded += HolographicSpace_CameraAdded;
            InteractionManager            = SpatialInteractionManager.GetForCurrentView();
            if (InteractionManager != null)
            {
                InteractionManager.InteractionDetected += (s, e) => GesturesManager?.HandleInteraction(e.Interaction);
            }

            while (!windowClosed)
            {
                if (appInited && windowVisible && (null != HolographicSpace))
                {
                    if (Game != null)
                    {
                        CurrentFrame = HolographicSpace.CreateNextFrame();
                        CurrentFrame.UpdateCurrentPrediction();
                        var prediction = CurrentFrame.CurrentPrediction;
                        if (prediction.CameraPoses.Count < 1)
                        {
                            continue;
                        }
                        var cameraPose = prediction.CameraPoses[0];

                        var viewBox = cameraPose.TryGetViewTransform(ReferenceFrame.CoordinateSystem);
                        if (viewBox != null)
                        {
                            Matrix4x4 leftViewMatrixDx  = viewBox.Value.Left;
                            Matrix4x4 rightViewMatrixDx = viewBox.Value.Right;
                            Matrix4x4 leftProjMatrixDx  = cameraPose.ProjectionTransform.Left;
                            Matrix4x4 rightProjMatrixDx = cameraPose.ProjectionTransform.Right;

                            Matrix4 leftViewMatrixUrho  = *(Matrix4 *)(void *)&leftViewMatrixDx;
                            Matrix4 rightViewMatrixUrho = *(Matrix4 *)(void *)&rightViewMatrixDx;
                            Matrix4 leftProjMatrixUrho  = *(Matrix4 *)(void *)&leftProjMatrixDx;
                            Matrix4 rightProjMatrixUrho = *(Matrix4 *)(void *)&rightProjMatrixDx;
                            Game.UpdateStereoView(leftViewMatrixUrho, rightViewMatrixUrho, leftProjMatrixUrho, rightProjMatrixUrho);
                        }

                        var parameters = CurrentFrame.GetRenderingParameters(cameraPose);
                        if (Game.FocusWorldPoint != Vector3.Zero)
                        {
                            parameters.SetFocusPoint(ReferenceFrame.CoordinateSystem,
                                                     new System.Numerics.Vector3(
                                                         Game.FocusWorldPoint.X,
                                                         Game.FocusWorldPoint.Y,
                                                         -Game.FocusWorldPoint.Z));                //LH->RH
                        }
                        Game.Engine.RunFrame();
                        CurrentFrame.PresentUsingCurrentPrediction(HolographicFramePresentWaitBehavior.WaitForFrameToFinish);
                    }
                    CoreWindow.GetForCurrentThread().Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);
                }
                else
                {
                    CoreWindow.GetForCurrentThread().Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessOneAndAllPending);
                }
            }
        }