Prostorové mapování v Unity

Prostorové mapování umožňuje načíst trojúhelníkové sítě, které představují povrchy kolem zařízení HoloLens. Povrchová data můžete použít k umístění, okluzi a analýze místností, abyste svým projektům Unity poskytli další dávku ponoření.

Unity zahrnuje plnou podporu prostorového mapování, které je vývojářům zpřístupněno následujícími způsoby:

  1. Komponenty prostorového mapování dostupné v sadě MixedRealityToolkit, které poskytují pohodlný a rychlý způsob, jak začít s prostorovým mapováním
  2. Rozhraní API prostorového mapování nižší úrovně, která poskytují plnou kontrolu a umožňují sofistikovanější přizpůsobení specifické pro aplikace.

Pokud chcete ve své aplikaci použít prostorové mapování, musí být v aplikaci AppxManifest nastavená funkce SpatialPerception.

Podpora zařízení

Funkce HoloLens (první generace) HoloLens 2 Imerzivní náhlavní soupravy
Prostorové mapování ✔️ ✔️

Nastavení funkce SpatialPerception

Aby aplikace mohla využívat data prostorového mapování, musí být povolená funkce SpatialPerception.

Povolení funkce SpatialPerception:

  1. V Unity Editoru otevřete podokno Nastavení přehrávače (Upravit > přehrávač nastavení > projektu).
  2. Vyberte na kartě Windows Store .
  3. Rozbalte nastavení publikování a v seznamu Schopností zkontrolujte možnost SpatialPerception.

Poznámka

Pokud jste už projekt Unity vyexportovali do řešení sady Visual Studio, budete muset buď exportovat do nové složky, nebo tuto funkci ručně nastavit v appxManifestu v sadě Visual Studio.

Prostorové mapování také vyžaduje MaxVersionTested minimálně 10.0.10586.0:

  1. V sadě Visual Studio klikněte pravým tlačítkem na Package.appxmanifest v Průzkumník řešení a vyberte Zobrazit kód.
  2. Vyhledejte řádek určující TargetDeviceFamily a změňte MaxVersionTested="10.0.10240.0" na MaxVersionTested="10.0.10586.0".
  3. Uložte soubor Package.appxmanifest.

Jak přidat mapování v Unity

Systém pro sledování prostoru

V MRTK najdete informace o nastavení různých pozorovatelů prostorových sítí v příručce Začínáme s prostorovou informovaností.

Informace o pozorovatelích v zařízení najdete v příručce Konfigurace pozorovatelů sítě pro zařízení .

Informace o pozorovatelích, kteří rozumí scéně, najdete v průvodci pozorovatelem pro pochopení scény .

Analýza sítě na vyšší úrovni: Prostorové porozumění

Upozornění

Funkce Prostorové porozumění se přestala používat ve prospěch porozumění scéně.

MixedRealityToolkit je kolekce kódu nástrojů pro holografický vývoj, která je založená na holografických rozhraních API Unity.

Prostorové porozumění

Při umísťování hologramů do fyzického světa je často žádoucí jít nad rámec prostorového mapování sítě a roviny povrchu. Když se umístění provádí procedurálně, je žádoucí vyšší úroveň porozumění životnímu prostředí. To obvykle vyžaduje rozhodnutí o tom, co je podlaha, strop a zdi. Můžete také provést optimalizaci s ohledem na sadu omezení umístění a určit tak nejlepší fyzická umístění pro holografické objekty.

Během vývoje Young Conker and Fragments, Asobo Studios čelit tomuto problému čelem vývoje místnosti řešitele. Každá z těchto her měla potřeby specifické pro hru, ale sdílely základní technologii prostorového porozumění. Knihovna HoloToolkit.SpatialUnderstanding tuto technologii zapouzdřuje a umožňuje vám rychle najít prázdná místa na stěnách, umístit objekty na strop, identifikovat místo, kde mají postavy sedět, a nesčetné množství dalších dotazů na prostorové porozumění.

Součástí je veškerý zdrojový kód, který vám umožní přizpůsobit ho vašim potřebám a sdílet vylepšení s komunitou. Kód řešitele C++ byl zabalen do knihovny DLL UPW a zpřístupněn Unity s poklesem v prefabu obsaženém v sadě MixedRealityToolkit.

Principy modulů

Modul nabízí tři primární rozhraní: topologii pro jednoduché povrchové a prostorové dotazy, tvar pro detekci objektů a řešitel umístění objektů pro umísťování sad objektů na základě omezení. Každý z těchto kroků je popsán níže. Kromě tří primárních rozhraní modulu lze k načtení označených typů povrchů použít rozhraní pro přetypování paprsků a vlastní vodotěsnou síť playspace lze zkopírovat.

Ray Casting

Po dokončení skenování místnosti se štítky generují interně pro povrchy, jako je podlaha, strop a stěny. Funkce PlayspaceRaycast vezme paprsek a vrátí, pokud se paprsek srazí se známým povrchem, a pokud ano, informace o daném povrchu ve tvaru RaycastResult.

struct RaycastResult
{
    enum SurfaceTypes
    {
        Invalid,    // No intersection
        Other,
        Floor,
        FloorLike,  // Not part of the floor topology,
                    //  but close to the floor and looks like the floor
        Platform,   // Horizontal platform between the ground and
                    //  the ceiling
        Ceiling,
        WallExternal,
        WallLike,   // Not part of the external wall surface,
                    //  but vertical surface that looks like a
                    //  wall structure
    };
    SurfaceTypes SurfaceType;
    float SurfaceArea;  // Zero if unknown
                        //  (i.e. if not part of the topology analysis)
    DirectX::XMFLOAT3 IntersectPoint;
    DirectX::XMFLOAT3 IntersectNormal;
};

Interně se raycast počítá s vypočítanou 8cm voxelovou reprezentací playspace. Každý voxel obsahuje sadu prvků povrchu se zpracovanými topologickými daty (neboli surfely). Povrchy obsažené v protínané voxelové buňce jsou porovnány a nejlepší shoda se používá k vyhledání informací o topologii. Tato data topologie obsahují popisky vrácené ve formě výčtu "SurfaceTypes" a také plochu protínaného povrchu.

V ukázce Unity kurzor přetypuje paprsek na každý snímek. Za prvé, proti kolidům Unity. Za druhé, proti světové reprezentaci modulu understanding. A nakonec opět prvky uživatelského rozhraní. V této aplikaci získá uživatelské rozhraní prioritu, dále výsledek porozumění a nakonec kolidátory Unity. SurfaceType se hlásí jako text vedle kurzoru.

Typ povrchu je označený vedle kurzoru.
Typ povrchu je označený vedle kurzoru.

Dotazy na topologii

V rámci knihovny DLL zpracovává popisky prostředí správce topologie. Jak je uvedeno výše, většina dat je uložena v surfely, obsažené v svazku voxel. Kromě toho se struktura "PlaySpaceInfos" používá k ukládání informací o herním prostoru, včetně zarovnání světa (více podrobností o tom níže), podlahy a výšky stropu. Heuristika se používá k určení podlahy, stropu a stěn. Za podlahu se považuje například největší a nejnižší vodorovná plocha s plochou větší než 1 m2.

Poznámka

V tomto procesu se používá také cesta ke kameře během procesu skenování.

Podmnožina dotazů vystavených správcem topologie je zpřístupněna prostřednictvím knihovny DLL. Vystavené dotazy na topologii jsou následující.

QueryTopology_FindPositionsOnWalls
QueryTopology_FindLargePositionsOnWalls
QueryTopology_FindLargestWall
QueryTopology_FindPositionsOnFloor
QueryTopology_FindLargestPositionsOnFloor
QueryTopology_FindPositionsSittable

Každý z dotazů má sadu parametrů specifických pro daný typ dotazu. V následujícím příkladu uživatel určí minimální výšku & šířku požadovaného objemu, minimální výšku umístění nad podlahou a minimální volný prostor před objemem. Všechna měření jsou v metrech.

EXTERN_C __declspec(dllexport) int QueryTopology_FindPositionsOnWalls(
    _In_ float minHeightOfWallSpace,
    _In_ float minWidthOfWallSpace,
    _In_ float minHeightAboveFloor,
    _In_ float minFacingClearance,
    _In_ int locationCount,
    _Inout_ Dll_Interface::TopologyResult* locationData)

Každý z těchto dotazů přebírá předem přidělené pole struktur TopologyResult. Parametr locationCount určuje délku předaného pole. Vrácená hodnota hlásí počet vrácených umístění. Toto číslo není nikdy větší než hodnota předaná v parametru locationCount.

"TopologyResult" obsahuje středovou pozici vráceného objemu, směr směru (tj. normální) a rozměry nalezeného prostoru.

struct TopologyResult
{
    DirectX::XMFLOAT3 position;
    DirectX::XMFLOAT3 normal;
    float width;
    float length;
};

Poznámka

V ukázce Unity je každý z těchto dotazů propojený s tlačítkem na virtuálním panelu uživatelského rozhraní. Ukázka pevně kóduje parametry pro každý z těchto dotazů na přiměřené hodnoty. Další příklady najdete v souboru SpaceVisualizer.cs ve vzorovém kódu.

Dotazy na obrazce

V knihovně DLL analyzátor obrazců ("ShapeAnalyzer_W") používá analyzátor topologie ke shodě s vlastními obrazci definovanými uživatelem. Ukázka Unity definuje sadu obrazců a zveřejňuje výsledky prostřednictvím nabídky dotazů v aplikaci na kartě obrazce. Záměrem je, aby uživatel mohl definovat vlastní dotazy na tvarování objektů a využívat je podle potřeby aplikace.

Analýza obrazců funguje pouze na vodorovných površích. Například gauč je definován plochou sedadla a plochým vrškem zadní části gauče. Dotaz na obrazec hledá dvě plochy s konkrétní velikostí, výškou a rozsahem stran, přičemž tyto dvě plochy jsou zarovnané a propojené. Při použití terminologie rozhraní API jsou posazení a zadní část součástí obrazce a požadavky na zarovnání jsou omezení součástí obrazce.

Příklad dotazu definovaného v ukázce Unity (ShapeDefinition.cs) pro "sittable" objekty je následující.

shapeComponents = new List<ShapeComponent>()
{
    new ShapeComponent(
        new List<ShapeComponentConstraint>()
        {
            ShapeComponentConstraint.Create_SurfaceHeight_Between(0.2f, 0.6f),
            ShapeComponentConstraint.Create_SurfaceCount_Min(1),
            ShapeComponentConstraint.Create_SurfaceArea_Min(0.035f),
        }
    ),
};
AddShape("Sittable", shapeComponents);

Každý dotaz obrazce je definován sadou součástí obrazce, z nichž každá má sadu omezení komponent a sadu omezení obrazce, která obsahuje závislosti mezi komponentami. Tento příklad obsahuje tři omezení v jedné definici komponenty a žádná omezení obrazce mezi komponentami (protože existuje pouze jedna komponenta).

Naproti tomu obrazec gauče má dvě součásti obrazce a čtyři omezení obrazce. Komponenty se identifikují podle indexu v seznamu komponent uživatele (v tomto příkladu 0 a 1).

shapeConstraints = new List<ShapeConstraint>()
{
    ShapeConstraint.Create_RectanglesSameLength(0, 1, 0.6f),
    ShapeConstraint.Create_RectanglesParallel(0, 1),
    ShapeConstraint.Create_RectanglesAligned(0, 1, 0.3f),
    ShapeConstraint.Create_AtBackOf(1, 0),
};

Funkce obálky jsou k dispozici v modulu Unity pro snadné vytváření vlastních definic obrazců. Úplný seznam omezení komponent a obrazců najdete v souboru SpatialUnderstandingDll.cs v rámci struktur ShapeComponentConstraint a ShapeConstraint.

Na tomto povrchu se nachází obdélníkový obrazec.
Na tomto povrchu se nachází obdélníkový obrazec.

Řešitel umístění objektů

Řešitel umístění objektů lze použít k identifikaci ideálních umístění ve fyzické místnosti pro umístění objektů. Řešitel najde nejvhodnější umístění s ohledem na pravidla a omezení objektu. Kromě toho dotazy na objekty přetrvávají, dokud se objekt neodebere pomocí volání "Solver_RemoveObject" nebo "Solver_RemoveAllObjects", což umožňuje omezené umístění více objektů. Dotazy na umístění objektů se skládají ze tří částí: typu umístění s parametry, seznamu pravidel a seznamu omezení. Ke spuštění dotazu použijte následující rozhraní API.

public static int Solver_PlaceObject(
            [In] string objectName,
            [In] IntPtr placementDefinition,        // ObjectPlacementDefinition
            [In] int placementRuleCount,
            [In] IntPtr placementRules,             // ObjectPlacementRule
            [In] int constraintCount,
            [In] IntPtr placementConstraints,       // ObjectPlacementConstraint
            [Out] IntPtr placementResult)

Tato funkce přebírá název objektu, definici umístění a seznam pravidel a omezení. Obálky jazyka C# poskytují pomocné funkce pro vytváření pravidel a omezení. Definice umístění obsahuje typ dotazu – to znamená jeden z následujících.

public enum PlacementType
{
    Place_OnFloor,
    Place_OnWall,
    Place_OnCeiling,
    Place_OnShape,
    Place_OnEdge,
    Place_OnFloorAndCeiling,
    Place_RandomInAir,
    Place_InMidAir,
    Place_UnderFurnitureEdge,
};

Každý z typů umístění má sadu parametrů, které jsou pro tento typ jedinečné. Struktura "ObjectPlacementDefinition" obsahuje sadu statických pomocných funkcí pro vytváření těchto definic. Pokud například chcete najít místo pro umístění objektu na podlahu, můžete použít následující funkci. public static ObjectPlacementDefinition Create_OnFloor(Vector3 halfDims) Kromě typu umístění můžete zadat sadu pravidel a omezení. Pravidla nelze porušit. Možná umístění, která vyhovují typu a pravidlům, se pak optimalizují s ohledem na sadu omezení, aby bylo možné vybrat optimální umístění umístění. Všechna pravidla a omezení mohou být vytvořena pomocí poskytovaných funkcí statického vytváření. Příklad stavební funkce pravidla a omezení je uveden níže.

public static ObjectPlacementRule Create_AwayFromPosition(
    Vector3 position, float minDistance)
public static ObjectPlacementConstraint Create_NearPoint(
    Vector3 position, float minDistance = 0.0f, float maxDistance = 0.0f)

Níže uvedený dotaz na umístění objektu hledá místo pro umístění půlmetrové datové krychle na okraji povrchu, daleko od ostatních objektů, které jste předtím umístili, a blízko středu místnosti.

List<ObjectPlacementRule> rules =
    new List<ObjectPlacementRule>() {
        ObjectPlacementRule.Create_AwayFromOtherObjects(1.0f),
    };

List<ObjectPlacementConstraint> constraints =
    new List<ObjectPlacementConstraint> {
        ObjectPlacementConstraint.Create_NearCenter(),
    };

Solver_PlaceObject(
    “MyCustomObject”,
    new ObjectPlacementDefinition.Create_OnEdge(
        new Vector3(0.25f, 0.25f, 0.25f),
        new Vector3(0.25f, 0.25f, 0.25f)),
    rules.Count,
    UnderstandingDLL.PinObject(rules.ToArray()),
    constraints.Count,
    UnderstandingDLL.PinObject(constraints.ToArray()),
    UnderstandingDLL.GetStaticObjectPlacementResultPtr());

V případě úspěchu se vrátí struktura ObjectPlacementResult obsahující umístění, rozměry a orientaci. Kromě toho je umístění přidáno do interního seznamu umístěných objektů knihovny DLL. Následné dotazy na umístění budou tento objekt brát v úvahu. Soubor LevelSolver.cs v ukázce Unity obsahuje další příklady dotazů.

Výsledky umístění objektu
Obrázek 3: Modré pole, jak výsledek ze tří míst v dotazech na podlaze s mimo pravidla pro umístění kamery

Při řešení umístění více objektů požadovaných pro scénář úrovně nebo aplikace nejprve vyřešte nepostradatelné a velké objekty, aby se maximalizovala pravděpodobnost nalezení mezery. Pořadí umístění je důležité. Pokud nelze najít umístění objektů, zkuste konfigurace s méně omezenými omezeními. Sada záložních konfigurací je důležitá pro podporu funkcí v mnoha konfiguracích místností.

Proces skenování místností

I když je řešení prostorového mapování, které poskytuje HoloLens, navržené tak, aby vyhovovalo potřebám celé škály problémových prostorů, modul prostorového porozumění byl vytvořen tak, aby podporoval potřeby dvou konkrétních her. Jeho řešení je strukturováno podle konkrétního procesu a sady předpokladů, které jsou shrnuty níže.

Fixed size playspace – The user specifies the maximum playspace size in the init call.

One-time scan process –
    The process requires a discrete scanning phase where the user walks around,
    defining the playspace.
    Query functions will not function until after the scan has been finalized.

Uživatelem řízené playspace "obraz" - Během fáze skenování, uživatel se pohybuje a rozhlíží se kolem hry tempo, efektivně malovat oblasti, které by měly být zahrnuty. Vygenerovaná síť je důležitá k poskytování zpětné vazby uživatelů během této fáze. Vnitřní nastavení domova nebo kanceláře – Funkce dotazů jsou navrženy kolem plochých povrchů a zdí v pravém úhlu. Jedná se o měkké omezení. Během fáze skenování se však dokončí analýza primární osy, aby se optimalizovala tessellace sítě podél hlavní a vedlejší osy. Zahrnutý soubor SpatialUnderstanding.cs spravuje proces fáze kontroly. Volá následující funkce.

SpatialUnderstanding_Init – Called once at the start.

GeneratePlayspace_InitScan – Indicates that the scan phase should begin.

GeneratePlayspace_UpdateScan_DynamicScan –
    Called each frame to update the scanning process. The camera position and
    orientation is passed in and is used for the playspace painting process,
    described above.

GeneratePlayspace_RequestFinish –
    Called to finalize the playspace. This will use the areas “painted” during
    the scan phase to define and lock the playspace. The application can query
    statistics during the scanning phase as well as query the custom mesh for
    providing user feedback.

Import_UnderstandingMesh –
    During scanning, the “SpatialUnderstandingCustomMesh” behavior provided by
    the module and placed on the understanding prefab will periodically query the
    custom mesh generated by the process. In addition, this is done once more
    after scanning has been finalized.

Tok kontroly, řízený "SpatialUnderstanding" chování volá InitScan a pak UpdateScan každý snímek. Když dotaz statistiky hlásí přiměřené pokrytí, uživatel může airtap volat RequestFinish označující konec fáze kontroly. UpdateScan bude nadále volána, dokud jeho návratová hodnota nenaznačí, že knihovna DLL dokončila zpracování.

Principy sítě

Knihovna DLL pro porozumění interně ukládá playspace jako mřížku voxelových krychlí o velikosti 8 cm. Během počáteční části skenování se dokončí analýza primárních komponent, která určí osy místnosti. Interně ukládá svůj prostor voxelu zarovnaný k těmto osám. Síť se generuje přibližně každou sekundu extrahováním izosurface z objemu voxelu.

Vygenerovaná síť vytvořená z objemu voxelu
Vygenerovaná síť vytvořená z objemu voxelu

Poradce při potížích

  • Ujistěte se, že jste nastavili funkci SpatialPerception .
  • Při ztrátě sledování odebere další událost OnSurfaceChanged všechny sítě.

Prostorové mapování v Mixed Reality Toolkit

Další informace o používání prostorového mapování se sadou Mixed Reality Toolkit najdete v části věnované povědomí o prostorech v dokumentaci MRTK.

Další kontrolní bod vývoje

Pokud sledujete cestu vývoje Unity, kterou jsme si nastavili, jste uprostřed zkoumání základních stavebních bloků MRTK. Odtud můžete pokračovat k dalšímu stavebnímu bloku:

Nebo přejděte na Mixed Reality možností a rozhraní API platformy:

Kdykoli se můžete vrátit k kontrolním bodům vývoje Unity .

Viz také