From a6105f96e0deb85dcb47333d5f023ab3fa85935d Mon Sep 17 00:00:00 2001 From: Patrick Schrottenbacher Date: Thu, 15 Oct 2026 14:56:37 +0200 Subject: [PATCH 1/2] docs: updated documentation to the current status of the project, added a project list and citation directory. --- .github/workflows/mkdocs.yml | 62 +- .gitignore | 4 +- .../Lab/Core/Runtime/Art/Icons/Name.png.meta | 51 +- .../Art/Icons/volume-play-white.png.meta | 51 +- .../edit_FILL1_wght700_GRAD0_opsz48.png.meta | 53 +- ...l_rule_FILL1_wght700_GRAD0_opsz48.png.meta | 53 +- .../save_FILL1_wght700_GRAD0_opsz48.png.meta | 53 +- .../Language/Flag_of_Germany.png.meta | 63 +- .../Flag_of_the_United_Kingdom_(1-2).png.meta | 63 +- .../Materials/Language/globe-solid 1.png.meta | 63 +- Assets/Oculus.meta | 8 + Assets/Samples.meta | 8 + Assets/XR.meta | 8 + Assets/XR/Loaders.meta | 8 + Assets/XR/Loaders/OpenXRLoader.asset | 14 + Assets/XR/Loaders/OpenXRLoader.asset.meta | 8 + Assets/XR/Settings.meta | 8 + .../XR/Settings/OpenXR Editor Settings.asset | 22 + .../OpenXR Editor Settings.asset.meta | 8 + .../XR/Settings/OpenXR Package Settings.asset | 1519 +++++++++++++++++ .../OpenXR Package Settings.asset.meta | 8 + .../XR/XRGeneralSettingsPerBuildTarget.asset | 80 + ...XRGeneralSettingsPerBuildTarget.asset.meta | 8 + .../docs/getting_started/adding_scenes.md | 221 +-- .../docs/getting_started/interview_client.md | 46 +- .../docs/getting_started/meta_avatar.md | 15 +- .../docs/getting_started/meta_interactions.md | 68 - .../docs/getting_started/player_controller.md | 58 + .../docs/getting_started/setting_up.md | 71 +- .../docs/getting_started/special_scenes.md | 31 +- Documentation/docs/images/logo/vasili-lab.svg | 216 +++ Documentation/docs/images/projects/FACES.png | Bin 0 -> 13665 bytes .../docs/images/projects/NewDataSpaces.png | Bin 33290 -> 60676 bytes Documentation/docs/index.md | 35 +- Documentation/docs/modules/bots.md | 57 + Documentation/docs/modules/endpoints.md | 41 + Documentation/docs/modules/eventsystem.md | 52 + Documentation/docs/modules/logging.md | 37 + Documentation/docs/other/bots.md | 2 - .../docs/other/experiment_visualization.md | 6 + .../docs/other/experiment_visualizer_audio.md | 102 -- .../experiment_visualizer_trackingdata.md | 173 -- Documentation/docs/other/replay.md | 38 +- Documentation/docs/projects/faces.md | 8 +- Documentation/docs/projects/index.md | 11 + Documentation/docs/publications.md | 528 +++++- Documentation/docs/scenarios/DGS.md | 2 - Documentation/docs/scenarios/ICIDS.md | 2 - Documentation/docs/scenarios/Meetingpoint.md | 2 - .../scenarios/OrganisationDistribution.md | 2 - .../docs/scenarios/OrganisationEducation.md | 2 - .../docs/scenarios/PraktikumScenario1.md | 35 - .../docs/scenarios/PraktikumScenario2.md | 55 - .../docs/scenarios/PraktikumScenario3.md | 29 - .../docs/scenarios/SchoolDistribution.md | 2 - Documentation/docs/scenarios/SchoolHetero.md | 2 - Documentation/docs/scenarios/index.md | 11 + Documentation/docs/server/server_structure.md | 7 +- Documentation/docs/server/ubiq_server.md | 8 +- Documentation/docs/students/documentation.md | 24 +- Documentation/docs/systems.md | 65 + Documentation/mkdocs.yml | 26 +- Packages/manifest.json | 2 +- Packages/packages-lock.json | 12 +- ProjectSettings/EditorBuildSettings.asset | 6 +- README.md | 78 +- Va.Si.Li-Lab-public.slnx | 246 +++ 67 files changed, 3711 insertions(+), 946 deletions(-) create mode 100644 Assets/Oculus.meta create mode 100644 Assets/Samples.meta create mode 100644 Assets/XR.meta create mode 100644 Assets/XR/Loaders.meta create mode 100644 Assets/XR/Loaders/OpenXRLoader.asset create mode 100644 Assets/XR/Loaders/OpenXRLoader.asset.meta create mode 100644 Assets/XR/Settings.meta create mode 100644 Assets/XR/Settings/OpenXR Editor Settings.asset create mode 100644 Assets/XR/Settings/OpenXR Editor Settings.asset.meta create mode 100644 Assets/XR/Settings/OpenXR Package Settings.asset create mode 100644 Assets/XR/Settings/OpenXR Package Settings.asset.meta create mode 100644 Assets/XR/XRGeneralSettingsPerBuildTarget.asset create mode 100644 Assets/XR/XRGeneralSettingsPerBuildTarget.asset.meta delete mode 100644 Documentation/docs/getting_started/meta_interactions.md create mode 100644 Documentation/docs/getting_started/player_controller.md create mode 100644 Documentation/docs/images/logo/vasili-lab.svg create mode 100644 Documentation/docs/images/projects/FACES.png create mode 100644 Documentation/docs/modules/bots.md create mode 100644 Documentation/docs/modules/endpoints.md create mode 100644 Documentation/docs/modules/eventsystem.md create mode 100644 Documentation/docs/modules/logging.md delete mode 100644 Documentation/docs/other/bots.md create mode 100644 Documentation/docs/other/experiment_visualization.md delete mode 100644 Documentation/docs/other/experiment_visualizer_audio.md delete mode 100644 Documentation/docs/other/experiment_visualizer_trackingdata.md create mode 100644 Documentation/docs/projects/index.md delete mode 100644 Documentation/docs/scenarios/DGS.md delete mode 100644 Documentation/docs/scenarios/ICIDS.md delete mode 100644 Documentation/docs/scenarios/Meetingpoint.md delete mode 100644 Documentation/docs/scenarios/OrganisationDistribution.md delete mode 100644 Documentation/docs/scenarios/OrganisationEducation.md delete mode 100644 Documentation/docs/scenarios/PraktikumScenario1.md delete mode 100644 Documentation/docs/scenarios/PraktikumScenario2.md delete mode 100644 Documentation/docs/scenarios/PraktikumScenario3.md delete mode 100644 Documentation/docs/scenarios/SchoolDistribution.md delete mode 100644 Documentation/docs/scenarios/SchoolHetero.md create mode 100644 Documentation/docs/scenarios/index.md create mode 100644 Documentation/docs/systems.md create mode 100644 Va.Si.Li-Lab-public.slnx diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml index 0bb8c624..0fdf74ee 100644 --- a/.github/workflows/mkdocs.yml +++ b/.github/workflows/mkdocs.yml @@ -1,31 +1,33 @@ -name: Build Documentation using MkDocs -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the master branch -# https://medium.com/dev-genius/continuous-deployment-for-mkdocs-with-github-actions-7dceec87f0ea -on: - push: - branches: [master,main] - pull_request: - branches: [master,main] -jobs: - build: - name: Build and Deploy Documentation - runs-on: ubuntu-latest - steps: - - name: Checkout Master - uses: actions/checkout@v2 +name: Build Documentation using MkDocs +# Builds the docs (strict, so broken links fail the check) and deploys them to the gh-pages branch, +# on pushes to main and on pull requests. +on: + push: + branches: [main] + paths: ['Documentation/**', '.github/workflows/mkdocs.yml'] + pull_request: + branches: [main] + paths: ['Documentation/**', '.github/workflows/mkdocs.yml'] +permissions: + contents: write +jobs: + build: + name: Build and Deploy Documentation + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 0 # full history for the git-revision-date plugin - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install mkdocs-material - pip install mkdocs-git-revision-date-localized-plugin - pip install mkdocs-git-committers-plugin-2 - pip install mkdocs-git-authors-plugin - pip install mkdocs-glightbox - - name: Deploy - run: | - mkdocs gh-deploy --config-file Documentation/mkdocs.yml --remote-branch gh-pages --force + uses: actions/setup-python@v7 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-glightbox + - name: Build + run: mkdocs build --strict --config-file Documentation/mkdocs.yml + - name: Deploy + run: mkdocs gh-deploy --config-file Documentation/mkdocs.yml --remote-branch gh-pages --force diff --git a/.gitignore b/.gitignore index 915908fa..5ded57db 100644 --- a/.gitignore +++ b/.gitignore @@ -73,9 +73,7 @@ crashlytics-build.properties # VSCode folder .vscode/ -# Ignore auto-generated XR because these are per-end user settings -/Assets/XR/ -/Assets/XR.meta +# Assets/XR (XR loader and OpenXR settings) is tracked on purpose so everyone builds with the same settings Recordings/ diff --git a/Assets/Lab/Core/Runtime/Art/Icons/Name.png.meta b/Assets/Lab/Core/Runtime/Art/Icons/Name.png.meta index 0e96e1d7..0686991b 100644 --- a/Assets/Lab/Core/Runtime/Art/Icons/Name.png.meta +++ b/Assets/Lab/Core/Runtime/Art/Icons/Name.png.meta @@ -1,9 +1,12 @@ fileFormatVersion: 2 guid: 303d29210c9b39446b1f6bc0e9d029be TextureImporter: - internalIDToNameTable: [] + internalIDToNameTable: + - first: + 213: 7405661294618894375 + second: Name_0 externalObjects: {} - serializedVersion: 11 + serializedVersion: 13 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -20,10 +23,12 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 + flipGreenChannel: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 + ignoreMipmapLimit: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -62,8 +67,10 @@ TextureImporter: textureFormatSet: 0 ignorePngGamma: 0 applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 platformSettings: - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -73,9 +80,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -85,9 +93,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Android maxTextureSize: 2048 resizeAlgorithm: 0 @@ -97,12 +106,36 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 - sprites: [] + sprites: + - serializedVersion: 2 + name: Name_0 + rect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1024 + height: 1024 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + customData: + outline: [] + physicsShape: [] + tessellationDetail: -1 + bones: [] + spriteID: 7206e98e5b136c660800000000000000 + internalID: 7405661294618894375 + vertices: [] + indices: + edges: [] + weights: [] outline: [] + customData: physicsShape: [] bones: [] spriteID: 5e97eb03825dee720800000000000000 @@ -112,9 +145,11 @@ TextureImporter: edges: [] weights: [] secondaryTextures: [] - spritePackingTag: + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Lab/Core/Runtime/Art/Icons/volume-play-white.png.meta b/Assets/Lab/Core/Runtime/Art/Icons/volume-play-white.png.meta index 9405cbb5..26e1a2ea 100644 --- a/Assets/Lab/Core/Runtime/Art/Icons/volume-play-white.png.meta +++ b/Assets/Lab/Core/Runtime/Art/Icons/volume-play-white.png.meta @@ -1,9 +1,12 @@ fileFormatVersion: 2 guid: 7b53e9eb18bf45341b03461b55a192b5 TextureImporter: - internalIDToNameTable: [] + internalIDToNameTable: + - first: + 213: 1061623916413588505 + second: volume-play-white_0 externalObjects: {} - serializedVersion: 11 + serializedVersion: 13 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -20,10 +23,12 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 + flipGreenChannel: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 + ignoreMipmapLimit: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -62,8 +67,10 @@ TextureImporter: textureFormatSet: 0 ignorePngGamma: 0 applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 1 platformSettings: - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -73,9 +80,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -85,9 +93,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Android maxTextureSize: 2048 resizeAlgorithm: 0 @@ -97,12 +106,36 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 - sprites: [] + sprites: + - serializedVersion: 2 + name: volume-play-white_0 + rect: + serializedVersion: 2 + x: 0 + y: 0 + width: 640 + height: 512 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + customData: + outline: [] + physicsShape: [] + tessellationDetail: -1 + bones: [] + spriteID: 91414e6c355abbe00800000000000000 + internalID: 1061623916413588505 + vertices: [] + indices: + edges: [] + weights: [] outline: [] + customData: physicsShape: [] bones: [] spriteID: 5e97eb03825dee720800000000000000 @@ -112,9 +145,11 @@ TextureImporter: edges: [] weights: [] secondaryTextures: [] - spritePackingTag: + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/edit_FILL1_wght700_GRAD0_opsz48.png.meta b/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/edit_FILL1_wght700_GRAD0_opsz48.png.meta index 2a775a8a..63347e20 100644 --- a/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/edit_FILL1_wght700_GRAD0_opsz48.png.meta +++ b/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/edit_FILL1_wght700_GRAD0_opsz48.png.meta @@ -1,9 +1,12 @@ fileFormatVersion: 2 guid: d233156b35457ee4c9ed3c1807d5fd91 TextureImporter: - internalIDToNameTable: [] + internalIDToNameTable: + - first: + 213: -7877580773724871505 + second: edit_FILL1_wght700_GRAD0_opsz48_0 externalObjects: {} - serializedVersion: 12 + serializedVersion: 13 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -20,11 +23,12 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 + flipGreenChannel: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 - ignoreMasterTextureLimit: 0 + ignoreMipmapLimit: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -63,9 +67,10 @@ TextureImporter: textureFormatSet: 0 ignorePngGamma: 0 applyGammaDecoding: 0 + swizzle: 50462976 cookieLightType: 0 platformSettings: - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -75,9 +80,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -87,9 +93,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Server maxTextureSize: 2048 resizeAlgorithm: 0 @@ -99,9 +106,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Android maxTextureSize: 2048 resizeAlgorithm: 0 @@ -111,12 +119,36 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 - sprites: [] + sprites: + - serializedVersion: 2 + name: edit_FILL1_wght700_GRAD0_opsz48_0 + rect: + serializedVersion: 2 + x: 0 + y: 0 + width: 48 + height: 48 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + customData: + outline: [] + physicsShape: [] + tessellationDetail: -1 + bones: [] + spriteID: fa4aea406063da290800000000000000 + internalID: -7877580773724871505 + vertices: [] + indices: + edges: [] + weights: [] outline: [] + customData: physicsShape: [] bones: [] spriteID: 5e97eb03825dee720800000000000000 @@ -126,10 +158,11 @@ TextureImporter: edges: [] weights: [] secondaryTextures: [] + spriteCustomMetadata: + entries: [] nameFileIdTable: {} - spritePackingTag: + mipmapLimitGroupName: pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/horizontal_rule_FILL1_wght700_GRAD0_opsz48.png.meta b/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/horizontal_rule_FILL1_wght700_GRAD0_opsz48.png.meta index 43b05ced..3fd55167 100644 --- a/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/horizontal_rule_FILL1_wght700_GRAD0_opsz48.png.meta +++ b/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/horizontal_rule_FILL1_wght700_GRAD0_opsz48.png.meta @@ -1,9 +1,12 @@ fileFormatVersion: 2 guid: cddf3f5a5bd7b4a46af42f38b466244c TextureImporter: - internalIDToNameTable: [] + internalIDToNameTable: + - first: + 213: 5920816587221518968 + second: horizontal_rule_FILL1_wght700_GRAD0_opsz48_0 externalObjects: {} - serializedVersion: 12 + serializedVersion: 13 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -20,11 +23,12 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 + flipGreenChannel: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 - ignoreMasterTextureLimit: 0 + ignoreMipmapLimit: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -63,9 +67,10 @@ TextureImporter: textureFormatSet: 0 ignorePngGamma: 0 applyGammaDecoding: 0 + swizzle: 50462976 cookieLightType: 0 platformSettings: - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -75,9 +80,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -87,9 +93,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Server maxTextureSize: 2048 resizeAlgorithm: 0 @@ -99,9 +106,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Android maxTextureSize: 2048 resizeAlgorithm: 0 @@ -111,12 +119,36 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 - sprites: [] + sprites: + - serializedVersion: 2 + name: horizontal_rule_FILL1_wght700_GRAD0_opsz48_0 + rect: + serializedVersion: 2 + x: 0 + y: 0 + width: 48 + height: 48 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + customData: + outline: [] + physicsShape: [] + tessellationDetail: -1 + bones: [] + spriteID: 87a4495f057fa2250800000000000000 + internalID: 5920816587221518968 + vertices: [] + indices: + edges: [] + weights: [] outline: [] + customData: physicsShape: [] bones: [] spriteID: 5e97eb03825dee720800000000000000 @@ -126,10 +158,11 @@ TextureImporter: edges: [] weights: [] secondaryTextures: [] + spriteCustomMetadata: + entries: [] nameFileIdTable: {} - spritePackingTag: + mipmapLimitGroupName: pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/save_FILL1_wght700_GRAD0_opsz48.png.meta b/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/save_FILL1_wght700_GRAD0_opsz48.png.meta index ab96c55d..c45f3869 100644 --- a/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/save_FILL1_wght700_GRAD0_opsz48.png.meta +++ b/Assets/Lab/Core/Runtime/Resources/VAInteractableObjects/save_FILL1_wght700_GRAD0_opsz48.png.meta @@ -1,9 +1,12 @@ fileFormatVersion: 2 guid: 7384d48146335344aa51c431428f3106 TextureImporter: - internalIDToNameTable: [] + internalIDToNameTable: + - first: + 213: -7185052849241797039 + second: save_FILL1_wght700_GRAD0_opsz48_0 externalObjects: {} - serializedVersion: 12 + serializedVersion: 13 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -20,11 +23,12 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 + flipGreenChannel: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 - ignoreMasterTextureLimit: 0 + ignoreMipmapLimit: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -63,9 +67,10 @@ TextureImporter: textureFormatSet: 0 ignorePngGamma: 0 applyGammaDecoding: 0 + swizzle: 50462976 cookieLightType: 0 platformSettings: - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -75,9 +80,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -87,9 +93,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Server maxTextureSize: 2048 resizeAlgorithm: 0 @@ -99,9 +106,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Android maxTextureSize: 2048 resizeAlgorithm: 0 @@ -111,12 +119,36 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 - sprites: [] + sprites: + - serializedVersion: 2 + name: save_FILL1_wght700_GRAD0_opsz48_0 + rect: + serializedVersion: 2 + x: 0 + y: 0 + width: 48 + height: 48 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + customData: + outline: [] + physicsShape: [] + tessellationDetail: -1 + bones: [] + spriteID: 15ec88c6080994c90800000000000000 + internalID: -7185052849241797039 + vertices: [] + indices: + edges: [] + weights: [] outline: [] + customData: physicsShape: [] bones: [] spriteID: 5e97eb03825dee720800000000000000 @@ -126,10 +158,11 @@ TextureImporter: edges: [] weights: [] secondaryTextures: [] + spriteCustomMetadata: + entries: [] nameFileIdTable: {} - spritePackingTag: + mipmapLimitGroupName: pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Lab/Core/Samples/Objects/Materials/Language/Flag_of_Germany.png.meta b/Assets/Lab/Core/Samples/Objects/Materials/Language/Flag_of_Germany.png.meta index 59fb2fed..b3558686 100644 --- a/Assets/Lab/Core/Samples/Objects/Materials/Language/Flag_of_Germany.png.meta +++ b/Assets/Lab/Core/Samples/Objects/Materials/Language/Flag_of_Germany.png.meta @@ -1,9 +1,12 @@ fileFormatVersion: 2 guid: 681c25958809b44bd8daaceece3dcd09 TextureImporter: - internalIDToNameTable: [] + internalIDToNameTable: + - first: + 213: 1572207362141225981 + second: Flag_of_Germany_0 externalObjects: {} - serializedVersion: 12 + serializedVersion: 13 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -20,11 +23,12 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 + flipGreenChannel: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 - ignoreMasterTextureLimit: 0 + ignoreMipmapLimit: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -63,9 +67,10 @@ TextureImporter: textureFormatSet: 0 ignorePngGamma: 0 applyGammaDecoding: 0 + swizzle: 50462976 cookieLightType: 0 platformSettings: - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -75,9 +80,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -87,9 +93,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Server maxTextureSize: 2048 resizeAlgorithm: 0 @@ -99,12 +106,49 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 - sprites: [] + sprites: + - serializedVersion: 2 + name: Flag_of_Germany_0 + rect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1000 + height: 600 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + customData: + outline: [] + physicsShape: [] + tessellationDetail: -1 + bones: [] + spriteID: df38ea5144a91d510800000000000000 + internalID: 1572207362141225981 + vertices: [] + indices: + edges: [] + weights: [] outline: [] + customData: physicsShape: [] bones: [] spriteID: 5e97eb03825dee720800000000000000 @@ -114,10 +158,11 @@ TextureImporter: edges: [] weights: [] secondaryTextures: [] + spriteCustomMetadata: + entries: [] nameFileIdTable: {} - spritePackingTag: + mipmapLimitGroupName: pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Lab/Core/Samples/Objects/Materials/Language/Flag_of_the_United_Kingdom_(1-2).png.meta b/Assets/Lab/Core/Samples/Objects/Materials/Language/Flag_of_the_United_Kingdom_(1-2).png.meta index 32ae22a4..401c1d47 100644 --- a/Assets/Lab/Core/Samples/Objects/Materials/Language/Flag_of_the_United_Kingdom_(1-2).png.meta +++ b/Assets/Lab/Core/Samples/Objects/Materials/Language/Flag_of_the_United_Kingdom_(1-2).png.meta @@ -1,9 +1,12 @@ fileFormatVersion: 2 guid: b727bfffc36524403a4cc0f75d4831b7 TextureImporter: - internalIDToNameTable: [] + internalIDToNameTable: + - first: + 213: 4047080015453609154 + second: Flag_of_the_United_Kingdom_(1-2)_0 externalObjects: {} - serializedVersion: 12 + serializedVersion: 13 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -20,11 +23,12 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 + flipGreenChannel: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 - ignoreMasterTextureLimit: 0 + ignoreMipmapLimit: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -63,9 +67,10 @@ TextureImporter: textureFormatSet: 0 ignorePngGamma: 0 applyGammaDecoding: 0 + swizzle: 50462976 cookieLightType: 0 platformSettings: - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -75,9 +80,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -87,9 +93,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Server maxTextureSize: 2048 resizeAlgorithm: 0 @@ -99,12 +106,49 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 - sprites: [] + sprites: + - serializedVersion: 2 + name: Flag_of_the_United_Kingdom_(1-2)_0 + rect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1200 + height: 600 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + customData: + outline: [] + physicsShape: [] + tessellationDetail: -1 + bones: [] + spriteID: 2ccd1bae4dd1a2830800000000000000 + internalID: 4047080015453609154 + vertices: [] + indices: + edges: [] + weights: [] outline: [] + customData: physicsShape: [] bones: [] spriteID: 5e97eb03825dee720800000000000000 @@ -114,10 +158,11 @@ TextureImporter: edges: [] weights: [] secondaryTextures: [] + spriteCustomMetadata: + entries: [] nameFileIdTable: {} - spritePackingTag: + mipmapLimitGroupName: pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Lab/Core/Samples/Objects/Materials/Language/globe-solid 1.png.meta b/Assets/Lab/Core/Samples/Objects/Materials/Language/globe-solid 1.png.meta index 3f2a27c8..16f4b5bd 100644 --- a/Assets/Lab/Core/Samples/Objects/Materials/Language/globe-solid 1.png.meta +++ b/Assets/Lab/Core/Samples/Objects/Materials/Language/globe-solid 1.png.meta @@ -1,9 +1,12 @@ fileFormatVersion: 2 guid: dc63444fc13444be6a8f8dd3c6b52d14 TextureImporter: - internalIDToNameTable: [] + internalIDToNameTable: + - first: + 213: -5420819394531046391 + second: globe-solid 1_0 externalObjects: {} - serializedVersion: 12 + serializedVersion: 13 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -20,11 +23,12 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 + flipGreenChannel: 0 isReadable: 0 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 - ignoreMasterTextureLimit: 0 + ignoreMipmapLimit: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -63,9 +67,10 @@ TextureImporter: textureFormatSet: 0 ignorePngGamma: 0 applyGammaDecoding: 0 + swizzle: 50462976 cookieLightType: 0 platformSettings: - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: DefaultTexturePlatform maxTextureSize: 2048 resizeAlgorithm: 0 @@ -75,9 +80,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Standalone maxTextureSize: 2048 resizeAlgorithm: 0 @@ -87,9 +93,10 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 + - serializedVersion: 4 buildTarget: Server maxTextureSize: 2048 resizeAlgorithm: 0 @@ -99,12 +106,49 @@ TextureImporter: crunchedCompression: 0 allowsAlphaSplitting: 0 overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 - sprites: [] + sprites: + - serializedVersion: 2 + name: globe-solid 1_0 + rect: + serializedVersion: 2 + x: 0 + y: 0 + width: 512 + height: 512 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + customData: + outline: [] + physicsShape: [] + tessellationDetail: -1 + bones: [] + spriteID: 90ccd6d3b7165c4b0800000000000000 + internalID: -5420819394531046391 + vertices: [] + indices: + edges: [] + weights: [] outline: [] + customData: physicsShape: [] bones: [] spriteID: 5e97eb03825dee720800000000000000 @@ -114,10 +158,11 @@ TextureImporter: edges: [] weights: [] secondaryTextures: [] + spriteCustomMetadata: + entries: [] nameFileIdTable: {} - spritePackingTag: + mipmapLimitGroupName: pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/Oculus.meta b/Assets/Oculus.meta new file mode 100644 index 00000000..df01e2ef --- /dev/null +++ b/Assets/Oculus.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7978697dc4b45c2499315e9b6fc5b36e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Samples.meta b/Assets/Samples.meta new file mode 100644 index 00000000..39968bc4 --- /dev/null +++ b/Assets/Samples.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eb2502cdffa176844948b16ccb48c8f3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XR.meta b/Assets/XR.meta new file mode 100644 index 00000000..c9f2c56b --- /dev/null +++ b/Assets/XR.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8a415278dab656d459fad9928d65d379 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XR/Loaders.meta b/Assets/XR/Loaders.meta new file mode 100644 index 00000000..f3ff7968 --- /dev/null +++ b/Assets/XR/Loaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b0a3a822e0cf885439fea67c613a8f8f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XR/Loaders/OpenXRLoader.asset b/Assets/XR/Loaders/OpenXRLoader.asset new file mode 100644 index 00000000..c177a9fa --- /dev/null +++ b/Assets/XR/Loaders/OpenXRLoader.asset @@ -0,0 +1,14 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d3552e428dc7646a88de3ed3650f87da, type: 3} + m_Name: OpenXRLoader + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.OpenXRLoader diff --git a/Assets/XR/Loaders/OpenXRLoader.asset.meta b/Assets/XR/Loaders/OpenXRLoader.asset.meta new file mode 100644 index 00000000..7da40169 --- /dev/null +++ b/Assets/XR/Loaders/OpenXRLoader.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0e870e5d88ccdd3449f81b0c7ea92ce8 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XR/Settings.meta b/Assets/XR/Settings.meta new file mode 100644 index 00000000..564f614d --- /dev/null +++ b/Assets/XR/Settings.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 182324fe1fe9e5a4fa7ac4a27a0c8a99 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XR/Settings/OpenXR Editor Settings.asset b/Assets/XR/Settings/OpenXR Editor Settings.asset new file mode 100644 index 00000000..b2f6566a --- /dev/null +++ b/Assets/XR/Settings/OpenXR Editor Settings.asset @@ -0,0 +1,22 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 975057b4fdcfb8142b3080d19a5cc712, type: 3} + m_Name: OpenXR Editor Settings + m_EditorClassIdentifier: Unity.XR.OpenXR.Editor::UnityEditor.XR.OpenXR.OpenXREditorSettings + Keys: 0100000007000000 + Values: + - featureSets: + - com.meta.openxr.featureset.metaxr + - featureSets: + - com.meta.openxr.featureset.metaxr + m_vulkanAdditionalGraphicsQueue: 0 + m_vulkanOffscreenSwapchainNoMainDisplay: 1 diff --git a/Assets/XR/Settings/OpenXR Editor Settings.asset.meta b/Assets/XR/Settings/OpenXR Editor Settings.asset.meta new file mode 100644 index 00000000..6bc8d74e --- /dev/null +++ b/Assets/XR/Settings/OpenXR Editor Settings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 684c8e601ffc98b47a60374943cf4972 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XR/Settings/OpenXR Package Settings.asset b/Assets/XR/Settings/OpenXR Package Settings.asset new file mode 100644 index 00000000..98654352 --- /dev/null +++ b/Assets/XR/Settings/OpenXR Package Settings.asset @@ -0,0 +1,1519 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-8545460186977742305 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2b7365b139f7aec43b23d26b7a48b5a6, type: 3} + m_Name: MetaQuestTouchPlusControllerProfile Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.MetaQuestTouchPlusControllerProfile + m_enabled: 0 + nameUi: Meta Quest Touch Plus Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.metaquestplus + openxrExtensionStrings: XR_META_touch_controller_plus + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-8391468794652365456 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0f6bfdbcb316ed242b30a8798c9eb853, type: 3} + m_Name: KHRSimpleControllerProfile Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.KHRSimpleControllerProfile + m_enabled: 0 + nameUi: Khronos Simple Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.khrsimpleprofile + openxrExtensionStrings: + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-8301964434126396227 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e573a2aed6698b047aff95224499b722, type: 3} + m_Name: MetaXREyeTrackedFoveationFeature Standalone + m_EditorClassIdentifier: Oculus.VR::Meta.XR.MetaXREyeTrackedFoveationFeature + m_enabled: 0 + nameUi: Meta XR Eye Tracked Foveation + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.eyetrackedfoveation + openxrExtensionStrings: XR_META_foveation_eye_tracked XR_FB_eye_tracking_social + XR_META_vulkan_swapchain_create_info + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-8079773780360711073 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 37086d3966675294eb1c38ad413c6817, type: 3} + m_Name: DetachedMetaQuestTouchPlusControllerProfile Android + m_EditorClassIdentifier: Oculus.VR::Meta.XR.DetachedMetaQuestTouchPlusControllerProfile + m_enabled: 0 + nameUi: Detached Meta Quest Touch Plus Controller Profile + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.input.metaquestplus.detached + openxrExtensionStrings: XR_META_detached_controllers + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-6844477915066494673 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3d28f705476c80d47acb3dfade3d3142, type: 3} + m_Name: MetaXRFoveationFeature Android + m_EditorClassIdentifier: Oculus.VR::Meta.XR.MetaXRFoveationFeature + m_enabled: 1 + nameUi: Meta XR Foveation + version: 1.0.0 + featureIdInternal: com.meta.openxr.feature.foveation + openxrExtensionStrings: 'XR_FB_foveation XR_FB_foveation_configuration XR_FB_foveation_vulkan ' + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-6542667958538541429 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7de993716e042c6499d0c18eed3a773c, type: 3} + m_Name: MockRuntime Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR.Features.MockRuntime::UnityEngine.XR.OpenXR.Features.Mock.MockRuntime + m_enabled: 0 + nameUi: Mock Runtime + version: 0.0.2 + featureIdInternal: com.unity.openxr.feature.mockruntime + openxrExtensionStrings: XR_UNITY_null_gfx XR_UNITY_android_present + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + ignoreValidationErrors: 0 +--- !u!114 &-6393979774375439216 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 01512f11fe5096443ad972feb69271f6, type: 3} + m_Name: SpaceWarpFeature Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.SpaceWarpFeature + m_enabled: 0 + nameUi: Application SpaceWarp + version: 1.0.0 + featureIdInternal: com.unity.openxr.feature.spacewarp + openxrExtensionStrings: XR_FB_space_warp + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + m_UseRightHandedNDC: 0 +--- !u!114 &-6138514551507227436 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b213d3e3c7f3109449eb46a4c8ee42f0, type: 3} + m_Name: XrPerformanceSettingsFeature Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Extensions.PerformanceSettings.XrPerformanceSettingsFeature + m_enabled: 0 + nameUi: XR Performance Settings + version: 1.0.0 + featureIdInternal: com.unity.openxr.feature.extension.performance_settings + openxrExtensionStrings: XR_EXT_performance_settings + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-5874362956514689893 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f928d0d73a35f294fbe357ca17aa3547, type: 3} + m_Name: MicrosoftHandInteraction Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.MicrosoftHandInteraction + m_enabled: 0 + nameUi: Microsoft Hand Interaction Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.handtracking + openxrExtensionStrings: XR_MSFT_hand_interaction + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-5308198659050868324 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7de993716e042c6499d0c18eed3a773c, type: 3} + m_Name: MockRuntime Android + m_EditorClassIdentifier: Unity.XR.OpenXR.Features.MockRuntime::UnityEngine.XR.OpenXR.Features.Mock.MockRuntime + m_enabled: 0 + nameUi: Mock Runtime + version: 0.0.2 + featureIdInternal: com.unity.openxr.feature.mockruntime + openxrExtensionStrings: XR_UNITY_null_gfx XR_UNITY_android_present + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + ignoreValidationErrors: 0 +--- !u!114 &-5090109445253957882 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a24be4b5ebfe5f4d8ed1de9b25cb7aa, type: 3} + m_Name: HandCommonPosesInteraction Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.HandCommonPosesInteraction + m_enabled: 0 + nameUi: Hand Interaction Poses + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.handinteractionposes + openxrExtensionStrings: XR_EXT_hand_interaction + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-5026095352258469728 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a24be4b5ebfe5f4d8ed1de9b25cb7aa, type: 3} + m_Name: HandCommonPosesInteraction Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.HandCommonPosesInteraction + m_enabled: 0 + nameUi: Hand Interaction Poses + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.handinteractionposes + openxrExtensionStrings: XR_EXT_hand_interaction + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-4970216369706289461 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2b7365b139f7aec43b23d26b7a48b5a6, type: 3} + m_Name: MetaQuestTouchPlusControllerProfile Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.MetaQuestTouchPlusControllerProfile + m_enabled: 0 + nameUi: Meta Quest Touch Plus Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.metaquestplus + openxrExtensionStrings: XR_META_touch_controller_plus + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-4898493728134337233 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f6a75d1f5ff90154ea2a8e58222a1f59, type: 3} + m_Name: FoveatedRenderingFeature Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.FoveatedRenderingFeature + m_enabled: 0 + nameUi: Foveated Rendering + version: 1 + featureIdInternal: com.unity.openxr.feature.foveatedrendering + openxrExtensionStrings: XR_UNITY_foveation XR_FB_foveation XR_FB_foveation_configuration + XR_FB_swapchain_update_state XR_FB_foveation_vulkan XR_META_foveation_eye_tracked + XR_META_vulkan_swapchain_create_info + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + enableSubsampledLayout: 0 +--- !u!114 &-4691887901876839608 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9c5b5af5107e35a43818d5411328bfc3, type: 3} + m_Name: DPadInteraction Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.DPadInteraction + m_enabled: 0 + nameUi: D-Pad Binding + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.dpadinteraction + openxrExtensionStrings: XR_KHR_binding_modification XR_EXT_dpad_binding + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + forceThresholdLeft: 0.5 + forceThresholdReleaseLeft: 0.4 + centerRegionLeft: 0.5 + wedgeAngleLeft: 1.5707964 + isStickyLeft: 0 + forceThresholdRight: 0.5 + forceThresholdReleaseRight: 0.4 + centerRegionRight: 0.5 + wedgeAngleRight: 1.5707964 + isStickyRight: 0 + extensionStrings: + - XR_KHR_binding_modification + - XR_EXT_dpad_binding +--- !u!114 &-4559526606425108497 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3d28f705476c80d47acb3dfade3d3142, type: 3} + m_Name: MetaXRFoveationFeature Standalone + m_EditorClassIdentifier: Oculus.VR::Meta.XR.MetaXRFoveationFeature + m_enabled: 1 + nameUi: Meta XR Foveation + version: 1.0.0 + featureIdInternal: com.meta.openxr.feature.foveation + openxrExtensionStrings: 'XR_FB_foveation XR_FB_foveation_configuration XR_FB_foveation_vulkan ' + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-4463675136939454006 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 486b5e28864f9a94b979b9620ce5006d, type: 3} + m_Name: ConformanceAutomationFeature Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR.Features.ConformanceAutomation::UnityEngine.XR.OpenXR.Features.ConformanceAutomation.ConformanceAutomationFeature + m_enabled: 0 + nameUi: Conformance Automation + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.conformance + openxrExtensionStrings: XR_EXT_conformance_automation + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-3658833149316982896 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 274c02963f889a64e90bc2e596e21d13, type: 3} + m_Name: HTCViveControllerProfile Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.HTCViveControllerProfile + m_enabled: 0 + nameUi: HTC Vive Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.htcvive + openxrExtensionStrings: + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-3655800558024972851 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5019471fb2174e5c852ecd4047163007, type: 3} + m_Name: HandInteractionProfile Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.HandInteractionProfile + m_enabled: 0 + nameUi: Hand Interaction Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.handinteraction + openxrExtensionStrings: XR_EXT_hand_interaction + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-3597834595480828386 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: eda5cc6e8db3d9944bf84a7379663d7c, type: 3} + m_Name: DetachedMetaQuestTouchProControllerProfile Standalone + m_EditorClassIdentifier: Oculus.VR::Meta.XR.DetachedMetaQuestTouchProControllerProfile + m_enabled: 0 + nameUi: Detached Meta Quest Touch Pro Controller Profile + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.input.metaquestpro.detached + openxrExtensionStrings: XR_META_detached_controllers + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-3539015442152043752 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b3aced3429e5911458f4da2dac9d0f29, type: 3} + m_Name: MetaHandTrackingAim Android + m_EditorClassIdentifier: Unity.XR.Hands::UnityEngine.XR.Hands.OpenXR.MetaHandTrackingAim + m_enabled: 0 + nameUi: Meta Hand Tracking Aim + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.metahandtrackingaim + openxrExtensionStrings: XR_FB_hand_tracking_aim + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-3455479848038917648 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5019471fb2174e5c852ecd4047163007, type: 3} + m_Name: HandInteractionProfile Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.HandInteractionProfile + m_enabled: 0 + nameUi: Hand Interaction Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.handinteraction + openxrExtensionStrings: XR_EXT_hand_interaction + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-3022032382842232193 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 056125dd64c0ed540b40a4af74f7b495, type: 3} + m_Name: RuntimeDebuggerOpenXRFeature Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR.Features.RuntimeDebugger::UnityEngine.XR.OpenXR.Features.RuntimeDebugger.RuntimeDebuggerOpenXRFeature + m_enabled: 0 + nameUi: Runtime Debugger + version: 1 + featureIdInternal: com.unity.openxr.features.runtimedebugger + openxrExtensionStrings: + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + cacheSize: 1048576 + perThreadCacheSize: 51200 +--- !u!114 &-2371518837694837324 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b3cf79659a011bd419c7a2a30eb74e9a, type: 3} + m_Name: EyeGazeInteraction Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.EyeGazeInteraction + m_enabled: 0 + nameUi: Eye Gaze Interaction Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.eyetracking + openxrExtensionStrings: XR_EXT_eye_gaze_interaction + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-2184912740526592088 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1927c045052a06d49a9b21fdcaa26db6, type: 3} + m_Name: MetaXRFeature Standalone + m_EditorClassIdentifier: Oculus.VR::Meta.XR.MetaXRFeature + m_enabled: 1 + nameUi: Meta XR Feature + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.metaxr + openxrExtensionStrings: XR_KHR_vulkan_enable XR_KHR_D3D11_enable XR_OCULUS_common_reference_spaces + XR_FB_display_refresh_rate XR_EXT_performance_settings XR_FB_composition_layer_image_layout + XR_KHR_android_surface_swapchain XR_FB_android_surface_swapchain_create XR_KHR_composition_layer_color_scale_bias + XR_FB_color_space XR_EXT_hand_tracking XR_FB_swapchain_update_state XR_FB_swapchain_update_state_opengl_es + XR_FB_swapchain_update_state_vulkan XR_FB_composition_layer_alpha_blend XR_KHR_composition_layer_depth + XR_KHR_composition_layer_cylinder XR_KHR_composition_layer_cube XR_KHR_composition_layer_equirect2 + XR_KHR_convert_timespec_time XR_KHR_visibility_mask XR_FB_render_model XR_FB_spatial_entity + XR_FB_spatial_entity_user XR_FB_spatial_entity_query XR_FB_spatial_entity_storage + XR_FB_spatial_entity_storage_batch XR_META_spatial_entity_mesh XR_META_performance_metrics + XR_FB_spatial_entity_sharing XR_FB_scene XR_FB_spatial_entity_container XR_FB_scene_capture + XR_FB_face_tracking XR_FB_face_tracking2 XR_FB_eye_tracking XR_FB_eye_tracking_social + XR_FB_body_tracking XR_META_body_tracking_full_body XR_META_body_tracking_calibration + XR_META_body_tracking_fidelity XR_FB_keyboard_tracking XR_META_virtual_keyboard + XR_FB_passthrough XR_FB_triangle_mesh XR_FB_passthrough_keyboard_hands XR_META_passthrough_layer_resumed_event + XR_META_passthrough_color_lut XR_META_passthrough_preferences XR_OCULUS_audio_device_guid + XR_FB_common_events XR_FB_hand_tracking_capsules XR_FB_hand_tracking_mesh XR_FB_hand_tracking_aim + XR_FB_touch_controller_pro XR_FB_touch_controller_proximity XR_FB_composition_layer_depth_test + XR_FB_haptic_amplitude_envelope XR_FB_haptic_pcm XR_EXT_haptic_parametric XR_META_local_dimming + XR_META_hand_tracking_wide_motion_mode XR_EXT_hand_tracking_data_source XR_EXT_hand_joints_motion_range + XR_META_touch_controller_plus XR_META_simultaneous_hands_and_controllers XR_MSFT_hand_interaction + XR_EXT_hand_interaction XR_FB_hand_tracking_confidence XR_META_detached_controllers + XR_LOGITECH_mx_ink_stylus_interaction XR_META_colocation_discovery XR_META_spatial_entity_sharing + XR_META_spatial_entity_group_sharing XR_EXT_debug_utils XR_META_dynamic_object_tracker + XR_META_dynamic_object_keyboard XR_META_hand_tracking_microgestures XR_META_spatial_entity_persistence + XR_META_spatial_entity_discovery XR_META_spatial_entity_room_mesh XR_META_boundary_visibility + XR_META_face_tracking_visemes XR_META_headset_id XR_FB_composition_layer_settings + XR_META_automatic_layer_filter XR_FB_composition_layer_secure_content XR_METAX1_spatial_entity_marker + XR_EXT_spatial_entity XR_EXT_spatial_marker_tracking XR_META_environment_raycast + XR_EXT_future XR_METAX2_debug_utils_region_profiling XR_METAX3_debug_utils_region_profiling + XR_EXTX2_stationary_reference_space XR_META_recommended_layer_resolution XR_EXT_local_floor + XR_METAX1_passthrough_camera_data XR_META_hand_tracking_frequency_hint XR_META_hand_tracking_unextrapolated_poses + XR_META_hand_tracking_wide_motion_mode2 XR_METAX1_agentic_external_tool + company: Meta + priority: 0 + targetOpenXRApiVersion: 1.1.54 + required: 0 + customRuntimeLoaderName: +--- !u!114 &-1690673217515633499 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b82a8cddc5afeb145ad4e1d76511063f, type: 3} + m_Name: DetachedOculusTouchControllerProfile Standalone + m_EditorClassIdentifier: Oculus.VR::Meta.XR.DetachedOculusTouchControllerProfile + m_enabled: 0 + nameUi: Detached Oculus Touch Controller Profile + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.input.oculustouch.detached + openxrExtensionStrings: XR_META_detached_controllers + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-1332385295733761299 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1927c045052a06d49a9b21fdcaa26db6, type: 3} + m_Name: MetaXRFeature Android + m_EditorClassIdentifier: Oculus.VR::Meta.XR.MetaXRFeature + m_enabled: 1 + nameUi: Meta XR Feature + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.metaxr + openxrExtensionStrings: XR_KHR_vulkan_enable XR_KHR_D3D11_enable XR_OCULUS_common_reference_spaces + XR_FB_display_refresh_rate XR_EXT_performance_settings XR_FB_composition_layer_image_layout + XR_KHR_android_surface_swapchain XR_FB_android_surface_swapchain_create XR_KHR_composition_layer_color_scale_bias + XR_FB_color_space XR_EXT_hand_tracking XR_FB_swapchain_update_state XR_FB_swapchain_update_state_opengl_es + XR_FB_swapchain_update_state_vulkan XR_FB_composition_layer_alpha_blend XR_KHR_composition_layer_depth + XR_KHR_composition_layer_cylinder XR_KHR_composition_layer_cube XR_KHR_composition_layer_equirect2 + XR_KHR_convert_timespec_time XR_KHR_visibility_mask XR_FB_render_model XR_FB_spatial_entity + XR_FB_spatial_entity_user XR_FB_spatial_entity_query XR_FB_spatial_entity_storage + XR_FB_spatial_entity_storage_batch XR_META_spatial_entity_mesh XR_META_performance_metrics + XR_FB_spatial_entity_sharing XR_FB_scene XR_FB_spatial_entity_container XR_FB_scene_capture + XR_FB_face_tracking XR_FB_face_tracking2 XR_FB_eye_tracking XR_FB_eye_tracking_social + XR_FB_body_tracking XR_META_body_tracking_full_body XR_META_body_tracking_calibration + XR_META_body_tracking_fidelity XR_FB_keyboard_tracking XR_META_virtual_keyboard + XR_FB_passthrough XR_FB_triangle_mesh XR_FB_passthrough_keyboard_hands XR_META_passthrough_layer_resumed_event + XR_META_passthrough_color_lut XR_META_passthrough_preferences XR_OCULUS_audio_device_guid + XR_FB_common_events XR_FB_hand_tracking_capsules XR_FB_hand_tracking_mesh XR_FB_hand_tracking_aim + XR_FB_touch_controller_pro XR_FB_touch_controller_proximity XR_FB_composition_layer_depth_test + XR_FB_haptic_amplitude_envelope XR_FB_haptic_pcm XR_EXT_haptic_parametric XR_META_local_dimming + XR_META_hand_tracking_wide_motion_mode XR_EXT_hand_tracking_data_source XR_EXT_hand_joints_motion_range + XR_META_touch_controller_plus XR_META_simultaneous_hands_and_controllers XR_MSFT_hand_interaction + XR_EXT_hand_interaction XR_FB_hand_tracking_confidence XR_META_detached_controllers + XR_LOGITECH_mx_ink_stylus_interaction XR_META_colocation_discovery XR_META_spatial_entity_sharing + XR_META_spatial_entity_group_sharing XR_EXT_debug_utils XR_META_dynamic_object_tracker + XR_META_dynamic_object_keyboard XR_META_hand_tracking_microgestures XR_META_spatial_entity_persistence + XR_META_spatial_entity_discovery XR_META_spatial_entity_room_mesh XR_META_boundary_visibility + XR_META_face_tracking_visemes XR_META_headset_id XR_FB_composition_layer_settings + XR_META_automatic_layer_filter XR_FB_composition_layer_secure_content XR_METAX1_spatial_entity_marker + XR_EXT_spatial_entity XR_EXT_spatial_marker_tracking XR_META_environment_raycast + XR_EXT_future XR_METAX2_debug_utils_region_profiling XR_METAX3_debug_utils_region_profiling + XR_EXTX2_stationary_reference_space XR_META_recommended_layer_resolution XR_EXT_local_floor + XR_METAX1_passthrough_camera_data XR_META_hand_tracking_frequency_hint XR_META_hand_tracking_unextrapolated_poses + XR_META_hand_tracking_wide_motion_mode2 XR_METAX1_agentic_external_tool + company: Meta + priority: 0 + targetOpenXRApiVersion: 1.1.54 + required: 0 + customRuntimeLoaderName: +--- !u!114 &-740649823150378031 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 761fdd4502cb7a84e9ec7a2b24f33f37, type: 3} + m_Name: MicrosoftMotionControllerProfile Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.MicrosoftMotionControllerProfile + m_enabled: 0 + nameUi: Microsoft Motion Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.microsoftmotioncontroller + openxrExtensionStrings: + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &-346955242896614811 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b3cf79659a011bd419c7a2a30eb74e9a, type: 3} + m_Name: EyeGazeInteraction Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.EyeGazeInteraction + m_enabled: 0 + nameUi: Eye Gaze Interaction Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.eyetracking + openxrExtensionStrings: XR_EXT_eye_gaze_interaction + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9f0ebc320a151d3408ea1e9fce54d40e, type: 3} + m_Name: OpenXR Package Settings + m_EditorClassIdentifier: Unity.XR.OpenXR.Editor::UnityEditor.XR.OpenXR.OpenXRPackageSettings + Keys: 0100000007000000 + Values: + - {fileID: 8239263627717655857} + - {fileID: 661457664759247413} +--- !u!114 &514913860157979488 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f028123e2efe1d443875bc7609b4a98b, type: 3} + m_Name: PalmPoseInteraction Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.PalmPoseInteraction + m_enabled: 0 + nameUi: Palm Pose + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.palmpose + openxrExtensionStrings: XR_EXT_palm_pose + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &661457664759247413 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b5a1f07dc5afe854f9f12a4194aca3fb, type: 3} + m_Name: Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.OpenXRSettings + features: + - {fileID: -6393979774375439216} + - {fileID: 8491903573475356180} + - {fileID: 2427869867896373191} + - {fileID: -8079773780360711073} + - {fileID: 7318270000366015885} + - {fileID: 4235903070861687951} + - {fileID: -4691887901876839608} + - {fileID: -2371518837694837324} + - {fileID: -4898493728134337233} + - {fileID: -5090109445253957882} + - {fileID: -3455479848038917648} + - {fileID: -8391468794652365456} + - {fileID: -3539015442152043752} + - {fileID: 8441244962955347208} + - {fileID: -8545460186977742305} + - {fileID: 5324850346934748536} + - {fileID: 1171202278767176483} + - {fileID: -1332385295733761299} + - {fileID: -6844477915066494673} + - {fileID: 8823919161308870415} + - {fileID: 5628859817768950485} + - {fileID: -5874362956514689893} + - {fileID: -5308198659050868324} + - {fileID: 2822130261872731885} + - {fileID: 2298118815013777068} + - {fileID: 514913860157979488} + - {fileID: 8624520518106406360} + - {fileID: 5124575738883539091} + - {fileID: 7211974077433819038} + customLoaderName: + m_renderMode: 1 + m_latencyOptimization: 0 + m_autoColorSubmissionMode: 1 + m_colorSubmissionModes: + m_List: 00000000 + m_depthSubmissionMode: 0 + m_spacewarpMotionVectorTextureFormat: 0 + m_optimizeBufferDiscards: 0 + m_symmetricProjection: 0 + m_optimizeMultiviewRenderRegions: 0 + m_multiviewRenderRegionsOptimizationMode: 0 + m_hasMigratedMultiviewRenderRegionSetting: 1 + m_foveatedRenderingApi: 0 + m_useOpenXRPredictedTime: 0 +--- !u!114 &1171202278767176483 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e573a2aed6698b047aff95224499b722, type: 3} + m_Name: MetaXREyeTrackedFoveationFeature Android + m_EditorClassIdentifier: Oculus.VR::Meta.XR.MetaXREyeTrackedFoveationFeature + m_enabled: 0 + nameUi: Meta XR Eye Tracked Foveation + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.eyetrackedfoveation + openxrExtensionStrings: XR_META_foveation_eye_tracked XR_FB_eye_tracking_social + XR_META_vulkan_swapchain_create_info + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &1216846649806117509 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f928d0d73a35f294fbe357ca17aa3547, type: 3} + m_Name: MicrosoftHandInteraction Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.MicrosoftHandInteraction + m_enabled: 0 + nameUi: Microsoft Hand Interaction Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.handtracking + openxrExtensionStrings: XR_MSFT_hand_interaction + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &1945843790895154872 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f6a75d1f5ff90154ea2a8e58222a1f59, type: 3} + m_Name: FoveatedRenderingFeature Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.FoveatedRenderingFeature + m_enabled: 0 + nameUi: Foveated Rendering + version: 1 + featureIdInternal: com.unity.openxr.feature.foveatedrendering + openxrExtensionStrings: XR_UNITY_foveation XR_FB_foveation XR_FB_foveation_configuration + XR_FB_swapchain_update_state XR_FB_foveation_vulkan XR_META_foveation_eye_tracked + XR_META_vulkan_swapchain_create_info + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + enableSubsampledLayout: 0 +--- !u!114 &2298118815013777068 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: feeef8d85de8db242bdda70cc7ff5acd, type: 3} + m_Name: OculusTouchControllerProfile Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.OculusTouchControllerProfile + m_enabled: 0 + nameUi: Oculus Touch Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.oculustouch + openxrExtensionStrings: + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &2427869867896373191 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 486b5e28864f9a94b979b9620ce5006d, type: 3} + m_Name: ConformanceAutomationFeature Android + m_EditorClassIdentifier: Unity.XR.OpenXR.Features.ConformanceAutomation::UnityEngine.XR.OpenXR.Features.ConformanceAutomation.ConformanceAutomationFeature + m_enabled: 0 + nameUi: Conformance Automation + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.conformance + openxrExtensionStrings: XR_EXT_conformance_automation + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &2822130261872731885 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9ef793c31862a37448e907829482ef80, type: 3} + m_Name: OculusQuestFeature Android + m_EditorClassIdentifier: Unity.XR.OpenXR.Features.OculusQuestSupport::UnityEngine.XR.OpenXR.Features.OculusQuestSupport.OculusQuestFeature + m_enabled: 0 + nameUi: Oculus Quest Support + version: 1.0.0 + featureIdInternal: com.unity.openxr.feature.oculusquest + openxrExtensionStrings: XR_OCULUS_android_initialize_loader + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + targetQuest: 1 + targetQuest2: 1 +--- !u!114 &3197600739401666463 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9c5b5af5107e35a43818d5411328bfc3, type: 3} + m_Name: DPadInteraction Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.DPadInteraction + m_enabled: 0 + nameUi: D-Pad Binding + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.dpadinteraction + openxrExtensionStrings: XR_KHR_binding_modification XR_EXT_dpad_binding + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + forceThresholdLeft: 0.5 + forceThresholdReleaseLeft: 0.4 + centerRegionLeft: 0.5 + wedgeAngleLeft: 1.5707964 + isStickyLeft: 0 + forceThresholdRight: 0.5 + forceThresholdReleaseRight: 0.4 + centerRegionRight: 0.5 + wedgeAngleRight: 1.5707964 + isStickyRight: 0 + extensionStrings: + - XR_KHR_binding_modification + - XR_EXT_dpad_binding +--- !u!114 &4235903070861687951 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b82a8cddc5afeb145ad4e1d76511063f, type: 3} + m_Name: DetachedOculusTouchControllerProfile Android + m_EditorClassIdentifier: Oculus.VR::Meta.XR.DetachedOculusTouchControllerProfile + m_enabled: 0 + nameUi: Detached Oculus Touch Controller Profile + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.input.oculustouch.detached + openxrExtensionStrings: XR_META_detached_controllers + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &4509487202842071153 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0d6ccd3d0ef0f1d458e69421dccbdae1, type: 3} + m_Name: ValveIndexControllerProfile Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.ValveIndexControllerProfile + m_enabled: 0 + nameUi: Valve Index Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.valveindex + openxrExtensionStrings: + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &4593565983164920196 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e5315f812f023cf4ebf26f7e5d2d70f2, type: 3} + m_Name: HPReverbG2ControllerProfile Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.HPReverbG2ControllerProfile + m_enabled: 0 + nameUi: HP Reverb G2 Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.hpreverb + openxrExtensionStrings: XR_EXT_hp_mixed_reality_controller + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &5124575738883539091 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b213d3e3c7f3109449eb46a4c8ee42f0, type: 3} + m_Name: XrPerformanceSettingsFeature Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Extensions.PerformanceSettings.XrPerformanceSettingsFeature + m_enabled: 0 + nameUi: XR Performance Settings + version: 1.0.0 + featureIdInternal: com.unity.openxr.feature.extension.performance_settings + openxrExtensionStrings: XR_EXT_performance_settings + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &5324850346934748536 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c4b862ee14fb479fbfe5fffe655d3ed3, type: 3} + m_Name: MetaQuestTouchProControllerProfile Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.MetaQuestTouchProControllerProfile + m_enabled: 0 + nameUi: Meta Quest Touch Pro Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.metaquestpro + openxrExtensionStrings: XR_FB_touch_controller_pro + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &5374551171412220916 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e314dfef9af0904e80129bcc0a79361, type: 3} + m_Name: HandTracking Standalone + m_EditorClassIdentifier: Unity.XR.Hands::UnityEngine.XR.Hands.OpenXR.HandTracking + m_enabled: 0 + nameUi: Hand Tracking Subsystem + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.handtracking + openxrExtensionStrings: XR_EXT_hand_tracking + company: Unity + priority: -100 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &5628859817768950485 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4710975c7840e7d499bbb3757c22b0a5, type: 3} + m_Name: MetaXRSubsampledLayout Android + m_EditorClassIdentifier: Oculus.VR::Meta.XR.MetaXRSubsampledLayout + m_enabled: 0 + nameUi: Meta XR Subsampled Layout + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.subsampledLayout + openxrExtensionStrings: XR_META_vulkan_swapchain_create_info + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &6689541080443264643 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4710975c7840e7d499bbb3757c22b0a5, type: 3} + m_Name: MetaXRSubsampledLayout Standalone + m_EditorClassIdentifier: Oculus.VR::Meta.XR.MetaXRSubsampledLayout + m_enabled: 0 + nameUi: Meta XR Subsampled Layout + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.subsampledLayout + openxrExtensionStrings: XR_META_vulkan_swapchain_create_info + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &7211974077433819038 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e314dfef9af0904e80129bcc0a79361, type: 3} + m_Name: HandTracking Android + m_EditorClassIdentifier: Unity.XR.Hands::UnityEngine.XR.Hands.OpenXR.HandTracking + m_enabled: 0 + nameUi: Hand Tracking Subsystem + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.handtracking + openxrExtensionStrings: XR_EXT_hand_tracking + company: Unity + priority: -100 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &7318270000366015885 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: eda5cc6e8db3d9944bf84a7379663d7c, type: 3} + m_Name: DetachedMetaQuestTouchProControllerProfile Android + m_EditorClassIdentifier: Oculus.VR::Meta.XR.DetachedMetaQuestTouchProControllerProfile + m_enabled: 0 + nameUi: Detached Meta Quest Touch Pro Controller Profile + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.input.metaquestpro.detached + openxrExtensionStrings: XR_META_detached_controllers + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &7586535614002654520 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b3aced3429e5911458f4da2dac9d0f29, type: 3} + m_Name: MetaHandTrackingAim Standalone + m_EditorClassIdentifier: Unity.XR.Hands::UnityEngine.XR.Hands.OpenXR.MetaHandTrackingAim + m_enabled: 0 + nameUi: Meta Hand Tracking Aim + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.metahandtrackingaim + openxrExtensionStrings: XR_FB_hand_tracking_aim + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &7881956948370518578 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 37086d3966675294eb1c38ad413c6817, type: 3} + m_Name: DetachedMetaQuestTouchPlusControllerProfile Standalone + m_EditorClassIdentifier: Oculus.VR::Meta.XR.DetachedMetaQuestTouchPlusControllerProfile + m_enabled: 0 + nameUi: Detached Meta Quest Touch Plus Controller Profile + version: 0.0.1 + featureIdInternal: com.meta.openxr.feature.input.metaquestplus.detached + openxrExtensionStrings: XR_META_detached_controllers + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &7940003794889302453 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0f6bfdbcb316ed242b30a8798c9eb853, type: 3} + m_Name: KHRSimpleControllerProfile Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.KHRSimpleControllerProfile + m_enabled: 0 + nameUi: Khronos Simple Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.khrsimpleprofile + openxrExtensionStrings: + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &8025915861305470529 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f028123e2efe1d443875bc7609b4a98b, type: 3} + m_Name: PalmPoseInteraction Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.PalmPoseInteraction + m_enabled: 0 + nameUi: Palm Pose + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.palmpose + openxrExtensionStrings: XR_EXT_palm_pose + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &8239263627717655857 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b5a1f07dc5afe854f9f12a4194aca3fb, type: 3} + m_Name: Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.OpenXRSettings + features: + - {fileID: -4463675136939454006} + - {fileID: 7881956948370518578} + - {fileID: -3597834595480828386} + - {fileID: -1690673217515633499} + - {fileID: 3197600739401666463} + - {fileID: -346955242896614811} + - {fileID: 1945843790895154872} + - {fileID: -5026095352258469728} + - {fileID: -3655800558024972851} + - {fileID: 4593565983164920196} + - {fileID: -3658833149316982896} + - {fileID: 7940003794889302453} + - {fileID: 7586535614002654520} + - {fileID: -4970216369706289461} + - {fileID: 8608467602246666787} + - {fileID: -8301964434126396227} + - {fileID: -2184912740526592088} + - {fileID: -4559526606425108497} + - {fileID: 6689541080443264643} + - {fileID: 1216846649806117509} + - {fileID: -740649823150378031} + - {fileID: -6542667958538541429} + - {fileID: 8346866549190165165} + - {fileID: 8025915861305470529} + - {fileID: -3022032382842232193} + - {fileID: 4509487202842071153} + - {fileID: -6138514551507227436} + - {fileID: 5374551171412220916} + customLoaderName: + m_renderMode: 1 + m_latencyOptimization: 0 + m_autoColorSubmissionMode: 1 + m_colorSubmissionModes: + m_List: 00000000 + m_depthSubmissionMode: 0 + m_spacewarpMotionVectorTextureFormat: 0 + m_optimizeBufferDiscards: 0 + m_symmetricProjection: 0 + m_optimizeMultiviewRenderRegions: 0 + m_multiviewRenderRegionsOptimizationMode: 0 + m_hasMigratedMultiviewRenderRegionSetting: 1 + m_foveatedRenderingApi: 0 + m_useOpenXRPredictedTime: 0 +--- !u!114 &8346866549190165165 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: feeef8d85de8db242bdda70cc7ff5acd, type: 3} + m_Name: OculusTouchControllerProfile Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.OculusTouchControllerProfile + m_enabled: 1 + nameUi: Oculus Touch Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.oculustouch + openxrExtensionStrings: + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &8441244962955347208 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f647cc0545697264a9878224faada6d5, type: 3} + m_Name: MetaQuestFeature Android + m_EditorClassIdentifier: Unity.XR.OpenXR.Features.MetaQuestSupport::UnityEngine.XR.OpenXR.Features.MetaQuestSupport.MetaQuestFeature + m_enabled: 0 + nameUi: Meta Quest Support + version: 1.0.0 + featureIdInternal: com.unity.openxr.feature.metaquest + openxrExtensionStrings: XR_OCULUS_android_initialize_loader + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + targetDevices: + - visibleName: Quest + manifestName: quest + enabled: 1 + - visibleName: Quest 2 + manifestName: quest2 + enabled: 1 + - visibleName: Quest Pro + manifestName: cambria + enabled: 1 + - visibleName: Quest 3 + manifestName: eureka + enabled: 1 + - visibleName: Quest 3S + manifestName: quest3s + enabled: 1 + forceRemoveInternetPermission: 0 + m_symmetricProjection: 0 + m_foveatedRenderingApi: 0 + systemSplashScreen: {fileID: 0} + m_optimizeBufferDiscards: 1 + lateLatchingMode: 0 + lateLatchingDebug: 0 + optimizeMultiviewRenderRegions: 0 + m_multiviewRenderRegionsOptimizationMode: 0 + m_hasMigratedMultiviewRenderRegions: 1 + spacewarpMotionVectorTextureFormat: 0 +--- !u!114 &8491903573475356180 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 92efb7dda02dc484c90845a437c4784e, type: 3} + m_Name: AutomaticDynamicResolutionFeature Android + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.AutomaticDynamicResolutionFeature + m_enabled: 0 + nameUi: Automatic Viewport Dynamic Resolution + version: 1.0.0 + featureIdInternal: com.unity.openxr.feature.ViewportDynamicResolution + openxrExtensionStrings: XR_META_recommended_layer_resolution XR_ANDROID_recommended_resolution + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + m_MinResolutionScalar: 0.05 + m_MaxResolutionScalar: 1 +--- !u!114 &8608467602246666787 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c4b862ee14fb479fbfe5fffe655d3ed3, type: 3} + m_Name: MetaQuestTouchProControllerProfile Standalone + m_EditorClassIdentifier: Unity.XR.OpenXR::UnityEngine.XR.OpenXR.Features.Interactions.MetaQuestTouchProControllerProfile + m_enabled: 0 + nameUi: Meta Quest Touch Pro Controller Profile + version: 0.0.1 + featureIdInternal: com.unity.openxr.feature.input.metaquestpro + openxrExtensionStrings: XR_FB_touch_controller_pro + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: +--- !u!114 &8624520518106406360 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 056125dd64c0ed540b40a4af74f7b495, type: 3} + m_Name: RuntimeDebuggerOpenXRFeature Android + m_EditorClassIdentifier: Unity.XR.OpenXR.Features.RuntimeDebugger::UnityEngine.XR.OpenXR.Features.RuntimeDebugger.RuntimeDebuggerOpenXRFeature + m_enabled: 0 + nameUi: Runtime Debugger + version: 1 + featureIdInternal: com.unity.openxr.features.runtimedebugger + openxrExtensionStrings: + company: Unity + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: + cacheSize: 1048576 + perThreadCacheSize: 51200 +--- !u!114 &8823919161308870415 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 81954520b8bbd2f458104fe69f5a7680, type: 3} + m_Name: MetaXRSpaceWarp Android + m_EditorClassIdentifier: Oculus.VR::Meta.XR.MetaXRSpaceWarp + m_enabled: 0 + nameUi: Meta XR Space Warp + version: 1.0.0 + featureIdInternal: com.meta.openxr.feature.spacewarp + openxrExtensionStrings: XR_FB_space_warp + company: Meta + priority: 0 + targetOpenXRApiVersion: + required: 0 + customRuntimeLoaderName: diff --git a/Assets/XR/Settings/OpenXR Package Settings.asset.meta b/Assets/XR/Settings/OpenXR Package Settings.asset.meta new file mode 100644 index 00000000..0a5bd4eb --- /dev/null +++ b/Assets/XR/Settings/OpenXR Package Settings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 66627204218bd16438ec45a1666eccd9 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XR/XRGeneralSettingsPerBuildTarget.asset b/Assets/XR/XRGeneralSettingsPerBuildTarget.asset new file mode 100644 index 00000000..73a45050 --- /dev/null +++ b/Assets/XR/XRGeneralSettingsPerBuildTarget.asset @@ -0,0 +1,80 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-7935334623553793341 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4c3631f5e58749a59194e0cf6baf6d5, type: 3} + m_Name: Android Providers + m_EditorClassIdentifier: Unity.XR.Management::UnityEngine.XR.Management.XRManagerSettings + m_RequiresSettingsUpdate: 0 + m_AutomaticLoading: 0 + m_AutomaticRunning: 0 + m_Loaders: + - {fileID: 11400000, guid: 0e870e5d88ccdd3449f81b0c7ea92ce8, type: 2} +--- !u!114 &-7164159512700380013 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d236b7d11115f2143951f1e14045df39, type: 3} + m_Name: Standalone Settings + m_EditorClassIdentifier: Unity.XR.Management::UnityEngine.XR.Management.XRGeneralSettings + m_LoaderManagerInstance: {fileID: 6187744304250330120} + m_InitManagerOnStart: 1 +--- !u!114 &-2026642463250226861 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d236b7d11115f2143951f1e14045df39, type: 3} + m_Name: Android Settings + m_EditorClassIdentifier: Unity.XR.Management::UnityEngine.XR.Management.XRGeneralSettings + m_LoaderManagerInstance: {fileID: -7935334623553793341} + m_InitManagerOnStart: 1 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d2dc886499c26824283350fa532d087d, type: 3} + m_Name: XRGeneralSettingsPerBuildTarget + m_EditorClassIdentifier: Unity.XR.Management.Editor::UnityEditor.XR.Management.XRGeneralSettingsPerBuildTarget + Keys: 0100000007000000 + Values: + - {fileID: -7164159512700380013} + - {fileID: -2026642463250226861} +--- !u!114 &6187744304250330120 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4c3631f5e58749a59194e0cf6baf6d5, type: 3} + m_Name: Standalone Providers + m_EditorClassIdentifier: Unity.XR.Management::UnityEngine.XR.Management.XRManagerSettings + m_RequiresSettingsUpdate: 0 + m_AutomaticLoading: 0 + m_AutomaticRunning: 0 + m_Loaders: + - {fileID: 11400000, guid: 0e870e5d88ccdd3449f81b0c7ea92ce8, type: 2} diff --git a/Assets/XR/XRGeneralSettingsPerBuildTarget.asset.meta b/Assets/XR/XRGeneralSettingsPerBuildTarget.asset.meta new file mode 100644 index 00000000..51b9d98f --- /dev/null +++ b/Assets/XR/XRGeneralSettingsPerBuildTarget.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 64b052f9363a9eb439fabb890edb4f0e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Documentation/docs/getting_started/adding_scenes.md b/Documentation/docs/getting_started/adding_scenes.md index e210adde..c64a1b66 100644 --- a/Documentation/docs/getting_started/adding_scenes.md +++ b/Documentation/docs/getting_started/adding_scenes.md @@ -4,13 +4,17 @@ you must first add the scene to the Unity project and then to the MongoDB databa ## Add Scene in Unity ### Create a new Scene -- Scenes are placed in the `Assets/Local/Scenes` folder. -- Right-click in the `Assets/Local/Scenes` folder and select `Create > Scene`. -- Add and activate scene in the build settings `File/Build Setting > Add Open Scene`. +- Place your scenes in a folder of your own project, e.g. `Assets/Scenes`, not inside `Assets/Lab`. +- The easiest start is a copy of the `Example` sample scene (see [Special Scenes](special_scenes.md)). It already + contains the `Social Network Scene` prefab for networking. +- Don't add a player or camera: the [player](player_controller.md) comes from MetaStart. +- Add a GameObject for each spawn point and name it like the role's `spawnPosition` (e.g. `DefaultSpawn`). +- Add the scene to the build profile (*File > Build Profiles > Scene List*), after MetaStart. #### Debug Scene without MetaStart -Add the following prefabs: `Social Network Scene`, `MetaPlayer`, `AvatarSdkManagerHorizon` to the scene. -(Not testet. `Social Network Scene` e.g. is not nessessary for the scene to work.) +To test a scene on its own, temporarily add the prefabs `MetaPlayer2.0` and `AvatarSdkManagerStyle2Meta` (from the +Meta Avatars *Sample Scenes*, folder `Common/Prefabs/AvatarSdkManager/Recommended`), as MetaStart does. Rename the +manager to `AvatarSdkManagerMeta`: the avatar scripts look it up by that name. Remove both again before building. ## Add Scene to the Database The Scene must be added to the database to be accessible via MetaStart. There are @@ -22,171 +26,72 @@ two ways to do this: don't need direct database access - just an API key. Start there; the walkthrough builds exactly the structure documented below, one call at a time. - **Directly in MongoDB.** As a student, ask your corresponding supervisor to add - the scene for you. The scenes live in `Experiment/scenarios-languages`, in the + the scene for you. Scenes are stored in the `scenarios` collection, in the structure below. -The .json structure - what either route produces - is as follows: +This is the structure of a scene, as `GET /scene` returns it and as the client reads it (`ApiScene` in +`Assets/Lab/Core/Runtime/Scripts/SceneManagement/SceneManagerTypes.cs`): -``` json title="Parameter Explanation" -{ - "name": Name of the Scene in the scene selector, - "internalName": Name of the Scene in Unity, - "roles": Roles in the Scenario. Currently supporting english and german - { - "name": Name of the Role, - "description": Description of the Role, - "spawnPosition": Spawn Position of the Role, - "mode": Mode of the Role (player, observer), - "maxCount": Maximum Count of the Role, - "admin": Admin Role (start and ending levels), - "level": Level Descriptions for that role - }, - "level": Levels in the Scenario, - { - "id": ID of the Level, - "delay": Delay of the Level (stops the level after n minutes; null if no delay) - }, - "enable": Visible via MetaStart, - "amountPlayersRequired": Amount of Players Required, until admin can start the scenario -} -``` +| Field | Meaning | +|---|---| +| `name`, `shortName` | Name in the scene selector, and a short version where space is limited | +| `author` | Author of the scenario | +| `internalName` | Name of the Unity scene | +| `enabled` | Visible in MetaStart | +| `roles` | Roles by identifier (your own key, e.g. `interviewee`) | +| `roles..mode` | `player` or `spectator` (`webcam` exists but is not used by the client yet) | +| `roles..spawnPosition` | Name of the GameObject in the scene the role spawns at | +| `roles..maxCount` | Maximum number of players with this role | +| `roles..admin` | The admin starts and ends the levels | +| `roles..restrictions` | Restrictions of the role, e.g. `blur` | +| `roles..locales.` | `name` and `description` of the role per language (`EN`, `DE`) | +| `levels` | The stages of the scenario, in order | +| `levels[].delay` | Stops the level after n minutes (`null`: no limit) | +| `levels[].roleDescriptions..locales.` | What the role does in this level | + +The example below defines the `InterView` sample scene: an interviewee in VR who starts and ends the level, and an +optional spectator. The spawn points `DefaultSpawn` and `spectator` exist in that scene. ``` json title="Example Scene Entry" { - "name": "Praktikum Experiment 3", - "shortName": "Praktikum 3", - "author": "Alexander Henlein", - "internalName": "PraktikumScenario03", + "name": "InterView Sample", + "shortName": "InterView", + "author": "Jane Doe", + "internalName": "InterView", + "enabled": true, "roles": { - "DE": [ - { - "name": "Person 1", - "description": [ - { - "id": 1, - "description": "Rundfahrt erklären" - } - ], - "spawnPosition": "P1", - "mode": "player", - "maxCount": 1, - "admin": true, - "level": [ - { - "id": 1, - "description": "Rundfahrt" - }, - { - "id": 2, - "description": "Erklären" - }, - { - "id": 3, - "description": "Warten" - } - ] - }, - { - "name": "Person 2", - "description": [ - { - "id": 1, - "description": "Weg finden" - } - ], - "spawnPosition": "P2", - "mode": "player", - "maxCount": 1, - "admin": false, - "level": [ - { - "id": 1, - "description": "Warten" - }, - { - "id": 2, - "description": "Erklären lassen" - }, - { - "id": 3, - "description": "Finden" - } - ] + "interviewee": { + "mode": "player", + "spawnPosition": "DefaultSpawn", + "maxCount": 1, + "admin": true, + "restrictions": [], + "locales": { + "EN": { "name": "Interviewee", "description": ["Answer the interviewer's questions."] }, + "DE": { "name": "Befragte Person", "description": ["Beantworte die Fragen der interviewenden Person."] } } - ], - "EN": [ - { - "name": "Person 1", - "description": [ - { - "id": 1, - "description": "Rundfahrt" - } - ], - "spawnPosition": "P1", - "mode": "player", - "maxCount": 1, - "admin": true, - "level": [ - { - "id": 1, - "description": "Rundfahrt" - }, - { - "id": 2, - "description": "Erklären" - }, - { - "id": 3, - "description": "Warten" - } - ] - }, - { - "name": "Person 2", - "description": [ - { - "id": 1, - "description": "Erklären lassen" - } - ], - "spawnPosition": "P2", - "mode": "player", - "maxCount": 1, - "admin": false, - "level": [ - { - "id": 1, - "description": "Warten" - }, - { - "id": 2, - "description": "Erklären lassen" - }, - { - "id": 3, - "description": "Finden" - } - ] + }, + "spectator": { + "mode": "spectator", + "spawnPosition": "spectator", + "maxCount": 1, + "admin": false, + "restrictions": [], + "locales": { + "EN": { "name": "Spectator", "description": ["Watch the interview."] }, + "DE": { "name": "Beobachtung", "description": ["Beobachte das Interview."] } } - ] + } }, - "level": [ + "levels": [ { "id": 1, - "delay": null - }, - { - "id": 2, - "delay": null - }, - { - "id": 3, - "delay": null + "delay": null, + "roleDescriptions": { + "interviewee": { "locales": { "EN": { "description": ["Interview"] }, "DE": { "description": ["Interview"] } } }, + "spectator": { "locales": { "EN": { "description": ["Observe"] }, "DE": { "description": ["Beobachten"] } } } + } } - ], - "enable": true, - "amountPlayersRequired": 2 + ] } ``` - diff --git a/Documentation/docs/getting_started/interview_client.md b/Documentation/docs/getting_started/interview_client.md index 7e7702ac..76ab3350 100644 --- a/Documentation/docs/getting_started/interview_client.md +++ b/Documentation/docs/getting_started/interview_client.md @@ -23,31 +23,34 @@ itself, its services and their deployment are documented separately: ## What the client connects to -Four independent services. Each is configured in a different place, and each can -fail without the others noticing. +Four independent services, all configured in the [endpoints file](../modules/endpoints.md) +(`Assets/Resources/VasiliEndpoints.asset`). Each can fail without the others noticing. -| Service | Purpose | Configured in | +| Service | Purpose | Endpoints field | |---|---|---| -| Janus | Audio/video and the control data channel | `WebCamClient` | -| Ubiq | VR room and avatar state | `RoomClient` connection definition | -| Logging API | Tracking data and events | Va.Si.Li API asset | -| Questionnaire | The survey instrument | `InterviewTokenManager` | +| Janus | Audio/video and the control data channel | `janus`, `iceServers` | +| Ubiq | VR room and avatar state | `ubiqServer` | +| Logging API | Tracking data and events | `api` | +| Questionnaire | The survey instrument | `questionnaire` | ## Configuration -Open the FACES scene and configure the components below. +The InterView sample scenes are in `Assets/Lab/Core/Samples/Scenes`: `InterViewStart` (token entry, holds the +`InterviewTokenManager`), `InterView` (the interview room, holds the `WebCamClient`) and `InterViewReturn`. Add all +three to the build profile, `InterViewStart` first, and check the components below. ### `WebCamClient` The Janus client. Publishes local audio and video, subscribes to the interviewer's feed, and hosts the textroom data channel that carries chat, -answer options, gaze updates and the recording signal. +answer options, gaze updates and the recording signal. Its server comes from +`janus` in the endpoints: use `wss://janus.`, the TLS endpoint of your +reverse proxy, not Janus's own port. `iceServers` must match the TURN server the +backend uses. | Field | Value | Notes | |---|---|---| -| `ServerUrl` | `wss://janus.` | Must be `wss://` - the TLS endpoint of your reverse proxy, not Janus's own port | | `SubProtocol` | `janus-protocol` | Leave unchanged | -| `IceServers` | TURN URL, username, credential | Must match the TURN server the backend uses | | `RecordingPath` | `/mnt/recordings/` | Path **inside the Janus container**; the room ID is appended automatically | | `captureWidth` / `captureHeight` | `854` × `480` | | | `maxBitrate` / `minBitrate` | `1000000` / `250000` | | @@ -59,14 +62,12 @@ Holds the participant token across scene loads and derives every identifier from it, so the headset and the interviewer's browser meet without a coordination step. -| Field | Value | -|---|---| -| `BrowserBaseUrl` | Your questionnaire URL. The token is appended as `?token=…&room=…` | +The questionnaire URL is `questionnaire` in the endpoints. The token is appended as `?token=…&room=…`. ``` token ──┬─→ RoomId (Janus room ID) ├─→ UbiqRoomName = "interview-{token}" - └─→ BrowserUrl = {BrowserBaseUrl}?token={token}&room={token} + └─→ BrowserUrl = {questionnaire}?token={token}&room={token} ``` The room ID is the token parsed as an integer when it is all digits, and @@ -80,15 +81,14 @@ otherwise a DJB2 hash (seed 5381, multiplier 33), absolute value, minimum 1. ### Ubiq connection -Set the `RoomClient` connection definition to your Ubiq host and its published -TCP port (**16485** in the default deployment). +Set `ubiqServer` in the endpoints to a Ubiq connection definition with your Ubiq host +and its published TCP port (**16485** in the default deployment). ### Logging API -Set the Va.Si.Li API asset `host` to your API URL, and the API key to the same -value the backend was deployed with. +Set `api` in the endpoints to your Database API URL. -!!! warning "A wrong API key loses the whole session, silently" +!!! warning "A wrong API address loses the whole session, silently" Logging failures do not interrupt an interview. The session looks completely normal and records nothing. Verify that data is arriving **before** a participant sits down, not afterwards. @@ -101,11 +101,11 @@ value the backend was deployed with. ## Pre-session checklist -- [ ] `ServerUrl` reachable from the headset's network +- [ ] `janus` reachable from the headset's network - [ ] TURN credentials current and matching the server - [ ] Ubiq host and port correct -- [ ] API key matches the backend -- [ ] `BrowserBaseUrl` points at the correct questionnaire +- [ ] `api` points at the running Database API +- [ ] `questionnaire` points at the correct questionnaire - [ ] A full test interview completed, with data confirmed in the database ## Troubleshooting diff --git a/Documentation/docs/getting_started/meta_avatar.md b/Documentation/docs/getting_started/meta_avatar.md index 1cf101d7..db373081 100644 --- a/Documentation/docs/getting_started/meta_avatar.md +++ b/Documentation/docs/getting_started/meta_avatar.md @@ -1,6 +1,6 @@ # Meta Avatar -Instead of the biq Avatars, we are using the [Meta Avatar](https://developer.oculus.com/documentation/unity/meta-avatars-overview/) system. +Instead of the Ubiq avatars, we are using the [Meta Avatar](https://developers.meta.com/horizon/documentation/unity/meta-avatars-overview/) system. The avatars have the following advantages: * Diverse cast of pre-built avatars + customization options @@ -9,10 +9,13 @@ The avatars have the following advantages: * Visualisation of Facial Expressions ## Usage -At the moment the meta avatars are still loaded via an extra private Git project. -In the next version, these will be available as a standard module of the main project. +The Meta Avatars SDK (`com.meta.xr.sdk.avatars`, 40.0.1) is installed from the Unity registry as a dependency of +Va.Si.Li-Lab. Its *Sample Scenes* sample must be imported, because Va.Si.Li-Lab uses `SampleAvatarEntity` and the +`AvatarSdkManagerStyle2Meta` prefab from it (in MetaStart, renamed to `AvatarSdkManagerMeta`, the name the avatar scripts look up), see [Setting Up](setting_up.md#import-the-required-samples). + +The avatar scripts of Va.Si.Li-Lab are in `Assets/Lab/Core/Runtime/Scripts/MetaAvatars`. The local avatar is driven by +`MetaAvatarInput` on the [player](player_controller.md). ## References -* [Meta Avatar Documentation](https://developer.oculus.com/documentation/unity/meta-avatars-overview/) -* [Meta Avatar SDK](https://assetstore.unity.com/packages/tools/integration/meta-avatars-sdk-271958) -* [Meta Avatar SDK Sample](https://assetstore.unity.com/packages/tools/integration/meta-avatars-sdk-sample-assets-272863) \ No newline at end of file +* [Meta Avatar Documentation](https://developers.meta.com/horizon/documentation/unity/meta-avatars-overview/) +* [Meta Avatars SDK on the Unity registry](https://docs.unity3d.com/Manual/upm-ui.html) (*Package Manager > Unity Registry > Meta Avatars SDK*) diff --git a/Documentation/docs/getting_started/meta_interactions.md b/Documentation/docs/getting_started/meta_interactions.md deleted file mode 100644 index 8db94bfc..00000000 --- a/Documentation/docs/getting_started/meta_interactions.md +++ /dev/null @@ -1,68 +0,0 @@ -## OVRCameraRigInteraction - -If you have the CoreSDK/InteractionSDK Assets installed, delete the Default Camera in your scene and just add this prefab into your scene. This Camera works both with Controllers and Handtracking by default. - - - -## Usage -The (hand) interactions made possible with this setup include: - -* Grabs (Special Grabs include i.e. Pinch and Pointer) -* Distance Grabs -* Ray Grabs -* Locomotion -* Teleportation - -## How to Add Interactions -To add interactions to your OVRCameraRig, all that is required is to modify the state of the object you want to make interactable. - -For each type of grab interaction, follow these steps: - -Highlight your GameObject, right-click, search for INTERACTION SDK, and choose the type of grab interaction you want to apply to your GameObject. -If your object doesn’t have a Collider or Rigidbody yet, a window will pop up prompting you to click "Create." This will add a child GameObject named "ISDK_...", allowing the object to be interacted with. (This only works because the OVRCameraRigInteraction already has all of the necessary interactors.) -It is recommended NOT to attach every type of interactor to a single GameObject. If you have a large object but only want a small part of it to be interactable, the same rule applies. - -There are multiple types of interactions that you can add to a GameObject: -* Hand Grab -* Distance Grab -* Poke -* Ray Grab -* etc. - -[For more check out this link](https://developers.meta.com/horizon/documentation/unity/unity-isdk-interaction-sdk-overview/) - -## Custom Interactions - -To add custom interactions for hand/controllers, you will need to reference the OVRHand class or the appropriate controller class for the controllers you’re using. You can also directly read button inputs using the OVRInput class. For an example of both methods, refer to the MetaPen.cs script, or check the official documentation for [more information](https://developers.meta.com/horizon/documentation/unity/unity-inputactions). - -## Locomotion - -The OVRCameraRigInteractable prefab already comes with the necessary setup to implement teleporting and turning via hand tracking. -To enable teleportation, you will need to copy HotspotVoidFloor and NavMeshHotspotWalkable from the Meta Locomotion sample scene. This will create a large plane that allows for teleportation. If you want to prevent teleportation through objects, you will also need to copy CollidersTeleportBlocker. - -It may be necessary to adjust the Y-axis of HotspotVoidFloor to ensure the floor does not block teleportation. - -Alternatively, for more complex environments, you can use the "Add Teleport Quick Action" from the Oculus SDK. You can also bake a NavMesh and add a teleport interactable to it. However, this is not recommended. - -## Scirpts -### FireworkSpawn.cs -Added the Firework Spawn script that takes Spawn Object, Spawn Point, Height Offset, Upward Force. -It spawns an object with upward force (firework) when interacted with via a RayInteractor (Hand and Controller). - - -### Metamovement.cs -Component script in OVRCameraRig to make sure that the left Oculus-joystick of the Player ensures forward/backward/left/right movement even if head is turned. - -### TeleportOnTrigger.cs -Added logic from previous, changed the way it teleports a player on entry. Updated teleport spots to stop teleportation from occuring in the ground. - - -### PraktikumScenario01_RoleManager.cs -Changed varaibles to fit new camera setup. Tweaked logic to ensure it handles the player correctly. - - - - -### References -[MetaInteractionSDK](https://developer.oculus.com/documentation/unity/unity-isdk-interaction-sdk-overview/) -[HandTracking](https://developer.oculus.com/documentation/unity/unity-handtracking-overview/) diff --git a/Documentation/docs/getting_started/player_controller.md b/Documentation/docs/getting_started/player_controller.md new file mode 100644 index 00000000..75f04b48 --- /dev/null +++ b/Documentation/docs/getting_started/player_controller.md @@ -0,0 +1,58 @@ +# Player Controller + +The player is the prefab `MetaPlayer2.0` in `Assets/Lab/Core/Runtime/Prefabs`. It is built from Meta XR +[Building Blocks](https://developers.meta.com/horizon/documentation/unity/bb-overview/) and works with controllers and +hand tracking. + +## How it is used +- Only the `MetaStart` scene contains the player. `DontDestroyOnLoad` keeps it alive when a scenario scene is loaded, + so scenario scenes must **not** contain their own player or camera. +- When the role or scene changes, `PlayerSpawnManager` moves the player to the role's spawn point: a GameObject whose + name matches the role's `spawnPosition` in the [scene definition](adding_scenes.md). Afterwards + `MenuRequestManager` opens the social menu. + +## Structure + +| Object | Contents | +|---|---| +| `MetaPlayer2.0` (root) | `OVRPlayerController` + `CharacterController` (thumbstick movement, 45° snap turn, gravity), `PlayerSpawnManager`, `MenuRequestManager`, `DontDestroyOnLoad`, `DistanceObjectDesktopUser` | +| `[BuildingBlock] Camera Rig` | `OVRCameraRig` and `OVRManager`: head, eye and hand anchors | +| `[BuildingBlock] Interaction` | Interaction SDK rig: hand and controller interactions (grab, distance grab, poke, ray), synthetic hands, the `Locomotor` (teleport arc, turning, step locomotion with hands) and the eye-gaze ray (`EyeGazePointerPose`) | +| `Meta Avatar Input (OVR)` | `MetaAvatarInput`: feeds head and hand tracking into the local Meta avatar | +| `BlurEffect` | Blurred vision for roles with the `blur` restriction | + +## Movement scripts +All in `Assets/Lab/Core/Runtime/Scripts/Movement`: + +| Script | Purpose | +|---|---| +| `PlayerSpawnManager` | Moves the local player to the role's spawn point after a role or scene change | +| `MovementLock` | Locks movement while the player's status is *waiting* and lifts the `blur` restriction meanwhile | +| `TeleportOnTrigger` | Teleports a player to a target when they enter a trigger collider | +| `ContinousMovementEventBroadcaster` | Turns a thumbstick axis into continuous locomotion events | + +## Input +The project uses the Input System only (*Player Settings > Active Input Handling*). For buttons that should work with +controllers, hand tracking and a desktop keyboard alike, use `VaSiLi.Helper.LabInput` (e.g. `LabInput.PrimaryDown`). +For controller- or hand-specific input use `OVRInput` and `OVRHand`, see +[Meta input actions](https://developers.meta.com/horizon/documentation/unity/unity-inputactions). + +## Adding interactions to objects +The player already has all interactors, so an object only needs an interactable: + +1. Select the GameObject, right-click and choose *Interaction SDK* and the interaction you want (hand grab, distance + grab, poke, ray grab, ...). +2. If the object has no Collider or Rigidbody yet, click *Create* in the dialog. This adds an `ISDK_...` child object. + +Don't put every interaction type on one object. If only part of a large object should be interactable, add the +interactable to that part only. More: [Interaction SDK overview](https://developers.meta.com/horizon/documentation/unity/unity-isdk-interaction-sdk-overview/). + +## Teleporting in a scene +The `Locomotor` handles teleporting and turning. To make a floor teleportable, add a teleport interactable to it, for +example with *Add Teleport Quick Action* from the Interaction SDK, or copy `HotspotVoidFloor` and +`NavMeshHotspotWalkable` from Meta's locomotion sample scene (and `CollidersTeleportBlocker` to stop teleports through +walls). You may need to adjust the floor's height so it doesn't block the arc. + +## References +- [Meta Interaction SDK](https://developers.meta.com/horizon/documentation/unity/unity-isdk-interaction-sdk-overview/) +- [Hand tracking](https://developers.meta.com/horizon/documentation/unity/unity-handtracking-overview/) diff --git a/Documentation/docs/getting_started/setting_up.md b/Documentation/docs/getting_started/setting_up.md index 268bbe79..0e209c44 100644 --- a/Documentation/docs/getting_started/setting_up.md +++ b/Documentation/docs/getting_started/setting_up.md @@ -6,42 +6,57 @@ `git clone https://github.com/texttechnologylab/Va.Si.Li-Lab.git` ### Open the Project with UnityHub -Unity Hub downloads the correct Unity Version for you. -Add Android Support, if you want to build for Oculus VR Devices. +Unity Hub downloads the correct Unity version (6000.3) for you. +Add Android Build Support if you want to build for Meta Quest headsets. +### Import the required samples +Va.Si.Li-Lab uses code and prefabs from two package samples. Import them in *Window > Package Manager* (select the +package, *Samples* tab, *Import*). Until then you get compile errors such as `SampleAvatarEntity could not be found`. -## Import as Unity Package (Work in Progress) +| Package | Sample | +|---|---| +| Meta Avatars SDK | Sample Scenes | +| Ubiq | Demo (XRI) | -### Unity -Install Ubiq as a git package in the Unity Package Manager -``` -https://github.com/UCL-VR/ubiq.git#upm-unity-v1.0.0-pre.14 -``` -Install Va.Si.Li-Lab -``` -https://github.com/texttechnologylab/Va.Si.Li-Lab.git#upm +The Meta Avatars sample doesn't compile against Platform SDK 207 (`'CAPI' does not exist in the namespace +'Oculus.Platform'`). In `Assets/Samples/Meta Avatars SDK/40.0.1/Sample Scenes/Scripts/Utility/AvatarEditorUtils.cs` +replace the line `var result = new Request<…>(Oculus.Platform.CAPI.ovr_Avatar_LaunchAvatarEditor((IntPtr)options));` +with: + +```csharp +var result = Oculus.Platform.Avatar.LaunchAvatarEditor(options); ``` -Import Meta Avatar Samples from the Meta Avatars SDK(UPM). +Also import *TextMesh Pro Essential Resources* when Unity asks. -Fix all remaining issues listed in the Meta Project Setup Tools. +### Quick-start +1. Run *Tools > Va.Si.Li > Create Endpoints Config*. This creates `Assets/Resources/VasiliEndpoints.asset`, which holds + the addresses of all servers (Ubiq server, Database API, speech, chatbot, WebRTC). Point it to your own + [server installation](../server/server_structure.md). For quick tests, set *Ubiq Server* to the + `Nexus Connection Definition` provided by UCL (features that need our backend will be missing). +2. Open the `MetaStart` scene in `Assets/Lab/Core/Samples/Scenes` and press Play. Without a headset, use the + Meta XR Simulator. -(WIP) Ensure Active Input Handling(Player Settings) is set to Both. -(WIP) Navigate to Packages/VaSiLi-Lab/Runtime/Scenes/MetaStart or LocalLoopbackTest and open the scene. -For now only the MetaXRSimulator or a VR headset is supported. - +The event system ([Va.Si.Li-ES](../systems.md#vasili-es)) is a separate, optional package: +`"org.texttechnologylab.vasili-es": "https://github.com/texttechnologylab/Va.Si.Li-Lab.git#upm-eventsystem"`. +All other dependencies (Meta XR SDKs, XR Interaction Toolkit, WebRTC, ...) are installed automatically. +Then: +1. Import the [required samples](#import-the-required-samples) and apply the `AvatarEditorUtils.cs` fix. +2. Import the Va.Si.Li-Lab samples (*Package Manager > Va.Si.Li-Lab > Samples*) for the [scenes](special_scenes.md). +3. Fix the remaining issues listed in *Meta XR Project Setup Tool*. +4. Set *Player Settings > Active Input Handling* to *Input System Package (New)*. +5. Continue with the [quick-start](#quick-start). diff --git a/Documentation/docs/getting_started/special_scenes.md b/Documentation/docs/getting_started/special_scenes.md index ae3ac4bc..d8e72d23 100644 --- a/Documentation/docs/getting_started/special_scenes.md +++ b/Documentation/docs/getting_started/special_scenes.md @@ -1,20 +1,27 @@ # Special Scenes +The sample scenes are in `Assets/Lab/Core/Samples/Scenes`. When Va.Si.Li-Lab is installed as a package, import them +via *Package Manager > Va.Si.Li-Lab > Samples*. ## MetaStart -Starting Scene for every experiment. -Here the user can select an avatar and join a scenario. +Starting scene for every experiment. It contains the [player](player_controller.md), the scene selector and the +network connection. Here the user selects an avatar and joins a scenario. ## MetaReturn -Helping scene, when disconnecting from a scenario. -The user returns here, when he disconnects from a scenario, not to MetaStart. -Some Scripts are deleted here, that otherwise would cause problems. - -## Start -The Starting scene, using Ubiq Avatars. **Deprecated.** +Helper scene the user returns to when disconnecting from a scenario (instead of MetaStart). +Some scripts that would otherwise cause problems are removed here. ## Tutorial -Tutorial scene to get familiar with the controls. -Can be started from MetaStart. +Tutorial scene to get familiar with the controls. Can be started from MetaStart. + +## Example +Minimal scenario scene (networking and a box of pens) to copy when [adding a scene](adding_scenes.md). + +## InterViewStart, InterView, InterViewReturn +The scenes of [InterView](../systems.md#interview), used instead of MetaStart/MetaReturn for VR interviews: + +- `InterViewStart`: the participant enters the interview token (`InterviewTokenManager`). +- `InterView`: the interview room with the interviewee's seat, a mirror (self-view), the in-world browser for the + questionnaire and the WebRTC (Janus) connection to the interviewer's browser. +- `InterViewReturn`: shown after the interview. -## TestScenes/LocalLoopback Test -Test scene for local loopback testing > NetworkCapabilities. +See [InterView VR Client](interview_client.md) for their configuration. diff --git a/Documentation/docs/images/logo/vasili-lab.svg b/Documentation/docs/images/logo/vasili-lab.svg new file mode 100644 index 00000000..a127a296 --- /dev/null +++ b/Documentation/docs/images/logo/vasili-lab.svg @@ -0,0 +1,216 @@ + + + + AAAWgmp1bWIAAAAeanVtZGMycGEAEQAQgAAAqgA4m3EDYzJwYQAAABZcanVtYgAAAEdqdW1kYzJtYQARABCAAACqADibcQN1cm46YzJwYTpkMmQ4YmExYy1kY2YzLTRiNGUtYmViMy1lMzBlMGVlYWVkMmIAAAADl2p1bWIAAAApanVtZGMyYXMAEQAQgAAAqgA4m3EDYzJwYS5hc3NlcnRpb25zAAAAALxqdW1iAAAARGp1bWRjYm9yABEAEIAAAKoAOJtxE2MycGEuaW5ncmVkaWVudC52MwAAAAAYYzJzaM114EIx/uddSgUJjgYNmTUAAABwY2JvcqNpZGM6Zm9ybWF0bWltYWdlL3N2Zyt4bWxqaW5zdGFuY2VJRHgseG1wOmlpZDphYWFiODg3OS1mZGNmLTQyZDAtOWY1ZC1kZWNkYzg1MzIxM2VscmVsYXRpb25zaGlwaHBhcmVudE9mAAAB4mp1bWIAAABBanVtZGNib3IAEQAQgAAAqgA4m3ETYzJwYS5hY3Rpb25zLnYyAAAAABhjMnNoOvtyo99fczuY0Rl5t+dFNQAAAZljYm9yomdhY3Rpb25zgqJmYWN0aW9ua2MycGEub3BlbmVkanBhcmFtZXRlcnOha2luZ3JlZGllbnRzgaJjdXJseC1zZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmluZ3JlZGllbnQudjNkaGFzaFggARfTJlEJzGaSLQTQc0xD0K4wyROqbZ2QZvz8noP9OGCkZmFjdGlvbngdY29tLmFudGhyb3BpYy5jbGF1ZGUucHJvdmlkZWRqcGFyYW1ldGVyc6F4H2NvbS5hbnRocm9waWMub3JpZ2luLWNvbmZpZGVuY2VndW5rbm93bmtkZXNjcmlwdGlvbnhmQ2xhdWRlIHByb3ZpZGVkIHRoaXMgZmlsZSBhdCB0aGUgcmVxdWVzdCBvZiBhIHVzZXIgYW5kIG1heSBoYXZlIGNyZWF0ZWQgb3IgbW9kaWZpZWQgdGhlIGZpbGUgY29udGVudHMubXNvZnR3YXJlQWdlbnShZG5hbWVmQ2xhdWRlcmFsbEFjdGlvbnNJbmNsdWRlZPUAAADIanVtYgAAAEBqdW1kY2JvcgARABCAAACqADibcRNjMnBhLmhhc2guZGF0YQAAAAAYYzJzaO9wNInPpRo5pHQtb7T4ZGYAAACAY2JvcqVjYWxnZnNoYTI1NmNwYWRMAAAAAAAAAAAAAAAAZGhhc2hYIMoJpbJT9j06su5kOQseJa9VaSd3+7TP8QsiO4TbljFcZG5hbWVuanVtYmYgbWFuaWZlc3RqZXhjbHVzaW9uc4GiZXN0YXJ0GQGeZmxlbmd0aBkeBAAAAj5qdW1iAAAAJ2p1bWRjMmNsABEAEIAAAKoAOJtxA2MycGEuY2xhaW0udjIAAAACD2Nib3KlY2FsZ2ZzaGEyNTZpc2lnbmF0dXJleE1zZWxmI2p1bWJmPS9jMnBhL3VybjpjMnBhOmQyZDhiYTFjLWRjZjMtNGI0ZS1iZWIzLWUzMGUwZWVhZWQyYi9jMnBhLnNpZ25hdHVyZWppbnN0YW5jZUlEeCx4bXA6aWlkOjNjMDc4N2FlLWZiZmItNDExNS05Nzc5LTJkZmNhYWY3OGI0YXJjcmVhdGVkX2Fzc2VydGlvbnODomN1cmx4LXNlbGYjanVtYmY9YzJwYS5hc3NlcnRpb25zL2MycGEuaW5ncmVkaWVudC52M2RoYXNoWCABF9MmUQnMZpItBNBzTEPQrjDJE6ptnZBm/Pyeg/04YKJjdXJseCpzZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmFjdGlvbnMudjJkaGFzaFggNSg4QvP4R3scx0EuAzRtnpVPKK9QfqFCkqfENpe7CjKiY3VybHgpc2VsZiNqdW1iZj1jMnBhLmFzc2VydGlvbnMvYzJwYS5oYXNoLmRhdGFkaGFzaFgggK+3tBrZtdLaV89RdoEI3+mIQX32AcTg/etjiJxG0p90Y2xhaW1fZ2VuZXJhdG9yX2luZm+jZG5hbWVvQW50aHJvcGljIEZpbGVzZ3ZlcnNpb25lMS4wLjBrc3BlY1ZlcnNpb25lMi40LjAAABA4anVtYgAAAChqdW1kYzJjcwARABCAAACqADibcQNjMnBhLnNpZ25hdHVyZQAAABAIY2JvctKEWQISogEmGCFZAgowggIGMIIBjaADAgECAhRA5aAK7sI50L64g/oGQgU9Z1UTADAKBggqhkjOPQQDAzBJMRcwFQYDVQQKEw5BbnRocm9waWMsIFBCQzEuMCwGA1UEAxMlQW50aHJvcGljIENvbnRlbnQgQ3JlZGVudGlhbHMgUm9vdCBDQTAeFw0yNjA4MDcxODQzNTZaFw0yODA4MDYxOTQzNTZaMEQxFzAVBgNVBAoTDkFudGhyb3BpYywgUEJDMSkwJwYDVQQDEyBBbnRocm9waWMgQ2xhdWRlIENvbnRlbnQgU2lnbmluZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJh6CmvLUBgFFNU0vUKlOVtE6djd17L5SuwX0LemFisBM3dkd/3cyjxFA3Qo5S46fX0/ihY0VZ7mfb9KF703t5OjWDBWMA4GA1UdDwEB/wQEAwIHgDAVBgNVHSUEDjAMBgorBgEEAYPoXgIBMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUzlHiBIFOZFsj+OPEz5o+nMHXXMIwCgYIKoZIzj0EAwMDZwAwZAIwMXMdFJ4BetLLVY7ORuE9noqbbAZOZn/aArXyTwFAZfKrPzxF2vPoJNf1+UCdg1XGAjBwX1zd9WGqYkqmL5SFqw1QySjr1zJfpJM9+1rdDwSPLMOPOjKuiXjoU/pUUeG9RwmhY3BhZFkNngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPZYQOucfH7jWY0Hf5sF5zvflqdwbU5QYhDCWnScFk0zuRrJzMHxhUajibTa+ds8KJCAaf305w0HUoKnOkABkhShEYw= + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + V + a. + S + i. + L + i-Lab + + + diff --git a/Documentation/docs/images/projects/FACES.png b/Documentation/docs/images/projects/FACES.png new file mode 100644 index 0000000000000000000000000000000000000000..347706c79b8fb0990cf5561664788e9c8958e8d8 GIT binary patch literal 13665 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 j*?))@Bmu#``I*-S5rw|Ggg$ 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 diff --git a/Documentation/docs/index.md b/Documentation/docs/index.md index b79b1d5f..d9b21c60 100644 --- a/Documentation/docs/index.md +++ b/Documentation/docs/index.md @@ -1,22 +1,30 @@ # Va.Si.Li-Lab +![Va.Si.Li-Lab](images/logo/vasili-lab.svg){ width="420" } + ## Description a **V**R-L**a**b for **Si**mulation-based **L**earn**i**ng. +Va.Si.Li-Lab is a Unity framework for collaborative, multi-user VR with customisable avatars and environments. +It was established in [DigiTeLL](projects/digitell.md) and is used in several [projects](projects/index.md). +Systems built on it, such as [InterView](systems.md#interview) for VR survey interviews, are listed under +[Systems](systems.md). + ## Disclaimer This documentation is work in progress. -And not all functions discribed here are implemented yet. +And not all functions described here are implemented yet. + +## Core Team +Current members of the [Text Technology Lab](https://www.texttechnologylab.org/team/) working on Va.Si.Li-Lab: -## Team -* Prof. Dr. Alexander Mehler (Leader) [:fontawesome-brands-github:](https://github.com/amehler) [:fontawesome-brands-researchgate:](https://www.researchgate.net/profile/Alexander-Mehler-2) +* Prof. Dr. Alexander Mehler (Leader) [:fontawesome-brands-github:](https://github.com/amehler) [:fontawesome-brands-researchgate:](https://www.researchgate.net/profile/Alexander-Mehler-2) * Giuseppe Abrami [:fontawesome-brands-github:](https://github.com/abrami) [:fontawesome-brands-researchgate:](https://www.researchgate.net/profile/Giuseppe-Abrami) * Mevlüt Bagci [:fontawesome-brands-github:](https://github.com/mevbagci) [:fontawesome-brands-researchgate:](https://www.researchgate.net/profile/Mevluet-Bagci) * Dr. Alexander Henlein [:fontawesome-brands-github:](https://github.com/henlein) [:fontawesome-brands-researchgate:](https://www.researchgate.net/profile/Alexander-Henlein) * Patrick Schrottenbacher [:fontawesome-brands-github:](https://github.com/TheBv) [:fontawesome-brands-researchgate:](https://www.researchgate.net/profile/Patrick-Schrottenbacher) -* Atef Ezziddin [:fontawesome-brands-github:](https://github.com/AtefEzziddin) ## Citation Please see the [publications](publications.md) for further details. @@ -27,11 +35,20 @@ Please see the [publications](publications.md) for further details. - [x] Init Documentation - [ ] Current Documentation State * [x] Home - * [ ] Getting Started + * [x] Getting Started + * [x] Modules (Endpoints, Event System, Bots, Logging) * [ ] Other Functions - * [X] Replay Experiment - * [ ] Bots - * [ ] Scenarios + * [ ] Replay Experiment (new version in preparation) + * [ ] Experiment Visualization (new version in preparation) + * [x] Scenarios * [ ] Server Structure * [x] Projects - * [x] Publications \ No newline at end of file + * [x] Systems + * [x] Publications + +## Contributors +Generated from the [GitHub contributors](https://github.com/texttechnologylab/Va.Si.Li-Lab/graphs/contributors) of the repository. + + + Contributors + diff --git a/Documentation/docs/modules/bots.md b/Documentation/docs/modules/bots.md new file mode 100644 index 00000000..288bdc95 --- /dev/null +++ b/Documentation/docs/modules/bots.md @@ -0,0 +1,57 @@ +# Bots + +Va.Si.Li-Lab has LLM-based agents that users talk to by voice and that can act in the scene through *tools*. The code +is in `Assets/Lab/Core/Runtime/Scripts/LLM` (namespace `VaSiLi.Llm`). The agents need two backend services: +[vr-agent](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/vr_agent/) (`agent` in the [endpoints](endpoints.md)), which talks to the LLM, and +[tts-stt](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/tts_stt/) (`speechSynthesis`) for speech in and out. + +## Prefabs +Both are samples (`Assets/Lab/Core/Samples/Objects/Prefabs`): + +| Prefab | Contents | +|---|---| +| `AgentToolkit` | One per scene: `AgentManager` (creates the agents), `AgentToolProvider` (collects the tools), `PlayerMicListener` (push-to-talk) and `ToolExamples` | +| `AgentBot` | One agent: the bot model, `AgentInstance`, `ChatAPI` (speech in and out) and its UI (`AgentActivatorUI`, `ToolWhitelistUI`, `ToolLogUI`) | + +`MetaStart` contains an `AgentToolkit`; `AgentManager` spawns `AgentBot` instances from it. + +## How it works +1. `AgentManager` creates the agents listed in its *Agents* field: for each it instantiates the `AgentBot` prefab at the + given position and registers the agent with the agent service (`/createAgent`). The system prompt is the agent's + *Persona* followed by the tool-call instructions. Set the list on the `AgentToolkit` instance of each scene. +2. The user activates an agent (`AgentActivatorUI`) and talks to it. `PlayerMicListener` records while *A* (or the + right index pinch, or *V* on a keyboard) is held and passes the recording to every active agent. It only records + while at least one agent is active. +3. `ChatAPI` transcribes the audio (`speechSynthesis/whisperx`) and sends the text to the agent (`agent/chat`). +4. The agent answers with text, which `ChatAPI` speaks (`speechSynthesis/tts`), or with a tool call. +5. `AgentInstance` runs tool calls the user has allowed for that agent (`ToolWhitelistUI`) and logs them (`ToolLogUI`). + +## Tools +A tool is any method marked with `[AgentTool]` on a `MonoBehaviour` in the scene. `AgentToolProvider` finds them by +reflection and sends their descriptions to the agent service (`/toolDescriptions`): + +```csharp +using UnityEngine; +using VaSiLi.Llm; + +public class LampTools : MonoBehaviour +{ + public Light lamp; + + [AgentTool("switch_lamp", "Call when the user wants the lamp switched on or off.")] + public string SwitchLamp(bool on) + { + lamp.enabled = on; + return on ? "The lamp is on" : "The lamp is off"; + } +} +``` + +Parameters can be `string`, `int`, `float`, `double`, `bool` and `Vector3`; for other types the agent passes the name of an +earlier tool call, and that call's return value is used. The returned string goes back to the agent as the result. `ToolExamples` has more examples (spawning prefabs, +changing colours and textures). Components that implement `IAgentContextInfo` add information about the scene to +the agent's context. + +## Chatbot module +`Assets/Lab/Core/Runtime/Scripts/Modules/Chatbot` is an older, simpler voice chatbot: `ChatBotManager` sends recorded +audio to `speech/query` and plays the answer, `ChatBotSelectButton` picks the chatbot. It uses the `speech` service. diff --git a/Documentation/docs/modules/endpoints.md b/Documentation/docs/modules/endpoints.md new file mode 100644 index 00000000..b8d6ae4e --- /dev/null +++ b/Documentation/docs/modules/endpoints.md @@ -0,0 +1,41 @@ +# Endpoints Configuration + +All server addresses of the client live in one asset, `VasiliEndpoints` +(`Assets/Lab/Core/Runtime/Scripts/Networking/VasiliEndpoints.cs`). It is loaded from any `Resources` folder by the +name `VasiliEndpoints`. + +The repository doesn't ship one. Create yours with *Tools > Va.Si.Li > Create Endpoints Config*, which writes +`Assets/Resources/VasiliEndpoints.asset`. Until then, every service falls back to `localhost` and a warning is +logged at start-up. + +!!! warning "Don't commit your endpoints file to a public repository" + It contains your server addresses and TURN credentials. Keep it in a private folder or repository. + +## Fields + +| Field | Default | Used by | Without it | +|---|---|---|---| +| `ubiqServer` | `127.0.0.1:8009` (TCP) | `VasiliServerConnection` on the `RoomClient` of the `Social Network Scene` prefab | No multiplayer room | +| `api` | `http://localhost:8000` | [Database API](../server/python_data_logger.md): scene definitions (`SceneManager`), [logging](logging.md), tutorials, connection status | No scenes in MetaStart, nothing is logged | +| `speech` | `http://localhost:8001` | [speech2text](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/speech/): `MicrophoneListener` (`/whisper`); [chatbot host](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/chatbot/): `ChatBotManager` (`/query`). Both are expected at this address | No speech input | +| `agent` | `http://localhost:8002` | [vr-agent](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/vr_agent/): `AgentManager`, `AgentInstance`, `AgentToolProvider`, `ChatAPI` (`/chat`), see [Bots](bots.md) | No agents | +| `speechSynthesis` | `http://localhost:8003` | [tts-stt](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/tts_stt/): `ChatAPI` transcription (`/whisperx`) and text-to-speech (`/tts`) | Agents don't hear or speak | +| `shapeNet` | `http://localhost:8004` | ShapeNet object search and download (`ShapeNetInterface`) | No ShapeNet objects | +| `eventTemplates` | `http://localhost:4567` | [Event System](eventsystem.md) templates (`/defaultTemplates`) | No saved or default event systems | +| `questionnaire` | *(empty)* | [InterView](../getting_started/interview_client.md): questionnaire page opened in the in-world browser (`InterviewTokenManager`) | Empty browser in InterView | +| `janus` | `ws://localhost:8188` | WebRTC (Janus) for InterView and the webcam screen (`WebCamClient`) | No audio/video with the interviewer | +| `iceServers` | *(empty)* | STUN/TURN servers for WebRTC. Leave `username`/`credential` empty for STUN | WebRTC only works on the same network | + +Base URLs are written without a trailing slash. Use `wss://` for Janus behind a TLS reverse proxy. + +## In code + +```csharp +using VaSiLi.Networking; + +string url = VasiliEndpoints.Current.api + "/logging/status"; +``` + +`VasiliEndpoints.Current` is loaded once and cached. To add a new service, add a field with a `localhost` default and +a tooltip to `VasiliEndpoints`, and read it through `Current`. Don't hard-code hosts: +`Tools/Publish/check-public.sh` reports them. diff --git a/Documentation/docs/modules/eventsystem.md b/Documentation/docs/modules/eventsystem.md new file mode 100644 index 00000000..fefbdcf3 --- /dev/null +++ b/Documentation/docs/modules/eventsystem.md @@ -0,0 +1,52 @@ +# Event System (Va.Si.Li-ES) + +The event system lets users build *event systems* at run time, inside VR: **triggers** (an area is entered, an object +is used, a timer runs out) start **events** (spawn, move or delete objects, teleport players, change the weather, +start a vote or show feedback). Event systems can be saved as templates and loaded automatically when a scene starts. +It is described in the paper [Va.Si.Li-ES](../publications.md#vasili-es). + +The code is in `Assets/Lab/EventSystem` (assembly `Vasili.EventSystem`). As a Unity package it is installed +separately from the core, see [Setting Up](../getting_started/setting_up.md#import-as-unity-package). + +## Concepts + +| Concept | Interface | Implementations (`Runtime/...`) | +|---|---|---| +| Event system | `IEventSystem` | `EventSystem`: holds triggers and events in numbered groups, can be repeatable | +| Trigger | `ITrigger` | `Triggers/AreaTrigger`, `InteractionTrigger`, `TimeTrigger` | +| Event | `IEvent` | `Events/ObjectSpawningEvent`, `ObjectMovingEvent`, `ObjectDestructionEvent`, `PlayerTeleportationEvent`, `WeatherEvent`, `VotingEvent`, `FeedbackEvent`, `FollowingEventSystemEvent` (starts another event system) | +| Modifier | `IModifier` | `Modifiers/Modifier_Gravity`, `_Jump`, `_Speed`, `_Weather`, `_Zoom`, `_Map`, `_Admin`; `Modefier_Handler` switches the modifiers in its `Modifier_Container` on or off according to the scene's `ModifierSettings` | + +When all triggers of a group have fired, the events of that group run. Group `0` is shared: its triggers are required +by every group, and its events run whenever any group fires. A repeatable event system resets its triggers afterwards, +otherwise it deletes itself. Triggers and events serialise themselves to JSON (`createJson`), which is how templates +are stored. + +## Building blocks + +| Prefab | Purpose | +|---|---| +| `Manager/EventSystemManager` | Menu that lists the scene's event systems, loads templates and the scene's default event systems on start | +| `Factory/EventSystemFactory` | Creates one event system with its triggers and events | +| `MarkerTool/MarkerTool` | Tool for placing triggers and events in the scene | +| `EnvironmentSystem/Weather/Weather_Controller` | Weather (rain, snow, thunderstorm) used by `WeatherEvent` and `Modifier_Weather` | +| `VotingSystem/Voting_Controller` | Votes (yes/no or single choice) used by `VotingEvent` | +| `FeedbackSystem/Notification Manager`, `FeedbackWindow` | Notifications and feedback used by `FeedbackEvent` | +| `EventSystemPrefabs/*` | Ready-made items: binoculars, jump and sprint shoes, map, weather clouds, environment changer | + +To use it in a scene, add the `EventSystemManager` prefab (and the controllers for the events you need) to the scene. + +## Templates +`EventSystemManager` reads and writes templates at `eventTemplates + "/defaultTemplates"` (see +[Endpoints](endpoints.md)). A template belongs to the scene whose name it stores; templates of the current scene are +offered in the template panel, and default ones are created when the scene loads. + +## Extending +- **New trigger:** a `MonoBehaviour` implementing `ITrigger`. Call `notifySystem()` when it fires, and return its + state from `getState()`. +- **New event:** a `MonoBehaviour` implementing `IEvent`. Do the work in `trigger()`, show what will happen in + `previewOn()`/`previewOff()`. +- **New modifier:** implement `IModifier` and add it to the `Modifier_Container` used by `Modefier_Handler`. The + scene's `ModifierSettings` decide whether it is allowed and clamp its value. + +Both triggers and events need `createJson(groupID)` so they can be saved in templates. diff --git a/Documentation/docs/modules/logging.md b/Documentation/docs/modules/logging.md new file mode 100644 index 00000000..78caac75 --- /dev/null +++ b/Documentation/docs/modules/logging.md @@ -0,0 +1,37 @@ +# Logging + +Va.Si.Li-Lab records what happens in a session (movement, gaze, faces, hands, interactions, audio) and sends it to +the [Database API](../server/python_data_logger.md), which stores it in [MongoDB](../server/mongodb.md). The data +model behind it is described in +[A Multimodal Data Model for Simulation-Based Learning with Va.Si.Li-Lab](../publications.md#mehler2023). + +The code is in `Assets/Lab/Core/Runtime/Scripts/Logging`. The address comes from `api` in the +[endpoints configuration](endpoints.md). + +## MetaDataLogger +`MetaDataLogger` on the `Social Network Scene` prefab collects the data of the local player and sends it in batches: + +| Route (`api` + ...) | Content | +|---|---| +| `/logging/playerLogIn` | A player joins | +| `/logging/playerRoleLogIn` | A player takes a role | +| `/logging/levelChange` | The admin changes the level | +| `/logging/player` | Head, hand and body tracking; with Meta avatars also eyes, face and fingers (`metaMessage`) | +| `/logging/object` | Positions of logged objects | +| `/logging/special` | Button presses and spawned objects | +| `/logging/logMisc` | Other events | + +The message types are in `DataLoggerTypes.cs`. How the API splits them into collections is described in the +[Database API documentation](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/database_api/). + +!!! warning "Logging failures don't stop a session" + If the API can't be reached, the session continues normally and nothing is stored. Check that data arrives + (e.g. `api + /logging/status`, shown by `ConnectionStatusMonitor`) before a study session starts. + +## Other loggers +| Component | Purpose | +|---|---| +| `FileLogger` | Writes the JSON messages to the local file system instead | +| `LogManager`, `Collectors/MovementLogCollector` | Collector-based logging (`ILogCollector`, `IContinousLogCollector`, `IEventLogCollector`) | +| `LogToScreen` | Shows Unity log output in VR | +| `DevLogConfig` | Disables per-log stack traces in development builds | diff --git a/Documentation/docs/other/bots.md b/Documentation/docs/other/bots.md deleted file mode 100644 index a2d24672..00000000 --- a/Documentation/docs/other/bots.md +++ /dev/null @@ -1,2 +0,0 @@ -# Bots -This documentation is work in progress. \ No newline at end of file diff --git a/Documentation/docs/other/experiment_visualization.md b/Documentation/docs/other/experiment_visualization.md new file mode 100644 index 00000000..f49267a0 --- /dev/null +++ b/Documentation/docs/other/experiment_visualization.md @@ -0,0 +1,6 @@ +# Experiment Visualization + +!!! info "In preparation" + A new tool for analysing and visualising recorded experiments (audio transcription, tracking data) is in + preparation and will be documented here once it is released. The previous Streamlit tools are no longer + maintained. diff --git a/Documentation/docs/other/experiment_visualizer_audio.md b/Documentation/docs/other/experiment_visualizer_audio.md deleted file mode 100644 index bb08f066..00000000 --- a/Documentation/docs/other/experiment_visualizer_audio.md +++ /dev/null @@ -1,102 +0,0 @@ -# Experiment Visualization Audio - -## Introduction - -This tool enables the transcription of voice recordings made of participants in experiments. A sentiment analysis is automatically included in the visualisation. Additionally, users may highlight tags that they have defined. Each turn can be analysed by a LLM, and the prompt used can be customised. There is a default prompt with predefined types of turns. Furthermore, users can generate a wordcloud of the transcription of the selected scenario. - -## Setup - -### Requirements - -- Python 3.12.2 -- login.json in directory ../db/login/login.json (Login data for MongoDB) - -#### Packages -- streamlit (1.38.0) [(more information)](https://docs.streamlit.io/get-started/installation) -- pymongo (4.8.0) [(more information)](https://pymongo.readthedocs.io/en/stable/installation.html) -- pydub (0.25.1) [(more information)](https://github.com/jiaaro/pydub) -- numpy (1.26.4) [(more information)](https://numpy.org/install/) -- openai-whisper (20231117) [(more information)](https://github.com/openai/whisper) -- spacy (3.7.6) [(more information)](https://spacy.io/usage) -- wordcloud (1.9.3) [(more information)](https://github.com/amueller/word_cloud) -- matplotlib (3.9.2) [(more information)](https://matplotlib.org/stable/) -- textblob (0.18.0.post0) [(more information)](https://textblob.readthedocs.io/en/dev/) -- transformers (4.44.2) [(more information)](https://github.com/huggingface/transformers) -- torch (2.4.0) [(more information)](https://pytorch.org/) - -### Getting started - -To start enter "streamlit run Live_Experiment_Analysis.py" in terminal. - -## Pages - -### Audiodata Analysis - -#### Load Data - -On this page you can initialize the transcription and see the visualisation. - -The first step is to select the scenario and the date from which the voice recordings are to be analyzed. -This tool uses Whisper to transcribe the audio data. There are different modelsizes of whisper available. Therefore, in the next step, select one of the modelsizes from the dropdown menu. -Once you have selected the scenario, date and model size, press the button **load data** to - -1. Export documents from the MongoDB "Audio" database with the selected scene and date. -2. Convert the audio data into a .wav file and export it. -3. Transcribe the audio files using the whisper model of your choice. - -The button **load turntaking analysis** allows you to load a turntaking analysis using the llm "NousResearch/Llama-2-7b-chat-hf" from [Huggingface](https://huggingface.co/NousResearch/Llama-2-7b-chat-hf). The prompt that the LLM takes as input can be edited in the [Settings](#edit-prompt-for-turntaking-analysis). - -If you have previously loaded the turntaking analysis and wish to reload it (e.g. after editing the prompt), you can press the **reload turntaking analysis** button. - -#### Wordcloud - -By pressing the button **show wordcloud**, you can create a wordcloud of the full transcription of the scenario. Words contained in the german_stopwords_full.txt file are excluded. - -#### Show Transcription and Turntaking Analysis - -Use the slider bar to set the interval at which the transcription will be displayed. - -You have the option to highlight personalised tags in the transcription. Tags can be added or deleted in the [Settings](#set-tags). To highlight your tags, make sure the corresponding checkbox is selected. - -Finally, you can visualise the voice recordings as a messenger by clicking on either **show transcription** or **show transcription with turntaking analysis**. To view the transcription with a turntaking analysis, you must first click on **load turntaking analysis**. - -The visualisation of the speech recordings also includes a sentiment analysis. The sentiment of each sentence is colour coded in five categories: negative (red), tendence negative (orange), neutral (grey), tendence positive (blue) and positive (green). The thresholds between each category can be adjusted in the [Settings](#set-thresholds-for-sentiment-analysis). - -### Settings - -This is the page where you can personalise the features of this tool according to your preferences. - -#### Set Tags - -Tags can be added using the input field on the left and removed with the input field on the right. The tags currently defined are displayed below the input fields. All of the tags that are shown below *current tags* will be highlighted if you select the corresponding option in the [Audiodata Analysis](#audiodata-analysis). - -#### Set Thresholds for Sentiment Analysis - -This tool allows you to view five different levels of sentiment: negative, tendence negative, neutral, tendence positive and positive. Each level represents an interval within the range (-1, 1). The value of the sentiment is within the interval indicated by the color of the transcription. - -- a is the threshold between "negative" and "tendence negative" -- b is the threshold between "tendence negative" and "neutral" -- c is the threshold between "neutral" and "tendence positive" -- d is the threshold between "tendence positive" and "positive" - -Note that the parameters should be selected according to a < b < c < d. Also, no parameter should be selected the same as another. -If you reload the "Settings" page, the thresholds will be set to te default values (a=-0.2, b=-0.01, c=0.01, d=0.2). - -#### Edit Prompt for Turntaking Analysis - -To analyze the turns of the speech recordings, the LLM takes a prompt describing the types of turns. -The prompt consists of two parts: one is editable and the other is not. - -The first part of the prompt can be edited using the input field *customize prompt*. - -There is a default prompt which you can see below *see full default prompt here* when you first open the "Settings" page. - -The input field is not expandable. If you want to edit a part of the default prompt, it is recommended that you copy the default prompt and edit it externally in a text editor of your choice. -You can then press *empty prompt* and paste your edited prompt into the input field. Then press Enter to submit the updated prompt. -To return to the default prompt, press *set prompt to default*. - -The following part of the prompt cannot be edited. This is to ensure, that the two parts of a turn are placed correctly within the prompt. - -``` -"Turn: Person X says: {first part of the turn} Person Y responds to Person X: {second part of the turn}"<\input> -``` diff --git a/Documentation/docs/other/experiment_visualizer_trackingdata.md b/Documentation/docs/other/experiment_visualizer_trackingdata.md deleted file mode 100644 index 3a245c02..00000000 --- a/Documentation/docs/other/experiment_visualizer_trackingdata.md +++ /dev/null @@ -1,173 +0,0 @@ -# Experiment Visualisation Trackingdata - -## Overview - -### Description -This Streamlit Web Application uses Data stored in a MongoDB from Experiments and displays multiple plots visualising the behavior of the test subjects. - -## Setup -Python version 3.12.0 -login.json in directory ../db/login/login.json (Login data for MongoDB) - -### Requirements -The Requirements.txt is in the Project - -- matplotlib==3.9.0 -- numpy==1.26.4 -- numpy_quaternion==2023.0.4 -- pandas==2.2.2 -- Pillow==10.3.0 -- plotly==5.22.0 -- pydub==0.25.1 -- pymongo==4.7.2 -- Requests==2.31.0 -- scipy==1.13.1 -- seaborn==0.13.2 -- streamlit==1.34.0 -- textblob==0.18.0.post0 -- whisper==1.1.10 - - -## How to use - -### starting the Application -In your Terminal type streamlit run streamlit run Live_Experiment_Analysis.py -In the Sidebar navigate to Trackingdata. - -### Usage - -In the Sidebar first select the experiment and the date. This will display all playerIds that where logged in that day. - -![image](https://github.com/user-attachments/assets/c6c39c4e-d952-4686-95cd-74217f3d7785) - -**Optional** You can now filter the players to only show one role -*Note** some experiments have no role or role is not stored correctly - -![image](https://github.com/user-attachments/assets/8bd4ec7c-7e9c-4433-a0bb-14e25197131e) - -Now select the playerIds. This will first load the level selector. After Loading finished you can click the "Load Plots" button. -When a player is first loaded data from the mongodb has to be fetched, which will take some time. After the first time no data has to be fetched again (only session wise). - -At the top you can switch between the Plots and Multimodal chat Tabs - -### Options -In the options Menu you have the ability to select different settings. -**You have to click submit to save the changes** -Starting from left to right. -- Select filtered Objects which will not be displayed in the Interaction Heatmap -- Select which Eye should be used to calclualte the Eygazes Plot. Default is 0 = left Eye -- Select smoothing factor for the Linegraphs. default is 250 lower number means less smoothing -- Select the Radius for the Head and Body Sphere (Hitbox) (When calculating if a person looked at another person) -- Checkbox display contious plots. Displays a continous motion of the facial expression polygons on the avatarface (Default is False because it does take a lot of time especially for the longer experiments to go through all players) -- checkbox show teleportations. Shows in the linegraphs when a player is teleportated (skews the graph) -- checkbox less expensive plots. Doesn't show facial expressions and the heatmap. The heatmap is what really takes a long time to calculate - -![image](https://github.com/user-attachments/assets/30ad7c08-8d08-403f-8d2e-da754c56fa46) - -### Levelselector -**You have to click submit to save the changes** -**Note you also have to tick the checkbox to filter out the time** -In the selectboxes you can see each level when it started for each player. -Then in the slider choose the time you want to see -The Interactionheatmap, Facial expressions and the multimodal chat is nopt influenced by the levelfilter - -![image](https://github.com/user-attachments/assets/49099bca-31ca-47f9-9026-99b343dd00f5) - -## Functions - -### What are the plots representing -- Eyegaze: The orange dot is the position of the Eye and the orange line is the straight forward looking direction. -The blue points represent where the person looked originating from [0, 0, 0] (orange dot) - -![image](https://github.com/user-attachments/assets/29fc171d-a5a4-45b2-b2ec-aa6c69230a33) - -- Handheatmap: The orange dot is the Position of the Head. The "Volumeheatmap" shows where relatively to the head the hand is. - **doesn't work as intended** The handposition is rotated to the direction which the **Body** faces, which causes the heatmap to be displayed "around" the player. - extra eklärung - -- Facial Expressions: Displays the intensity of movement for 63 key points on the face, indicating how much each part has moved. see project files for Legend - - Using this scale purple being the lowest and yellow the highest - -![image](https://github.com/user-attachments/assets/db7c8a18-82a9-43b5-b711-e1eef246c1e9) - -- Interaction heatmap: Shows where and how the player has interacted with an object on the map. (for some experiments are the sizes of the icons skewed because some experiments have different dimensions) - -- Heatmap: Shows a heatmap for positional points - -![image](https://github.com/user-attachments/assets/df35e730-e159-45f5-ada7-a60ac662e35d) - -If there is no no backroundmap the heatmap will be displayed on a white backround -![image](https://github.com/user-attachments/assets/3d9710be-74ea-44c5-9a86-5629a6639c26) - - -- Multimodal chat: Displays a timeline from top (start) to bottom (end), whether a player was looking at another player's head or body and when a player interacted with an object. - -### structure of data - -For all plots (except facial expressions) was first the data fetched and calculated upon and then with this data where the plots made. Some data is used multiple times for different plots. - -When the data is fetched every player is given a list where his data is stored [ [], [], [] ] - -See input output for how _fetch_data works - -Please see in project file /datastructure/body for List_of_every_player_body explanation diagramm - -list_of_every_player_head and list_of_every_player_hand follows a similiar formula - - - -## input Ouput - -Not all function are here, because some are very specific. - -### linegraph.py - -#### _fetch_data: -takes in( a list of playerids, the collection to search in, what to search for ) # playerId is always returned - - ["324Fg", "jshfu"], main.collection_body, {serverTime:1, position:1} - - Output: returns a list of lists [ [], [] ] where each list is for one player, in which the data is stored - -### Eye_tracking.py -#### create_quaternion(orientation): - -takes in a "quaternion" in a "list format" [0, 0, 0, 1] with w being the last element. - -output: a quaternion in matrix format - -### facial_expression.py -#### avatarId_finder(playerId): - -takes in **one** playerid as a string - -outputs: an int 0 to 31 representing the avatarId of the playerId - - -#### get_intensitity_for_expression(percent): -Input: Float number 0 to 1 (a percent) -Output: 4 tuple RGBA in normalized format (r,g,b,opacity) - -### interactions.py - -#### interactionShapeNetObjectAdder(interactionsObjects): -**Only for Shapenet objects if no shapenet object return the same dict** - -Input: a dictionary of interactions done {'objectName': '343434335353_center', 'hand': 'Right', 'interaction': 'ungrasped', 'playerId': '520708ed-59e733b7', 'server-timestamp': datetime.datetime(2024, 5, 29, 9, 34, 30), 'position': {'x': -821.1394, 'y': 51.47187, 'z': -770.7883}} -Output: return the dict with the objectName changed to the real Objectname + adds two new key values pairs. the old Id name and categories - -### levelSelecter.py - -#### getMinMaxTime(playerIds): -Input : list of playerIds -Output: **Across all playerIds** that were given outputs: a list of a dictionary with the min and max of the server time [ { maxServerTime: } ] -minServerTime first Servertime and "maxServerTime" last ServerTime (Login, Logoff) - -### multimodalChat.py - -#### collisionChecker(personPosition, personViewPosition, secondPersonSphere, radius=0.15): -Input: Position first point [ 0, 4, 3 ] , position second Point, PositionSphere, **optional radius=float** -Output: weather or not the line beetween the first two points, intersects the third position (Sphere) with the radius= - - diff --git a/Documentation/docs/other/replay.md b/Documentation/docs/other/replay.md index 478b4509..74b09f90 100644 --- a/Documentation/docs/other/replay.md +++ b/Documentation/docs/other/replay.md @@ -1,22 +1,26 @@ # Simulations & Experiments Playback +!!! warning "Not available in the current version" + The `SimulationLoader` scene and the `Assets/Simulation_dev` folder described here are not part of the current + repository. A new replay tool is in preparation; until then this page documents the earlier one. + Simulations and Experiments performed using this project can be replayed using the following steps: ## Add Scenes to Build Setting -Scenes to be replayed and the Simulaton loader scene should be added to build setting. +Scenes to be replayed and the SimulationLoader scene should be added to build setting. -1. Open `SmulatonLoader` scene located in `Assets/Simulation_dev/Scenes`. +1. Open `SimulationLoader` scene located in `Assets/Simulation_dev/Scenes`. 2. From `File` tab choose `Build Settings...`. -3. Add `SimulatoinLoader` scene to build by clickng `Add Open Scenes`. -4. Make sure `SimulatioinLoader` scene is enabled using the toggle to its left side. +3. Add `SimulationLoader` scene to build by clicking `Add Open Scenes`. +4. Make sure `SimulationLoader` scene is enabled using the toggle to its left side. 5. Add and enable all scenes of the Simulations/Experiments to be replayed. ## Start Playback -To start playback open and play `SimulatonLoader` scene. +To start playback open and play `SimulationLoader` scene. ### Local Playback @@ -26,11 +30,11 @@ Choose the scene, date and players to be replayed then click on `Next`. ### Online Playback -If no local data found, or if online data is preferred, using the `Load Online Data` toggle **(Disabled by default)** will connect to the server and retreive information about Simulations and its data. +If no local data found, or if online data is preferred, using the `Load Online Data` toggle **(Disabled by default)** will connect to the server and retrieve information about Simulations and its data. -By online Playback the followng options are available: +By online Playback the following options are available: -- Keeping the chosen playbacks data if local instances of it are found, or Saving the chosen playbacks if no local data of it found using the `Keep Json Copy` toggle. Loacl data will be yellow colored by the list of players to choose from. **(Enabled by default)** +- Keeping the chosen playbacks data if local instances of it are found, or Saving the chosen playbacks if no local data of it found using the `Keep Json Copy` toggle. Local data will be yellow colored by the list of players to choose from. **(Enabled by default)** - Use online data instead of local data of the chosen playbacks, if any local data found, using the `Updated Info` toggle. This will Replace local data if `Keep Json Copy` toggle is enabled. **(Disabled by default)** - **Note**: - Disabling `Keep Json Copy` will remove any local data, **of the chosen playbacks only**, saved previously. @@ -41,9 +45,9 @@ After choosing players click on `Next`. ### Choosing Avatars -After choosng players and clicking `Next`, a new page is loaded with the name of chosen Scene, *[Instructions](#keyboard)* on how to control playback with keyboard and the ability to choose different avatars for each player. +After choosing players and clicking `Next`, a new page is loaded with the name of chosen Scene, *[Instructions](#keyboard)* on how to control playback with keyboard and the ability to choose different avatars for each player. -Default avatars will be set according to the info retreived online or from local data. If none found, Avatar Nr. 0 will be set as default. +Default avatars will be set according to the info retrieved online or from local data. If none found, Avatar Nr. 0 will be set as default. Click on `Load Scene` to Start playback after all required data have been loaded. @@ -69,7 +73,7 @@ There are several ways to control the playback: - `C`: Activate/Disable 1. Person Camera. -**Note:** While in 1. Person Camera, no camera movements controls are available. This will imitate being in the prespective of the current player. +**Note:** While in 1. Person Camera, no camera movements controls are available. This will imitate being in the perspective of the current player. #### Free Camera @@ -78,7 +82,7 @@ There are several ways to control the playback: - `T,G`: Vertical Rotation. - `F,H`: Horizontal Rotation. - `Z,X`: Height Control. -- `V,B`: Jump to nexy player's position. +- `V,B`: Jump to next player's position. **Note:** Once activated, Camera will be positioned at a default location. Depending on the scene, this location might be far from players. using `V,B` will move Camera to the position of the next/previous player. @@ -105,16 +109,16 @@ click on `Simulation(Clone)` object under `DontDestroyOnLoad`. Custom inspector - `Face/Eye Weights`: With a value between 0 and 2 to control the intensity of the Face/Eye pose for **all** playbacks. - `Hand Pos. Senset.`: With a value between 0.4 and 1.5. When the difference in vertical hand position between the current frame and the previous one is bigger than this value, -the old value from the previos frame will be taken instead and ignore the current one, to avoid having hands in extrem positions. This can happen mostly when switching +the old value from the previous frame will be taken instead and ignore the current one, to avoid having hands in extreme positions. This can happen mostly when switching between Finger tracking and Controller tracking. -- `Voice Ind. Senset.`: With a value between 0.0001 and 1. Controls the sensetivity of the voice indicator above each player's avatar. -Higher values will requier higher sounds to activate the indicator. By value 1 the voice indicator will mostly be disabled. +- `Voice Ind. Senset.`: With a value between 0.0001 and 1. Controls the sensitivity of the voice indicator above each player's avatar. +Higher values will require higher sounds to activate the indicator. By value 1 the voice indicator will mostly be disabled. #### Camera Control - `1. Person view` toggle to activate 1. Person Camera. - `Free Camera` toggle to activate Free Camera. This will show additional buttons underneath for movement control. -- `Rotation & Zoom` Controls when Free Camera is disabled / `Movament, Rotation & Height` Controls When Free Camera +- `Rotation & Zoom` Controls when Free Camera is disabled / `Movement, Rotation & Height` Controls When Free Camera is activated. #### Debug Mode @@ -124,7 +128,7 @@ is activated. ### Time & Speed Slider - `Speed Slider`: With a value between 0.1 and 2, will control the speed of all playbacks' movements and sounds. -- `Time Slider`: Once selected or changed value, playbacks' movements and sounds will be paused. Unpause through inspector or keypoard `P` to continue. +- `Time Slider`: Once selected or changed value, playbacks' movements and sounds will be paused. Unpause through inspector or keyboard `P` to continue. ## Record Playback diff --git a/Documentation/docs/projects/faces.md b/Documentation/docs/projects/faces.md index 4b869fa3..2d401663 100644 --- a/Documentation/docs/projects/faces.md +++ b/Documentation/docs/projects/faces.md @@ -6,8 +6,11 @@ ## FACES +![FACES](../images/projects/FACES.png){loading=lazy width=320} + [FACES](https://gepris.dfg.de/gepris/projekt/539621548?language=en) (Feasibility, acceptance, and data quality of new multimodal surveys) is part of this SPP. +Project website: [texttechnologylab.github.io/FACES](https://texttechnologylab.github.io/FACES/). Conventional surveys record the answer and discard everything that produced it - the hesitation, the gaze, whether the question was understood at all. FACES asks @@ -27,7 +30,10 @@ hand movement, facial expression and the answers themselves are all captured on shared clock. InterView is built on Va.Si.Li-Lab and adds a WebRTC media layer, a browser-based -interviewer console, and a token-driven session model. +interviewer console, and a token-driven session model. Avatar emotions come from +[ReEmote](../systems.md#reemote). Both are listed under +[Systems using Va.Si.Li-Lab](../systems.md), their papers under +[Publications](../publications.md#interview). !!! info "InterView has its own documentation" Architecture, the full deployment guide, and reference documentation for diff --git a/Documentation/docs/projects/index.md b/Documentation/docs/projects/index.md new file mode 100644 index 00000000..a121c0d0 --- /dev/null +++ b/Documentation/docs/projects/index.md @@ -0,0 +1,11 @@ +# Projects + +Research projects in which Va.Si.Li-Lab is developed and used. + +| Project | Funding | Va.Si.Li-Lab is used for | +|---|---|---| +| [DigiTeLL](digitell.md) | Goethe University Frankfurt, *Digital Teaching and Learning Lab* | Origin of Va.Si.Li-Lab: simulation-based learning in VR for teaching | +| [ViCom / GeMDiS](vicom.md) | DFG Priority Programme 2392 *Visual Communication* | Gestures in dialogue: VR-based multimodal data collection ([FraGA](../systems.md#fraga), [Semantic Scene Builder](../systems.md#semantic-scene-builder)) | +| [New Data Spaces / FACES](faces.md) | DFG Priority Programme 2431 *New Data Spaces* | Survey interviews in VR ([InterView](../systems.md#interview), [ReEmote](../systems.md#reemote)) | + +Systems built on Va.Si.Li-Lab are listed in [Systems using Va.Si.Li-Lab](../systems.md). diff --git a/Documentation/docs/publications.md b/Documentation/docs/publications.md index 65124dfa..18220327 100644 --- a/Documentation/docs/publications.md +++ b/Documentation/docs/publications.md @@ -1,70 +1,476 @@ -## Publications - -#### A Multimodal Data Model for Simulation-Based Learning with Va.Si.Li-Lab - -``` bibtex -@inproceedings{Mehler:et:al:2023:a, - author = {Mehler, Alexander and Bagci, Mevl{\"u}t and Henlein, Alexander - and Abrami, Giuseppe and Spiekermann, Christian and Schrottenbacher, Patrick - and Konca, Maxim and L{\"u}cking, Andy and Engel, Juliane and Quintino, Marc - and Schreiber, Jakob and Saukel, Kevin and Zlatkin-Troitschanskaia, Olga}, - address = {Cham}, - booktitle = {Digital Human Modeling and Applications in Health, Safety, Ergonomics and Risk Management}, - editor = {Duffy, Vincent G.}, - isbn = {978-3-031-35741-1}, - pages = {539--565}, - publisher = {Springer Nature Switzerland}, - title = {A Multimodal Data Model for Simulation-Based Learning with Va.Si.Li-Lab}, - year = {2023}, - doi = {10.1007/978-3-031-35741-1_39} -} -``` -[[Link]](https://link.springer.com/chapter/10.1007/978-3-031-35741-1_39) [[RG]](https://www.researchgate.net/publication/372298766_A_Multimodal_Data_Model_for_Simulation-Based_Learning_with_VaSiLi-Lab) +# Publications +Publications on Va.Si.Li-Lab and on the systems built with it. + +If you use Va.Si.Li-Lab, please cite [A Multimodal Data Model for Simulation-Based Learning with Va.Si.Li-Lab](#mehler2023). + +## Va.Si.Li-Lab + +### Va.Si.Li-Lab: A Virtual Reality Solution for Applications in the Field of Educational and Social Science Technologies + +**Schrottenbacher, Abrami, Bagci & Mehler** (2026). In *Digitale Learning Designs für die Hochschullehre gemeinschaftlich +entwickeln*, Waxmann, 212–229. +[[DOI]](https://doi.org/10.31244/9783818851170) + +??? note "BibTeX" + + ```bibtex + @incollection{Schrottenbacher:et:al:2026:b, + author = {Schrottenbacher, Patrick and Abrami, Giuseppe and Bagci, Mevl{\"u}t + and Mehler, Alexander}, + title = {{Va.Si.Li-Lab}: A Virtual Reality Solution for Applications in + the Field of Educational and Social Science Technologies}, + booktitle = {Digitale Learning Designs f{\"u}r die Hochschullehre gemeinschaftlich + entwickeln: Werkzeuge -- Ressourcen -- Szenarien}, + editor = {Zeaiter, Sabrina and Stierwald, Mona}, + publisher = {Waxmann}, + year = {2026}, + pages = {212--229}, + doi = {10.31244/9783818851170} + } + ``` + +--- + +### Simulation-Based Learning in Virtual Reality: Three Use Cases from Social Science and Technological Foundations in Terms of Va.Si.Li-Lab + +**Bagci, Mehler, Abrami, Schrottenbacher, Spiekermann, Konca, Schreiber, Saukel, Quintino & Engel** (2025). +*Technology, Knowledge and Learning*, Springer Nature. +[[DOI]](https://doi.org/10.1007/s10758-025-09837-7) + +??? note "BibTeX" + + ```bibtex + @article{Bagci:et:al:2025, + author = {Bagci, Mevl{\"u}t and Mehler, Alexander and Abrami, Giuseppe and Schrottenbacher, Patrick + and Spiekermann, Christian and Konca, Maxim and Schreiber, Jakob and Saukel, Kevin + and Quintino, Marc and Engel, Juliane}, + title = {Simulation-Based Learning in Virtual Reality: Three Use Cases + from Social Science and Technological Foundations in Terms of + Va.Si.Li-Lab}, + journal = {Technology, Knowledge and Learning}, + publisher = {Springer Nature}, + year = {2025}, + month = {April}, + day = {01}, + issn = {2211-1670}, + doi = {10.1007/s10758-025-09837-7}, + url = {https://doi.org/10.1007/s10758-025-09837-7} + } + ``` + +--- + +### Towards New Data Spaces for the Study of Multiple Documents with Va.Si.Li-Lab: A Conceptual Analysis + +**Mehler, Bagci, Schrottenbacher, Henlein, Konca, Abrami, Bönisch, Stoeckel, Spiekermann & Engel** (2024). +In *Students', Graduates' and Young Professionals' Critical Use of Online Information*, Springer, 259–303. +[[DOI]](https://doi.org/10.1007/978-3-031-69510-0_12) + +??? note "BibTeX" + + ```bibtex + @inbook{Mehler:et:al:2024:a, + author = {Mehler, Alexander and Bagci, Mevl{\"u}t and Schrottenbacher, Patrick + and Henlein, Alexander and Konca, Maxim and Abrami, Giuseppe and B{\"o}nisch, Kevin + and Stoeckel, Manuel and Spiekermann, Christian and Engel, Juliane}, + editor = {Zlatkin-Troitschanskaia, Olga and Nagel, Marie-Theres and Klose, Verena + and Mehler, Alexander}, + title = {Towards New Data Spaces for the Study of Multiple Documents with + Va.Si.Li-Lab: A Conceptual Analysis}, + booktitle = {Students', Graduates' and Young Professionals' Critical Use of + Online Information: Digital Performance Assessment and Training + within and across Domains}, + year = {2024}, + publisher = {Springer Nature Switzerland}, + address = {Cham}, + pages = {259--303}, + isbn = {978-3-031-69510-0}, + doi = {10.1007/978-3-031-69510-0_12}, + url = {https://doi.org/10.1007/978-3-031-69510-0_12}, + } + ``` + +--- + +### A Multimodal Data Model for Simulation-Based Learning with Va.Si.Li-Lab { #mehler2023 } + +**Mehler, Bagci, Henlein, Abrami, Spiekermann, Schrottenbacher, Konca, Lücking, Engel, Quintino, Schreiber, Saukel & +Zlatkin-Troitschanskaia** (2023). *Digital Human Modeling and Applications in Health, Safety, Ergonomics and Risk +Management* (HCII 2023), Springer, 539–565. +[[Link]](https://link.springer.com/chapter/10.1007/978-3-031-35741-1_39) +[[RG]](https://www.researchgate.net/publication/372298766_A_Multimodal_Data_Model_for_Simulation-Based_Learning_with_VaSiLi-Lab) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Mehler:et:al:2023:a, + address = {Cham}, + author = {Mehler, Alexander and Bagci, Mevl{\"u}t and Henlein, Alexander + and Abrami, Giuseppe and Spiekermann, Christian and Schrottenbacher, Patrick + and Konca, Maxim and L{\"u}cking, Andy and Engel, Juliane and Quintino, Marc + and Schreiber, Jakob and Saukel, Kevin and Zlatkin-Troitschanskaia, Olga}, + booktitle = {Digital Human Modeling and Applications in Health, Safety, Ergonomics + and Risk Management}, + editor = {Duffy, Vincent G.}, + isbn = {978-3-031-35741-1}, + pages = {539--565}, + publisher = {Springer Nature Switzerland}, + title = {A Multimodal Data Model for Simulation-Based Learning with Va.Si.Li-Lab}, + year = {2023}, + doi = {10.1007/978-3-031-35741-1_39}, + } + ``` + +--- + +### Va.Si.Li-Lab as a Collaborative Multi-User Annotation Tool in Virtual Reality and Its Potential Fields of Application + +**Abrami, Mehler, Bagci, Schrottenbacher, Henlein, Spiekermann, Engel & Schreiber** (2023). *Proceedings of the 34th ACM +Conference on Hypertext and Social Media* (HT '23). +[[Link]](https://dl.acm.org/doi/10.1145/3603163.3609076) [[PDF]](https://dl.acm.org/doi/pdf/10.1145/3603163.3609076) +[[RG]](https://www.researchgate.net/publication/371303212_VaSiLi-Lab_as_a_collaborative_multi-user_annotation_tool_in_virtual_reality_and_its_potential_fields_of_application) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Abrami:et:al:2023, + author = {Abrami, Giuseppe and Mehler, Alexander and Bagci, Mevl\"{u}t and Schrottenbacher, Patrick + and Henlein, Alexander and Spiekermann, Christian and Engel, Juliane + and Schreiber, Jakob}, + title = {Va.Si.Li-Lab as a Collaborative Multi-User Annotation Tool in + Virtual Reality and Its Potential Fields of Application}, + year = {2023}, + isbn = {9798400702327}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + url = {https://doi.org/10.1145/3603163.3609076}, + doi = {10.1145/3603163.3609076}, + booktitle = {Proceedings of the 34th ACM Conference on Hypertext and Social Media}, + articleno = {22}, + numpages = {9}, + location = {Rome, Italy}, + series = {HT '23}, + pdf = {https://dl.acm.org/doi/pdf/10.1145/3603163.3609076} + } + ``` + +## Systems using Va.Si.Li-Lab + +The systems are described in [Systems using Va.Si.Li-Lab](systems.md). + +### InterView: Towards a Unified VR-Capable Interview Environment { #interview } + +**Schrottenbacher, Mehler, Abrami, Kleine & Stingl** (2026). Preprint, under review at the *International Journal of +Human-Computer Studies*. +[[DOI]](https://doi.org/10.2139/ssrn.7459949) + +??? note "BibTeX" + + ```bibtex + @misc{Schrottenbacher:et:al:2026:c, + author = {Schrottenbacher, Patrick and Mehler, Alexander and Abrami, Giuseppe + and Kleine, Lydia and Stingl, Doris}, + title = {{InterView}: Towards a Unified {VR}-Capable Interview Environment}, + year = {2026}, + howpublished = {SSRN preprint}, + doi = {10.2139/ssrn.7459949}, + url = {https://ssrn.com/abstract=7459949}, + note = {Under review} + } + ``` + +--- + +### ReEmote: Towards Emotion Representation in VR Through Va.Si.Li-Lab { #reemote } + +**Schrottenbacher, Mehler, Bernhardt, Rohe & Abrami** (2026). *Proceedings of XR Salento 2026*, Springer (accepted). + +??? note "BibTeX" + + ```bibtex + @inproceedings{Schrottenbacher:et:al:2026:a, + author = {Schrottenbacher, Patrick and Mehler, Alexander and Bernhardt, Vivienne + and Rohe, Leon and Abrami, Giuseppe}, + title = {ReEmote: Towards Emotion Representation in {VR} Through {Va.Si.Li}-Lab}, + booktitle = {Proceedings of XR Salento 2026}, + year = {2026}, + publisher = {Springer International Publishing}, + note = {accepted} + } + ``` + +--- + +### Head and Hand Movements During Turn Transitions: Data-Based Multimodal Analysis Using the Frankfurt VR Gesture–Speech Alignment Corpus (FraGA) { #fraga } + +**Lücking, Voll, Rott, Henlein & Mehler** (2025). *Proceedings of the 29th Workshop on the Semantics and Pragmatics of +Dialogue* (SemDial '25), 146–156. +[[PDF]](http://semdial.org/anthology/Z25-Luecking_semdial_3316.pdf) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Luecking:Voll:Rott:Henlein:Mehler:2025-fraga, + title = {Head and Hand Movements During Turn Transitions: Data-Based Multimodal + Analysis Using the {Frankfurt VR Gesture--Speech Alignment Corpus} + ({FraGA})}, + author = {Lücking, Andy and Voll, Felix and Rott, Daniel and Henlein, Alexander + and Mehler, Alexander}, + year = {2025}, + booktitle = {Proceedings of the 29th Workshop on The Semantics and Pragmatics + of Dialogue -- Full Papers}, + series = {SemDial'25 -- Bialogue}, + publisher = {SEMDIAL}, + url = {http://semdial.org/anthology/Z25-Luecking_semdial_3316.pdf}, + pages = {146--156}, + } + ``` + +--- + +### VR-ParlExplorer: A Hypertext System for the Collaborative Interaction in Parliamentary Debate Spaces { #vr-parlexplorer } + +**Abrami, Bundan, Manolis & Mehler** (2025). *Proceedings of the 36th ACM Conference on Hypertext and Social Media* +(HT '25), 177–183. +[[Link]](https://doi.org/10.1145/3720553.3746672) [[PDF]](https://dl.acm.org/doi/pdf/10.1145/3720553.3746672) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Abrami:et:al:2025:c, + author = {Abrami, Giuseppe and Bundan, Daniel and Manolis, Chrisowaladis + and Mehler, Alexander}, + title = {VR-ParlExplorer: A Hypertext System for the Collaborative Interaction + in Parliamentary Debate Spaces}, + year = {2025}, + isbn = {9798400715341}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + url = {https://doi.org/10.1145/3720553.3746672}, + doi = {10.1145/3720553.3746672}, + booktitle = {Proceedings of the 36th ACM Conference on Hypertext and Social Media}, + pages = {177--183}, + numpages = {7}, + location = {Chicago, USA}, + series = {HT '25}, + pdf = {https://dl.acm.org/doi/pdf/10.1145/3720553.3746672} + } + ``` + +--- + +### Geo-spatial hypertext in virtual reality: mapping and navigating global news event spaces { #news-in-time-and-space } + +**Schrottenbacher, Mehler, Berg, Hustedt, Gagel, Lüttig & Abrami** (2025). *New Review of Hypermedia and Multimedia* +31(1–2), 76–105. +[[DOI]](https://doi.org/10.1080/13614568.2024.2383601) + +??? note "BibTeX" + + ```bibtex + @article{Schrottenbacher:et:al:2025, + author = {Schrottenbacher, Patrick and Mehler, Alexander and Berg, Theresa + and Hustedt, Jasper and Gagel, Julian and Lüttig, Timo and Abrami, Giuseppe}, + title = {Geo-spatial hypertext in virtual reality: mapping and navigating + global news event spaces}, + journal = {New Review of Hypermedia and Multimedia}, + volume = {31}, + number = {1-2}, + pages = {76--105}, + year = {2025}, + publisher = {Taylor \& Francis}, + doi = {10.1080/13614568.2024.2383601}, + url = {https://doi.org/10.1080/13614568.2024.2383601}, + } + ``` + +--- + +### Viki LibraRy: Collaborative Hypertext Browsing and Navigation in Virtual Reality { #viki-library } + +**Bönisch, Mehler, Babbili, Heinrich, Stephan & Abrami** (2025). *New Review of Hypermedia and Multimedia* 31(1–2), +45–75. +[[DOI]](https://doi.org/10.1080/13614568.2024.2383581) + +??? note "BibTeX" + + ```bibtex + @article{Boenisch:et:al:2025:b, + author = {B\"{o}nisch, Kevin and Mehler, Alexander and Babbili, Shaduan + and Heinrich, Yannick and Stephan, Philipp and Abrami, Giuseppe}, + title = {{Viki LibraRy: Collaborative Hypertext Browsing and Navigation + in Virtual Reality}}, + journal = {New Review of Hypermedia and Multimedia}, + volume = {31}, + number = {1-2}, + pages = {45--75}, + year = {2025}, + publisher = {Taylor \& Francis}, + doi = {10.1080/13614568.2024.2383581}, + url = {https://doi.org/10.1080/13614568.2024.2383581}, + } + ``` --- -#### Va.Si.Li-Lab as a Collaborative Multi-User Annotation Tool in Virtual Reality and Its Potential Fields of Application - -``` bibtex -@inproceedings{Abrami:et:al:2023, - author = {Abrami, Giuseppe and Mehler, Alexander and Bagci, Mevl\"{u}t and Schrottenbacher, Patrick - and Henlein, Alexander and Spiekermann, Christian and Engel, Juliane - and Schreiber, Jakob}, - title = {Va.Si.Li-Lab as a Collaborative Multi-User Annotation Tool in - Virtual Reality and Its Potential Fields of Application}, - year = {2023}, - isbn = {9798400702327}, - publisher = {Association for Computing Machinery}, - address = {New York, NY, USA}, - url = {https://doi.org/10.1145/3603163.3609076}, - doi = {10.1145/3603163.3609076}, - booktitle = {Proceedings of the 34th ACM Conference on Hypertext and Social Media}, - articleno = {22}, - numpages = {9}, - location = {Rome, Italy}, - series = {HT '23} -} -``` -[[Link]](https://dl.acm.org/doi/10.1145/3603163.3609076) [[pdf]](https://dl.acm.org/doi/pdf/10.1145/3603163.3609076) [[RG]](https://www.researchgate.net/publication/371303212_VaSiLi-Lab_as_a_collaborative_multi-user_annotation_tool_in_virtual_reality_and_its_potential_fields_of_application) + +### Va.Si.Li-ES: VR-based Dynamic Event Processing, Environment Change and User Feedback in Va.Si.Li-Lab { #vasili-es } + +**Abrami, Wontke, Singh & Mehler** (2024). *Proceedings of the 35th ACM Conference on Hypertext and Social Media* +(HT '24), 357–368. +[[Link]](https://dl.acm.org/doi/10.1145/3648188.3675154) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Abrami:et:al:2024:b, + author = {Abrami, Giuseppe and Wontke, Dominik Alexander and Singh, Gurpreet + and Mehler, Alexander}, + title = {Va.Si.Li-ES: VR-based Dynamic Event Processing, Environment Change + and User Feedback in Va.Si.Li-Lab}, + year = {2024}, + isbn = {9798400705953}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + url = {https://doi.org/10.1145/3648188.3675154}, + doi = {10.1145/3648188.3675154}, + booktitle = {Proceedings of the 35th ACM Conference on Hypertext and Social Media}, + pages = {357--368}, + numpages = {12}, + location = {Poznan, Poland}, + series = {HT '24} + } + ``` --- +### News in Time and Space: Global Event Exploration in Virtual Reality + +**Gagel, Hustedt, Lüttig, Berg, Abrami & Mehler** (2023). *Proceedings of the 34th ACM Conference on Hypertext and +Social Media* (HT '23). +[[Link]](https://doi.org/10.1145/3603163.3609080) [[PDF]](https://dl.acm.org/doi/pdf/10.1145/3603163.3609080) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Gagel:et:al:2023, + author = {Gagel, Julian and Hustedt, Jasper and L\"{u}ttig, Timo and Berg, Theresa + and Abrami, Giuseppe and Mehler, Alexander}, + title = {News in Time and Space: Global Event Exploration in Virtual Reality}, + year = {2023}, + isbn = {9798400702327}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + url = {https://doi.org/10.1145/3603163.3609080}, + doi = {10.1145/3603163.3609080}, + booktitle = {Proceedings of the 34th ACM Conference on Hypertext and Social Media}, + articleno = {7}, + numpages = {3}, + location = {Rome, Italy}, + series = {HT '23}, + pdf = {https://dl.acm.org/doi/pdf/10.1145/3603163.3609080} + } + ``` + +--- + +### Viki LibraRy: A Virtual Reality Library for Collaborative Browsing and Navigation through Hypertext + +**Babbili, Bönisch, Heinrich, Stephan, Abrami & Mehler** (2023). *Proceedings of the 34th ACM Conference on Hypertext +and Social Media* (HT '23). +[[Link]](https://doi.org/10.1145/3603163.3609079) [[PDF]](https://dl.acm.org/doi/pdf/10.1145/3603163.3609079) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Babbili:et:al:2023, + author = {Babbili, Shaduan and B\"{o}nisch, Kevin and Heinrich, Yannick + and Stephan, Philipp and Abrami, Giuseppe and Mehler, Alexander}, + title = {Viki LibraRy: A Virtual Reality Library for Collaborative Browsing + and Navigation through Hypertext}, + year = {2023}, + isbn = {9798400702327}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + url = {https://doi.org/10.1145/3603163.3609079}, + doi = {10.1145/3603163.3609079}, + booktitle = {Proceedings of the 34th ACM Conference on Hypertext and Social Media}, + articleno = {6}, + numpages = {3}, + location = {Rome, Italy}, + series = {HT '23}, + pdf = {https://dl.acm.org/doi/pdf/10.1145/3603163.3609079} + } + ``` + +--- + +### Semantic Scene Builder: Towards a Context Sensitive Text-to-3D Scene Framework { #semantic-scene-builder } + +**Henlein, Kett, Baumartz, Abrami, Mehler et al.** (2023). *Digital Human Modeling and Applications in Health, Safety, +Ergonomics and Risk Management* (HCII 2023), Springer, 461–479. +[[DOI]](https://doi.org/10.1007/978-3-031-35748-0_32) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Henlein:et:al:2023b, + author = {Henlein, Alexander and Kett, Attila and Baumartz, Daniel and Abrami, Giuseppe + and Mehler, Alexander and Bastian, Johannes and Blecher, Yannic and Budgenhagen, David + and Christof, Roman and Ewald, Tim-Oliver and Fauerbach, Tim and Masny, Patrick + and Mende, Julian and Schn{\"u}re, Paul and Viel, Marc}, + editor = {Duffy, Vincent G.}, + title = {Semantic Scene Builder: Towards a Context Sensitive Text-to-3D Scene Framework}, + booktitle = {Digital Human Modeling and Applications in Health, Safety, Ergonomics + and Risk Management}, + year = {2023}, + publisher = {Springer Nature Switzerland}, + address = {Cham}, + pages = {461--479}, + isbn = {978-3-031-35748-0}, + doi = {10.1007/978-3-031-35748-0_32}, + } + ``` ## Presentations / Posters -#### Towards grounding multimodal semantics in interaction data with Va.Si.Li-Lab - -``` bibtex -@inproceedings{Henlein:et:al:2023c, - title = {Towards grounding multimodal semantics in interaction data with Va.Si.Li-Lab}, - author = {Henlein, Alexander and Lücking, Andy and Bagci, Mevlüt and Mehler, Alexander}, - booktitle = {Proceedings of the 8th Conference on Gesture and Speech in Interaction (GESPIN)}, - location = {Nijmegen, Netherlands}, - year = {2023}, - keywords = {vasililab}, - pdf = {https://www.gespin2023.nl/documents/talks_and_posters/GeSpIn_2023_papers/GeSpIn_2023_paper_1692.pdf} -} -``` -[[pdf]](https://www.gespin2023.nl/documents/talks_and_posters/GeSpIn_2023_papers/GeSpIn_2023_paper_1692.pdf) - ---- \ No newline at end of file +### Virtually Restricting Modalities in Interactions: Va.Si.Li-Lab for Experimental Multimodal Research + +**Henlein, Lücking & Mehler** (2024). *2nd International Symposium on Multimodal Communication* (MMSYM 2024), 96–97. +[[PDF]](http://mmsym.org/wp-content/uploads/2024/09/BookOfAbstractsMMSYM2024-3.pdf) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Henlein:Luecking:Mehler:2024, + title = {Virtually Restricting Modalities in Interactions: Va.Si.Li-Lab + for Experimental Multimodal Research}, + author = {Henlein, Alexander and L{\"u}cking, Andy and Mehler, Alexander}, + booktitle = {Proceedings of the 2nd International Symposium on Multimodal Communication + (MMSYM 2024), Frankfurt, 25-27 September 2024}, + pages = {96--97}, + year = {2024}, + pdf = {http://mmsym.org/wp-content/uploads/2024/09/BookOfAbstractsMMSYM2024-3.pdf}, + } + ``` + +--- + +### Towards grounding multimodal semantics in interaction data with Va.Si.Li-Lab + +**Henlein, Lücking, Bagci & Mehler** (2023). *Proceedings of the 8th Conference on Gesture and Speech in Interaction* +(GESPIN 2023), Nijmegen. +[[PDF]](https://www.gespin2023.nl/documents/talks_and_posters/GeSpIn_2023_papers/GeSpIn_2023_paper_1692.pdf) + +??? note "BibTeX" + + ```bibtex + @inproceedings{Henlein:et:al:2023c, + title = {Towards grounding multimodal semantics in interaction data with Va.Si.Li-Lab}, + author = {Henlein, Alexander and Lücking, Andy and Bagci, Mevlüt and Mehler, Alexander}, + booktitle = {Proceedings of the 8th Conference on Gesture and Speech in Interaction (GESPIN)}, + location = {Nijmegen, Netherlands}, + year = {2023}, + pdf = {https://www.gespin2023.nl/documents/talks_and_posters/GeSpIn_2023_papers/GeSpIn_2023_paper_1692.pdf} + } + ``` diff --git a/Documentation/docs/scenarios/DGS.md b/Documentation/docs/scenarios/DGS.md deleted file mode 100644 index bf965699..00000000 --- a/Documentation/docs/scenarios/DGS.md +++ /dev/null @@ -1,2 +0,0 @@ -# DGS -This documentation is work in progress. \ No newline at end of file diff --git a/Documentation/docs/scenarios/ICIDS.md b/Documentation/docs/scenarios/ICIDS.md deleted file mode 100644 index 71f430eb..00000000 --- a/Documentation/docs/scenarios/ICIDS.md +++ /dev/null @@ -1,2 +0,0 @@ -# ICIDS -This documentation is work in progress. \ No newline at end of file diff --git a/Documentation/docs/scenarios/Meetingpoint.md b/Documentation/docs/scenarios/Meetingpoint.md deleted file mode 100644 index 2c48d0eb..00000000 --- a/Documentation/docs/scenarios/Meetingpoint.md +++ /dev/null @@ -1,2 +0,0 @@ -# Meetingpoint -This documentation is work in progress. \ No newline at end of file diff --git a/Documentation/docs/scenarios/OrganisationDistribution.md b/Documentation/docs/scenarios/OrganisationDistribution.md deleted file mode 100644 index 4640f583..00000000 --- a/Documentation/docs/scenarios/OrganisationDistribution.md +++ /dev/null @@ -1,2 +0,0 @@ -# Organisation Distribution -This documentation is work in progress. \ No newline at end of file diff --git a/Documentation/docs/scenarios/OrganisationEducation.md b/Documentation/docs/scenarios/OrganisationEducation.md deleted file mode 100644 index 2c805697..00000000 --- a/Documentation/docs/scenarios/OrganisationEducation.md +++ /dev/null @@ -1,2 +0,0 @@ -# Organisation Education -This documentation is work in progress. \ No newline at end of file diff --git a/Documentation/docs/scenarios/PraktikumScenario1.md b/Documentation/docs/scenarios/PraktikumScenario1.md deleted file mode 100644 index 67914a6d..00000000 --- a/Documentation/docs/scenarios/PraktikumScenario1.md +++ /dev/null @@ -1,35 +0,0 @@ -# Praktikum Scenario 1 - -## Description -Three people take part in the experiment. There are two runs. -Run 1: One person sees the flat furnished with abstract objects. The other two -The other two people have to use the descriptions to get the right objects from the storage and place them in the -and place them in the right place. The participants have random restrictions (sight, hearing, nothing). -After the first round, the participants can exchange ideas and tips with the restrictions and roles. -restrictions and roles. -Round 2: The roles and restrictions are then redistributed and the experiment is repeated. - - -## Parameter -* Number of participants: 3 -* Duration: 2h - - -## Rounds - -### Round 1 -* One person sees the flat furnished. -* The rooms are numbered on the doors (the large room in the centre has the number 8). -* The task is to describe the objects in the rooms in order so that the other people can get the right objects from the storage room and place them correctly. -* The placement does not have to be perfect. -* The round lasts 25min. Then person 3 should finish the round. (Stop the time!) - -### Round 2 -* All participants are allowed to exchange ideas and report on their experiences in the role and any limitations. -* The aim is to make it easier for the other participants to start the next round. -* When everyone has exchanged ideas, person 3 can start the next round. - -### Round 3 -* See round 1. -* The roles, restrictions and objects in the flat are redistributed randomly. -* At the end, simply close applications again and remove glasses. diff --git a/Documentation/docs/scenarios/PraktikumScenario2.md b/Documentation/docs/scenarios/PraktikumScenario2.md deleted file mode 100644 index 3ce74b7f..00000000 --- a/Documentation/docs/scenarios/PraktikumScenario2.md +++ /dev/null @@ -1,55 +0,0 @@ -# Praktikum Scenario 2 - Short Films - -## Description -In 4 rounds, the participants are each shown a different film at the same time. -After both people have seen their film (after each film), -they meet again in the living room (are automatically teleported) and are asked to give a summary of these films. - - -## Parameter -* Number of participants: 2 -* Duration: 1h - - -## Rounds - -### Round 1 -- As soon as everyone has clicked on "Bereit" and the round starts, they both watch their film. -- As soon as person 1 has finished the film, the level window appears and the level can be completed. -- As soon as person 2 has also finished the film, they can click on \enquote{Ready} and person 1 can start the next round. -- If person 2 finishes the film earlier, they simply wait until the \enquote{Ready} field appears in the level window. - -### Round 2 -- Both people face each other in VR and put down their controllers. -- First, person 1 narrates their film. -- After the narration, questions are welcome. -- At the end, person 1 should rate the film on a scale from 1 (bad) to 5 (good). -- Then person 2 narrates their film. -- After the narration, questions are welcome. -- Finally, person 2 should rate the film on a scale from 1 (bad) to 5 (good). -- (The ratings should later be used as a trigger to separate the two narratives) -- As soon as both people have retold their film, person 1 can end the level again (record controller for this). - -### Round 3 -- See round 1. - -### Round 4 -- See round 2. - -### Round 5-8 -- See round 1 - 4. - -## Movies -### Group 1 -- [For The Birds](https://youtu.be/nYTrIcn4rjg) -- [Snack Attack](https://youtu.be/38y_1EWIE9I) -### Group 2 -- [In the Green](https://youtu.be/nYTrIcn4rjg) -- [Mars](https://youtu.be/BmocltqxRak) -### Group 3 -- [The Mug](https://youtu.be/1y3h0B2b-HA) -- [The Black Hole](https://youtu.be/P5_Msrdg3Hk) -### Group 4 -- [Dji. Death Sails](https://www.youtube.com/OlOdyvZWtDQ) -- [The Choice](https://www.youtube.com/_HEnohs6yYw) - diff --git a/Documentation/docs/scenarios/PraktikumScenario3.md b/Documentation/docs/scenarios/PraktikumScenario3.md deleted file mode 100644 index ac67646e..00000000 --- a/Documentation/docs/scenarios/PraktikumScenario3.md +++ /dev/null @@ -1,29 +0,0 @@ -# Praktikum Scenario 3 - -## Description -Person 1 is driven through the fictitious [SaGA](https://pub.uni-bielefeld.de/record/2001935) city. -Person 1 then explains the route to person 2. -Person 2 then has to find their way through the SaGA city. - -## Parameter -* Number of participants: 3 -* Duration: 1h - - -## Rounds - -### Round 1 -- Person 1 is teleported to the starting point. As soon as the round begins, the city tour starts. -- The city tour itself lasts 7 minutes. -- Person 2 can be bored in the living room during this time. - -### Round 2 -- Both people face each other in VR and put away their controllers. -- Person 1 now has the task of explaining the route to person 2. -- At the end, both players can pick up their controllers again. -- Player 1 finishes the level and both get ready. - -### Round 3 -- Person 1 starts the round and can then twiddle their thumbs. -- Person 2 is teleported to the starting point and has the task of finding the way based on the previous directions. -- As soon as person 2 is hopelessly lost, the round can be cancelled. diff --git a/Documentation/docs/scenarios/SchoolDistribution.md b/Documentation/docs/scenarios/SchoolDistribution.md deleted file mode 100644 index 5899df23..00000000 --- a/Documentation/docs/scenarios/SchoolDistribution.md +++ /dev/null @@ -1,2 +0,0 @@ -# School Distribution -This documentation is work in progress. \ No newline at end of file diff --git a/Documentation/docs/scenarios/SchoolHetero.md b/Documentation/docs/scenarios/SchoolHetero.md deleted file mode 100644 index a3e24da9..00000000 --- a/Documentation/docs/scenarios/SchoolHetero.md +++ /dev/null @@ -1,2 +0,0 @@ -# School Hetero -This documentation is work in progress. \ No newline at end of file diff --git a/Documentation/docs/scenarios/index.md b/Documentation/docs/scenarios/index.md new file mode 100644 index 00000000..7a90af12 --- /dev/null +++ b/Documentation/docs/scenarios/index.md @@ -0,0 +1,11 @@ +# Scenarios + +A scenario is a scene plus its [scene definition](../getting_started/adding_scenes.md) (roles, levels, spawn points). +Scenario scenes made for studies are kept in the projects that run them; the public repository contains the +[sample scenes](../getting_started/special_scenes.md): + +| Scene | Purpose | +|---|---| +| `Example` | Minimal scenario to start a new scene from | +| `InterViewStart`, `InterView`, `InterViewReturn` | [InterView](../systems.md#interview): token entry, the interview room (seat, mirror, in-world browser, WebRTC connection to the interviewer) and the end screen | +| `Tutorial` | Learn the controls | diff --git a/Documentation/docs/server/server_structure.md b/Documentation/docs/server/server_structure.md index 9091d608..f84335de 100644 --- a/Documentation/docs/server/server_structure.md +++ b/Documentation/docs/server/server_structure.md @@ -7,7 +7,12 @@ depending on the scenario. |---|---|---| | [Ubiq Server](ubiq_server.md) | Room and session state - avatars, transforms, ownership | required | | [Database API](python_data_logger.md) | Scene definitions and the logging API, backed by [MongoDB](mongodb.md) | required | -| Chatbot, Speech, VR Agent | Conversational agents, speech-to-text and text-to-speech | optional | +| [VR Agent](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/vr_agent/) (`vr-agent/`) | LLM agents for the [Bots](../modules/bots.md) | optional | +| [TTS/STT](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/tts_stt/) (`tts-stt/`) | Speech-to-text and text-to-speech for the agents | optional | +| [Speech](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/speech/) (`speech2text/`) | Whisper speech-to-text for voice input | optional | +| [Chatbot](https://texttechnologylab.github.io/Va.Si.Li-Lab-backend/services/chatbot/) (`chatbot/`) | Older voice chatbot host | optional | + +Which client setting points to which service is listed in [Endpoints Configuration](../modules/endpoints.md). All of them live in the [Va.Si.Li-Lab-backend](https://github.com/texttechnologylab/Va.Si.Li-Lab-backend) diff --git a/Documentation/docs/server/ubiq_server.md b/Documentation/docs/server/ubiq_server.md index cd9d06a4..8064f9b4 100644 --- a/Documentation/docs/server/ubiq_server.md +++ b/Documentation/docs/server/ubiq_server.md @@ -43,8 +43,12 @@ docker run -d --restart unless-stopped -p 8009:8009 -p 8011:8011 ubiq ## Unity -`SocialNetworkScene > RoomClient` -### Docker Compose +The client reads the server address from *Ubiq Server* (a Ubiq `ConnectionDefinition`) in +`Assets/Resources/VasiliEndpoints.asset`. Create the file with *Tools > Va.Si.Li > Create Endpoints Config*. The +`VasiliServerConnection` component on the `RoomClient` of the `Social Network Scene` prefab applies it at start-up. If +the file is missing, the client falls back to `127.0.0.1:8009` and logs a warning. + +## Docker Compose The Ubiq server is also part of the combined [InterView deployment stack](https://texttechnologylab.github.io/InterView/services/ubiq/), diff --git a/Documentation/docs/students/documentation.md b/Documentation/docs/students/documentation.md index c01eac8e..9bac65bc 100644 --- a/Documentation/docs/students/documentation.md +++ b/Documentation/docs/students/documentation.md @@ -5,22 +5,30 @@ It is written in [Markdown](https://www.markdownguide.org/basic-syntax/) and can ## Testing locally -### Requirements +With [uv](https://docs.astral.sh/uv/getting-started/installation/) installed, no further setup is needed. From the +repository root: + ```bash -conda create -n mkdocs python=3.12 -conda activate mkdocs -pip install mkdocs-material -pip install mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-git-authors-plugin mkdocs-glightbox +cd Documentation +uvx --with mkdocs-material --with mkdocs-git-revision-date-localized-plugin --with mkdocs-glightbox mkdocs serve ``` -### Run +Then open . Pages reload when you save. + +Before opening a pull request, check that the docs build without warnings, as the CI does: ```bash -cd Documentation -mkdocs serve +uvx --with mkdocs-material --with mkdocs-git-revision-date-localized-plugin --with mkdocs-glightbox mkdocs build --strict ``` +Without uv, install the same packages with pip (`pip install mkdocs-material mkdocs-git-revision-date-localized-plugin +mkdocs-glightbox`) and run `mkdocs serve`. + ## Adding a new page To add a new page, create a new markdown file in the `Documentation/docs` folder. Then insert the file path in the `mkdocs.yml` file under the `nav` section. + +## Publishing +The docs are built and published to GitHub Pages on every push to `main` and on every pull request, so a pull +request shows up on the live site before it is merged. diff --git a/Documentation/docs/systems.md b/Documentation/docs/systems.md new file mode 100644 index 00000000..64df28c7 --- /dev/null +++ b/Documentation/docs/systems.md @@ -0,0 +1,65 @@ +# Systems using Va.Si.Li-Lab + +A list of Systems built on Va.Si.Li-Lab, as modules of this repository or as separate applications. Papers and BibTeX are listed +under [Publications](publications.md#systems-using-vasili-lab). + +| System | What it does | Paper | Part of | +|---|---|---|---| +| [InterView](#interview) | VR interviews: a participant in VR, the interviewer in a web browser | [Preprint](https://doi.org/10.2139/ssrn.7459949) | [FACES](projects/faces.md) | +| [ReEmote](#reemote) | Emotion representation for avatars and their environment | [XR Salento 2026](publications.md#reemote) (accepted) | [FACES](projects/faces.md) | +| [Va.Si.Li-ES](#vasili-es) | Event system: triggers, environment and weather changes, voting and feedback | [HT '24](https://doi.org/10.1145/3648188.3675154) | This repository (`Assets/Lab/EventSystem`) | +| [VR-ParlExplorer](#vr-parlexplorer) | Plenary debates in VR with chatbot members of parliament | [HT '25](https://doi.org/10.1145/3720553.3746672) | | +| [News in Time and Space](#news-in-time-and-space) | Geospatial hypertext: global news events on a virtual globe | [NRHM 2025](https://doi.org/10.1080/13614568.2024.2383601) | | +| [Viki LibraRy](#viki-library) | A collaborative VR library for browsing and reading hypertext | [NRHM 2025](https://doi.org/10.1080/13614568.2024.2383581) | | +| [Semantic Scene Builder](#semantic-scene-builder) | Text-to-3D scene generation, edited in VR | [HCII 2023](https://doi.org/10.1007/978-3-031-35748-0_32) | [ViCom](projects/vicom.md) | +| [FraGA](#fraga) | Frankfurt VR Gesture–Speech Alignment corpus, recorded in Va.Si.Li-Lab | [SemDial 2025](http://semdial.org/anthology/Z25-Luecking_semdial_3316.pdf) | [ViCom](projects/vicom.md) | + +## InterView + +A platform for VR survey interviews. The participant wears a headset and sits across from the interviewer's avatar; +the interviewer works from an ordinary browser. Speech, gaze, posture, hand movement, facial expression and the answers +are captured on a shared clock. InterView adds a WebRTC media layer (Janus), a browser-based interviewer console and a +token-driven session model to Va.Si.Li-Lab. + +- Platform documentation: [texttechnologylab.github.io/InterView](https://texttechnologylab.github.io/InterView/) +- VR client setup: [InterView VR Client](getting_started/interview_client.md) +- Paper: [InterView: Towards a Unified VR-Capable Interview Environment](publications.md#interview) + +## ReEmote + +Extends the face and hand tracking of Va.Si.Li-Lab with schema-based emotion mappings that affect both avatars and +their environments, so users and virtual agents share one emotional expression space. +Paper: [ReEmote](publications.md#reemote). + +## Va.Si.Li-ES + +The event system of Va.Si.Li-Lab. Events are created and serialised at run time and change situational and +environmental parameters (weather, objects, triggers); users are informed and can take part through voting and +feedback. It ships as its own package, see `Assets/Lab/EventSystem/README.md`. +Paper: [Va.Si.Li-ES](publications.md#vasili-es). + +## VR-ParlExplorer + +A plugin for Va.Si.Li-Lab that virtualises plenary debates: users interact with virtual members of parliament through +LLM-based chatbots. Paper: [VR-ParlExplorer](publications.md#vr-parlexplorer). + +## News in Time and Space + +News in Time and Space (NiTS) organises news articles (currently based on GDELT) as a geospatial hypertext on a virtual +globe, where users visualise, filter and explore global events and trends. +Paper: [Geo-spatial hypertext in virtual reality](publications.md#news-in-time-and-space). + +## Viki LibraRy + +A dynamically built library in VR that visualises hypertext systems, with an emphasis on collaborative reading and +spatial recall. Paper: [Viki LibraRy](publications.md#viki-library). + +## Semantic Scene Builder + +A VR-based text-to-3D framework: scenes are generated from annotated text descriptions and corrected by grabbing and +moving objects instead of editing annotations. Paper: [Semantic Scene Builder](publications.md#semantic-scene-builder). + +## FraGA + +The Frankfurt VR Gesture–Speech Alignment corpus, used for multimodal analyses of head and hand movements in dialogue. +Paper: [FraGA](publications.md#fraga). diff --git a/Documentation/mkdocs.yml b/Documentation/mkdocs.yml index 5ded50a3..a55087ba 100644 --- a/Documentation/mkdocs.yml +++ b/Documentation/mkdocs.yml @@ -22,23 +22,19 @@ nav: - InterView VR Client: ./getting_started/interview_client.md + - Modules: + - Endpoints Configuration: ./modules/endpoints.md + - Event System: ./modules/eventsystem.md + - Bots: ./modules/bots.md + - Logging: ./modules/logging.md + - Other Functions: - Replay Experiment: ./other/replay.md - - Bots: ./other/bots.md - - Experiment Visualization Audio: ./other/experiment_visualizer_audio.md + - Experiment Visualization: ./other/experiment_visualization.md - Scenarios: - - ICIDS: ./scenarios/ICIDS.md - - PraktikumScenario1: ./scenarios/PraktikumScenario1.md - - PraktikumScenario2: ./scenarios/PraktikumScenario2.md - - PraktikumScenario3: ./scenarios/PraktikumScenario3.md - - DGS: ./scenarios/DGS.md - - Meetingpoint: ./scenarios/Meetingpoint.md - - OrganisationDistribution: ./scenarios/OrganisationDistribution.md - - OrganisationEducation: ./scenarios/OrganisationEducation.md - - SchoolDistribution: ./scenarios/SchoolDistribution.md - - SchoolHetero: ./scenarios/SchoolHetero.md + - Overview: ./scenarios/index.md - Server Structure: - General: ./server/server_structure.md @@ -50,10 +46,13 @@ nav: - Documentation: ./students/documentation.md - Projects: - - Digitell: ./projects/digitell.md + - Overview: ./projects/index.md + - DigiTeLL: ./projects/digitell.md - ViCom: ./projects/vicom.md - New Data Spaces (FACES): ./projects/faces.md + - Systems: systems.md + - Publications: publications.md @@ -142,6 +141,7 @@ markdown_extensions: - pymdownx.superfences - admonition + - pymdownx.details - attr_list - md_in_html diff --git a/Packages/manifest.json b/Packages/manifest.json index 108e4025..2b8bace2 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -25,7 +25,7 @@ "com.unity.timeline": "1.8.13", "com.unity.ugui": "2.0.0", "com.unity.vectorgraphics": "3.0.0-preview.7", - "com.unity.webrtc": "3.0.0", + "com.unity.webrtc-ubiq-fork": "https://github.com/UCL-VR/unity-webrtc-ubiq-fork.git#v3.0.1-pre.7", "com.unity.xr.hands": "1.7.3", "com.unity.xr.interaction.toolkit": "3.3.2", "com.unity.xr.management": "4.6.1", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 57e54183..ebf1047d 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -403,16 +403,16 @@ }, "url": "https://packages.unity.com" }, - "com.unity.webrtc": { - "version": "3.0.0", + "com.unity.webrtc-ubiq-fork": { + "version": "https://github.com/UCL-VR/unity-webrtc-ubiq-fork.git#v3.0.1-pre.7", "depth": 0, - "source": "registry", + "source": "git", "dependencies": { - "com.unity.modules.audio": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", "com.unity.editorcoroutines": "1.0.0", - "com.unity.modules.jsonserialize": "1.0.0" + "com.unity.modules.audio": "1.0.0" }, - "url": "https://packages.unity.com" + "hash": "1724f81b5c39bb4f44bf550de64b9f1fa318ccc8" }, "com.unity.xr.core-utils": { "version": "2.6.0", diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset index c5552602..38bfca93 100644 --- a/ProjectSettings/EditorBuildSettings.asset +++ b/ProjectSettings/EditorBuildSettings.asset @@ -5,7 +5,7 @@ EditorBuildSettings: m_ObjectHideFlags: 0 serializedVersion: 2 m_Scenes: - - enabled: 1 + - enabled: 0 path: Assets/LabPrivate/Scenes/FACES_.unity guid: 912de1c6a9b21a044affe21425816298 - enabled: 1 @@ -16,6 +16,6 @@ EditorBuildSettings: guid: a20c8cfd9870a3942b37f0eaa4077803 m_configObjects: Unity.XR.Oculus.Settings: {fileID: 11400000, guid: 2acd84852d7486c4485f42afca1ff615, type: 2} - com.unity.xr.management.loader_settings: {fileID: 11400000, guid: e5d9c8f67f1518c429bb8eca89e53dc9, type: 2} - com.unity.xr.openxr.settings4: {fileID: 11400000, guid: 930343fcbf66e2d4cba10cfe8640789e, type: 2} + com.unity.xr.management.loader_settings: {fileID: 11400000, guid: 64b052f9363a9eb439fabb890edb4f0e, type: 2} + com.unity.xr.openxr.settings4: {fileID: 11400000, guid: 66627204218bd16438ec45a1666eccd9, type: 2} m_UseUCBPForAssetBundles: 0 diff --git a/README.md b/README.md index 5f010ac5..8be10ddc 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ -[![Paper_HCII](http://img.shields.io/badge/paper-HCII--2023-B31B1B.svg)](https://doi.org/10.1007/978-3-031-35741-1_39) -[![Paper_HT](http://img.shields.io/badge/paper-HT--2023-F31B1B.svg)](https://doi.org/10.1145/3603163.3609076) -[![Conference](http://img.shields.io/badge/conference-HCII--2023-4b44ce.svg)](https://2023.hci.international/) -[![version](https://img.shields.io/github/license/texttechnologylab/Va.Si.Li-Lab)]() -![GitHub release (with filter)](https://img.shields.io/github/v/release/texttechnologylab/Va.Si.Li-Lab) -[![Documentation](https://img.shields.io/badge/Material_for_MkDocs-526CFE?style=for-the-badge&logo=MaterialForMkDocs&logoColor=white)](https://texttechnologylab.github.io/Va.Si.Li-Lab/#citation) +

+ Va.Si.Li-Lab +

+ +[![Paper_HCII](https://img.shields.io/badge/paper-HCII--2023-B31B1B.svg)](https://doi.org/10.1007/978-3-031-35741-1_39) +[![Paper_HT](https://img.shields.io/badge/paper-HT--2023-F31B1B.svg)](https://doi.org/10.1145/3603163.3609076) +[![Paper_TKL](https://img.shields.io/badge/paper-TKL--2025-4b44ce.svg)](https://doi.org/10.1007/s10758-025-09837-7) +[![License](https://img.shields.io/github/license/texttechnologylab/Va.Si.Li-Lab)](LICENSE) +[![GitHub release](https://img.shields.io/github/v/release/texttechnologylab/Va.Si.Li-Lab)](https://github.com/texttechnologylab/Va.Si.Li-Lab/releases) +[![Documentation](https://img.shields.io/badge/Documentation-526CFE?logo=MaterialForMkDocs&logoColor=white)](https://texttechnologylab.github.io/Va.Si.Li-Lab/) # Va.Si.Li-Lab a **V**R-L**a**b for **Si**mulation-based **L**earn**i**ng @@ -12,20 +16,68 @@ a **V**R-L**a**b for **Si**mulation-based **L**earn**i**ng Va.Si.Li-Lab was established as part of the project "Digital Teaching and Learning Lab" (DigiTeLL) at the Goethe University Frankfurt. It has since evolved into a highly capable and flexible VR framework for enabling simultaneous, multi-user engagements. +# Projects +| Project | Va.Si.Li-Lab is used for | +|---|---| +| [DigiTeLL](https://texttechnologylab.github.io/Va.Si.Li-Lab/projects/digitell/) (Goethe University Frankfurt) | Origin of Va.Si.Li-Lab: simulation-based learning in VR for teaching | +| [ViCom / GeMDiS](https://texttechnologylab.github.io/Va.Si.Li-Lab/projects/vicom/) (DFG SPP 2392) | Gestures in dialogue: VR-based multimodal data collection | +| [New Data Spaces / FACES](https://texttechnologylab.github.io/Va.Si.Li-Lab/projects/faces/) (DFG SPP 2431) | Survey interviews in VR with [InterView](https://texttechnologylab.github.io/InterView/), see the [FACES studies](https://texttechnologylab.github.io/FACES/studies/) | + +# Systems using Va.Si.Li-Lab +* [InterView](https://texttechnologylab.github.io/InterView/): VR survey interviews, with the interviewer in a web browser ([paper](https://doi.org/10.2139/ssrn.7459949)) +* ReEmote: emotion representation for avatars and their environment ([paper](https://texttechnologylab.github.io/Va.Si.Li-Lab/publications/#reemote), XR Salento 2026, accepted) +* Va.Si.Li-ES: event system for environment changes, voting and feedback, `Assets/Lab/EventSystem` ([paper](https://doi.org/10.1145/3648188.3675154)) +* VR-ParlExplorer: plenary debates in VR with chatbot members of parliament ([paper](https://doi.org/10.1145/3720553.3746672)) +* News in Time and Space: global news events as geospatial hypertext on a virtual globe ([paper](https://doi.org/10.1080/13614568.2024.2383601)) +* Viki LibraRy: a collaborative VR library for browsing hypertext ([paper](https://doi.org/10.1080/13614568.2024.2383581)) +* Semantic Scene Builder: text-to-3D scene generation, edited in VR ([paper](https://doi.org/10.1007/978-3-031-35748-0_32)) +* FraGA: the Frankfurt VR Gesture–Speech Alignment corpus ([paper](http://semdial.org/anthology/Z25-Luecking_semdial_3316.pdf)) + +Details: [Systems](https://texttechnologylab.github.io/Va.Si.Li-Lab/systems/) · [Publications](https://texttechnologylab.github.io/Va.Si.Li-Lab/publications/) -# Va.Si.Li-Lab - Team -* Prof. Dr. Alexander Mehler (Leader) -* Giuseppe Abrami -* Mevlüt Bagci -* Dr. Alexander Henlein -* Patrick Schrottenbacher +# Core Team +Current members of the [Text Technology Lab](https://www.texttechnologylab.org/team/) working on Va.Si.Li-Lab: + +* Prof. Dr. Alexander Mehler (Leader) [@amehler](https://github.com/amehler) +* Giuseppe Abrami [@abrami](https://github.com/abrami) +* Mevlüt Bagci [@mevbagci](https://github.com/mevbagci) +* Dr. Alexander Henlein [@henlein](https://github.com/henlein) +* Patrick Schrottenbacher [@TheBv](https://github.com/TheBv) # Documentation https://texttechnologylab.github.io/Va.Si.Li-Lab/ +To use Va.Si.Li-Lab as a Unity package, see [Assets/Lab/Core/README.md](Assets/Lab/Core/README.md). # Cite -If you want to use the project or the corpus, please quote this as follows: [BibTeX](https://texttechnologylab.github.io/Va.Si.Li-Lab/publications/) +If you want to use the project, please cite: + +```bibtex +@inproceedings{Mehler:et:al:2023:a, + author = {Mehler, Alexander and Bagci, Mevl{\"u}t and Henlein, Alexander + and Abrami, Giuseppe and Spiekermann, Christian and Schrottenbacher, Patrick + and Konca, Maxim and L{\"u}cking, Andy and Engel, Juliane and Quintino, Marc + and Schreiber, Jakob and Saukel, Kevin and Zlatkin-Troitschanskaia, Olga}, + booktitle = {Digital Human Modeling and Applications in Health, Safety, Ergonomics + and Risk Management}, + editor = {Duffy, Vincent G.}, + address = {Cham}, + pages = {539--565}, + publisher = {Springer Nature Switzerland}, + title = {A Multimodal Data Model for Simulation-Based Learning with Va.Si.Li-Lab}, + year = {2023}, + doi = {10.1007/978-3-031-35741-1_39} +} +``` + +All publications with BibTeX: [Publications](https://texttechnologylab.github.io/Va.Si.Li-Lab/publications/) +# Contributors +Thank you to everyone who has contributed to Va.Si.Li-Lab! The list below is generated from the +[GitHub contributors](https://github.com/texttechnologylab/Va.Si.Li-Lab/graphs/contributors) of this repository and +needs no maintenance. + + Contributors + diff --git a/Va.Si.Li-Lab-public.slnx b/Va.Si.Li-Lab-public.slnx new file mode 100644 index 00000000..420268a8 --- /dev/null +++ b/Va.Si.Li-Lab-public.slnx @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 19b4978dddbc08e4b70df3acb53732779040256d Mon Sep 17 00:00:00 2001 From: Patrick Schrottenbacher Date: Thu, 15 Oct 2026 15:12:58 +0200 Subject: [PATCH 2/2] docs: added followupQuestionnaire variable --- Documentation/docs/getting_started/interview_client.md | 3 ++- Documentation/docs/modules/endpoints.md | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/docs/getting_started/interview_client.md b/Documentation/docs/getting_started/interview_client.md index 76ab3350..e2e08327 100644 --- a/Documentation/docs/getting_started/interview_client.md +++ b/Documentation/docs/getting_started/interview_client.md @@ -62,7 +62,8 @@ Holds the participant token across scene loads and derives every identifier from it, so the headset and the interviewer's browser meet without a coordination step. -The questionnaire URL is `questionnaire` in the endpoints. The token is appended as `?token=…&room=…`. +The questionnaire URL is `questionnaire` in the endpoints. The token is appended as `?token=…&room=…`. The follow-up +questionnaire that the interviewer can send afterwards is `followupQuestionnaire`. ``` token ──┬─→ RoomId (Janus room ID) diff --git a/Documentation/docs/modules/endpoints.md b/Documentation/docs/modules/endpoints.md index b8d6ae4e..99502ff5 100644 --- a/Documentation/docs/modules/endpoints.md +++ b/Documentation/docs/modules/endpoints.md @@ -23,6 +23,7 @@ logged at start-up. | `shapeNet` | `http://localhost:8004` | ShapeNet object search and download (`ShapeNetInterface`) | No ShapeNet objects | | `eventTemplates` | `http://localhost:4567` | [Event System](eventsystem.md) templates (`/defaultTemplates`) | No saved or default event systems | | `questionnaire` | *(empty)* | [InterView](../getting_started/interview_client.md): questionnaire page opened in the in-world browser (`InterviewTokenManager`) | Empty browser in InterView | +| `followupQuestionnaire` | *(empty)* | InterView: follow-up questionnaire the interviewer sends to the interviewee (`WebCamClient` follow-up button; the interview token is appended) | The follow-up button logs a warning and sends nothing | | `janus` | `ws://localhost:8188` | WebRTC (Janus) for InterView and the webcam screen (`WebCamClient`) | No audio/video with the interviewer | | `iceServers` | *(empty)* | STUN/TURN servers for WebRTC. Leave `username`/`credential` empty for STUN | WebRTC only works on the same network |