Koordinatensysteme in DirectXCoordinate systems in DirectX

Hinweis

Dieser Artikel bezieht sich auf die älteren WinRT-APIs.This article relates to the legacy WinRT native APIs. Bei neuen nativen App-Projekten wird die Verwendung der openxr-API empfohlen.For new native app projects, we recommend using the OpenXR API.

Koordinatensysteme bilden die Grundlage für das räumliche Verständnis von Windows Mixed Reality-APIs.Coordinate systems form the basis for spatial understanding offered by Windows Mixed Reality APIs.

Die heutigen VR-oder Einzel Raum-VR-Geräte richten ein Primäres Koordinatensystem für den nach verfolgten Speicher ein.Today's seated VR or single-room VR devices establish one primary coordinate system for their tracked space. Geräte mit gemischter Realität (z. b. hololens) sind für große, nicht definierte Umgebungen konzipiert, und das Gerät ermittelt und erfährt seine Umgebung, während der Benutzer Sie durchläuft.Mixed Reality devices like HoloLens are designed for large undefined environments, with the device discovering and learning about its surroundings as the user walks around. Das Gerät passt sich an, um das Wissen über die Räume des Benutzers ständig zu verbessern, führt jedoch zu Koordinatensystemen, die die Beziehung zwischen der Lebensdauer der apps untereinander ändern.The device adapts to continually improving knowledge about the user's rooms, but results in coordinate systems that change their relationship to one another over the apps lifetime. Die gemischte Realität von Windows unterstützt ein breites Spektrum an Geräten, die von sitzenden immersiven Headsets durch weltweit angehängte Referenzrahmen reichen.Windows Mixed Reality supports a wide spectrum of devices, ranging from seated immersive headsets through world-attached reference frames.

Hinweis

Die Code Ausschnitte in diesem Artikel veranschaulichen derzeit die Verwendung von C++/CX anstelle von C + +17-kompatiblen C++/WinRT, wie Sie in der C++ Holographic-Projektvorlageverwendet werden.The code snippets in this article currently demonstrate use of C++/CX rather than C++17-compliant C++/WinRT as used in the C++ holographic project template. Die Konzepte sind äquivalent zu einem C++/WinRT-Projekt. Sie müssen jedoch den Code übersetzen.The concepts are equivalent for a C++/WinRT project, though you will need to translate the code.

Räumliche Koordinatensysteme in WindowsSpatial coordinate systems in Windows

Der Kerntyp, der in Bezug auf echte Koordinatensysteme in Windows verwendet wird, ist das spatialcoordinatesystem.The core type used to reason about real-world coordinate systems in Windows is the SpatialCoordinateSystem. Eine Instanz dieses Typs stellt ein beliebiges Koordinatensystem dar, das eine Methode zum erhalten von Transformationsmatrix Daten bereitstellt, die Sie zum Transformieren zwischen zwei Koordinatensystemen verwenden können, ohne die Details der einzelnen Koordinaten zu verstehen.An instance of this type represents an arbitrary coordinate system, providing a method for getting transformation matrix data that you can use to transform between two coordinate systems without understanding the details of each.

Methoden, die räumliche Informationen zurückgeben, akzeptieren einen spatialcoordinatesystem-Parameter, um Ihnen die Entscheidung über das Koordinatensystem zu ermöglichen, in dem die zurück zugebende Koordinaten am nützlichsten sind.Methods that return spatial information will accept a SpatialCoordinateSystem parameter to let you decide the coordinate system in which it's most useful for those coordinates to be returned. Räumliche Informationen werden als Punkte, Strahlen oder Volumes in der Benutzerumgebung dargestellt, und die Einheiten für diese Koordinaten sind immer in Meter.Spatial information is represented as points, rays, or volumes in the user's surroundings, and the units for these coordinates will always be in meters.

Ein spatialcoordinatesystem verfügt über eine dynamische Beziehung mit anderen Koordinatensystemen, einschließlich derjenigen, die die Position des Geräts darstellen.A SpatialCoordinateSystem has a dynamic relationship with other coordinate systems, including those that represent the device's position. An jedem Punkt kann das Gerät einige Koordinatensysteme und keine anderen suchen.At any point, the device can locate some coordinate systems and not others. Für die meisten Koordinatensysteme muss Ihre APP bereit sein, Zeiträume zu verarbeiten, in denen Sie nicht gefunden werden können.For most coordinate systems, your app must be ready to handle periods of time during which they cannot be located.

Die Anwendung sollte spatialcoordinatesystems nicht direkt erstellen, stattdessen sollten Sie über die perception-APIs genutzt werden.Your application shouldn't create SpatialCoordinateSystems directly - rather they should be consumed via the Perception APIs. Es gibt drei primäre Quellen für Koordinatensysteme in den perception-APIs, von denen jede einem auf der Seite Koordinatensysteme beschriebenen Konzept zugeordnet ist:There are three primary sources of coordinate systems in the Perception APIs, each of which map to a concept described on the Coordinate systems page:

Alle Koordinatensysteme, die von diesen Objekten zurückgegeben werden, sind mit der rechten Hand, mit + y nach oben, + x nach rechts und + z rückwärts.All of the coordinate systems returned by these objects are right-handed, with +y up, +x to the right and +z backwards. Sie können sich merken, welche Richtung die positive z-Achse zeigt, indem Sie die Finger entweder von Links oder rechts in der positiven x-Richtung zeigen und in die positive y-Richtung hinein.You can remember which direction the positive z-axis points by pointing the fingers of either your left or right hand in the positive x direction and curling them into the positive y direction. Die Richtung, auf die sich der Ziehpunkt von Ihnen befindet, ist die Richtung, auf die die positive z-Achse für dieses Koordinatensystem zeigt.The direction your thumb points, either toward or away from you, is the direction that the positive z-axis points for that coordinate system. In der folgenden Abbildung werden diese beiden Koordinatensysteme veranschaulicht.The following illustration shows these two coordinate systems.

Linke und Rechte KoordinatensystemeLeft-hand and right-hand coordinate systems
Linke und Rechte KoordinatensystemeLeft-hand and right-hand coordinate systems

Verwenden Sie die spatizuweisung -Klasse, um entweder einen angefügten oder einen stationären Verweis Rahmen zu erstellen, der auf der Grundlage der hololens-Position in ein spatialcoordinatesystem Bootstrap.Use the SpatialLocator class to create either an attached or stationary frame of reference to bootstrap into a SpatialCoordinateSystem based on the HoloLens position. Fahren Sie mit dem nächsten Abschnitt fort, um weitere Informationen zu diesem Vorgang zu erhalten.Continue to the next section to learn more about this process.

Platzieren von holograms weltweit mithilfe einer räumlichen PhasePlace holograms in the world using a spatial stage

Das Koordinatensystem für nicht transparente Windows Mixed Reality-immersive Headsets wird mithilfe der statischen spatialstageframeofreferen:: Current -Eigenschaft aufgerufen.The coordinate system for opaque Windows Mixed Reality immersive headsets is accessed using the static SpatialStageFrameOfReference::Current property. Diese API bietet Folgendes:This API provides:

  • Ein KoordinatensystemA coordinate system
  • Informationen dazu, ob der Player oder mobil istInformation about whether the player is seated or mobile
  • Die Grenze eines sicheren Bereichs zum durchlaufen, wenn der Player mobil istThe boundary of a safe area for walking around if the player is mobile
  • Ein Hinweis darauf, ob das Headset direktional ist.An indication of whether the headset is directional.
  • Ein Ereignishandler für Aktualisierungen der räumlichen Phase.An event handler for updates to the spatial stage.

Zuerst erhalten wir die räumliche Phase und abonnieren Updates für Sie:First, we get the spatial stage and subscribe for updates to it:

Code für die Initialisierung räumlicher PhasenCode for Spatial stage initialization

SpatialStageManager::SpatialStageManager(
    const std::shared_ptr<DX::DeviceResources>& deviceResources, 
    const std::shared_ptr<SceneController>& sceneController)
    : m_deviceResources(deviceResources), m_sceneController(sceneController)
{
    // Get notified when the stage is updated.
    m_spatialStageChangedEventToken = SpatialStageFrameOfReference::CurrentChanged +=
        ref new EventHandler<Object^>(std::bind(&SpatialStageManager::OnCurrentChanged, this, _1));

    // Make sure to get the current spatial stage.
    OnCurrentChanged(nullptr);
}

In der OnCurrentChanged-Methode sollte Ihre APP die räumliche Phase überprüfen und die Benutzerumgebung aktualisieren.In the OnCurrentChanged method, your app should inspect the spatial stage and update the player experience. In diesem Beispiel stellen wir eine Visualisierung der Stufen Begrenzung und der vom Benutzer angegebenen Startposition sowie den Bereich der Ansicht und den Bereich der Verschiebungs Eigenschaften der Stufe bereit.In this example, we provide a visualization of the stage boundary and the start position specified by the user and the stage's range of view and range of movement properties. Wir greifen auch auf unser eigenes stationäres Koordinatensystem zurück, wenn eine Phase nicht bereitgestellt werden kann.We also fall back to our own stationary coordinate system, when a stage cannot be provided.

Code für das Update für räumliche StufenCode for Spatial stage update

void SpatialStageManager::OnCurrentChanged(Object^ /*o*/)
{
    // The event notifies us that a new stage is available.
    // Get the current stage.
    m_currentStage = SpatialStageFrameOfReference::Current;

    // Clear previous content.
    m_sceneController->ClearSceneObjects();

    if (m_currentStage != nullptr)
    {
        // Obtain stage geometry.
        auto stageCoordinateSystem = m_currentStage->CoordinateSystem;
        auto boundsVertexArray = m_currentStage->TryGetMovementBounds(stageCoordinateSystem);

        // Visualize the area where the user can move around.
        std::vector<float3> boundsVertices;
        boundsVertices.resize(boundsVertexArray->Length);
        memcpy(boundsVertices.data(), boundsVertexArray->Data, boundsVertexArray->Length * sizeof(float3));
        std::vector<unsigned short> indices = TriangulatePoints(boundsVertices);
        m_stageBoundsShape =
            std::make_shared<SceneObject>(
                    m_deviceResources,
                    reinterpret_cast<std::vector<XMFLOAT3>&>(boundsVertices),
                    indices,
                    XMFLOAT3(DirectX::Colors::SeaGreen),
                    stageCoordinateSystem);
        m_sceneController->AddSceneObject(m_stageBoundsShape);

        // In this sample, we draw a visual indicator for some spatial stage properties.
        // If the view is forward-only, the indicator is a half circle pointing forward - otherwise, it
        // is a full circle.
        // If the user can walk around, the indicator is blue. If the user is seated, it is red.

        // The indicator is rendered at the origin - which is where the user declared the center of the
        // stage to be during setup - above the plane of the stage bounds object.
        float3 visibleAreaCenter = float3(0.f, 0.001f, 0.f);

        // Its shape depends on the look direction range.
        std::vector<float3> visibleAreaIndicatorVertices;
        if (m_currentStage->LookDirectionRange == SpatialLookDirectionRange::ForwardOnly)
        {
            // Half circle for forward-only look direction range.
            visibleAreaIndicatorVertices = CreateCircle(visibleAreaCenter, 0.25f, 9, XM_PI);
        }
        else
        {
            // Full circle for omnidirectional look direction range.
            visibleAreaIndicatorVertices = CreateCircle(visibleAreaCenter, 0.25f, 16, XM_2PI);
        }

        // Its color depends on the movement range.
        XMFLOAT3 visibleAreaColor;
        if (m_currentStage->MovementRange == SpatialMovementRange::NoMovement)
        {
            visibleAreaColor = XMFLOAT3(DirectX::Colors::OrangeRed);
        }
        else
        {
            visibleAreaColor = XMFLOAT3(DirectX::Colors::Aqua);
        }

        std::vector<unsigned short> visibleAreaIndicatorIndices = TriangulatePoints(visibleAreaIndicatorVertices);

        // Visualize the look direction range.
        m_stageVisibleAreaIndicatorShape =
            std::make_shared<SceneObject>(
                    m_deviceResources,
                    reinterpret_cast<std::vector<XMFLOAT3>&>(visibleAreaIndicatorVertices),
                    visibleAreaIndicatorIndices,
                    visibleAreaColor,
                    stageCoordinateSystem);
        m_sceneController->AddSceneObject(m_stageVisibleAreaIndicatorShape);
    }
    else
    {
        // No spatial stage was found.
        // Fall back to a stationary coordinate system.
        auto locator = SpatialLocator::GetDefault();
        if (locator)
        {
            m_stationaryFrameOfReference = locator->CreateStationaryFrameOfReferenceAtCurrentLocation();

            // Render an indicator, so that we know we fell back to a mode without a stage.
            std::vector<float3> visibleAreaIndicatorVertices;
            float3 visibleAreaCenter = float3(0.f, -2.0f, 0.f);
            visibleAreaIndicatorVertices = CreateCircle(visibleAreaCenter, 0.125f, 16, XM_2PI);
            std::vector<unsigned short> visibleAreaIndicatorIndices = TriangulatePoints(visibleAreaIndicatorVertices);
            m_stageVisibleAreaIndicatorShape =
                std::make_shared<SceneObject>(
                    m_deviceResources,
                    reinterpret_cast<std::vector<XMFLOAT3>&>(visibleAreaIndicatorVertices),
                    visibleAreaIndicatorIndices,
                    XMFLOAT3(DirectX::Colors::LightSlateGray),
                    m_stationaryFrameOfReference->CoordinateSystem);
            m_sceneController->AddSceneObject(m_stageVisibleAreaIndicatorShape);
        }
    }
}

Die Reihe der Scheitel Punkte, die die Stufen Begrenzung definieren, werden im Uhrzeigersinn bereitgestellt.The set of vertices that define the stage boundary are provided in clockwise order. Die Windows Mixed Reality-Shell zeichnet einen Fence an der Grenze, wenn sich der Benutzer nähert, aber Sie möchten vielleicht den zu verwendbar enden Bereich für Ihre eigenen Zwecke verkleinern.The Windows Mixed Reality shell draws a fence at the boundary when the user approaches it, but you may want to triangularize the walkable area for your own purposes. Der folgende Algorithmus kann verwendet werden, um die Stufe zu verkleinern.The following algorithm can be used to triangularize the stage.

Code für die phangularisierung in räumlicher PhaseCode for Spatial stage triangularization

std::vector<unsigned short> SpatialStageManager::TriangulatePoints(std::vector<float3> const& vertices)
{
    size_t const& vertexCount = vertices.size();

    // Segments of the shape are removed as they are triangularized.
    std::vector<bool> vertexRemoved;
    vertexRemoved.resize(vertexCount, false);
    unsigned int vertexRemovedCount = 0;

    // Indices are used to define triangles.
    std::vector<unsigned short> indices;

    // Decompose into convex segments.
    unsigned short currentVertex = 0;
    while (vertexRemovedCount < (vertexCount - 2))
    {
        // Get next triangle:
        // Start with the current vertex.
        unsigned short index1 = currentVertex;

        // Get the next available vertex.
        unsigned short index2 = index1 + 1;

        // This cycles to the next available index.
        auto CycleIndex = [=](unsigned short indexToCycle, unsigned short stopIndex)
        {
            // Make sure the index does not exceed bounds.
            if (indexToCycle >= unsigned short(vertexCount))
            {
                indexToCycle -= unsigned short(vertexCount);
            }

            while (vertexRemoved[indexToCycle])
            {
                // If the vertex is removed, go to the next available one.
                ++indexToCycle;

                // Make sure the index does not exceed bounds.
                if (indexToCycle >= unsigned short(vertexCount))
                {
                    indexToCycle -= unsigned short(vertexCount);
                }

                // Prevent cycling all the way around.
                // Should not be needed, as we limit with the vertex count.
                if (indexToCycle == stopIndex)
                {
                    break;
                }
            }

            return indexToCycle;
        };
        index2 = CycleIndex(index2, index1);

        // Get the next available vertex after that.
        unsigned short index3 = index2 + 1;
        index3 = CycleIndex(index3, index1);

        // Vertices that may define a triangle inside the 2D shape.
        auto& v1 = vertices[index1];
        auto& v2 = vertices[index2];
        auto& v3 = vertices[index3];

        // If the projection of the first segment (in clockwise order) onto the second segment is 
        // positive, we know that the clockwise angle is less than 180 degrees, which tells us 
        // that the triangle formed by the two segments is contained within the bounding shape.
        auto v2ToV1 = v1 - v2;
        auto v2ToV3 = v3 - v2;
        float3 normalToV2ToV3 = { -v2ToV3.z, 0.f, v2ToV3.x };
        float projectionOntoNormal = dot(v2ToV1, normalToV2ToV3);
        if (projectionOntoNormal >= 0)
        {
            // Triangle is contained within the 2D shape.

            // Remove peak vertex from the list.
            vertexRemoved[index2] = true;
            ++vertexRemovedCount;

            // Create the triangle.
            indices.push_back(index1);
            indices.push_back(index2);
            indices.push_back(index3);

            // Continue on to the next outer triangle.
            currentVertex = index3;
        }
        else
        {
            // Triangle is a cavity in the 2D shape.
            // The next triangle starts at the inside corner.
            currentVertex = index2;
        }
    }

    indices.shrink_to_fit();
    return indices;
}

Platzieren von holograms auf der Welt mithilfe eines stationären Frame RahmensPlace holograms in the world using a stationary frame of reference

Die spatialstationaryframeofreferenzierungsklasse stellt einen Frame von Reference dar, der relativ zur Benutzerumgebung stationär bleibt , wenn der Benutzer sich bewegt.The SpatialStationaryFrameOfReference class represents a frame of reference that remains stationary relative to the user's surroundings as the user moves around. Dieser Frame des Verweises priorisiert die Stabilität der Koordinaten in der Nähe des Geräts.This frame of reference prioritizes keeping coordinates stable near the device. Eine zentrale Verwendung eines spatialstationaryframeofreferenzierungssystems besteht darin, beim Rendern von holograms als das zugrundeliegende weltweite Koordinatensystem in einer Rendering-Engine zu fungieren.One key use of a SpatialStationaryFrameOfReference is to act as the underlying world coordinate system within a rendering engine when rendering holograms.

Um eine spatialstationaryframeofreferenzierung abzurufen, verwenden Sie die spatizuweisung -Klasse und den Aufruf von " foratestationaryframeofreferenceatcurrentlocation".To get a SpatialStationaryFrameOfReference, use the SpatialLocator class and call CreateStationaryFrameOfReferenceAtCurrentLocation.

Aus dem Windows Holographic-App-Vorlagen Code:From the Windows Holographic app template code:

           // 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();
  • Stationäre Verweis Rahmen sind so konzipiert, dass Sie eine am besten geeignete Position relativ zum gesamten Bereich bereitstellen.Stationary reference frames are designed to provide a best-fit position relative to the overall space. Einzelne Positionen innerhalb dieses Bezugsrahmens dürfen leicht abweichen.Individual positions within that reference frame are allowed to drift slightly. Dies ist normal, da das Gerät mehr über die Umgebung erfährt.This is normal as the device learns more about the environment.
  • Wenn die genaue Platzierung einzelner Hologramme erforderlich ist, sollte ein spatialanchor verwendet werden, um das einzelne – Hologramm an eine Position in der realen Welt zu verankern, z. b. ein Punkt, den der Benutzer als besonderes Interesse andeutet.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. Anker Positionen werden nicht abweichen, Sie können jedoch korrigiert werden. der Anker verwendet die korrigierte Position, beginnend im nächsten Frame, nachdem die Korrektur erfolgt ist.Anchor positions don't drift, but can be corrected; the anchor will use the corrected position starting in the next frame after the correction has occurred.

Platzieren von holograms weltweit mithilfe räumlicher AnkerPlace holograms in the world using spatial anchors

Räumliche Anker sind eine gute Möglichkeit, Hologramme an einer bestimmten Stelle in der realen Welt zu platzieren, wobei das System sicherstellt, dass der Anker im Laufe der Zeit vorhanden ist.Spatial anchors are a great way to place holograms at a specific place in the real world, with the system ensuring the anchor stays in place over time. In diesem Thema wird erläutert, wie ein Anker erstellt und verwendet wird und wie mit Anker Daten gearbeitet wird.This topic explains how to create and use an anchor, and how to work with anchor data.

Sie können ein spatialanchor an beliebiger Position und Ausrichtung innerhalb des spatialcoordinatesystem Ihrer Wahl erstellen.You can create a SpatialAnchor at any position and orientation within the SpatialCoordinateSystem of your choosing. Das Gerät muss in der Lage sein, dieses Koordinatensystem zu einem bestimmten Zeitpunkt zu finden, und das System darf den Grenzwert räumlicher Anker nicht erreicht haben.The device must be able to locate that coordinate system at the moment, and the system must not have reached its limit of spatial anchors.

Sobald das Koordinatensystem eines räumalanchors definiert ist, wird es ständig angepasst, um die genaue Position und Ausrichtung der ursprünglichen Position zu erhalten.Once defined, the coordinate system of a SpatialAnchor adjusts continually to keep the precise position and orientation of its initial location. Anschließend können Sie mit diesem spatialanchor holograms so darstellen, dass Sie in der Benutzerumgebung an diesem exakten Speicherort korrigiert werden.You can then use this SpatialAnchor to render holograms that will appear fixed in the user's surroundings at that exact location.

Die Auswirkungen der Anpassungen, die den Anker an Ort halten, werden vergrößert, wenn sich die Entfernung vom Anker vergrößert.The effects of the adjustments that keep the anchor in place are magnified as distance from the anchor increases. Sie sollten das Rendern von Inhalten in Relation zu einem Anker vermeiden, der mehr als ungefähr 3 Meter vom Ursprung dieses Ankers ist.You should avoid rendering content relative to an anchor that is more than about 3 meters from that anchor's origin.

Die CoordinateSystem -Eigenschaft ruft ein Koordinatensystem ab, mit dem Sie Inhalte relativ zum Anker platzieren können, wobei eine Beschleunigung angewendet wird, wenn das Gerät den genauen Speicherort des Ankers anpasst.The CoordinateSystem property gets a coordinate system that lets you place content relative to the anchor, with easing applied when the device adjusts the anchor's precise location.

Verwenden Sie die rawcoordinatesystem -Eigenschaft und das zugehörige rawcoordinatesystemadjusted -Ereignis, um diese Anpassungen selbst zu verwalten.Use the RawCoordinateSystem property and the corresponding RawCoordinateSystemAdjusted event to manage these adjustments yourself.

Beibehalten und freigeben räumlicher AnkerPersist and share spatial anchors

Sie können ein spatialanchor lokal mithilfe der spatialanchorstore -Klasse beibehalten und dann in einer zukünftigen App-Sitzung auf demselben hololens-Gerät wiederholen.You can persist a SpatialAnchor locally using the SpatialAnchorStore class and then get it back in a future app session on the same HoloLens device.

Mithilfe der räumlichen Anker von Azurekönnen Sie einen permanenten cloudenanchor von einem lokalen spatialanchor erstellen, das Ihre APP dann über mehrere hololens-, IOS-und Android-Geräte hinweg finden kann.By using Azure Spatial Anchors, you can create a durable cloud anchor from a local SpatialAnchor, which your app can then locate across multiple HoloLens, iOS and Android devices. Durch die gemeinsame Nutzung eines gemeinsamen räumlichen Ankers über mehrere Geräte hinweg kann jeder Benutzer in Echtzeit Inhalte sehen, die relativ zu diesem Anker am gleichen physischen Standort gerendert werden.By sharing a common spatial anchor across multiple devices, each user can see content rendered relative to that anchor in the same physical location in real time.

Sie können auch räumliche Azure-Anker für die asynchrone – Hologramm-Persistenz über hololens-, IOS-und Android-Geräte verwenden.You can also use Azure Spatial Anchors for asynchronous hologram persistence across HoloLens, iOS, and Android devices. Durch die gemeinsame Nutzung eines permanenten clouddiensts können mehrere Geräte im Lauf der Zeit dasselbe persistente Hologramm beobachten, auch wenn diese Geräte nicht gleichzeitig vorhanden sind.By sharing a durable cloud spatial anchor, multiple devices can observe the same persisted hologram over time, even if those devices aren't present together at the same time.

Um mit der Einführung von freigegebenen Erfahrungen in der hololens-APP zu beginnen, testen Sie den Schnellstart mit den fünfminütigen Azure Spatial Anchor hololens.To get started building shared experiences in your HoloLens app, try out the 5-minute Azure Spatial Anchors HoloLens quickstart.

Sobald Sie mit räumlichen Azure-Ankern arbeiten, können Sie Anker in hololens erstellen und lokalisieren.Once you're up and running with Azure Spatial Anchors, you can then create and locate anchors on HoloLens. Exemplarische Vorgehensweisen sind auch für Android und IOS verfügbar, sodass Sie dieselben Anker auf allen Geräten gemeinsam verwenden können.Walkthroughs are available for Android and iOS as well, enabling you to share the same anchors on all devices.

Erstellen von spatialanchor für Holographic ContentCreate SpatialAnchors for holographic content

In diesem Codebeispiel wurde die Windows Holographic-App-Vorlage so geändert, dass Anker erstellt werden, wenn die gedrückte Bewegung erkannt wird.For this code sample, we modified the Windows Holographic app template to create anchors when the Pressed gesture is detected. Der Cube wird dann während des Renderpass am Anker platziert.The cube is then placed at the anchor during the render pass.

Da mehrere Anker von der Hilfsklasse unterstützt werden, können wir so viele Cubes platzieren, wie wir dieses Codebeispiel verwenden möchten.Since multiple anchors are supported by the helper class, we can place as many cubes as we want to use this code sample!

Hinweis

Die IDs für Anker sind etwas, das Sie in ihrer App steuern.The IDs for anchors are something you control in your app. In diesem Beispiel haben wir ein Benennungs Schema erstellt, das auf der Grundlage der Anzahl der Anker basiert, die derzeit in der Auflistung von Ankern der APP gespeichert sind.In this example, we have created a naming scheme that is sequential based on the number of anchors currently stored in the app's collection of anchors.

   // Check for new input state since the last frame.
   SpatialInteractionSourceState^ pointerState = m_spatialInputHandler->CheckForInput();
   if (pointerState != nullptr)
   {
       // Try to get the pointer pose relative to the SpatialStationaryReferenceFrame.
       SpatialPointerPose^ pointerPose = pointerState->TryGetPointerPose(currentCoordinateSystem);
       if (pointerPose != nullptr)
       {
           // When a Pressed gesture is detected, the anchor will be created two meters in front of the user.

           // Get the gaze direction relative to the given coordinate system.
           const float3 headPosition = pointerPose->Head->Position;
           const float3 headDirection = pointerPose->Head->ForwardDirection;

           // The anchor position in the StationaryReferenceFrame.
           static const float distanceFromUser = 2.0f; // meters
           const float3 gazeAtTwoMeters = headPosition + (distanceFromUser * headDirection);

           // Create the anchor at position.
           SpatialAnchor^ anchor = SpatialAnchor::TryCreateRelativeTo(currentCoordinateSystem, gazeAtTwoMeters);

           if ((anchor != nullptr) && (m_spatialAnchorHelper != nullptr))
           {
               // In this example, we store the anchor in an IMap.
               auto anchorMap = m_spatialAnchorHelper->GetAnchorMap();

               // Create an identifier for the anchor.
               String^ id = ref new String(L"HolographicSpatialAnchorStoreSample_Anchor") + anchorMap->Size;

               anchorMap->Insert(id->ToString(), anchor);
           }
       }
   }

Asynchrones Laden und Zwischenspeichern von spatialanchorstoreAsynchronously load, and cache, the SpatialAnchorStore

Sehen wir uns an, wie Sie eine samplespatialanchorhelper-Klasse schreiben, die diese Persistenz behandelt, einschließlich:Let's see how to write a SampleSpatialAnchorHelper class that helps handle this persistence, including:

  • Speichern einer Auflistung von in-Memory-Ankern, indiziert von einem Platform:: String-Schlüssel.Storing a collection of in-memory anchors, indexed by a Platform::String key.
  • Anker aus dem spatialanchorstore des Systems werden geladen, die von der lokalen Auflistung im Arbeitsspeicher getrennt aufbewahrt werden.Loading anchors from the system's SpatialAnchorStore, which is kept separate from the local in-memory collection.
  • Speichern der lokalen in-Memory-Auflistung von Ankern im spatialanchorstore, wenn die App dafür entscheidet.Saving the local in-memory collection of anchors to the SpatialAnchorStore when the app chooses to do so.

Im folgenden wird beschrieben, wie Sie spatialanchor -Objekte im spatialanchorstorespeichern.Here's how to save SpatialAnchor objects in the SpatialAnchorStore.

Wenn die Klasse gestartet wird, fordern wir den spatialanchorstore asynchron an.When the class starts up, we request the SpatialAnchorStore asynchronously. Dies umfasst die System-e/a, da die API den Anker Speicher lädt, und diese API wird asynchron erstellt, sodass die e/a-Vorgänge nicht blockiert werden.This involves system I/O as the API loads the anchor store, and this API is made asynchronous so that the I/O is non-blocking.

   // Request the spatial anchor store, which is the WinRT object that will accept the imported anchor data.
   return create_task(SpatialAnchorManager::RequestStoreAsync())
       .then([](task<SpatialAnchorStore^> previousTask)
   {
       std::shared_ptr<SampleSpatialAnchorHelper> newHelper = nullptr;

       try
       {
           SpatialAnchorStore^ anchorStore = previousTask.get();

           // Once the SpatialAnchorStore has been loaded by the system, we can create our helper class.

           // Using "new" to access private constructor
           newHelper = std::shared_ptr<SampleSpatialAnchorHelper>(new SampleSpatialAnchorHelper(anchorStore));

           // Now we can load anchors from the store.
           newHelper->LoadFromAnchorStore();
       }
       catch (Exception^ exception)
       {
           PrintWstringToDebugConsole(
               std::wstring(L"Exception while loading the anchor store: ") +
               exception->Message->Data() +
               L"\n"
               );
       }

       // Return the initialized class instance.
       return newHelper;
   });

Sie erhalten einen spatialanchorstore, den Sie zum Speichern der Anker verwenden können.You'll be given a SpatialAnchorStore that you can use to save the anchors. Dies ist ein imapview, das Schlüsselwerte, die Zeichen folgen sind, mit Datenwerten, die spatialanchor sind, verknüpft.This is an IMapView that associates key values that are Strings, with data values that are SpatialAnchors. In unserem Beispielcode speichern wir dies in einer privaten Klassenmember-Variablen, auf die über eine öffentliche Funktion unserer Hilfsklasse zugegriffen werden kann.In our sample code, we store this in a private class member variable that is accessible through a public function of our helper class.

   SampleSpatialAnchorHelper::SampleSpatialAnchorHelper(SpatialAnchorStore^ anchorStore)
   {
       m_anchorStore = anchorStore;
       m_anchorMap = ref new Platform::Collections::Map<String^, SpatialAnchor^>();
   }

Hinweis

Vergessen Sie nicht, die Suspend/Resume-Ereignisse anzuschließen, um den Anker Speicher zu speichern und zu laden.Don't forget to hook up the suspend/resume events to save and load the anchor store.

   void HolographicSpatialAnchorStoreSampleMain::SaveAppState()
   {
       // For example, store information in the SpatialAnchorStore.
       if (m_spatialAnchorHelper != nullptr)
       {
           m_spatialAnchorHelper->TrySaveToAnchorStore();
       }
   }
   void HolographicSpatialAnchorStoreSampleMain::LoadAppState()
   {
       // For example, load information from the SpatialAnchorStore.
       LoadAnchorStore();
   }

Inhalt im Anker Speicher speichernSave content to the anchor store

Wenn das System Ihre APP anhält, müssen Sie Ihre räumlichen Anker im Anker Speicher speichern.When the system suspends your app, you need to save your spatial anchors to the anchor store. Sie können auch die Anker im Anker Speicher zu einem anderen Zeitpunkt speichern, da Sie für die Implementierung Ihrer APP erforderlich sind.You may also choose to save anchors to the anchor store at other times, as you find to be necessary for your app's implementation.

Wenn Sie bereit sind, die in-Memory-Anker im spatialanchorstore zu speichern, können Sie die Sammlung durchlaufen und versuchen, jede einzelne zu speichern.When you're ready to try saving the in-memory anchors to the SpatialAnchorStore, you can loop through your collection and try to save each one.

   // TrySaveToAnchorStore: Stores all anchors from memory into the app's anchor store.
   //
   // For each anchor in memory, this function tries to store it in the app's AnchorStore. The operation will fail if
   // the anchor store already has an anchor by that name.
   //
   bool SampleSpatialAnchorHelper::TrySaveToAnchorStore()
   {
       // This function returns true if all the anchors in the in-memory collection are saved to the anchor
       // store. If zero anchors are in the in-memory collection, we will still return true because the
       // condition has been met.
       bool success = true;

       // If access is denied, 'anchorStore' will not be obtained.
       if (m_anchorStore != nullptr)
       {
           for each (auto& pair in m_anchorMap)
           {
               auto const& id = pair->Key;
               auto const& anchor = pair->Value;

               // Try to save the anchors.
               if (!m_anchorStore->TrySave(id, anchor))
               {
                   // This may indicate the anchor ID is taken, or the anchor limit is reached for the app.
                   success=false;
               }
           }
       }

       return success;
   }

Inhalt aus dem Anker Speicher laden, wenn die APP fortgesetzt wirdLoad content from the anchor store when the app resumes

Sie können gespeicherte Anker im anchorstore wiederherstellen, indem Sie Sie aus der imapview des Anker Stores in ihren eigenen in-Memory Database von spatialanchor übertragen, wenn Ihre APP fortgesetzt wird, oder zu einem beliebigen Zeitpunkt.You can restore saved anchors in the AnchorStore by transferring them from the anchor store's IMapView to your own in-memory database of SpatialAnchors when your app resumes or at any time.

Um Anker aus dem spatialanchorstore wiederherzustellen, stellen Sie jeden, für den Sie sich interessieren, an ihrer eigenen in-Memory-Sammlung wieder her.To restore anchors from the SpatialAnchorStore, restore each one that you're interested in to your own in-memory collection.

Sie benötigen eine eigene in-Memory Database von spatialanchor, um Zeichen folgen den spatialanchor zuzuordnen, die Sie erstellen.You need your own in-memory database of SpatialAnchors to associate Strings with the SpatialAnchors that you create. In unserem Beispielcode wählen wir die Verwendung eines Windows:: Foundation:: Collections:: IMap zum Speichern der Anker aus, wodurch die Verwendung desselben Schlüssels und Datenwerts für den spatialanchorstore vereinfacht wird.In our sample code, we choose to use a Windows::Foundation::Collections::IMap to store the anchors, which makes it easy to use the same key and data value for the SpatialAnchorStore.

   // This is an in-memory anchor list that is separate from the anchor store.
   // These anchors may be used, reasoned about, and so on before committing the collection to the store.
   Windows::Foundation::Collections::IMap<Platform::String^, Windows::Perception::Spatial::SpatialAnchor^>^ m_anchorMap;

Hinweis

Ein Anker, der wieder hergestellt wird, ist möglicherweise nicht sofort verwendbar.An anchor that is restored might not be locatable right away. Beispielsweise kann es sich um einen Anker in einem separaten Raum oder in einem anderen Gebäude handeln.For example, it might be an anchor in a separate room or in a different building altogether. Anker, die aus dem anchorstore abgerufen werden, sollten vor deren Verwendung auf die Erreichbarkeit getestet werden.Anchors retrieved from the AnchorStore should be tested for locatability before using them.


Hinweis

In diesem Beispielcode rufen wir alle Anker aus dem anchorstore ab.In this example code, we retrieve all anchors from the AnchorStore. Dies ist keine Anforderung. Ihre APP könnte auch eine bestimmte Teilmenge von Ankern auswählen und auswählen, indem Sie Zeichen folgen Schlüsselwerte verwenden, die für Ihre Implementierung von Bedeutung sind.This is not a requirement; your app could just as well pick and choose a certain subset of anchors by using String key values that are meaningful to your implementation.

   // LoadFromAnchorStore: Loads all anchors from the app's anchor store into memory.
   //
   // The anchors are stored in memory using an IMap, which stores anchors using a string identifier. Any string can be used as
   // the identifier; it can have meaning to the app, such as "Game_Leve1_CouchAnchor," or it can be a GUID that is generated
   // by the app.
   //
   void SampleSpatialAnchorHelper::LoadFromAnchorStore()
   {
       // If access is denied, 'anchorStore' will not be obtained.
       if (m_anchorStore != nullptr)
       {
           // Get all saved anchors.
           auto anchorMapView = m_anchorStore->GetAllSavedAnchors();
           for each (auto const& pair in anchorMapView)
           {
               auto const& id = pair->Key;
               auto const& anchor = pair->Value;
               m_anchorMap->Insert(id, anchor);
           }
       }
   }

Den Anker Speicher bei Bedarf löschenClear the anchor store, when needed

Manchmal müssen Sie den App-Status löschen und neue Daten schreiben.Sometimes, you need to clear app state and write new data. Im folgenden wird erläutert, wie Sie mit dem spatialanchorstoreVorgehen.Here's how you do that with the SpatialAnchorStore.

Mit unserer Hilfsklasse ist es fast unnötig, die Clear-Funktion zu wrappen.Using our helper class, it's almost unnecessary to wrap the Clear function. Wir entscheiden uns hierfür in unserer Beispiel Implementierung, da unsere Hilfsklasse die Verantwortung für den Besitz der spatialanchorstore-Instanz erhält.We choose to do so in our sample implementation, because our helper class is given the responsibility of owning the SpatialAnchorStore instance.

   // ClearAnchorStore: Clears the AnchorStore for the app.
   //
   // This function clears the AnchorStore. It has no effect on the anchors stored in memory.
   //
   void SampleSpatialAnchorHelper::ClearAnchorStore()
   {
       // If access is denied, 'anchorStore' will not be obtained.
       if (m_anchorStore != nullptr)
       {
           // Clear all anchors from the store.
           m_anchorStore->Clear();
       }
   }

Beispiel: Verknüpfen von Anker Koordinatensystemen mit stationären Reference Frame-KoordinatensystemenExample: Relating anchor coordinate systems to stationary reference frame coordinate systems

Nehmen wir an, Sie haben einen Anker, und Sie möchten etwas im Koordinatensystem Ihres Ankers mit dem spatialstationaryreferenceframe verknüpfen, den Sie bereits für Ihre anderen Inhalte verwenden.Let's say you have an anchor, and you want to relate something in your anchor's coordinate system to the SpatialStationaryReferenceFrame you’re already using for your other content. Sie können trygettransformto verwenden, um eine Transformation vom Koordinatensystem des Ankers zu der des stationären Referenzrahmens zu erhalten:You can use TryGetTransformTo to get a transform from the anchor’s coordinate system to that of the stationary reference frame:

   // In this code snippet, someAnchor is a SpatialAnchor^ that has been initialized and is valid in the current environment.
   float4x4 anchorSpaceToCurrentCoordinateSystem;
   SpatialCoordinateSystem^ anchorSpace = someAnchor->CoordinateSystem;
   const auto tryTransform = anchorSpace->TryGetTransformTo(currentCoordinateSystem);
   if (tryTransform != nullptr)
   {
       anchorSpaceToCurrentCoordinateSystem = tryTransform->Value;
   }

Dieser Prozess ist auf zweierlei Weise nützlich:This process is useful to you in two ways:

  1. Es gibt Aufschluss darüber, ob die beiden Verweis Frames relativ zueinander verstanden werden können.It tells you if the two reference frames can be understood relative to one another, and;
  2. Wenn dies der Fall ist, stellt Sie eine Transformation bereit, um direkt von einem Koordinatensystem zum anderen zu wechseln.If so, it provides you a transform to go directly from one coordinate system to the other.

Mit diesen Informationen haben Sie einen Einblick in die räumliche Beziehung zwischen den Objekten zwischen den beiden Referenz Frames.With this information, you have an understanding of the spatial relation between objects between the two reference frames.

Zum Rendern können Sie häufig bessere Ergebnisse erzielen, indem Sie Objekte entsprechend ihrem ursprünglichen Referenzrahmen oder Anker gruppieren.For rendering, you can often obtain better results by grouping objects according to their original reference frame or anchor. Führen Sie einen separaten Zeichnungs Durchlauf für jede Gruppe aus.Perform a separate drawing pass for each group. Die Ansichts Matrizen sind für Objekte mit Modell Transformationen, die anfänglich mit demselben Koordinatensystem erstellt werden, genauer.The view matrices are more accurate for objects with model transforms that are created initially using the same coordinate system.

Erstellen von holograms mithilfe eines vom Gerät angefügten ReferenzrahmensCreate holograms using a device-attached frame of reference

Es gibt Zeiten, in denen ein – Hologramm geresgt werden soll, das an den Speicherort des Geräts angehängt bleibt , z. b. ein Panel mit Debuginformationen oder eine Informations Meldung, wenn das Gerät nur seine Ausrichtung und nicht seine Position im Raum ermitteln kann.There are times when you want to render a hologram that remains attached to the device's location, for example a panel with debugging information or an informational message when the device is only able to determine its orientation and not its position in space. Hierfür wird ein angefügter Verweis Rahmen verwendet.To accomplish this, we use an attached frame of reference.

Die spatizuweisung-Klasse "spatichedframeofreferenzierungssysteme" definiert Koordinatensysteme, die relativ zum Gerät und nicht in der realen Welt sind.The SpatialLocatorAttachedFrameOfReference class defines coordinate systems, which are relative to the device rather than to the real-world. Dieser Frame verfügt über eine festgelegte Überschrift in Bezug auf die Benutzerumgebung, die in der Richtung angezeigt wird, die der Benutzer beim Erstellen des Verweis Rahmens aufzeigte.This frame has a fixed heading relative to the user's surroundings that points in the direction the user was facing when the reference frame was created. Danach sind alle Ausrichtungen in diesem Verweis Verweis relativ zu dieser festgelegten Überschrift, auch wenn der Benutzer das Gerät dreht.From then on, all orientations in this frame of reference are relative to that fixed heading, even as the user rotates the device.

Bei hololens befindet sich der Ursprung des Koordinatensystems dieses Frames im Mittelpunkt der Drehung des Benutzer Kopfes, sodass seine Position nicht von der Kopfdrehung betroffen ist.For HoloLens, the origin of this frame's coordinate system is located at the center of rotation of the user's head, so that its position is not affected by head rotation. Ihre APP kann einen Offset relativ zu diesem Punkt angeben, um Hologramme vor dem Benutzer zu positionieren.Your app can specify an offset relative to this point to position holograms in front of the user.

Verwenden Sie zum Abrufen eines spatizucatorattachedframeofreferenzierers die spatidepcator-Klasse, und nennen Sie "forateattachedframeofreferenceatspatitheiading".To get a SpatialLocatorAttachedFrameOfReference, use the SpatialLocator class and call CreateAttachedFrameOfReferenceAtCurrentHeading.

Dies gilt für den gesamten Bereich von Windows Mixed Reality-Geräten.This applies to the entire range of Windows Mixed Reality devices.

Verwenden eines mit dem Gerät verbundenen ReferenzrahmensUse a reference frame attached to the device

In diesen Abschnitten wird erläutert, was wir in der Windows Holographic-App-Vorlage geändert haben, um mit dieser API einen mit dem Gerät verknüpften Referenzrahmen zu aktivieren.These sections talk about what we changed in the Windows Holographic app template to enable a device-attached frame of reference using this API. Dieses "angefügte" – Hologramm funktioniert zusammen mit stationären oder verankerten holograms und kann auch verwendet werden, wenn die Position des Geräts vorübergehend nicht gefunden werden kann.This "attached" hologram will work alongside stationary or anchored holograms, and may also be used when the device is temporarily unable to find its position in the world.

Zuerst haben wir die Vorlage so geändert, dass Sie ein spatidepaseorattachedframeofreferen-Objekt anstelle einer spatialstationaryframeofreferenzierung speichert:First, we changed the template to store a SpatialLocatorAttachedFrameOfReference instead of a SpatialStationaryFrameOfReference:

Aus holographictagalongsamplemain. h:From HolographicTagAlongSampleMain.h:

   // A reference frame attached to the holographic camera.
   Windows::Perception::Spatial::SpatialLocatorAttachedFrameOfReference^   m_referenceFrame;

Aus holographictagalongsamplemain. cpp:From HolographicTagAlongSampleMain.cpp:

   // In this example, we create a reference frame attached to the device.
   m_referenceFrame = m_locator->CreateAttachedFrameOfReferenceAtCurrentHeading();

Während des Updates erhalten wir nun das Koordinatensystem am Zeitstempel, der von mit der Frame Vorhersage abgerufen wurde.During the update, we now obtain the coordinate system at the time stamp obtained from with the frame prediction.

   // Next, we get a coordinate system from the attached frame of reference that is
   // associated with the current frame. Later, this coordinate system is used for
   // for creating the stereo view matrices when rendering the sample content.
   SpatialCoordinateSystem^ currentCoordinateSystem =
       m_referenceFrame->GetStationaryCoordinateSystemAtTimestamp(prediction->Timestamp);

Stellen Sie eine räumliche Zeiger Pose dar, und folgen Sie dem Benutzer.Get a spatial pointer pose, and follow the user's Gaze

Wir möchten, dass unser Beispiel – Hologramm dem Blickdes Benutzers folgt, ähnlich wie die Holographic Shell dem Blick des Benutzers folgen kann.We want our example hologram to follow the user's gaze, similar to how the holographic shell can follow the user's gaze. Hierfür müssen wir spatialpointerpose aus dem gleichen Zeitstempel erhalten.For this, we need to get the SpatialPointerPose from the same time stamp.

SpatialPointerPose^ pose = SpatialPointerPose::TryGetAtTimestamp(currentCoordinateSystem, prediction->Timestamp);

Diese spatialpointerpose verfügt über die Informationen, die erforderlich sind, um das – Hologramm entsprechend der aktuellen Überschrift des Benutzerszu positionieren.This SpatialPointerPose has the information needed to position the hologram according to the user's current heading.

Für den Benutzerkomfort wird die lineare interpolung ("Lerp") verwendet, um die Änderung an der Position innerhalb eines bestimmten Zeitraums zu glätten.For user comfort, we use linear interpolation ("lerp") to smooth the change in position over a period of time. Dies ist für den Benutzer besser, als das – Hologramm auf seinen Blick zu sperren.This is more comfortable for the user than locking the hologram to their gaze. Durch das lerping der Position des "Tag"-entlang des Hologramms können wir das Hologramm auch durch Dämpfen der Bewegung stabilisieren.Lerping the tag-along hologram's position also allows us to stabilize the hologram by dampening the movement. Wenn wir diese Dämpfung nicht durchführen, würde der Benutzer den – Hologramm-Jitter sehen, weil er normalerweise als unwahrliche Bewegungen des Benutzer Kopfes angesehen wird.If we didn't do this dampening, the user would see the hologram jitter because of what are normally considered to be imperceptible movements of the user's head.

Von stationaryquadrenderer::P ositionhologram:From StationaryQuadRenderer::PositionHologram:

   const float& dtime = static_cast<float>(timer.GetElapsedSeconds());

   if (pointerPose != nullptr)
   {
       // Get the gaze direction relative to the given coordinate system.
       const float3 headPosition  = pointerPose->Head->Position;
       const float3 headDirection = pointerPose->Head->ForwardDirection;

       // The tag-along hologram follows a point 2.0m in front of the user's gaze direction.
       static const float distanceFromUser = 2.0f; // meters
       const float3 gazeAtTwoMeters = headPosition + (distanceFromUser * headDirection);

       // Lerp the position, to keep the hologram comfortably stable.
       auto lerpedPosition = lerp(m_position, gazeAtTwoMeters, dtime * c_lerpRate);

       // This will be used as the translation component of the hologram's
       // model transform.
       SetPosition(lerpedPosition);
   }

Hinweis

Im Fall eines debuggingbereichs können Sie das Hologramm auf der Seite auf einen kleinen Wert zurücksetzen, damit die Ansicht nicht behindert wird.In the case of a debugging panel, you might choose to reposition the hologram off to the side a little so that it doesn't obstruct your view. Im folgenden finden Sie ein Beispiel dafür, wie Sie dies tun können.Here's an example of how you might do that.

Für stationaryquadrenderer::P ositionhologram:For StationaryQuadRenderer::PositionHologram:

       // If you're making a debug view, you might not want the tag-along to be directly in the
       // center of your field of view. Use this code to position the hologram to the right of
       // the user's gaze direction.
       /*
       const float3 offset = float3(0.13f, 0.0f, 0.f);
       static const float distanceFromUser = 2.2f; // meters
       const float3 gazeAtTwoMeters = headPosition + (distanceFromUser * (headDirection + offset));
       */

Das Hologramm drehen, um der Kamera zu begegnenRotate the hologram to face the camera

Es reicht nicht aus, um das Hologram zu positionieren, was in diesem Fall ein Vierfach ist. Wir müssen auch das Objekt drehen, um dem Benutzer zu begegnen.It isn't enough to position the hologram, which in this case is a quad; we must also rotate the object to face the user. Diese Rotation tritt im Raum der Welt auf, da das – Hologramm durch diese Art des Abbilds ein Teil der Benutzerumgebung bleiben kann.This rotation occurs in world space, because this type of billboarding allows the hologram to remain a part of the user's environment. Das Ansichts Leerraum-fakboardingvorgang ist nicht so komfortabel, da das – Hologramm in der Anzeige Ausrichtung gesperrt wird. in diesem Fall müssten Sie auch zwischen den linken und rechten Ansichts Matrizen interpolieren, um eine View-Space-Billboard-Transformation zu erhalten, die das Stereo Rendering nicht beeinträchtigt.View-space billboarding isn't as comfortable because the hologram becomes locked to the display orientation; in that case, you would also have to interpolate between the left and right view matrices to acquire a view-space billboard transform that doesn't disrupt stereo rendering. Hier drehen wir die X-und Z-Achsen, um dem Benutzer zu begegnen.Here, we rotate on the X and Z axes to face the user.

Von stationaryquadrenderer:: Update:From StationaryQuadRenderer::Update:

   // Seconds elapsed since previous frame.
   const float& dTime = static_cast<float>(timer.GetElapsedSeconds());

   // Create a direction normal from the hologram's position to the origin of person space.
   // This is the z-axis rotation.
   XMVECTOR facingNormal = XMVector3Normalize(-XMLoadFloat3(&m_position));

   // Rotate the x-axis around the y-axis.
   // This is a 90-degree angle from the normal, in the xz-plane.
   // This is the x-axis rotation.
   XMVECTOR xAxisRotation = XMVector3Normalize(XMVectorSet(XMVectorGetZ(facingNormal), 0.f, -XMVectorGetX(facingNormal), 0.f));

   // Create a third normal to satisfy the conditions of a rotation matrix.
   // The cross product  of the other two normals is at a 90-degree angle to
   // both normals. (Normalize the cross product to avoid floating-point math
   // errors.)
   // Note how the cross product will never be a zero-matrix because the two normals
   // are always at a 90-degree angle from one another.
   XMVECTOR yAxisRotation = XMVector3Normalize(XMVector3Cross(facingNormal, xAxisRotation));

   // Construct the 4x4 rotation matrix.

   // Rotate the quad to face the user.
   XMMATRIX rotationMatrix = XMMATRIX(
       xAxisRotation,
       yAxisRotation,
       facingNormal,
       XMVectorSet(0.f, 0.f, 0.f, 1.f)
       );

   // Position the quad.
   const XMMATRIX modelTranslation = XMMatrixTranslationFromVector(XMLoadFloat3(&m_position));

   // The view and projection matrices are provided by the system; they are associated
   // with holographic cameras, and updated on a per-camera basis.
   // Here, we provide the model transform for the sample hologram. The model transform
   // matrix is transposed to prepare it for the shader.
   XMStoreFloat4x4(&m_modelConstantBufferData.model, XMMatrixTranspose(rotationMatrix * modelTranslation));

Rendering des angefügten hologramsRender the attached hologram

In diesem Beispiel wählen wir auch das – Hologramm im Koordinatensystem von spatidepplatorattachedreferenceframe aus, in dem wir das – Hologramm positioniert haben.For this example, we also choose to render the hologram in the coordinate system of the SpatialLocatorAttachedReferenceFrame, which is where we positioned the hologram. (Wenn wir uns für das Renderingsystem mit einem anderen Koordinatensystem entschieden hätten, müssten wir eine Transformation vom Koordinatensystem des mit dem Gerät verbundenen Verweis Rahmens an dieses Koordinatensystem abrufen.)(If we had decided to render using another coordinate system, we would need to acquire a transform from the device-attached reference frame's coordinate system to that coordinate system.)

Aus holographictagalongsamplemain:: Rendering:From HolographicTagAlongSampleMain::Render:

   // The view and projection matrices for each holographic camera will change
   // every frame. This function refreshes the data in the constant buffer for
   // the holographic camera indicated by cameraPose.
   pCameraResources->UpdateViewProjectionBuffer(
       m_deviceResources,
       cameraPose,
       m_referenceFrame->GetStationaryCoordinateSystemAtTimestamp(prediction->Timestamp)
       );

Das war's.That's it! Das – Hologramm ist nun eine Position, die zwei Meter vor der Blick Richtung des Benutzers ist.The hologram will now "chase" a position that is 2 meters in front of the user's gaze direction.

Hinweis

In diesem Beispiel werden auch weitere Inhalte geladen, siehe stationaryquadrenderer. cpp.This example also loads additional content - see StationaryQuadRenderer.cpp.

Behandeln von nach Verfolgungs VerlustenHandling tracking loss

Wenn das Gerät sich nicht auf der ganzen Welt finden kann, kann der APP-Verlust nachverfolgt werden.When the device can't locate itself in the world, the app experiences "tracking loss". Windows Mixed Reality-apps sollten solche Unterbrechungen für das Positions Überwachungssystem verarbeiten können.Windows Mixed Reality apps should be able to handle such disruptions to the positional tracking system. Diese Unterbrechungen können beobachtet und Antworten erstellt werden, indem das locatabilitychanged-Ereignis im standardspaticator verwendet wird.These disruptions can be observed, and responses created, by using the LocatabilityChanged event on the default SpatialLocator.

Aus appmain:: abbildrfaden:From AppMain::SetHolographicSpace:

   // Be able to respond to changes in the positional tracking state.
   m_locatabilityChangedToken =
       m_locator->LocatabilityChanged +=
           ref new Windows::Foundation::TypedEventHandler<SpatialLocator^, Object^>(
               std::bind(&HolographicApp1Main::OnLocatabilityChanged, this, _1, _2)
               );

Wenn Ihre APP ein lochanabilitychanged-Ereignis empfängt, kann Sie das Verhalten nach Bedarf ändern.When your app receives a LocatabilityChanged event, it can change behavior as needed. Beispielsweise kann Ihre APP im positionaltrackinginhibited-Zustand den normalen Betrieb anhalten und ein Tag-entlang-– Hologramm , das eine Warnmeldung anzeigt, darstellen.For example, in the PositionalTrackingInhibited state, your app can pause normal operation and render a tag-along hologram that displays a warning message.

Die Vorlage für die Windows Holographic-app enthält bereits einen loaseabilitychanged-Handler, der bereits für Sie erstellt wurde.The Windows Holographic app template comes with a LocatabilityChanged handler already created for you. Standardmäßig wird in der Debugkonsole eine Warnung angezeigt, wenn die Positionsüberwachung nicht verfügbar ist.By default, it displays a warning in the debug console when positional tracking is unavailable. Sie können diesem Handler Code hinzufügen, um eine Antwort nach Bedarf in Ihrer APP bereitzustellen.You can add code to this handler to provide a response as needed from your app.

Aus appmain. cpp:From AppMain.cpp:

   void HolographicApp1Main::OnLocatabilityChanged(SpatialLocator^ sender, Object^ args)
   {
       switch (sender->Locatability)
       {
       case SpatialLocatability::Unavailable:
           // Holograms cannot be rendered.
           {
               String^ message = L"Warning! Positional tracking is " +
                                           sender->Locatability.ToString() + L".\n";
               OutputDebugStringW(message->Data());
           }
           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;
       }
   }

Räumliche AbbildungSpatial mapping

Die APIs für die räumliche Zuordnung verwenden Koordinatensysteme, um Modell Transformationen für Oberflächen Netze zu erhalten.The spatial mapping APIs make use of coordinate systems to get model transforms for surface meshes.

Siehe auchSee also