mirror of
https://github.com/SlimeVR/SlimeVR-Server.git
synced 2026-04-06 02:01:58 +02:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b73e147d17 | ||
|
|
4dae31a138 | ||
|
|
74351dbb00 | ||
|
|
ec541685a2 | ||
|
|
cd4388e605 | ||
|
|
a36a6bceee | ||
|
|
0043c30c36 | ||
|
|
f030496659 | ||
|
|
32d0674aad | ||
|
|
3e308b222f | ||
|
|
a8a5a5c93c | ||
|
|
d87514a9ea | ||
|
|
4dac09e61e | ||
|
|
995c07dc08 | ||
|
|
961c32a8da | ||
|
|
87ba356fb0 | ||
|
|
580178de05 | ||
|
|
0e8b8dc500 | ||
|
|
9415eceb85 | ||
|
|
03f9115f75 | ||
|
|
30ca65e875 | ||
|
|
9cde4058ad | ||
|
|
564be6112a | ||
|
|
3374e45d62 | ||
|
|
48493c8c15 | ||
|
|
e858464064 | ||
|
|
64a8b1aab0 | ||
|
|
0c787b6675 | ||
|
|
6c7550ee56 | ||
|
|
c5d666d335 | ||
|
|
6b042ff903 | ||
|
|
0dd5ec7dfe | ||
|
|
50eef6ea7f | ||
|
|
db64d48bfe | ||
|
|
a008958f37 | ||
|
|
148a1edeac | ||
|
|
03eeb87498 | ||
|
|
c3d8eba264 | ||
|
|
269a79c87a |
23
.editorconfig
Normal file
23
.editorconfig
Normal file
@@ -0,0 +1,23 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
|
||||
# Fluent files only support spaces for indentation
|
||||
[*.ftl]
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
|
||||
# Current config in eslint uses 2 spaces for indentation
|
||||
[*.{.tsx,ts,jsx,js}]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
max_line_length = 88
|
||||
|
||||
# This is how everything should actually be
|
||||
[*.{kt,kts,java,rs}]
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
max_line_length = 88
|
||||
26
.github/CODEOWNERS
vendored
Normal file
26
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Global code owner
|
||||
* @Eirenliel
|
||||
|
||||
# Make Loucas the owner of all GUI stuff
|
||||
/gui/ @loucass003
|
||||
|
||||
# Uriel and Erimel responsible for i18n
|
||||
/gui/public/i18n/ @ImUrX @Louka3000
|
||||
/gui/src/i18n/ @ImUrX @Louka3000 @loucass003
|
||||
|
||||
/gui/src/components/settings/ @Louka3000 @loucass003
|
||||
|
||||
/gui/src-tauri/ @ImUrX @TheButlah
|
||||
|
||||
# Some server code~
|
||||
/server/ @ButterscotchV @Eirenliel @Louka3000
|
||||
|
||||
/server/src/main/java/dev/slimevr/autobone/ @ButterscotchV
|
||||
/server/src/main/java/dev/slimevr/poserecorder/ @ButterscotchV
|
||||
/server/src/main/java/dev/slimevr/posestreamer/ @ButterscotchV
|
||||
|
||||
/server/src/main/java/dev/slimevr/osc/ @Louka3000
|
||||
/server/src/main/java/dev/slimevr/vr/processor/ @Louka3000
|
||||
/server/src/main/java/dev/slimevr/filtering/ @Louka3000
|
||||
|
||||
server/src/main/java/dev/slimevr/config/ @loucass003
|
||||
12
.github/workflows/build-gui.yml
vendored
12
.github/workflows/build-gui.yml
vendored
@@ -36,9 +36,15 @@ jobs:
|
||||
|
||||
- if: matrix.os == 'ubuntu-20.04'
|
||||
name: Set up Linux dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf
|
||||
uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
with:
|
||||
packages: libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf
|
||||
# Increment to invalidate the cache
|
||||
version: 1.0
|
||||
# Enables a workaround to attempt to run pre and post install scripts
|
||||
execute_install_scripts: true
|
||||
# Disables uploading logs as a build artifact
|
||||
debug: false
|
||||
|
||||
- name: Cache cargo dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
||||
12
.github/workflows/gradle.yaml
vendored
12
.github/workflows/gradle.yaml
vendored
@@ -80,9 +80,15 @@ jobs:
|
||||
path: server/build/libs/
|
||||
|
||||
- name: Set up Linux dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf libfuse2
|
||||
uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
with:
|
||||
packages: libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf libfuse2
|
||||
# Increment to invalidate the cache
|
||||
version: 1.0
|
||||
# Enables a workaround to attempt to run pre and post install scripts
|
||||
execute_install_scripts: true
|
||||
# Disables uploading logs as a build artifact
|
||||
debug: false
|
||||
|
||||
- name: Cache cargo dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
||||
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@@ -8,7 +8,8 @@
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"rust-lang.rust-analyzer",
|
||||
"bradlc.vscode-tailwindcss"
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"EditorConfig.EditorConfig"
|
||||
],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": []
|
||||
|
||||
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -2560,9 +2560,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "shadow-rs"
|
||||
version = "0.19.0"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c401e795850edb4e9fdde5940f856364f0fbab573e8dea58f6ee5f85fcf471d"
|
||||
checksum = "8da90bd2a722461267a2c5d20b2c6de76dba087348e60484fd6c3fbb48b766d6"
|
||||
dependencies = [
|
||||
"const_format",
|
||||
"git2",
|
||||
@@ -2609,10 +2609,12 @@ dependencies = [
|
||||
name = "slimevr"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"clap",
|
||||
"clap-verbosity-flag",
|
||||
"const_format",
|
||||
"glob",
|
||||
"log",
|
||||
"open",
|
||||
"pretty_env_logger",
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"@fluent/react": "^0.14.1",
|
||||
"@fontsource/poppins": "^4.5.8",
|
||||
"@formatjs/intl-localematcher": "^0.2.32",
|
||||
"@react-three/fiber": "^8.10.0",
|
||||
"@tauri-apps/api": "^1.2.0",
|
||||
"@vitejs/plugin-react": "^3.0.0",
|
||||
"browserslist": "^4.18.1",
|
||||
@@ -25,7 +26,6 @@
|
||||
"postcss-normalize": "^10.0.1",
|
||||
"postcss-preset-env": "^7.0.1",
|
||||
"prompts": "^2.4.2",
|
||||
"quaternion": "^1.4.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dev-utils": "^12.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
@@ -34,6 +34,7 @@
|
||||
"react-router-dom": "^6.2.2",
|
||||
"semver": "^7.3.5",
|
||||
"solarxr-protocol": "file:../solarxr-protocol",
|
||||
"three": "^0.148.0",
|
||||
"typescript": "^4.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -71,6 +72,7 @@
|
||||
"@types/react": "18.0.25",
|
||||
"@types/react-dom": "^18.0.5",
|
||||
"@types/react-modal": "3.13.1",
|
||||
"@types/three": "^0.148.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.43.0",
|
||||
"@typescript-eslint/parser": "^5.43.0",
|
||||
"autoprefixer": "^10.4.4",
|
||||
|
||||
520
gui/public/i18n/de/translation.ftl
Normal file
520
gui/public/i18n/de/translation.ftl
Normal file
@@ -0,0 +1,520 @@
|
||||
### SlimeVR complete GUI translations
|
||||
# Please developers (not translators) don't reuse a key inside another key
|
||||
# or concat text with a translation string in the code, use the appropriate
|
||||
# features like variables and selectors in each appropriate case!
|
||||
# And also comment the string if it's something not easy to translate, so you help
|
||||
# translators on what it means
|
||||
|
||||
## Websocket (server) status
|
||||
websocket-connecting = Verbindung zum Server wird hergestellt...
|
||||
websocket-connection_lost = Verbindung zum Server verloren. Versuche Verbindung wiederherzustellen ...
|
||||
|
||||
## Tips
|
||||
tips-find_tracker = Sie sind sich nicht sicher, welcher Tracker welcher ist? Schütteln Sie einen Tracker, um den zugehörigen Eintrag hervorzuheben.
|
||||
tips-do_not_move_heels = Stellen Sie sicher, dass Sie Ihre Fersen während der Aufnahme nicht bewegen!
|
||||
|
||||
## Body parts
|
||||
body_part-NONE = Nicht zugewiesen
|
||||
body_part-HEAD = Kopf
|
||||
body_part-NECK = Hals
|
||||
body_part-RIGHT_SHOULDER = Rechte Schulter
|
||||
body_part-RIGHT_UPPER_ARM = Rechter Oberarm
|
||||
body_part-RIGHT_LOWER_ARM = Rechter Unterarm
|
||||
body_part-RIGHT_HAND = Rechte Hand
|
||||
body_part-RIGHT_UPPER_LEG = Rechter Oberschenkel
|
||||
body_part-RIGHT_LOWER_LEG = Rechter Unterschenkel
|
||||
body_part-RIGHT_FOOT = Rechter Fuß
|
||||
body_part-RIGHT_CONTROLLER = Rechter Controller
|
||||
body_part-CHEST = Brust
|
||||
body_part-WAIST = Taille
|
||||
body_part-HIP = Hüfte
|
||||
body_part-LEFT_SHOULDER = Linke Schulter
|
||||
body_part-LEFT_UPPER_ARM = Linker Oberarm
|
||||
body_part-LEFT_LOWER_ARM = Linker Unterarm
|
||||
body_part-LEFT_HAND = Linke Hand
|
||||
body_part-LEFT_UPPER_LEG = Linker Oberschenkel
|
||||
body_part-LEFT_LOWER_LEG = Linker Unterschenkel
|
||||
body_part-LEFT_FOOT = Linker Fuß
|
||||
body_part-LEFT_CONTROLLER = Linker Controller
|
||||
|
||||
## Skeleton stuff
|
||||
skeleton_bone-NONE = Keine
|
||||
skeleton_bone-HEAD = Kopfverschiebung
|
||||
skeleton_bone-NECK = Halslänge
|
||||
skeleton_bone-CHEST = Brustabstand
|
||||
skeleton_bone-CHEST_OFFSET = Brustversatz
|
||||
skeleton_bone-WAIST = Taillenabstand
|
||||
skeleton_bone-HIP = Hüftlänge
|
||||
skeleton_bone-HIP_OFFSET = Hüftversatz
|
||||
skeleton_bone-HIPS_WIDTH = Hüftbreite
|
||||
skeleton_bone-UPPER_LEG = Linker Oberschenkellänge
|
||||
skeleton_bone-LOWER_LEG = Linker Unterschenkellänge
|
||||
skeleton_bone-FOOT_LENGTH = Fußlänge
|
||||
skeleton_bone-FOOT_SHIFT = Fußverschiebung
|
||||
skeleton_bone-SKELETON_OFFSET = Skelettversatz
|
||||
skeleton_bone-SHOULDERS_DISTANCE = Schulterentfernung
|
||||
skeleton_bone-SHOULDERS_WIDTH = Schulterbreite
|
||||
skeleton_bone-UPPER_ARM = Oberarmlänge
|
||||
skeleton_bone-LOWER_ARM = Unterarmlänge
|
||||
skeleton_bone-CONTROLLER_Y = Controller Abstand Y
|
||||
skeleton_bone-CONTROLLER_Z = Controller Abstand Z
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Alle Proportionen zurücksetzen
|
||||
reset-full = Reset
|
||||
reset-mounting = Befestigungs-Reset
|
||||
reset-quick = Schneller Reset
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = Neues serielles Gerät erkannt!
|
||||
serial_detection-new_device-p1 = Geben Sie Ihre WLAN-Zugangsdaten ein!
|
||||
serial_detection-new_device-p2 = Bitte wählen Sie, was Sie damit machen möchten
|
||||
serial_detection-open_wifi = Mit WLAN verbinden
|
||||
serial_detection-open_serial = Serielle Konsole öffnen
|
||||
serial_detection-submit = Absenden!
|
||||
serial_detection-close = Schließen
|
||||
|
||||
## Navigation bar
|
||||
navbar-home = Start
|
||||
navbar-body_proportions = Körpermaße
|
||||
navbar-trackers_assign = Tracker-Zuordnung
|
||||
navbar-mounting = Tracker-Ausrichtung
|
||||
navbar-onboarding = Einrichtungs-Assistent
|
||||
navbar-settings = Einstellungen
|
||||
|
||||
## Bounding volume hierarchy recording
|
||||
bvh-start_recording = BVH aufnehmen
|
||||
bvh-recording = Aufnahme läuft...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = Visualisierungs-Overlay in SteamVR anzeigen
|
||||
overlay-is_mirrored_label = Visualisierung spiegeln
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = Kein Status
|
||||
tracker-status-busy = Beschäftigt
|
||||
tracker-status-error = Fehler
|
||||
tracker-status-disconnected = Getrennt
|
||||
tracker-status-occluded = Verdeckt
|
||||
tracker-status-ok = Verbunden
|
||||
|
||||
## Tracker status columns
|
||||
tracker-table-column-name = Name
|
||||
tracker-table-column-type = Typ
|
||||
tracker-table-column-battery = Batterie
|
||||
tracker-table-column-ping = Latenz
|
||||
tracker-table-column-rotation = Rotation X/Y/Z
|
||||
tracker-table-column-position = Position X/Y/Z
|
||||
tracker-table-column-url = Adresse
|
||||
|
||||
## Tracker rotation
|
||||
tracker-rotation-front = Vorne
|
||||
tracker-rotation-left = Links
|
||||
tracker-rotation-right = Rechts
|
||||
tracker-rotation-back = Hinten
|
||||
|
||||
## Tracker information
|
||||
tracker-infos-manufacturer = Hersteller
|
||||
tracker-infos-display_name = Anzeigename
|
||||
tracker-infos-custom_name = Benutzerdefinierter Name
|
||||
tracker-infos-url = Tracker-Adresse
|
||||
|
||||
## Tracker settings
|
||||
tracker-settings-back = Zurück zur Tracker-Liste
|
||||
tracker-settings-title = Tracker-Einstellungen
|
||||
tracker-settings-assignment_section = Zuweisung
|
||||
tracker-settings-assignment_section-description = Welcher Körperteil dem Tracker zugewiesen ist.
|
||||
tracker-settings-assignment_section-edit = Zuweisung bearbeiten
|
||||
tracker-settings-mounting_section = Befestigungsposition
|
||||
tracker-settings-mounting_section-description = Wo ist der Tracker befestigt?
|
||||
tracker-settings-mounting_section-edit = Befestigung bearbeiten
|
||||
tracker-settings-drift_compensation_section = Drift-Kompensierung
|
||||
tracker-settings-drift_compensation_section-description = Soll dieser Tracker Drift kompensieren, wenn die Drift-Kompensierung allgemein aktiviert ist?
|
||||
tracker-settings-drift_compensation_section-edit = Erlaube Drift Kompensierung
|
||||
# The .<name> means it's an attribute and it's related to the top key.
|
||||
# In this case that is the settings for the assignment section.
|
||||
tracker-settings-name_section = Trackername
|
||||
tracker-settings-name_section-description = Geben Sie ihm einen süßen Spitznamen :)
|
||||
tracker-settings-name_section-placeholder = NightyBeast's linkes Bein
|
||||
|
||||
## Tracker part card info
|
||||
tracker-part_card-no_name = Kein Name
|
||||
tracker-part_card-unassigned = Nicht zugewiesen
|
||||
|
||||
## Body assignment menu
|
||||
body_assignment_menu = Wo tragen Sie diesen Tracker?
|
||||
body_assignment_menu-description = Wählen Sie die Position aus, an dem Sie diesen Tracker befestigt haben. Alternativ können Sie auch alle Tracker auf einmal verwalten statt einzeln.
|
||||
body_assignment_menu-show_advanced_locations = Zeige erweiterte Tracker-Positionen
|
||||
body_assignment_menu-manage_trackers = Verwalte alle Tracker
|
||||
body_assignment_menu-unassign_tracker = Zuweisung des Trackers aufheben
|
||||
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Welcher Tracker soll
|
||||
tracker_selection_menu-NONE = Welchen Tracker möchten Sie zuweisen?
|
||||
tracker_selection_menu-HEAD = { -tracker_selection-part } dem Kopf zugewiesen werden?
|
||||
tracker_selection_menu-NECK = { -tracker_selection-part } dem Nacken zugewiesen werden?
|
||||
tracker_selection_menu-RIGHT_SHOULDER = { -tracker_selection-part } der rechten Schulter zugewiesen werden?
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = { -tracker_selection-part } dem rechten Oberarm zugewiesen werden?
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = { -tracker_selection-part } dem rechten Unterarm zugewiesen werden?
|
||||
tracker_selection_menu-RIGHT_HAND = { -tracker_selection-part } der rechten Hand zugewiesen werden?
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = { -tracker_selection-part } dem rechten Oberschenkel zugewiesen werden?
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = { -tracker_selection-part } dem rechten Unterschenkel zugewiesen werden?
|
||||
tracker_selection_menu-RIGHT_FOOT = { -tracker_selection-part } dem rechten Fuß zugewiesen werden?
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = { -tracker_selection-part } dem rechten Controller zugewiesen werden?
|
||||
tracker_selection_menu-CHEST = { -tracker_selection-part } der Brust zugewiesen werden?
|
||||
tracker_selection_menu-WAIST = { -tracker_selection-part } der Taille zugewiesen werden?
|
||||
tracker_selection_menu-HIP = { -tracker_selection-part } der Hüfte zugewiesen werden?
|
||||
tracker_selection_menu-LEFT_SHOULDER = { -tracker_selection-part } der linken Schulter zugewiesen werden?
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = { -tracker_selection-part } dem linken Oberarm zugewiesen werden?
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = { -tracker_selection-part } dem linken Unterarm zugewiesen werden?
|
||||
tracker_selection_menu-LEFT_HAND = { -tracker_selection-part } der linken Hand zugewiesen werden?
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = { -tracker_selection-part } dem linken Oberschenkel zugewiesen werden?
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = { -tracker_selection-part } dem linken Unterschenkel zugewiesen werden?
|
||||
tracker_selection_menu-LEFT_FOOT = { -tracker_selection-part } dem Linken Fuß zugewiesen zugewiesen werden?
|
||||
tracker_selection_menu-LEFT_CONTROLLER = { -tracker_selection-part } dem linken Controller zugewiesen werden?
|
||||
|
||||
tracker_selection_menu-unassigned = Nicht zugewiesene Tracker
|
||||
tracker_selection_menu-assigned = Zugewiesene Tracker
|
||||
tracker_selection_menu-dont_assign = Nicht zuweisen
|
||||
|
||||
## Mounting menu
|
||||
mounting_selection_menu = Wo möchten Sie diesen Tracker platzieren?
|
||||
mounting_selection_menu-close = Schließen
|
||||
|
||||
## Sidebar settings
|
||||
settings-sidebar-title = Einstellungen
|
||||
settings-sidebar-general = Allgemein
|
||||
settings-sidebar-tracker_mechanics = Tracker-Mechanik
|
||||
settings-sidebar-fk_settings = FK-Einstellungen
|
||||
settings-sidebar-gesture_control = Gestensteuerung
|
||||
settings-sidebar-interface = Bedienoberfläche
|
||||
settings-sidebar-osc_router = OSC-Router
|
||||
settings-sidebar-utils = Werkzeuge
|
||||
settings-sidebar-serial = Serielle Konsole
|
||||
|
||||
## SteamVR settings
|
||||
settings-general-steamvr = SteamVR
|
||||
settings-general-steamvr-subtitle = SteamVR-Tracker
|
||||
# Not all translation keys support multiline, only the ones that specify it will actually
|
||||
# split it in lines (that also means you can split in lines however you want in those).
|
||||
# The first spaces (not tabs) for indentation will be ignored, just to make the file look nice when writing.
|
||||
# This one is one of this cases that cares about multilines
|
||||
settings-general-steamvr-description =
|
||||
Aktivieren oder deaktivieren Sie bestimmte SteamVR-Tracker.
|
||||
Nützlich für Spiele oder Apps, die nur bestimmte Tracker unterstützen.
|
||||
settings-general-steamvr-trackers-waist = Taille
|
||||
settings-general-steamvr-trackers-chest = Brust
|
||||
settings-general-steamvr-trackers-feet = Füße
|
||||
settings-general-steamvr-trackers-knees = Knie
|
||||
settings-general-steamvr-trackers-elbows = Ellbogen
|
||||
settings-general-steamvr-trackers-hands = Hände
|
||||
|
||||
## Tracker mechanics
|
||||
settings-general-tracker_mechanics = Tracker-Verhalten
|
||||
settings-general-tracker_mechanics-filtering = Filtern
|
||||
# This also cares about multilines
|
||||
settings-general-tracker_mechanics-filtering-description =
|
||||
Wählen Sie den Filter-Typ für Ihre Tracker aus.
|
||||
Vorhersage: prognostiziert Bewegung. Glättung: Bewegung werden geglättet.
|
||||
settings-general-tracker_mechanics-filtering-type = Filter-Typ
|
||||
settings-general-tracker_mechanics-filtering-type-none = Kein Filter
|
||||
settings-general-tracker_mechanics-filtering-type-none-description = Verwendet die unveränderten Rotationsdaten der Tracker.
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing = Glättung
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing-description = Glättet Bewegungen, fügt aber etwas Verzögerung hinzu.
|
||||
settings-general-tracker_mechanics-filtering-type-prediction = Vorhersage
|
||||
settings-general-tracker_mechanics-filtering-type-prediction-description = Verringert die Latenz und macht die Bewegungen schneller, kann aber Zittern erhöhen.
|
||||
settings-general-tracker_mechanics-filtering-amount = Stärke
|
||||
settings-general-tracker_mechanics-drift_compensation = Drift-Kompensierung
|
||||
# This cares about multilines
|
||||
settings-general-tracker_mechanics-drift_compensation-description =
|
||||
Kompensiert IMU Drift auf der Gier-Achse durch Anwenden einer invertierten Rotation.
|
||||
Ändern Sie die Menge der Kompensierung und die Anzahl der Resets, welche für die Berechnung genutzt werden.
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = Drift-Kompensierung
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = Kompensierungsmenge
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = Nutze die letzten x Resets
|
||||
|
||||
## FK/Tracking settings
|
||||
settings-general-fk_settings = FK-Einstellungen
|
||||
settings-general-fk_settings-leg_tweak = Beinoptimierungen
|
||||
settings-general-fk_settings-leg_tweak-description = Bodenclip kann das einsinken in den Boden reduzieren oder sogar beseitigen, kann aber beim Knien Probleme verursachen. Die Rutsch-Korrektur verringert das Rutschen auf dem Boden, kann aber bei bestimmten Bewegungsmustern die Genauigkeit verringern.
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Bodenclip
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
settings-general-fk_settings-leg_tweak-skating_correction = Rutschkorrektur
|
||||
settings-general-fk_settings-leg_tweak-skating_correction-amount = Rutschkorrekturstärke
|
||||
settings-general-fk_settings-arm_fk = Arm-Tracking
|
||||
settings-general-fk_settings-arm_fk-description = Ändern Sie die Art und Weise, wie die Arme berechnet werden.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Arme vom VR-Headset erzwingen
|
||||
settings-general-fk_settings-skeleton_settings = Skeletteinstellungen
|
||||
settings-general-fk_settings-skeleton_settings-description = Schalten Sie Skeletteinstellungen ein oder aus. Es wird empfohlen, diese eingeschaltet zu lassen.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Erweiterte Wirbelsäule
|
||||
settings-general-fk_settings-skeleton_settings-extended_pelvis = Erweiterter Beckenbereich
|
||||
settings-general-fk_settings-skeleton_settings-extended_knees = Erweiterte Knie
|
||||
settings-general-fk_settings-vive_emulation-title = Vive-Simulierung
|
||||
settings-general-fk_settings-vive_emulation-description = Simuliere die Tracking-Probleme, welche bei Vive-Trackern auftreten. Dies ist ein Scherz und verschlechtert das Tracking.
|
||||
settings-general-fk_settings-vive_emulation-label = Vive-Simulierung
|
||||
|
||||
## Gesture control settings (tracker tapping)
|
||||
settings-general-gesture_control = Gestensteuerung
|
||||
settings-general-gesture_control-subtitle = Reset durch Antippen
|
||||
settings-general-gesture_control-description = Erlaubt Reset durch das Antippen eines Trackers auszulösen. Der höchste Tracker auf dem Oberkörper wird für schnelle Resets genutzt, der höchste Tracker auf dem linken Bein wird für Reset genutzt und der höchste Tracker auf dem rechten Bein wird für Befestigungs-Reset genutzt. Das Antippen muss innerhalb von 0.5 Sekunden erfolgen, um erkannt zu werden.
|
||||
# This is a unit: 3 taps, 2 taps, 1 tap
|
||||
# $amount (Number) - Amount of taps (touches to the tracker's case)
|
||||
settings-general-gesture_control-taps = { $amount ->
|
||||
[one] 1-mal antippen
|
||||
*[other] { $amount }-mal antippen
|
||||
}
|
||||
settings-general-gesture_control-quickResetEnabled = Antippen für schnellen Reset
|
||||
settings-general-gesture_control-quickResetDelay = Verzögerung für schnellen Reset
|
||||
settings-general-gesture_control-quickResetTaps = Anzahl für schnellen Reset
|
||||
settings-general-gesture_control-resetEnabled = Antippen für Reset
|
||||
settings-general-gesture_control-resetDelay = Reset-Verzögerung
|
||||
settings-general-gesture_control-resetTaps = Anzahl für Reset
|
||||
settings-general-gesture_control-mountingResetEnabled = Antippen für Befestigungs-Reset
|
||||
settings-general-gesture_control-mountingResetDelay = Befestigungs-Reset-Verzügerung
|
||||
settings-general-gesture_control-mountingResetTaps = Anzahl für Befestigungs-Reset
|
||||
|
||||
## Interface settings
|
||||
settings-general-interface = Bedienoberfläche
|
||||
settings-general-interface-dev_mode = Entwicklermodus
|
||||
settings-general-interface-dev_mode-description = Der Entwicklermodus stellt mehr Daten dar und erlaubt auch erweiterte Einstellungen, so wie erweiterte Optionen bei verbundenen Trackern.
|
||||
settings-general-interface-dev_mode-label = Entwicklermodus
|
||||
settings-general-interface-serial_detection = Serielle Geräteerkennung
|
||||
settings-general-interface-serial_detection-description = Diese Option zeigt jedes Mal ein Pop-up-Fenster an, wenn ein neues serielles Gerät angeschlossen wird, das ein Tracker sein könnte. Dies hilft beim Einrichtungsprozess des Trackers
|
||||
settings-general-interface-serial_detection-label = Serielle Geräteerkennung
|
||||
settings-general-interface-lang = Sprachauswahl
|
||||
settings-general-interface-lang-description = Ändern Sie die Standard-Sprache, die Sie verwenden möchten
|
||||
settings-general-interface-lang-placeholder = Wählen Sie die zu verwendende Sprache aus
|
||||
|
||||
## Serial settings
|
||||
settings-serial = Serielle Konsole
|
||||
# This cares about multilines
|
||||
settings-serial-description =
|
||||
Dies ist ein Live-Ansicht der seriellen Kommunikation.
|
||||
Diese ist zur Unterstützung bei der Problemsuche mit Trackern.
|
||||
settings-serial-connection_lost = Verbindung zur seriellen Schnittstelle verloren, Verbindung wird wiederhergestellt...
|
||||
settings-serial-reboot = Neustart
|
||||
settings-serial-factory_reset = Werkseinstellungen zurücksetzen
|
||||
settings-serial-get_infos = Informationen abrufen
|
||||
settings-serial-serial_select = Wählen Sie einen seriellen Anschluss
|
||||
settings-serial-auto_dropdown_item = Auto
|
||||
|
||||
## OSC router settings
|
||||
settings-osc-router = OSC Router
|
||||
# This cares about multilines
|
||||
settings-osc-router-description =
|
||||
Senden von OSC Daten an ein andere Programm.
|
||||
Nützlich wenn z.B. ein anderes OSC Programm zusammen mit VRChat verwendet wird.
|
||||
settings-osc-router-enable = Aktivieren
|
||||
settings-osc-router-enable-description = Ein- und Ausschalten des Sendens und Empfangen von Daten
|
||||
settings-osc-router-enable-label = Aktivieren
|
||||
settings-osc-router-network = Netzwerk-Ports
|
||||
# This cares about multilines
|
||||
settings-osc-router-network-description =
|
||||
Setzte die Ports zum Empfangen und Versenden von Daten.
|
||||
Diese können die selben Ports sein, welche vom SlimeVR Server verwendet werden.
|
||||
settings-osc-router-network-port_in =
|
||||
.label = Eingangsport
|
||||
.placeholder = Eingangsport (Standard: 9002)
|
||||
settings-osc-router-network-port_out =
|
||||
.label = Ausgangsport
|
||||
.placeholder = Ausgangsport (Standard: 9000)
|
||||
settings-osc-router-network-address = Netzwerk-Adresse
|
||||
settings-osc-router-network-address-description = Setze die Adresse, welche zum versenden von Daten genutzt wird.
|
||||
settings-osc-router-network-address-placeholder = IPv4 Adresse
|
||||
|
||||
## OSC VRChat settings
|
||||
settings-osc-vrchat = VRChat-OSC-Trackers
|
||||
# This cares about multilines
|
||||
settings-osc-vrchat-description =
|
||||
Ändern Sie VRChat-spezifische Einstellungen, um Headset- und Tracker-Daten für FBT zu empfangen und zu senden (funktioniert auch im Standalone-Modus auf der Meta Quest).
|
||||
settings-osc-vrchat-enable = Aktivieren
|
||||
settings-osc-vrchat-enable-description = Ein- und Ausschalten des Sendens und Empfangen von Daten
|
||||
settings-osc-vrchat-enable-label = Aktivieren
|
||||
settings-osc-vrchat-network = Netzwerk-Ports
|
||||
settings-osc-vrchat-network-description = Festlegen der Ports zum Empfangen und Senden von Daten an VRChat
|
||||
settings-osc-vrchat-network-port_in =
|
||||
.label = Eingangsport
|
||||
.placeholder = Eingangsport (Standard: 9001)
|
||||
settings-osc-vrchat-network-port_out =
|
||||
.label = Ausgangsport
|
||||
.placeholder = Ausgangsport (Standard: 9000)
|
||||
settings-osc-vrchat-network-address = Netzwerkadresse
|
||||
settings-osc-vrchat-network-address-description = Wählen Sie, an welche Adresse die Daten an VRChat gesendet werden sollen (überprüfen Sie Ihre WLAN-Einstellungen auf Ihrem Gerät)
|
||||
settings-osc-vrchat-network-address-placeholder = VRChat-IP-Adresse
|
||||
settings-osc-vrchat-network-trackers = Tracker
|
||||
settings-osc-vrchat-network-trackers-description = Ein- und Ausschalten des Sendens und Empfangens von Daten
|
||||
settings-osc-vrchat-network-trackers-chest = Brust
|
||||
settings-osc-vrchat-network-trackers-waist = Taille
|
||||
settings-osc-vrchat-network-trackers-knees = Knie
|
||||
settings-osc-vrchat-network-trackers-feet = Füße
|
||||
settings-osc-vrchat-network-trackers-elbows = Ellbogen
|
||||
|
||||
## Setup/onboarding menu
|
||||
onboarding-skip = Einrichtung überspringen
|
||||
onboarding-continue = Fortsetzen
|
||||
onboarding-wip = Noch in Bearbeitung
|
||||
|
||||
## WiFi setup
|
||||
onboarding-wifi_creds-back = Zurück zur Einführung
|
||||
onboarding-wifi_creds = WLAN-Zugangsdaten eingeben
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
Die Tracker nutzen diese Zugangsdaten, um sich mit dem WLAN zu verbinden.
|
||||
Bitte verwenden Sie die Zugangsdaten, mit denen ihr PC gerade verbunden sind.
|
||||
Dieses WLAN-Netzwerk muss ein 2.4 GHz-Netzwerk sein.
|
||||
onboarding-wifi_creds-skip = WLAN-Zugangsdaten überspringen
|
||||
onboarding-wifi_creds-submit = Weiter!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
.placeholder = SSID eingeben
|
||||
onboarding-wifi_creds-password =
|
||||
.label = Passwort
|
||||
.placeholder = Passwort eingeben
|
||||
|
||||
## Mounting setup
|
||||
onboarding-reset_tutorial-back = Zurück zur Trackerausrichtung
|
||||
onboarding-reset_tutorial = Tutorial neustarten
|
||||
onboarding-reset_tutorial-description = Diese Funktion ist noch nicht fertig, drücken Sie einfach auf Fortsetzen
|
||||
|
||||
## Setup start
|
||||
onboarding-home = Willkommen zu SlimeVR
|
||||
# This cares about multilines and it's centered!!
|
||||
onboarding-home-description =
|
||||
VR-Fullbody Tracking
|
||||
für alle
|
||||
onboarding-home-start = Los geht’s!
|
||||
|
||||
## Enter VR part of setup
|
||||
onboarding-enter_vr-back = Zurück zur Trackerzuweisung
|
||||
onboarding-enter_vr-title = Zeit für VR!
|
||||
onboarding-enter_vr-description = Ziehen Sie alle Tracker an und betreten Sie dann VR!
|
||||
onboarding-enter_vr-ready = Ich bin bereit!
|
||||
|
||||
## Setup done
|
||||
onboarding-done-title = Alles eingerichtet!
|
||||
onboarding-done-description = Genießen Sie die Fullbody-Erfahrung
|
||||
onboarding-done-close = Einrichtung schließen
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = Zurück zu WLAN-Zugangsdaten
|
||||
onboarding-connect_tracker-title = Verbinde Tracker
|
||||
onboarding-connect_tracker-description-p0 = Nun zum unterhaltsamen Teil, verbinde alle Tracker!
|
||||
onboarding-connect_tracker-description-p1 = Verbinden Sie einfach alle Tracker, die noch nicht verbunden sind, über einen USB-Anschluss.
|
||||
onboarding-connect_tracker-issue-serial = Ich habe Schwierigkeiten die Tracker zu verbinden!
|
||||
onboarding-connect_tracker-usb = USB Tracker
|
||||
onboarding-connect_tracker-connection_status-connecting = Sende WLAN-Zugangsdaten
|
||||
onboarding-connect_tracker-connection_status-connected = Mit WLAN verbunden
|
||||
onboarding-connect_tracker-connection_status-error = Kann nicht mit WLAN verbinden
|
||||
onboarding-connect_tracker-connection_status-start_connecting = Suche nach Trackern
|
||||
onboarding-connect_tracker-connection_status-handshake = Mit dem Server verbunden
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
# More info on https://www.unicode.org/cldr/cldr-aux/charts/22/supplemental/language_plural_rules.html
|
||||
# English in this case only has 2 plural rules, which are "one" and "other",
|
||||
# we use 0 in an explicit way because there is no plural rule in english for 0, so we directly say
|
||||
# if $amount is 0 then we say "No trackers connected"
|
||||
onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
[0] Kein Tracker
|
||||
[one] 1 Tracker
|
||||
*[other] { $amount } Tracker
|
||||
} verbunden
|
||||
onboarding-connect_tracker-next = Ich habe alle meine Tracker verbunden.
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Zurück zu den WLAN-Zugangsdaten
|
||||
onboarding-assign_trackers-title = Tracker zuweisen
|
||||
onboarding-assign_trackers-description = Wählen Sie nun aus, welcher Tracker wo befestigt ist. Klicken Sie auf einen Ort, an dem der Tracker platziert ist.
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
# $assigned (Number) - Trackers that have been assigned a body part
|
||||
# $trackers (Number) - Trackers connected to the server
|
||||
onboarding-assign_trackers-assigned = { $assigned } von { $trackers ->
|
||||
[one] 1 Tracker
|
||||
*[other] { $trackers } Tracker
|
||||
} zugewiesen
|
||||
onboarding-assign_trackers-advanced = Erweiterte Zuweisungspositionen anzeigen
|
||||
onboarding-assign_trackers-next = Ich habe alle Tracker zugewiesen
|
||||
|
||||
## Tracker manual mounting setup
|
||||
onboarding-manual_mounting-back = Zurück zum Eintritt in VR
|
||||
onboarding-manual_mounting = Manuelle Definition der Befestigungsposition
|
||||
onboarding-manual_mounting-description = Klicken Sie auf jeden Tracker und wählen Sie aus, in welche Richtung diese montiert sind
|
||||
onboarding-manual_mounting-auto_mounting = Drehung automatisch ermitteln
|
||||
onboarding-manual_mounting-next = Nächster Schritt
|
||||
|
||||
## Tracker automatic mounting setup
|
||||
onboarding-automatic_mounting-back = Zurück zum Eintritt in VR
|
||||
onboarding-automatic_mounting-title = Kalibrierung der Tracker-Befestigung/Rotation
|
||||
onboarding-automatic_mounting-description = Damit die SlimeVR-Tracker korrekt funktionieren, müssen wir ihnen eine Drehung zuweisen, welche der Drehung entspricht wie diese befestigt sind.
|
||||
onboarding-automatic_mounting-manual_mounting = Drehung manuell einstellen
|
||||
onboarding-automatic_mounting-next = Nächster Schritt
|
||||
onboarding-automatic_mounting-prev_step = Vorheriger Schritt
|
||||
onboarding-automatic_mounting-done-title = Tracker Rotation kalibriert.
|
||||
onboarding-automatic_mounting-done-description = Ihre Rotations-Kalibrierung ist abgeschlossen!
|
||||
onboarding-automatic_mounting-done-restart = Zurück zum Start
|
||||
onboarding-automatic_mounting-mounting_reset-title = Drehungs-Reset
|
||||
onboarding-automatic_mounting-mounting_reset-step-0 = 1. Beugen Sie sich in die "Skifahren"-Pose mit gebeugten Beinen, geneigtem Oberkörper und gebeugten Armen.
|
||||
onboarding-automatic_mounting-mounting_reset-step-1 = 2. Drücken Sie die Schaltfläche "Befestigungs-Reset" und warten Sie 3 Sekunden, bevor die Drehungen der Tracker gesetzt werden.
|
||||
onboarding-automatic_mounting-preparation-title = Vorbereitung
|
||||
onboarding-automatic_mounting-preparation-step-0 = 1. Stehen Sie aufrecht mit Ihren Armen an den Seiten.
|
||||
onboarding-automatic_mounting-preparation-step-1 = 2. Drücken Sie die Schaltfläche "Reset" und warten Sie 3 Sekunden, bevor die Tracker zurückgesetzt werden.
|
||||
onboarding-automatic_mounting-put_trackers_on-title = Legen Sie Ihre Tracker an
|
||||
onboarding-automatic_mounting-put_trackers_on-description = Um die Drehung der Tracker zu kalibrieren, werden die Tracker verwendet, welche Sie gerade zugewiesen haben. Ziehen Sie alle Ihre Tracker an, in der Abbildung rechts können sie sehen um welchen Tracker es sich handelt.
|
||||
onboarding-automatic_mounting-put_trackers_on-next = Ich habe alle meine Tracker angelegt
|
||||
|
||||
## Tracker manual proportions setup
|
||||
onboarding-manual_proportions-back = Gehen Sie zurück zum Reset-Tutorial
|
||||
onboarding-manual_proportions-title = Manuelle Körperproportionen
|
||||
onboarding-manual_proportions-precision = Feinanpassung
|
||||
onboarding-manual_proportions-auto = Automatische Kalibrierung
|
||||
|
||||
## Tracker automatic proportions setup
|
||||
onboarding-automatic_proportions-back = Gehen Sie zurück zum Reset-Tutorial
|
||||
onboarding-automatic_proportions-title = Messen Sie Ihre Proportionen
|
||||
onboarding-automatic_proportions-description = Damit die SlimeVR-Tracker funktionieren, müssen wir Ihre Proportionen kennen. Diese kurze Kalibrierung wird sie für Sie messen.
|
||||
onboarding-automatic_proportions-manual = Manuelle Kalibrierung
|
||||
onboarding-automatic_proportions-prev_step = Vorheriger Schritt
|
||||
onboarding-automatic_proportions-put_trackers_on-title = Legen Sie Ihre Tracker an
|
||||
onboarding-automatic_proportions-put_trackers_on-description = Um Ihre Proportionen zu kalibrieren, werden wir die Tracker verwenden, die Sie gerade zugewiesen haben. Legen Sie alle Ihre Tracker an. Sie können rechts in der Abbildung sehen, welche welche sind.
|
||||
onboarding-automatic_proportions-put_trackers_on-next = Ich habe alle meine Tracker angelegt
|
||||
onboarding-automatic_proportions-preparation-title = Vorbereitung
|
||||
onboarding-automatic_proportions-preparation-description = Stellen Sie einen Stuhl direkt hinter Ihnen in Ihrem Spielbereich. Seien Sie bereit, während der Autobone-Einrichtung zu sitzen.
|
||||
onboarding-automatic_proportions-preparation-next = Ich stehe vor einem Stuhl
|
||||
onboarding-automatic_proportions-start_recording-title = Bereiten Sie sich auf ein paar Bewegungen vor
|
||||
onboarding-automatic_proportions-start_recording-description = Wir werden nun einige bestimmte Posen und Bewegungen aufnehmen. Diese werden im nächsten Bildschirm angezeigt. Bereiten Sie sicht darauf vor, wenn Sie den Knopf drücken!
|
||||
onboarding-automatic_proportions-start_recording-next = Aufnahme starten
|
||||
onboarding-automatic_proportions-recording-title = Aufnahme
|
||||
onboarding-automatic_proportions-recording-description-p0 = Aufnahme läuft...
|
||||
onboarding-automatic_proportions-recording-description-p1 = Machen Sie die unten beschriebenen Bewegungen:
|
||||
onboarding-automatic_proportions-recording-steps-0 = Beuge ein paar Mal die Knie.
|
||||
onboarding-automatic_proportions-recording-steps-1 = Bitte setzen Sie sich auf den Stuhl und stehen Sie wieder auf.
|
||||
onboarding-automatic_proportions-recording-steps-2 = Drehe den oberen Körper nach links, dann beuge dich nach rechts.
|
||||
onboarding-automatic_proportions-recording-steps-3 = Drehe den oberen Körper nach rechts, dann beuge dich nach links.
|
||||
onboarding-automatic_proportions-recording-steps-4 = Bewege dich, bis die Zeit abgelaufen ist.
|
||||
onboarding-automatic_proportions-recording-processing = Aufnahme wird verarbeitet...
|
||||
# $time (Number) - Seconds left for the automatic calibration recording to finish (max 15)
|
||||
onboarding-automatic_proportions-recording-timer = { $time ->
|
||||
[one] 1 Sekunde verbleibend
|
||||
*[other] { $time } Sekunden verbleibend
|
||||
}
|
||||
onboarding-automatic_proportions-verify_results-title = Ergebnisse überprüfen
|
||||
onboarding-automatic_proportions-verify_results-description = Überprüfe die Ergebnisse unten, sehen sie korrekt aus?
|
||||
onboarding-automatic_proportions-verify_results-results = Aufnahme-Ergebnisse
|
||||
onboarding-automatic_proportions-verify_results-processing = Ergebnis wird bearbeitet
|
||||
onboarding-automatic_proportions-verify_results-redo = Aufnahme wiederholen
|
||||
onboarding-automatic_proportions-verify_results-confirm = Ergebnisse sind korrekt
|
||||
onboarding-automatic_proportions-done-title = Körper gemessen und gespeichert.
|
||||
onboarding-automatic_proportions-done-description = Deine Körperproportionen-Kalibrierung ist abgeschlossen!
|
||||
|
||||
## Home
|
||||
home-no_trackers = Keine Tracker erkannt oder zugewiesen
|
||||
|
||||
@@ -37,7 +37,7 @@ body_part-LEFT_LOWER_LEG = weft wowwe weg
|
||||
body_part-LEFT_FOOT = weft pawb
|
||||
body_part-LEFT_CONTROLLER = weft wontwolew
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = none
|
||||
skeleton_bone-HEAD = hed shyft
|
||||
skeleton_bone-NECK = nyeck wength
|
||||
@@ -58,6 +58,7 @@ skeleton_bone-UPPER_ARM = uppew awm wength
|
||||
skeleton_bone-LOWER_ARM = fowewawm disyance
|
||||
skeleton_bone-CONTROLLER_Y = cyontwowla disance y
|
||||
skeleton_bone-CONTROLLER_Z = cyontwowla disance z
|
||||
skeleton_bone-ELBOW_OFFSET = ewbow awfsewt
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = weset aww pwopowtions~
|
||||
@@ -67,7 +68,7 @@ reset-quick = quick weset
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = nyu sewiaw device detected~!
|
||||
serial_detection-new_device-p1 = entaw youw wifi cwedentiaws~!
|
||||
serial_detection-new_device-p1 = entaw youw wi-fi cwedentiaws~!
|
||||
serial_detection-new_device-p2 = pwease sewect what youw want to do wit it
|
||||
serial_detection-open_wifi = cownnyect to wyfy~
|
||||
serial_detection-open_serial = awpen sewiaw console >w<
|
||||
@@ -86,9 +87,25 @@ navbar-settings = sewtings
|
||||
bvh-start_recording = wecowd bvh
|
||||
bvh-recording = wecowding...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = show owovelay in steawmvr
|
||||
overlay-is_mirrored_label = dispway owovelay as miwwow
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = owovelay
|
||||
widget-overlay-is_visible_label = show owovelay in steawmvr
|
||||
widget-overlay-is_mirrored_label = dispway owovelay as miwwow
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = devwowwewow mode
|
||||
widget-developer_mode-high_contrast = high contwast
|
||||
widget-developer_mode-precise_rotation = pwecise wotation
|
||||
widget-developer_mode-fast_data_feed = fast data feed
|
||||
widget-developer_mode-filter_slimes_and_hmd = fiwtew swimes a-and HMD
|
||||
widget-developer_mode-sort_by_name = sowt by nyame
|
||||
widget-developer_mode-raw_slime_rotation = waw wotation
|
||||
widget-developer_mode-more_info = mowe info
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = wotation
|
||||
widget-imu_visualizer-rotation_raw = waw
|
||||
widget-imu_visualizer-rotation_preview = pwewiew
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = no stawtus
|
||||
@@ -103,6 +120,9 @@ tracker-table-column-name = nayme
|
||||
tracker-table-column-type = type
|
||||
tracker-table-column-battery = battewy
|
||||
tracker-table-column-ping = pyng
|
||||
tracker-table-column-tps = tps
|
||||
tracker-table-column-temperature = temp. °C
|
||||
tracker-table-column-linear-acceleration = accew. X/Y/Z
|
||||
tracker-table-column-rotation = wotaytion x/y/z
|
||||
tracker-table-column-position = pawsytion x/y/z
|
||||
tracker-table-column-url = uawl
|
||||
@@ -151,7 +171,7 @@ body_assignment_menu-unassign_tracker = unassyign twayckaw
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Which tracker to assign to your
|
||||
@@ -207,12 +227,12 @@ settings-general-steamvr-subtitle = steamvr twayckaws~
|
||||
settings-general-steamvr-description =
|
||||
enyable or dysabywe specific twacking pawts.
|
||||
usefuw if yew want mowwe contwoww owew what swimevr does.
|
||||
settings-general-steamvr-trackers-waist = wyayst
|
||||
settings-general-steamvr-trackers-chest = chwest
|
||||
settings-general-steamvr-trackers-feet = pawbsies~
|
||||
settings-general-steamvr-trackers-waist = wyayst~
|
||||
settings-general-steamvr-trackers-chest = chwest~
|
||||
settings-general-steamvr-trackers-feet = pweets~
|
||||
settings-general-steamvr-trackers-knees = knyees~
|
||||
settings-general-steamvr-trackers-elbows = ewbows~
|
||||
settings-general-steamvr-trackers-hands = Hands
|
||||
settings-general-steamvr-trackers-hands = pawbsies~
|
||||
|
||||
## Tracker mechanics
|
||||
settings-general-tracker_mechanics = twayckaw mechanics~
|
||||
@@ -242,27 +262,28 @@ settings-general-tracker_mechanics-drift_compensation-max_resets-label = nuwmbew
|
||||
settings-general-fk_settings = fk sewttings
|
||||
settings-general-fk_settings-leg_tweak = leg tweeks
|
||||
settings-general-fk_settings-leg_tweak-description = floo-cwip can wowduce owow even ewiminates cwipping with teh fwoor but may cause pwobweems when on yowur neeys. skayting-cowwection cowwects fow wowce skating, but can wowcyancy accuwowacy in cewtain wowvement wowttewns.
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = fwoow cwip
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
settings-general-fk_settings-leg_tweak-skating_correction = skayting wowcowwection
|
||||
settings-general-fk_settings-leg_tweak-skating_correction-amount = Skating correction strength
|
||||
settings-general-fk_settings-leg_tweak-skating_correction-amount = skawting cowwection stwength
|
||||
settings-general-fk_settings-arm_fk = awm fk
|
||||
settings-general-fk_settings-arm_fk-description = chawnge teh way teh awms awe twacked.
|
||||
settings-general-fk_settings-arm_fk-force_arms = fowce awms fwom hmd
|
||||
settings-general-fk_settings-arm_fk-i_pose = uwse i powse insted of t powse
|
||||
settings-general-fk_settings-skeleton_settings = skeweton sewttings
|
||||
settings-general-fk_settings-skeleton_settings-description = toggwe skeweton sewttings on owow off. is wowcommended to weawve these on~
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = ewtended spine
|
||||
settings-general-fk_settings-skeleton_settings-extended_pelvis = ewtended pelvis
|
||||
settings-general-fk_settings-skeleton_settings-extended_knees = ewtended neey
|
||||
settings-general-fk_settings-vive_emulation-title = Vive emulation
|
||||
settings-general-fk_settings-vive_emulation-description = Emulate the waist tracker problems that Vive trackers have. This is a joke and makes tracking worse.
|
||||
settings-general-fk_settings-vive_emulation-label = Enable Vive emulation
|
||||
settings-general-fk_settings-vive_emulation-title = vive emuwation
|
||||
settings-general-fk_settings-vive_emulation-description = emuwate the waist twackew pwobwems that vive twackews hawe. tis is a jowke and mawkes twacking wowse eheh ^^
|
||||
settings-general-fk_settings-vive_emulation-label = enabwe vive emuwation
|
||||
|
||||
## Gesture control settings (tracker tapping)
|
||||
settings-general-gesture_control = gestauw cantwol
|
||||
@@ -312,7 +333,7 @@ settings-serial-auto_dropdown_item = awto
|
||||
## OSC router settings
|
||||
settings-osc-router = OSC wouwter
|
||||
# This cares about multilines
|
||||
settings-osc-router-description =
|
||||
settings-osc-router-description =
|
||||
fowwawd osc messages fwom anothew pwogwam
|
||||
usefuww fow uwsing anothew osc pwogwam with VRChat fow exampwe
|
||||
settings-osc-router-enable = enaybwe
|
||||
@@ -351,36 +372,36 @@ settings-osc-vrchat-network-port_out =
|
||||
.label = pawt out
|
||||
.placeholder = pawt out (defawwt: 9000)
|
||||
settings-osc-vrchat-network-address = network addwess
|
||||
settings-osc-vrchat-network-address-description = choose which addwess to send out data to vwchat (check yuw wifi settwings on yuw device)
|
||||
settings-osc-vrchat-network-address-description = choose which addwess to send out data to vwchat (check yuw wi-fi settwings on yuw device)
|
||||
settings-osc-vrchat-network-address-placeholder = vwchat ip addwess
|
||||
settings-osc-vrchat-network-trackers = trayckawws
|
||||
settings-osc-vrchat-network-trackers-description = toggle teh sending of spweciwic twackers viwa OSC
|
||||
settings-osc-vrchat-network-trackers-chest = chest
|
||||
settings-osc-vrchat-network-trackers-waist = wayst
|
||||
settings-osc-vrchat-network-trackers-knees = knees
|
||||
settings-osc-vrchat-network-trackers-feet = pawbs
|
||||
settings-osc-vrchat-network-trackers-elbows = elbows
|
||||
settings-osc-vrchat-network-trackers-chest = chwest~
|
||||
settings-osc-vrchat-network-trackers-waist = wyayst~
|
||||
settings-osc-vrchat-network-trackers-knees = knyees~
|
||||
settings-osc-vrchat-network-trackers-feet = pweets~
|
||||
settings-osc-vrchat-network-trackers-elbows = ewbows~
|
||||
|
||||
## Setup/onboarding menu
|
||||
onboarding-skip = skipy setup
|
||||
onboarding-continue = continyue
|
||||
onboarding-wip = wowwk in pwowgress
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = gaww bawwk to intwoduction
|
||||
onboarding-wifi_creds = input wifi cwedentials
|
||||
onboarding-wifi_creds = input wi-fi cwedentials
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
teh twawckaws will use these cwedentials to connect wirelessly
|
||||
pwease use teh cwedentials that yaww awe cwowently cownyected to
|
||||
onboarding-wifi_creds-skip = skipy wifi settiwyngs
|
||||
onboarding-wifi_creds-skip = skipy wi-fi settiwyngs
|
||||
onboarding-wifi_creds-submit = suwbmyt!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
.placeholder = Enter SSID
|
||||
.label = wi-fi nawme
|
||||
.placeholder = entew wi-fi nawme
|
||||
onboarding-wifi_creds-password =
|
||||
.label = Password
|
||||
.placeholder = Enter password
|
||||
.label = passwowod
|
||||
.placeholder = entew passwowod
|
||||
|
||||
## Mounting setup
|
||||
onboarding-reset_tutorial-back = gaww bawwk to meownting cawwibwation
|
||||
@@ -407,15 +428,15 @@ onboarding-done-description = enjoy yoaww fuww body expewwience
|
||||
onboarding-done-close = cwose the guide
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = gaww bawwk to wifi cwedentials
|
||||
onboarding-connect_tracker-back = gaww bawwk to wi-fi cwedentials
|
||||
onboarding-connect_tracker-title = connect twackaws
|
||||
onboarding-connect_tracker-description-p0 = now onto teh fun pawwt, connecting awe teh twackaws!
|
||||
onboarding-connect_tracker-description-p1 = simply connect awe that awe nawt cownyected yet, through a usb powwt.
|
||||
onboarding-connect_tracker-issue-serial = i'm having twouble connecting!
|
||||
onboarding-connect_tracker-usb = usb twacker
|
||||
onboarding-connect_tracker-connection_status-connecting = sending wifi cwedentials
|
||||
onboarding-connect_tracker-connection_status-connected = cownyected to wifi
|
||||
onboarding-connect_tracker-connection_status-error = unabwe to cownyect to wifi
|
||||
onboarding-connect_tracker-connection_status-connecting = sending wi-fi cwedentials
|
||||
onboarding-connect_tracker-connection_status-connected = cownyected to wi-fi
|
||||
onboarding-connect_tracker-connection_status-error = unabwe to cownyect to wi-fi
|
||||
onboarding-connect_tracker-connection_status-start_connecting = wooking for twackaws
|
||||
onboarding-connect_tracker-connection_status-handshake = cownyected to teh sewvew
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -431,7 +452,7 @@ onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
onboarding-connect_tracker-next = i cownyected awe my twackaws
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = go bak to wifi credyentials
|
||||
onboarding-assign_trackers-back = go bak to wi-fi credyentials
|
||||
onboarding-assign_trackers-title = assign twackaws
|
||||
onboarding-assign_trackers-description = wets choyse which twackaw goes whewe. cwick on a wocation whewe yowo want to payce a twackaw
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
|
||||
@@ -37,7 +37,7 @@ body_part-LEFT_LOWER_LEG = Left ankle
|
||||
body_part-LEFT_FOOT = Left foot
|
||||
body_part-LEFT_CONTROLLER = Left controller
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = None
|
||||
skeleton_bone-HEAD = Head Shift
|
||||
skeleton_bone-NECK = Neck Length
|
||||
@@ -58,6 +58,7 @@ skeleton_bone-UPPER_ARM = Upper Arm Length
|
||||
skeleton_bone-LOWER_ARM = Lower Arm Length
|
||||
skeleton_bone-CONTROLLER_Y = Controller Distance Y
|
||||
skeleton_bone-CONTROLLER_Z = Controller Distance Z
|
||||
skeleton_bone-ELBOW_OFFSET = Elbow Offset
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Reset all proportions
|
||||
@@ -67,9 +68,9 @@ reset-quick = Quick Reset
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = New serial device detected!
|
||||
serial_detection-new_device-p1 = Enter your WiFi credentials!
|
||||
serial_detection-new_device-p1 = Enter your Wi-Fi credentials!
|
||||
serial_detection-new_device-p2 = Please select what you want to do with it
|
||||
serial_detection-open_wifi = Connect to WiFi
|
||||
serial_detection-open_wifi = Connect to Wi-Fi
|
||||
serial_detection-open_serial = Open Serial Console
|
||||
serial_detection-submit = Submit!
|
||||
serial_detection-close = Close
|
||||
@@ -86,9 +87,25 @@ navbar-settings = Settings
|
||||
bvh-start_recording = Record BVH
|
||||
bvh-recording = Recording...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = Show Overlay in SteamVR
|
||||
overlay-is_mirrored_label = Display Overlay as Mirror
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = Overlay
|
||||
widget-overlay-is_visible_label = Show Overlay in SteamVR
|
||||
widget-overlay-is_mirrored_label = Display Overlay as Mirror
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = Developer Mode
|
||||
widget-developer_mode-high_contrast = High contrast
|
||||
widget-developer_mode-precise_rotation = Precise rotation
|
||||
widget-developer_mode-fast_data_feed = Fast data feed
|
||||
widget-developer_mode-filter_slimes_and_hmd = Filter slimes and HMD
|
||||
widget-developer_mode-sort_by_name = Sort by name
|
||||
widget-developer_mode-raw_slime_rotation = Raw rotation
|
||||
widget-developer_mode-more_info = More info
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = Rotation
|
||||
widget-imu_visualizer-rotation_raw = Raw
|
||||
widget-imu_visualizer-rotation_preview = Preview
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = No Status
|
||||
@@ -103,6 +120,9 @@ tracker-table-column-name = Name
|
||||
tracker-table-column-type = Type
|
||||
tracker-table-column-battery = Battery
|
||||
tracker-table-column-ping = Ping
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = Temp. °C
|
||||
tracker-table-column-linear-acceleration = Accel. X/Y/Z
|
||||
tracker-table-column-rotation = Rotation X/Y/Z
|
||||
tracker-table-column-position = Position X/Y/Z
|
||||
tracker-table-column-url = URL
|
||||
@@ -151,7 +171,7 @@ body_assignment_menu-unassign_tracker = Unassign tracker
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Which tracker to assign to your
|
||||
@@ -242,11 +262,11 @@ settings-general-tracker_mechanics-drift_compensation-max_resets-label = Use up
|
||||
settings-general-fk_settings = Tracking settings
|
||||
settings-general-fk_settings-leg_tweak = Leg tweaks
|
||||
settings-general-fk_settings-leg_tweak-description = Floor-clip can Reduce or even eliminates clipping with the floor but may cause problems when on your knees. Skating-correction corrects for ice skating, but can decrease accuracy in certain movement patterns.
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Floor clip
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
@@ -255,6 +275,7 @@ settings-general-fk_settings-leg_tweak-skating_correction-amount = Skating corre
|
||||
settings-general-fk_settings-arm_fk = Arm tracking
|
||||
settings-general-fk_settings-arm_fk-description = Change the way the arms are tracked.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Force arms from HMD
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = Skeleton settings
|
||||
settings-general-fk_settings-skeleton_settings-description = Toggle skeleton settings on or off. It is recommended to leave these on.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Extended spine
|
||||
@@ -351,7 +372,7 @@ settings-osc-vrchat-network-port_out =
|
||||
.label = Port Out
|
||||
.placeholder = Port out (default: 9000)
|
||||
settings-osc-vrchat-network-address = Network address
|
||||
settings-osc-vrchat-network-address-description = Choose which address to send out data to VRChat (check your wifi settings on your device).
|
||||
settings-osc-vrchat-network-address-description = Choose which address to send out data to VRChat (check your Wi-Fi settings on your device).
|
||||
settings-osc-vrchat-network-address-placeholder = VRChat ip address
|
||||
settings-osc-vrchat-network-trackers = Trackers
|
||||
settings-osc-vrchat-network-trackers-description = Toggle the sending of specific trackers via OSC.
|
||||
@@ -366,18 +387,18 @@ onboarding-skip = Skip setup
|
||||
onboarding-continue = Continue
|
||||
onboarding-wip = Work in progress
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = Go Back to introduction
|
||||
onboarding-wifi_creds = Input WiFi credentials
|
||||
onboarding-wifi_creds = Input Wi-Fi credentials
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
The Trackers will use these credentials to connect wirelessly.
|
||||
Please use the credentials that you are currently connected to.
|
||||
onboarding-wifi_creds-skip = Skip wifi settings
|
||||
onboarding-wifi_creds-skip = Skip Wi-Fi settings
|
||||
onboarding-wifi_creds-submit = Submit!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
.placeholder = Enter SSID
|
||||
.label = Wi-Fi name
|
||||
.placeholder = Enter Wi-Fi name
|
||||
onboarding-wifi_creds-password =
|
||||
.label = Password
|
||||
.placeholder = Enter password
|
||||
@@ -407,15 +428,15 @@ onboarding-done-description = Enjoy your full body experience
|
||||
onboarding-done-close = Close the guide
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = Go Back to WiFi credentials
|
||||
onboarding-connect_tracker-back = Go Back to Wi-Fi credentials
|
||||
onboarding-connect_tracker-title = Connect trackers
|
||||
onboarding-connect_tracker-description-p0 = Now onto the fun part, connecting all the trackers!
|
||||
onboarding-connect_tracker-description-p1 = Simply connect all that aren't connected yet, through a USB port.
|
||||
onboarding-connect_tracker-issue-serial = I'm having trouble connecting!
|
||||
onboarding-connect_tracker-usb = USB Tracker
|
||||
onboarding-connect_tracker-connection_status-connecting = Sending wifi credentials
|
||||
onboarding-connect_tracker-connection_status-connected = Connected to WiFi
|
||||
onboarding-connect_tracker-connection_status-error = Unable to connect to Wifi
|
||||
onboarding-connect_tracker-connection_status-connecting = Sending Wi-Fi credentials
|
||||
onboarding-connect_tracker-connection_status-connected = Connected to Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-error = Unable to connect to Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-start_connecting = Looking for trackers
|
||||
onboarding-connect_tracker-connection_status-handshake = Connected to the Server
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -431,7 +452,7 @@ onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
onboarding-connect_tracker-next = I connected all my trackers
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Go Back to Wifi Credentials
|
||||
onboarding-assign_trackers-back = Go Back to Wi-Fi Credentials
|
||||
onboarding-assign_trackers-title = Assign trackers
|
||||
onboarding-assign_trackers-description = Let's choose which tracker goes where. Click on a location where you want to place a tracker
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
|
||||
@@ -37,7 +37,7 @@ body_part-LEFT_LOWER_LEG = Tobillo izquierdo
|
||||
body_part-LEFT_FOOT = Pie izquierdo
|
||||
body_part-LEFT_CONTROLLER = Control izquierdo
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = Nada
|
||||
skeleton_bone-HEAD = Inclinación de cabeza
|
||||
skeleton_bone-NECK = Largo del cuello
|
||||
@@ -58,6 +58,7 @@ skeleton_bone-UPPER_ARM = Largo del brazo superior
|
||||
skeleton_bone-LOWER_ARM = Distancia del antebrazo
|
||||
skeleton_bone-CONTROLLER_Y = Distancia Y del mando
|
||||
skeleton_bone-CONTROLLER_Z = Distancia Z del mando
|
||||
skeleton_bone-ELBOW_OFFSET = Desplazamiento del codo
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Reiniciar todas las proporciones
|
||||
@@ -67,9 +68,9 @@ reset-quick = Reinicio rápido
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = ¡Nuevo dispositivo serial detectado!
|
||||
serial_detection-new_device-p1 = ¡Ingresa tus credenciales del WiFi!
|
||||
serial_detection-new_device-p1 = ¡Ingresa tus credenciales del Wi-Fi!
|
||||
serial_detection-new_device-p2 = Por favor selecciona que quieres hacer con el
|
||||
serial_detection-open_wifi = Conectarse al WiFi
|
||||
serial_detection-open_wifi = Conectarse al Wi-Fi
|
||||
serial_detection-open_serial = Abrir consola serial
|
||||
serial_detection-submit = ¡Enviar!
|
||||
serial_detection-close = Cerrar
|
||||
@@ -86,9 +87,25 @@ navbar-settings = Ajustes
|
||||
bvh-start_recording = Grabar BVH
|
||||
bvh-recording = Grabando...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = Mostrar interfaz en SteamVR
|
||||
overlay-is_mirrored_label = Mostrar interfaz reflejada
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = Overlay
|
||||
widget-overlay-is_visible_label = Mostrar interfaz en SteamVR
|
||||
widget-overlay-is_mirrored_label = Mostrar interfaz reflejada
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = Developer Mode
|
||||
widget-developer_mode-high_contrast = High contrast
|
||||
widget-developer_mode-precise_rotation = Precise rotation
|
||||
widget-developer_mode-fast_data_feed = Fast data feed
|
||||
widget-developer_mode-filter_slimes_and_hmd = Filter slimes and HMD
|
||||
widget-developer_mode-sort_by_name = Sort by name
|
||||
widget-developer_mode-raw_slime_rotation = Raw rotation
|
||||
widget-developer_mode-more_info = More info
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = Rotation
|
||||
widget-imu_visualizer-rotation_raw = Raw
|
||||
widget-imu_visualizer-rotation_preview = Preview
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = Sin estado
|
||||
@@ -103,6 +120,9 @@ tracker-table-column-name = Nombre
|
||||
tracker-table-column-type = Tipo
|
||||
tracker-table-column-battery = Batería
|
||||
tracker-table-column-ping = Latencia
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = Temp. °C
|
||||
tracker-table-column-linear-acceleration = Accel. X/Y/Z
|
||||
tracker-table-column-rotation = Rotación X/Y/Z
|
||||
tracker-table-column-position = Posición X/Y/Z
|
||||
tracker-table-column-url = URL
|
||||
@@ -128,9 +148,9 @@ tracker-settings-assignment_section-edit = Editar asignación
|
||||
tracker-settings-mounting_section = Posición de montura
|
||||
tracker-settings-mounting_section-description = ¿Dónde está montado el sensor?
|
||||
tracker-settings-mounting_section-edit = Editar montura
|
||||
tracker-settings-drift_compensation_section = Allow drift compensation
|
||||
tracker-settings-drift_compensation_section-description = Should this tracker compensate for its drift when drift compensation is enabled?
|
||||
tracker-settings-drift_compensation_section-edit = Allow drift compensation
|
||||
tracker-settings-drift_compensation_section = Permitir compensación de desviación
|
||||
tracker-settings-drift_compensation_section-description = ¿Este sensor deberia compensar la desviación?
|
||||
tracker-settings-drift_compensation_section-edit = Permitir compensación de desviación
|
||||
# The .<name> means it's an attribute and it's related to the top key.
|
||||
# In this case that is the settings for the assignment section.
|
||||
tracker-settings-name_section = Nombre del sensor
|
||||
@@ -151,32 +171,32 @@ body_assignment_menu-unassign_tracker = Desasignar sensor
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Which tracker to assign to your
|
||||
tracker_selection_menu-NONE = Which tracker do you want to be unassigned?
|
||||
tracker_selection_menu-HEAD = { -tracker_selection-part } head?
|
||||
tracker_selection_menu-NECK = { -tracker_selection-part } neck?
|
||||
tracker_selection_menu-RIGHT_SHOULDER = { -tracker_selection-part } right shoulder?
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = { -tracker_selection-part } right upper arm?
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = { -tracker_selection-part } right lower arm?
|
||||
tracker_selection_menu-RIGHT_HAND = { -tracker_selection-part } right hand?
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = { -tracker_selection-part } right thigh?
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = { -tracker_selection-part } right ankle?
|
||||
tracker_selection_menu-RIGHT_FOOT = { -tracker_selection-part } right foot?
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = { -tracker_selection-part } right controller?
|
||||
tracker_selection_menu-CHEST = { -tracker_selection-part } chest?
|
||||
tracker_selection_menu-WAIST = { -tracker_selection-part } waist?
|
||||
tracker_selection_menu-HIP = { -tracker_selection-part } hip?
|
||||
tracker_selection_menu-LEFT_SHOULDER = { -tracker_selection-part } left shoulder?
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = { -tracker_selection-part } left upper arm?
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = { -tracker_selection-part } left lower arm?
|
||||
tracker_selection_menu-LEFT_HAND = { -tracker_selection-part } left hand?
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = { -tracker_selection-part } left thigh?
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = { -tracker_selection-part } left ankle?
|
||||
tracker_selection_menu-LEFT_FOOT = { -tracker_selection-part } left foot?
|
||||
tracker_selection_menu-LEFT_CONTROLLER = { -tracker_selection-part } left controller?
|
||||
-tracker_selection-part = ¿Qué sensor asignar a tu
|
||||
tracker_selection_menu-NONE = ¿Qué sensor quieres que esté sin asignar?
|
||||
tracker_selection_menu-HEAD = { -tracker_selection-part } cabeza?
|
||||
tracker_selection_menu-NECK = { -tracker_selection-part } cuello?
|
||||
tracker_selection_menu-RIGHT_SHOULDER = { -tracker_selection-part } hombro derecho?
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = { -tracker_selection-part } brazo superior derecho?
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = { -tracker_selection-part } antebrazo derecho?
|
||||
tracker_selection_menu-RIGHT_HAND = { -tracker_selection-part } mano derecha?
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = { -tracker_selection-part } muslo derecho?
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = { -tracker_selection-part } tobillo derecho?
|
||||
tracker_selection_menu-RIGHT_FOOT = { -tracker_selection-part } pie derecho?
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = { -tracker_selection-part } mando derecho?
|
||||
tracker_selection_menu-CHEST = { -tracker_selection-part } pecho?
|
||||
tracker_selection_menu-WAIST = { -tracker_selection-part } cintura?
|
||||
tracker_selection_menu-HIP = { -tracker_selection-part } cadera?
|
||||
tracker_selection_menu-LEFT_SHOULDER = { -tracker_selection-part } hombro izquierdo?
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = { -tracker_selection-part } brazo superior izquierdo?
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = { -tracker_selection-part } antebrazo izquierdo?
|
||||
tracker_selection_menu-LEFT_HAND = { -tracker_selection-part } mano izquierda?
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = { -tracker_selection-part } muslo izquierdo?
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = { -tracker_selection-part } tobillo izquiero?
|
||||
tracker_selection_menu-LEFT_FOOT = { -tracker_selection-part } pie izquierdo?
|
||||
tracker_selection_menu-LEFT_CONTROLLER = { -tracker_selection-part } mando izquierdo?
|
||||
|
||||
tracker_selection_menu-unassigned = Sensores sin asignar
|
||||
tracker_selection_menu-assigned = Sensores asignados
|
||||
@@ -229,24 +249,24 @@ settings-general-tracker_mechanics-filtering-type-smoothing-description = Suaviz
|
||||
settings-general-tracker_mechanics-filtering-type-prediction = Predicción
|
||||
settings-general-tracker_mechanics-filtering-type-prediction-description = Reduce la latencia y los movimientos serán más inmediatos, pero puede incrementar la inestabilidad.
|
||||
settings-general-tracker_mechanics-filtering-amount = Cantidad
|
||||
settings-general-tracker_mechanics-drift_compensation = Drift compensation
|
||||
settings-general-tracker_mechanics-drift_compensation = Compensación de desviación
|
||||
# This cares about multilines
|
||||
settings-general-tracker_mechanics-drift_compensation-description =
|
||||
Compensates IMU yaw drift by applying an inverse rotation.
|
||||
Change amount of compensation and up to how many resets are taken into account.
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = Drift compensation
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = Compensation amount
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = Use up to x last resets
|
||||
Compensa la desviación del eje vertical de los sensores aplicando una rotación inversa.
|
||||
Cambia la fuerza de la compensación y hasta cuantos reinicios tomar en cuenta.
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = Compensación de desviación
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = Fuerza de la compensación
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = Utilizar hasta los últimos x reinicios
|
||||
|
||||
## FK/Tracking settings
|
||||
settings-general-fk_settings = Ajustes de sensores
|
||||
settings-general-fk_settings-leg_tweak = Corrección de piernas
|
||||
settings-general-fk_settings-leg_tweak-description = El clip del suelo puede reducir o incluso eliminar el traspaso del piso pero puede causar problemas cuando te arrodilles. Corrección del patinaje corrige el patinaje, pero puede disminuir la precisión de ciertos movimientos.
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Clip del suelo
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
@@ -255,6 +275,7 @@ settings-general-fk_settings-leg_tweak-skating_correction-amount = Agresividad d
|
||||
settings-general-fk_settings-arm_fk = Trackeo de brazos
|
||||
settings-general-fk_settings-arm_fk-description = Cambia cómo el movimiento de los brazos es detectado.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Forzar brazos desde el HMD
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = Ajustes de esqueleto
|
||||
settings-general-fk_settings-skeleton_settings-description = Habilita o deshabilita los ajustes de esqueleto. Es recomendado dejar estos ajustes habilitados.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Extención de columna
|
||||
@@ -271,8 +292,8 @@ settings-general-gesture_control-description = Permite la ejecución de un reini
|
||||
# This is a unit: 3 taps, 2 taps, 1 tap
|
||||
# $amount (Number) - Amount of taps (touches to the tracker's case)
|
||||
settings-general-gesture_control-taps = { $amount ->
|
||||
[one] 1 tap
|
||||
*[other] { $amount } taps
|
||||
[one] 1 toque
|
||||
*[other] { $amount } toques
|
||||
}
|
||||
settings-general-gesture_control-quickResetEnabled = Activar toques para reinicio rápido
|
||||
settings-general-gesture_control-quickResetDelay = Retraso de reinicio rápido
|
||||
@@ -334,7 +355,7 @@ settings-osc-router-network-address-description = Establece la direción a la cu
|
||||
settings-osc-router-network-address-placeholder = Dirección IPv4
|
||||
|
||||
## OSC VRChat settings
|
||||
settings-osc-vrchat = VRChat OSC Trackers
|
||||
settings-osc-vrchat = Sensores OSC de VRChat
|
||||
# This cares about multilines
|
||||
settings-osc-vrchat-description =
|
||||
Cambiar ajustes específicos de VRChat para recibir datos del HMD y enviar
|
||||
@@ -351,7 +372,7 @@ settings-osc-vrchat-network-port_out =
|
||||
.label = Puerto de salida
|
||||
.placeholder = Puerto de salida (por defecto: 9000)
|
||||
settings-osc-vrchat-network-address = Dirección de red
|
||||
settings-osc-vrchat-network-address-description = Establece la dirección donde se enviarán los datos de VRChat (revisa los ajustes de WiFi de tu dispositivo que tenga el juego).
|
||||
settings-osc-vrchat-network-address-description = Establece la dirección donde se enviarán los datos de VRChat (revisa los ajustes de Wi-Fi de tu dispositivo que tenga el juego).
|
||||
settings-osc-vrchat-network-address-placeholder = Dirección IP de VRChat
|
||||
settings-osc-vrchat-network-trackers = Sensores
|
||||
settings-osc-vrchat-network-trackers-description = Habilita el envío de sensores específicos mediante OSC.
|
||||
@@ -366,21 +387,21 @@ onboarding-skip = Saltar configuración
|
||||
onboarding-continue = Continuar
|
||||
onboarding-wip = Trabajo en progreso
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = Volver a la introducción
|
||||
onboarding-wifi_creds = Ingresar credenciales del WiFi
|
||||
onboarding-wifi_creds = Ingresar credenciales del Wi-Fi
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
Los sensores utilizarán estas credenciales para conectarse inalámbricamente.
|
||||
Por favor usa las credenciales del WiFi al cuál estás conectado actualmente.
|
||||
onboarding-wifi_creds-skip = Saltar ajustes de WiFi
|
||||
Los sensores utilizarán estas credenciales para conectarse inalámbricamente.
|
||||
Por favor usa las credenciales del Wi-Fi al cuál estás conectado actualmente.
|
||||
onboarding-wifi_creds-skip = Saltar ajustes de Wi-Fi
|
||||
onboarding-wifi_creds-submit = ¡Enviar!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
.placeholder = Enter SSID
|
||||
.label = Nombre del WiFi
|
||||
.placeholder = Ingresa el nombre del WiFi
|
||||
onboarding-wifi_creds-password =
|
||||
.label = Password
|
||||
.placeholder = Enter password
|
||||
.label = Contraseña
|
||||
.placeholder = Ingresa la contraseña
|
||||
|
||||
## Mounting setup
|
||||
onboarding-reset_tutorial-back = Volver a la calibración de montura
|
||||
@@ -407,15 +428,15 @@ onboarding-done-description = Disfruta moverte en la realidad virtual
|
||||
onboarding-done-close = Cerrar la guía
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = Volver a las credenciales WiFi
|
||||
onboarding-connect_tracker-back = Volver a las credenciales Wi-Fi
|
||||
onboarding-connect_tracker-title = Conecta tus sensores
|
||||
onboarding-connect_tracker-description-p0 = Ahora la parte divertida, ¡Conectar todos tus sensores!
|
||||
onboarding-connect_tracker-description-p1 = Simplemente conecta todos los sensores que aún no están conectados, por medio de un puerto USB.
|
||||
onboarding-connect_tracker-issue-serial = ¡Tengo problemas conectándolos!
|
||||
onboarding-connect_tracker-usb = Sensor USB
|
||||
onboarding-connect_tracker-connection_status-connecting = Enviando credenciales WiFi
|
||||
onboarding-connect_tracker-connection_status-connected = Conectado al WiFi
|
||||
onboarding-connect_tracker-connection_status-error = Incapaz de conectar al WiFi
|
||||
onboarding-connect_tracker-connection_status-connecting = Enviando credenciales Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-connected = Conectado al Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-error = Incapaz de conectar al Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-start_connecting = Buscando sensores
|
||||
onboarding-connect_tracker-connection_status-handshake = Conectado con el servidor
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -424,23 +445,23 @@ onboarding-connect_tracker-connection_status-handshake = Conectado con el servid
|
||||
# we use 0 in an explicit way because there is no plural rule in english for 0, so we directly say
|
||||
# if $amount is 0 then we say "No trackers connected"
|
||||
onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
[0] No trackers
|
||||
[one] 1 tracker
|
||||
*[other] { $amount } trackers
|
||||
} connected
|
||||
[0] No hay sensores conectados
|
||||
[one] 1 sensor conectado
|
||||
*[other] { $amount } sensores conectados
|
||||
}
|
||||
onboarding-connect_tracker-next = He conectado todos mis sensores
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Volver a las credenciales WiFi
|
||||
onboarding-assign_trackers-back = Volver a las credenciales Wi-Fi
|
||||
onboarding-assign_trackers-title = Asignación de sensores
|
||||
onboarding-assign_trackers-description = Debes escoger dónde van los sensores. Has clic en la ubicación donde quieras colocar un sensor
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
# $assigned (Number) - Trackers that have been assigned a body part
|
||||
# $trackers (Number) - Trackers connected to the server
|
||||
onboarding-assign_trackers-assigned = { $assigned } of { $trackers ->
|
||||
[one] 1 tracker
|
||||
*[other] { $trackers } trackers
|
||||
} assigned
|
||||
onboarding-assign_trackers-assigned = { $assigned } de { $trackers ->
|
||||
[one] 1 sensor asignado
|
||||
*[other] { $trackers } sensores asignados
|
||||
}
|
||||
onboarding-assign_trackers-advanced = Mostrar ubicación de asignaciones avanzados.
|
||||
onboarding-assign_trackers-next = He asignado todos los sensores
|
||||
|
||||
@@ -503,8 +524,8 @@ onboarding-automatic_proportions-recording-steps-4 = Menea tu cuerpo hasta que e
|
||||
onboarding-automatic_proportions-recording-processing = Procesando el resultado
|
||||
# $time (Number) - Seconds left for the automatic calibration recording to finish (max 15)
|
||||
onboarding-automatic_proportions-recording-timer = { $time ->
|
||||
[one] 1 second left
|
||||
*[other] { $time } seconds left
|
||||
[one] falta 1 segundo
|
||||
*[other] faltan { $time } segundos
|
||||
}
|
||||
onboarding-automatic_proportions-verify_results-title = Verificando resultados
|
||||
onboarding-automatic_proportions-verify_results-description = Comprueba abajo los resultados, ¿Parecen correctos?
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
### SlimeVR complete GUI translations
|
||||
# Please developers (not translators) don't reuse a key inside another key
|
||||
# or concat text with a translation string in the code, use the appropiate
|
||||
# features like variables and selectors in each appropiate case!
|
||||
# And also comment the string if it's something not easy to translate so you help
|
||||
# or concat text with a translation string in the code, use the appropriate
|
||||
# features like variables and selectors in each appropriate case!
|
||||
# And also comment the string if it's something not easy to translate, so you help
|
||||
# translators on what it means
|
||||
|
||||
## Websocket (server) status
|
||||
@@ -37,7 +37,7 @@ body_part-LEFT_LOWER_LEG = Vasak säär
|
||||
body_part-LEFT_FOOT = Vasak jalg
|
||||
body_part-LEFT_CONTROLLER = Vasak kontroller
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = Mitte midagi
|
||||
skeleton_bone-HEAD = Pea Nihe
|
||||
skeleton_bone-NECK = Kaela Pikkus
|
||||
@@ -58,6 +58,7 @@ skeleton_bone-UPPER_ARM = Õlavarre Pikkus
|
||||
skeleton_bone-LOWER_ARM = Käsivarre Kaugus
|
||||
skeleton_bone-CONTROLLER_Y = Kontrolleri Kaugus Y
|
||||
skeleton_bone-CONTROLLER_Z = Kontrolleri Kaugus Z
|
||||
skeleton_bone-ELBOW_OFFSET = Küünarnuki Nihe
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Lähtesta kõik proportsioonid
|
||||
@@ -67,9 +68,9 @@ reset-quick = Kiir Lähtestamine
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = Uus jadaseade tuvastatud!
|
||||
serial_detection-new_device-p1 = Sisestage enda WiFi andmed!
|
||||
serial_detection-new_device-p1 = Sisestage enda Wi-Fi andmed!
|
||||
serial_detection-new_device-p2 = Palun valige, mida te soovite sellega teha
|
||||
serial_detection-open_wifi = Ühendage WiFi-ga
|
||||
serial_detection-open_wifi = Ühendage Wi-Fi-ga
|
||||
serial_detection-open_serial = Avage Jadakonsool
|
||||
serial_detection-submit = Jätka!
|
||||
serial_detection-close = Sulge
|
||||
@@ -87,15 +88,15 @@ bvh-start_recording = Salvesta BVH
|
||||
bvh-recording = Salvestamine...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = Näita Ülekatet SteamVR-is
|
||||
overlay-is_mirrored_label = Näita Ülekatet Peeglina
|
||||
widget-overlay-is_visible_label = Näita Ülekatet SteamVR-is
|
||||
widget-overlay-is_mirrored_label = Näita Ülekatet Peeglina
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = Staatuseta
|
||||
tracker-status-busy = Hõivatud
|
||||
tracker-status-error = Viga
|
||||
tracker-status-disconnected = Ühendus katkestatud
|
||||
tracker-status-occluded = Jälgija kadunud
|
||||
tracker-status-occluded = Jälgija kadunud
|
||||
tracker-status-ok = OK
|
||||
|
||||
## Tracker status columns
|
||||
@@ -144,14 +145,14 @@ tracker-part_card-unassigned = Määramata
|
||||
## Body assignment menu
|
||||
body_assignment_menu = Kus te soovite, et jälgija oleks?
|
||||
body_assignment_menu-description = Vali asukoht kuhu te soovite, et jälgija määratakse. Alternatiivina saate te hallata kõiki jälgijaid korraga mitte ükshaaval.
|
||||
body_assignment_menu-show_advanced_locations = Kuva täpsem määramise asukoht
|
||||
body_assignment_menu-show_advanced_locations = Kuva täpsem määramise asukoht
|
||||
body_assignment_menu-manage_trackers = Halda kõiki jälgijaid
|
||||
body_assignment_menu-unassign_tracker = Tühista jälgija määramine
|
||||
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Millist jälgijat määrata teie
|
||||
@@ -242,11 +243,11 @@ settings-general-tracker_mechanics-drift_compensation-max_resets-label = Use up
|
||||
settings-general-fk_settings = Jälgija seaded
|
||||
settings-general-fk_settings-leg_tweak = Jälgija näpunäiteid
|
||||
settings-general-fk_settings-leg_tweak-description = Põranda läbimine saab vähendada või isegi elimineerida jalgade positsiooni läbimist põrandaga, võib põhjustada probleeme põlvedega. Libisemise korrigeerimine korregeerib jalgade libisemist liikudes, aga võib vähendada täpsust teatud liikumiste puhul.
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Põranda läbimine
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
@@ -255,6 +256,7 @@ settings-general-fk_settings-leg_tweak-skating_correction-amount = Libisemise ko
|
||||
settings-general-fk_settings-arm_fk = Käe jälgimine
|
||||
settings-general-fk_settings-arm_fk-description = Muuda viisi kuidas käsi jälgitakse.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Sunni käed HMD-st
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = Skeletti seaded
|
||||
settings-general-fk_settings-skeleton_settings-description = Lülita skeletti seaded sisse või välja. Soovitatud on see sisse jätta.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Selgroo laiendamine
|
||||
@@ -267,7 +269,7 @@ settings-general-fk_settings-vive_emulation-label = Luba Vive-i emulatsioon
|
||||
## Gesture control settings (tracker tapping)
|
||||
settings-general-gesture_control = Žesti juhtimine
|
||||
settings-general-gesture_control-subtitle = Puudutusepõhised lähtestused
|
||||
settings-general-gesture_control-description = Lubab lähtestada jälgija puudutades jälgijat. Jälgija kere kõige kõrgemal osal kasutatakse kiireks lähtestamiseks, jälgija vasaku jala kõige kõrgemal osal kasutatakse lähtestamiseks ja jälgija parema jala kõige kõrgemal osal kasutatakse paigalduse lähtestamiseks. Vajutused peavad toimuma 0.6 sekundi jooksul, et need registreeritaks.
|
||||
settings-general-gesture_control-description = Lubab lähtestada jälgija puudutades jälgijat. Jälgija kere kõige kõrgemal osal kasutatakse kiireks lähtestamiseks, jälgija vasaku jala kõige kõrgemal osal kasutatakse lähtestamiseks ja jälgija parema jala kõige kõrgemal osal kasutatakse paigalduse lähtestamiseks. Vajutused peavad toimuma 0.6 sekundi jooksul, et need registreeritaks.
|
||||
# This is a unit: 3 taps, 2 taps, 1 tap
|
||||
# $amount (Number) - Amount of taps (touches to the tracker's case)
|
||||
settings-general-gesture_control-taps = { $amount ->
|
||||
@@ -337,7 +339,7 @@ settings-osc-router-network-address-placeholder = IPV4 aadress
|
||||
settings-osc-vrchat = VRChat OSC Jälgija
|
||||
# This cares about multilines
|
||||
settings-osc-vrchat-description =
|
||||
Muuda VRChat-i spetsiifiliseid seadeid, et saada ja saata HMD andmeid.
|
||||
Muuda VRChat-i spetsiifiliseid seadeid, et saada ja saata HMD andmeid.
|
||||
Jälgijate andmed FBT jaoks (töötab Questi peal ilma arvuti ühenduseta).
|
||||
settings-osc-vrchat-enable = Luba
|
||||
settings-osc-vrchat-enable-description = Lülitage andmete sisestamine sisse/välja.
|
||||
@@ -351,7 +353,7 @@ settings-osc-vrchat-network-port_out =
|
||||
.label = Võrguport välja
|
||||
.placeholder = Võrguport välja (vaikimisi: 9000)
|
||||
settings-osc-vrchat-network-address = Võrgu aadress
|
||||
settings-osc-vrchat-network-address-description = Vali, mis aadressile saata andmeid VRChat-i jaoks (kontrolli enda WiFi seadeid seadmest).
|
||||
settings-osc-vrchat-network-address-description = Vali, mis aadressile saata andmeid VRChat-i jaoks (kontrolli enda Wi-Fi seadeid seadmest).
|
||||
settings-osc-vrchat-network-address-placeholder = VRChat ip aadress
|
||||
settings-osc-vrchat-network-trackers = Jälgia
|
||||
settings-osc-vrchat-network-trackers-description = Lülita sisse/välja teatud jälgijate andmete saatmise OSC kaudu.
|
||||
@@ -366,14 +368,14 @@ onboarding-skip = Jäta seadistamine vahele
|
||||
onboarding-continue = Jätka
|
||||
onboarding-wip = Töö käib
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = Mine tagasi juhistele
|
||||
onboarding-wifi_creds = Sisestage enda WiFi andmed!
|
||||
onboarding-wifi_creds = Sisestage enda Wi-Fi andmed!
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
Jälgijad kasutavad neid andmeid, et ühendada juhtmevabalt.
|
||||
Palun kasutage neid WiFi andmeid, millega te praegu olete ühendatud.
|
||||
onboarding-wifi_creds-skip = Jätke WiFi seaded vahele.
|
||||
Jälgijad kasutavad neid andmeid, et ühendada juhtmevabalt.
|
||||
Palun kasutage neid Wi-Fi andmeid, millega te praegu olete ühendatud.
|
||||
onboarding-wifi_creds-skip = Jätke Wi-Fi seaded vahele.
|
||||
onboarding-wifi_creds-submit = Jätka!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
@@ -407,15 +409,15 @@ onboarding-done-description = Nautige enda kogu keha jälgimis kogemust
|
||||
onboarding-done-close = Sulgege juhend
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = Minge tagasi WiFi andmetesse
|
||||
onboarding-connect_tracker-back = Minge tagasi Wi-Fi andmetesse
|
||||
onboarding-connect_tracker-title = Ühendage jälgijad
|
||||
onboarding-connect_tracker-description-p0 = Nüüd lähme lõbusa osa juurde, ühendame kõik jälgijad-
|
||||
onboarding-connect_tracker-description-p1 = Lihtsalt ühendage kõik jälgijad, mis ei ole ühendatud läbi USB enda arvutisse.
|
||||
onboarding-connect_tracker-issue-serial = Mul on probleeme ühenduse loomisega!
|
||||
onboarding-connect_tracker-usb = USB Jälgija
|
||||
onboarding-connect_tracker-connection_status-connecting = Saadame WiFi andmeid
|
||||
onboarding-connect_tracker-connection_status-connected = Ühendatud WiFi võrguga
|
||||
onboarding-connect_tracker-connection_status-error = WiFi-ga ei saa ühendust luua!
|
||||
onboarding-connect_tracker-connection_status-connecting = Saadame Wi-Fi andmeid
|
||||
onboarding-connect_tracker-connection_status-connected = Ühendatud Wi-Fi võrguga
|
||||
onboarding-connect_tracker-connection_status-error = Wi-Fi-ga ei saa ühendust luua!
|
||||
onboarding-connect_tracker-connection_status-start_connecting = Jälgijate otsimine
|
||||
onboarding-connect_tracker-connection_status-handshake = Ühendatud serveriga
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -431,7 +433,7 @@ onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
onboarding-connect_tracker-next = Olen ühendanud kõik oma jälgijad
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Minge tagasi WiFi andmetesse
|
||||
onboarding-assign_trackers-back = Minge tagasi Wi-Fi andmetesse
|
||||
onboarding-assign_trackers-title = Määrake jälgijad asukoht
|
||||
onboarding-assign_trackers-description = Valime mis jälgijad lähevad kuhu. Vajutage asukohale kuhu te tahate, et jälgija läheks.
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
|
||||
@@ -37,7 +37,7 @@ body_part-LEFT_LOWER_LEG = Cheville gauche
|
||||
body_part-LEFT_FOOT = Pied gauche
|
||||
body_part-LEFT_CONTROLLER = Left controller
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = Aucun
|
||||
skeleton_bone-HEAD = Décalage de la tête
|
||||
skeleton_bone-NECK = Longueur du cou
|
||||
@@ -58,6 +58,7 @@ skeleton_bone-UPPER_ARM = Longueur des bras supérieurs
|
||||
skeleton_bone-LOWER_ARM = Longueur des avant-bras
|
||||
skeleton_bone-CONTROLLER_Y = Distance Y des contrôleurs
|
||||
skeleton_bone-CONTROLLER_Z = Distance Z des contrôleurs
|
||||
skeleton_bone-ELBOW_OFFSET = Écart des coudes
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Réinitialiser toutes les proportions
|
||||
@@ -86,9 +87,25 @@ navbar-settings = Réglages
|
||||
bvh-start_recording = Enregistrer BVH
|
||||
bvh-recording = Enregistrement...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = Superposer le squelette dans SteamVR
|
||||
overlay-is_mirrored_label = Afficher le squelette en tant que miroir
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = Squelette
|
||||
widget-overlay-is_visible_label = Superposer le squelette dans SteamVR
|
||||
widget-overlay-is_mirrored_label = Afficher le squelette en tant que miroir
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = Mode développeur
|
||||
widget-developer_mode-high_contrast = Contraste élevé
|
||||
widget-developer_mode-precise_rotation = Rotation précise
|
||||
widget-developer_mode-fast_data_feed = Flux de données rapide
|
||||
widget-developer_mode-filter_slimes_and_hmd = Filtrer les capteurs SlimeVR et le casque VR
|
||||
widget-developer_mode-sort_by_name = Trier par nom
|
||||
widget-developer_mode-raw_slime_rotation = Rotation brute
|
||||
widget-developer_mode-more_info = Plus d'informations
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = Rotation
|
||||
widget-imu_visualizer-rotation_raw = Brute
|
||||
widget-imu_visualizer-rotation_preview = Aperçu
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = Pas de statut
|
||||
@@ -103,6 +120,9 @@ tracker-table-column-name = Nom
|
||||
tracker-table-column-type = Type
|
||||
tracker-table-column-battery = Batterie
|
||||
tracker-table-column-ping = Ping
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = Temp. °C
|
||||
tracker-table-column-linear-acceleration = Accél. X/Y/Z
|
||||
tracker-table-column-rotation = Rotation X/Y/Z
|
||||
tracker-table-column-position = Position X/Y/Z
|
||||
tracker-table-column-url = URL
|
||||
@@ -151,7 +171,7 @@ body_assignment_menu-unassign_tracker = Désassigner
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Which tracker to assign to your
|
||||
@@ -242,11 +262,11 @@ settings-general-tracker_mechanics-drift_compensation-max_resets-label = Nombre
|
||||
settings-general-fk_settings = Paramètres de la capture
|
||||
settings-general-fk_settings-leg_tweak = Ajustement des jambes
|
||||
settings-general-fk_settings-leg_tweak-description = Le limitage au sol empêche vos pieds de traverser le sol, mais peut causer des problèmes lorsque vous êtes à genoux. La correction du glissement réduit le glissement, mais peut réduire la précision de certains mouvements.
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Limitage au sol
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
@@ -255,6 +275,7 @@ settings-general-fk_settings-leg_tweak-skating_correction-amount = Force de la c
|
||||
settings-general-fk_settings-arm_fk = Capture des bras
|
||||
settings-general-fk_settings-arm_fk-description = Changez la façon dont les bras sont captés.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Forcer les bras en provenance du casque VR
|
||||
settings-general-fk_settings-arm_fk-i_pose = Utiliser la i-pose au lieu de la t-pose
|
||||
settings-general-fk_settings-skeleton_settings = Paramètres du squelette
|
||||
settings-general-fk_settings-skeleton_settings-description = Activez ou désactivez des paramètres avancés de capture.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Colone vertébrale avancée
|
||||
@@ -366,7 +387,7 @@ onboarding-skip = Passer
|
||||
onboarding-continue = Continuer
|
||||
onboarding-wip = Pas encore implémenté
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = Retour à l'introduction
|
||||
onboarding-wifi_creds = Saisir les identifiants Wi-Fi
|
||||
# This cares about multilines
|
||||
@@ -376,11 +397,11 @@ onboarding-wifi_creds-description =
|
||||
onboarding-wifi_creds-skip = Passer la configuration Wi-Fi
|
||||
onboarding-wifi_creds-submit = Valider
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
.placeholder = Enter SSID
|
||||
.label = Nom du Wi-Fi
|
||||
.placeholder = Nom
|
||||
onboarding-wifi_creds-password =
|
||||
.label = Password
|
||||
.placeholder = Enter password
|
||||
.label = Mot de passe du Wi-Fi
|
||||
.placeholder = Mot de passe
|
||||
|
||||
## Mounting setup
|
||||
onboarding-reset_tutorial-back = Retourner à l'alignement des capteurs
|
||||
@@ -490,7 +511,7 @@ onboarding-automatic_proportions-preparation-title = Préparation
|
||||
onboarding-automatic_proportions-preparation-description = Placez une chaise directement derrière vous dans votre espace de jeu.
|
||||
onboarding-automatic_proportions-preparation-next = je suis devant une chaise
|
||||
onboarding-automatic_proportions-start_recording-title = Préparez-vous à bouger
|
||||
onboarding-automatic_proportions-start_recording-description = Nous allons maintenant enregistrer des poses et des mouvements spécifiques.
|
||||
onboarding-automatic_proportions-start_recording-description = Nous allons maintenant enregistrer des poses et des mouvements spécifiques.
|
||||
onboarding-automatic_proportions-start_recording-next = Commencer l'enregistrement
|
||||
onboarding-automatic_proportions-recording-title = Enregistrement
|
||||
onboarding-automatic_proportions-recording-description-p0 = Enregistrement en cours...
|
||||
|
||||
@@ -37,7 +37,7 @@ body_part-LEFT_LOWER_LEG = Caviglia sinistra
|
||||
body_part-LEFT_FOOT = Piede sinistro
|
||||
body_part-LEFT_CONTROLLER = Left controller
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = Non assegnato
|
||||
skeleton_bone-HEAD = Correzione Testa
|
||||
skeleton_bone-NECK = Lunghezza Collo
|
||||
@@ -58,6 +58,7 @@ skeleton_bone-UPPER_ARM = Lunghezza Braccia
|
||||
skeleton_bone-LOWER_ARM = Distanza Avambracci
|
||||
skeleton_bone-CONTROLLER_Y = Distanza Y Controller
|
||||
skeleton_bone-CONTROLLER_Z = Distanza Z Controller
|
||||
skeleton_bone-ELBOW_OFFSET = Correzione Gomito
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Ripristina tutte le proporzioni
|
||||
@@ -67,9 +68,9 @@ reset-quick = Reset veloce
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = Nuovo dispositivo seriale rilevato!
|
||||
serial_detection-new_device-p1 = Inserisci le tue credenziali WiFi!
|
||||
serial_detection-new_device-p1 = Inserisci le tue credenziali Wi-Fi!
|
||||
serial_detection-new_device-p2 = Seleziona come utilizzare il tracker, per piacere
|
||||
serial_detection-open_wifi = Connetti al WiFi
|
||||
serial_detection-open_wifi = Connetti al Wi-Fi
|
||||
serial_detection-open_serial = Apri la Serial Console
|
||||
serial_detection-submit = Conferma!
|
||||
serial_detection-close = Chiudi
|
||||
@@ -86,9 +87,25 @@ navbar-settings = Impostazioni
|
||||
bvh-start_recording = Registra BVH
|
||||
bvh-recording = Registrazione in corso...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = Mostra Overlay in SteamVR
|
||||
overlay-is_mirrored_label = Includi uno specchio nel Overlay
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = Overlay
|
||||
widget-overlay-is_visible_label = Mostra Overlay in SteamVR
|
||||
widget-overlay-is_mirrored_label = Includi uno specchio nel Overlay
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = Developer Mode
|
||||
widget-developer_mode-high_contrast = High contrast
|
||||
widget-developer_mode-precise_rotation = Precise rotation
|
||||
widget-developer_mode-fast_data_feed = Fast data feed
|
||||
widget-developer_mode-filter_slimes_and_hmd = Filter slimes and HMD
|
||||
widget-developer_mode-sort_by_name = Sort by name
|
||||
widget-developer_mode-raw_slime_rotation = Raw rotation
|
||||
widget-developer_mode-more_info = More info
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = Rotation
|
||||
widget-imu_visualizer-rotation_raw = Raw
|
||||
widget-imu_visualizer-rotation_preview = Preview
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = Nessuno Stato
|
||||
@@ -103,6 +120,9 @@ tracker-table-column-name = Nome
|
||||
tracker-table-column-type = Tipologia
|
||||
tracker-table-column-battery = Batteria
|
||||
tracker-table-column-ping = Ping
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = Temp. °C
|
||||
tracker-table-column-linear-acceleration = Accel. X/Y/Z
|
||||
tracker-table-column-rotation = Rotazione X/Y/Z
|
||||
tracker-table-column-position = Rotazione X/Y/Z
|
||||
tracker-table-column-url = URL
|
||||
@@ -151,7 +171,7 @@ body_assignment_menu-unassign_tracker = Rimuovi assegnazione del tracker
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Which tracker to assign to your
|
||||
@@ -242,11 +262,11 @@ settings-general-tracker_mechanics-drift_compensation-max_resets-label = Use up
|
||||
settings-general-fk_settings = Impostazioni FK
|
||||
settings-general-fk_settings-leg_tweak = Impostazioni Gambe
|
||||
settings-general-fk_settings-leg_tweak-description = "Compenetrazione pavimento" può ridurre o anche eliminare completamente la compenetrazione con il pavimento, ma può causare problemi quando in ginocchio. "Correzione pattinaggio" corregge l'effetto che fa sembrare che pattini sul ghiaccio, ma può peggiorare la precisione di certi movimenti.
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Compenetrazione pavimento
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
@@ -255,6 +275,7 @@ settings-general-fk_settings-leg_tweak-skating_correction-amount = Forza fattore
|
||||
settings-general-fk_settings-arm_fk = FK Braccia
|
||||
settings-general-fk_settings-arm_fk-description = Cambia la modalità di tracciamento delle braccia.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Forza il calcolo della posizione delle braccia a utilizzare il HMD
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = Impostazioni scheletro
|
||||
settings-general-fk_settings-skeleton_settings-description = Abilita o disabilita le impostazioni dello scheletro. É raccomandato lasciare queste impostazioni attive.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Estensione colonna vertebrale
|
||||
@@ -351,7 +372,7 @@ settings-osc-vrchat-network-port_out =
|
||||
.label = Porta in uscita
|
||||
.placeholder = Porta in uscita (predefinito: 9000)
|
||||
settings-osc-vrchat-network-address = Indirizzo di rete
|
||||
settings-osc-vrchat-network-address-description = Scegli a quale indirizzo di rete inviare i dati di VRChat (controlla le impostazioni WiFi sul tuo dispositivo)
|
||||
settings-osc-vrchat-network-address-description = Scegli a quale indirizzo di rete inviare i dati di VRChat (controlla le impostazioni Wi-Fi sul tuo dispositivo)
|
||||
settings-osc-vrchat-network-address-placeholder = Indirizzo IP di VRChat
|
||||
settings-osc-vrchat-network-trackers = Tracker
|
||||
settings-osc-vrchat-network-trackers-description = Attiva o disattiva l'invio e la ricezione dei dati
|
||||
@@ -366,14 +387,14 @@ onboarding-skip = Salta la configurazione
|
||||
onboarding-continue = Continua
|
||||
onboarding-wip = Lavori in corso
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = Torna all'introduzione
|
||||
onboarding-wifi_creds = Inserisci credenziali WiFi
|
||||
onboarding-wifi_creds = Inserisci credenziali Wi-Fi
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
I tracker utilizzeranno queste credenziali per connettersi in modalità wireless
|
||||
Si prega di utilizzare le stesse credenziali con cui si è attualmente connessi
|
||||
onboarding-wifi_creds-skip = Salta impostazioni WiFi
|
||||
onboarding-wifi_creds-skip = Salta impostazioni Wi-Fi
|
||||
onboarding-wifi_creds-submit = Conferma!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
@@ -407,15 +428,15 @@ onboarding-done-description = Goditi la tua esperienza di full-body tracking
|
||||
onboarding-done-close = Chiudi la guida
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = Torna alle credenziali WiFi
|
||||
onboarding-connect_tracker-back = Torna alle credenziali Wi-Fi
|
||||
onboarding-connect_tracker-title = Connetti i tracker
|
||||
onboarding-connect_tracker-description-p0 = Ora passiamo alla parte divertente, colleghiamo tutti i tracker!
|
||||
onboarding-connect_tracker-description-p1 = Collega semplicemente tutti i tracker che non sono ancora collegati tramite una porta USB.
|
||||
onboarding-connect_tracker-issue-serial = Ho problemi con la connessione!
|
||||
onboarding-connect_tracker-usb = Tracker USB
|
||||
onboarding-connect_tracker-connection_status-connecting = Invio credenziali WiFi in corso.
|
||||
onboarding-connect_tracker-connection_status-connected = Connesso al WiFi
|
||||
onboarding-connect_tracker-connection_status-error = Impossibile connettersi al WiFi
|
||||
onboarding-connect_tracker-connection_status-connecting = Invio credenziali Wi-Fi in corso.
|
||||
onboarding-connect_tracker-connection_status-connected = Connesso al Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-error = Impossibile connettersi al Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-start_connecting = Ricerca dei tracker in corso
|
||||
onboarding-connect_tracker-connection_status-handshake = Connesso al Server
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -431,7 +452,7 @@ onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
onboarding-connect_tracker-next = Ho collegato tutti i miei tracker
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Torna alle credenziali WiFi
|
||||
onboarding-assign_trackers-back = Torna alle credenziali Wi-Fi
|
||||
onboarding-assign_trackers-title = Assegna i tracker
|
||||
onboarding-assign_trackers-description = Scegliamo quale tracker va dove. Fare clic su una parte del corpo in cui si desidera assegnare un tracker
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
|
||||
@@ -37,18 +37,18 @@ body_part-LEFT_LOWER_LEG = 左足
|
||||
body_part-LEFT_FOOT = 左足先
|
||||
body_part-LEFT_CONTROLLER = 左コントローラ
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = 無し
|
||||
skeleton_bone-HEAD = ヘッドシフト
|
||||
skeleton_bone-NECK = 首長さ
|
||||
skeleton_bone-CHEST = Chest Length
|
||||
skeleton_bone-CHEST_OFFSET = Chest Offset
|
||||
skeleton_bone-WAIST = Waist Length
|
||||
skeleton_bone-HIP = Hip Length
|
||||
skeleton_bone-CHEST = 胸囲
|
||||
skeleton_bone-CHEST_OFFSET = 胸オフセット
|
||||
skeleton_bone-WAIST = ウエスト長さ
|
||||
skeleton_bone-HIP = ヒップ長さ
|
||||
skeleton_bone-HIP_OFFSET = ヒップオフセット
|
||||
skeleton_bone-HIPS_WIDTH = ヒップ幅
|
||||
skeleton_bone-UPPER_LEG = Upper Leg Length
|
||||
skeleton_bone-LOWER_LEG = Lower Leg Length
|
||||
skeleton_bone-UPPER_LEG = 膝長さ
|
||||
skeleton_bone-LOWER_LEG = 足長さ
|
||||
skeleton_bone-FOOT_LENGTH = 足先長さ
|
||||
skeleton_bone-FOOT_SHIFT = 足先シフト
|
||||
skeleton_bone-SKELETON_OFFSET = スケルトンオフセット
|
||||
@@ -58,6 +58,7 @@ skeleton_bone-UPPER_ARM = 上腕長さ
|
||||
skeleton_bone-LOWER_ARM = 前腕長さ
|
||||
skeleton_bone-CONTROLLER_Y = コントローラ距離 Y
|
||||
skeleton_bone-CONTROLLER_Z = コントローラ距離 Z
|
||||
skeleton_bone-ELBOW_OFFSET = 肘オフセット
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = すべてのプロポーションをリセット
|
||||
@@ -67,9 +68,9 @@ reset-quick = クイックリセット
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = 新しいシリアルデバイスを検出しました!
|
||||
serial_detection-new_device-p1 = wifiの認証情報を入力してください!
|
||||
serial_detection-new_device-p1 = Wi-Fiの認証情報を入力してください!
|
||||
serial_detection-new_device-p2 = 何をするか選択してください
|
||||
serial_detection-open_wifi = WiFiに接続
|
||||
serial_detection-open_wifi = Wi-Fiに接続
|
||||
serial_detection-open_serial = シリアルコンソールを開く
|
||||
serial_detection-submit = 実行!
|
||||
serial_detection-close = 閉じる
|
||||
@@ -86,9 +87,25 @@ navbar-settings = 設定
|
||||
bvh-start_recording = BVHレコーディング
|
||||
bvh-recording = レコーディング中...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = SteamVRでオーバーレイを表示する
|
||||
overlay-is_mirrored_label = オーバーレイをミラーとして表示する
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = オーバーレイ設定
|
||||
widget-overlay-is_visible_label = SteamVRでオーバーレイを表示する
|
||||
widget-overlay-is_mirrored_label = オーバーレイをミラーとして表示する
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = 開発者モード
|
||||
widget-developer_mode-high_contrast = ハイ コントラスト
|
||||
widget-developer_mode-precise_rotation = 正確な回転角度を表示
|
||||
widget-developer_mode-fast_data_feed = 高速表示モード
|
||||
widget-developer_mode-filter_slimes_and_hmd = SlimeVRとHMDのみを表示
|
||||
widget-developer_mode-sort_by_name = 表示名順
|
||||
widget-developer_mode-raw_slime_rotation = 元の回転角度
|
||||
widget-developer_mode-more_info = 他情報
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = Rotation
|
||||
widget-imu_visualizer-rotation_raw = Raw
|
||||
widget-imu_visualizer-rotation_preview = プレビュー
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = ステータスなし
|
||||
@@ -101,10 +118,13 @@ tracker-status-ok = 接続中
|
||||
## Tracker status columns
|
||||
tracker-table-column-name = Name
|
||||
tracker-table-column-type = Type
|
||||
tracker-table-column-battery = Battery
|
||||
tracker-table-column-battery = バッテリー
|
||||
tracker-table-column-ping = Ping
|
||||
tracker-table-column-rotation = Rotation X/Y/Z
|
||||
tracker-table-column-position = Position X/Y/Z
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = 温度. °C
|
||||
tracker-table-column-linear-acceleration = 加速度. X/Y/Z
|
||||
tracker-table-column-rotation = 回転 X/Y/Z
|
||||
tracker-table-column-position = 位置 X/Y/Z
|
||||
tracker-table-column-url = URL
|
||||
|
||||
## Tracker rotation
|
||||
@@ -128,9 +148,9 @@ tracker-settings-assignment_section-edit = 割り当ての編集
|
||||
tracker-settings-mounting_section = 装着方向
|
||||
tracker-settings-mounting_section-description = トラッカーをどの方向に装着していますか?
|
||||
tracker-settings-mounting_section-edit = 装着向きの編集
|
||||
tracker-settings-drift_compensation_section = Allow drift compensation
|
||||
tracker-settings-drift_compensation_section-description = Should this tracker compensate for its drift when drift compensation is enabled?
|
||||
tracker-settings-drift_compensation_section-edit = Allow drift compensation
|
||||
tracker-settings-drift_compensation_section = ドリフト補正を行う
|
||||
tracker-settings-drift_compensation_section-description = ドリフト補正が有効になっている場合、このトラッカーはドリフトを補正する必要がありますか?
|
||||
tracker-settings-drift_compensation_section-edit = ドリフト補正を行う
|
||||
# The .<name> means it's an attribute and it's related to the top key.
|
||||
# In this case that is the settings for the assignment section.
|
||||
tracker-settings-name_section = トラッカー名称
|
||||
@@ -151,32 +171,32 @@ body_assignment_menu-unassign_tracker = トラッカーの割り当て解除
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Which tracker to assign to your
|
||||
tracker_selection_menu-NONE = Which tracker do you want to be unassigned?
|
||||
tracker_selection_menu-HEAD = { -tracker_selection-part } head?
|
||||
tracker_selection_menu-NECK = { -tracker_selection-part } neck?
|
||||
tracker_selection_menu-RIGHT_SHOULDER = { -tracker_selection-part } right shoulder?
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = { -tracker_selection-part } right upper arm?
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = { -tracker_selection-part } right lower arm?
|
||||
tracker_selection_menu-RIGHT_HAND = { -tracker_selection-part } right hand?
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = { -tracker_selection-part } right thigh?
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = { -tracker_selection-part } right ankle?
|
||||
tracker_selection_menu-RIGHT_FOOT = { -tracker_selection-part } right foot?
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = { -tracker_selection-part } right controller?
|
||||
tracker_selection_menu-CHEST = { -tracker_selection-part } chest?
|
||||
tracker_selection_menu-WAIST = { -tracker_selection-part } waist?
|
||||
tracker_selection_menu-HIP = { -tracker_selection-part } hip?
|
||||
tracker_selection_menu-LEFT_SHOULDER = { -tracker_selection-part } left shoulder?
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = { -tracker_selection-part } left upper arm?
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = { -tracker_selection-part } left lower arm?
|
||||
tracker_selection_menu-LEFT_HAND = { -tracker_selection-part } left hand?
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = { -tracker_selection-part } left thigh?
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = { -tracker_selection-part } left ankle?
|
||||
tracker_selection_menu-LEFT_FOOT = { -tracker_selection-part } left foot?
|
||||
tracker_selection_menu-LEFT_CONTROLLER = { -tracker_selection-part } left controller?
|
||||
-tracker_selection-part = どのトラッカーを{ $body-part }に割り当てますか?
|
||||
tracker_selection_menu-NONE = どのトラッカーに割り当てないか?
|
||||
tracker_selection_menu-HEAD = { -tracker_selection-part(body-part: "頭") }
|
||||
tracker_selection_menu-NECK = { -tracker_selection-part(body-part: "首") }
|
||||
tracker_selection_menu-RIGHT_SHOULDER = { -tracker_selection-part(body-part: "右肩") }
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = { -tracker_selection-part(body-part: "右上腕") }
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = { -tracker_selection-part(body-part: "右前腕") }
|
||||
tracker_selection_menu-RIGHT_HAND = { -tracker_selection-part(body-part: "右手") }
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = { -tracker_selection-part(body-part: "右太もも") }
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = { -tracker_selection-part(body-part: "右足首") }
|
||||
tracker_selection_menu-RIGHT_FOOT = { -tracker_selection-part(body-part: "右足先") }
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = { -tracker_selection-part(body-part: "右コントローラ") }
|
||||
tracker_selection_menu-CHEST = { -tracker_selection-part(body-part: "胸") }
|
||||
tracker_selection_menu-WAIST = { -tracker_selection-part(body-part: "腰") }
|
||||
tracker_selection_menu-HIP = { -tracker_selection-part(body-part: "ヒップ") }
|
||||
tracker_selection_menu-LEFT_SHOULDER = { -tracker_selection-part(body-part: "左肩") }
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = { -tracker_selection-part(body-part: "左上腕") }
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = { -tracker_selection-part(body-part: "左前腕") }
|
||||
tracker_selection_menu-LEFT_HAND = { -tracker_selection-part(body-part: "左手") }
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = { -tracker_selection-part(body-part: "左太もも") }
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = { -tracker_selection-part(body-part: "左足首") }
|
||||
tracker_selection_menu-LEFT_FOOT = { -tracker_selection-part(body-part: "左足先") }
|
||||
tracker_selection_menu-LEFT_CONTROLLER = { -tracker_selection-part(body-part: "左コントローラ") }
|
||||
|
||||
tracker_selection_menu-unassigned = 未割り当てのトラッカー
|
||||
tracker_selection_menu-assigned = 割り当て済みのトラッカー
|
||||
@@ -191,9 +211,9 @@ settings-sidebar-title = 設定
|
||||
settings-sidebar-general = 一般
|
||||
settings-sidebar-tracker_mechanics = トラッカーメカニズム
|
||||
settings-sidebar-fk_settings = FK設定
|
||||
settings-sidebar-gesture_control = Gesture control
|
||||
settings-sidebar-gesture_control = ジェスチャーコントロール
|
||||
settings-sidebar-interface = インターフェース
|
||||
settings-sidebar-osc_router = OSC router
|
||||
settings-sidebar-osc_router = OSCルーター
|
||||
settings-sidebar-utils = ユーティリティ
|
||||
settings-sidebar-serial = シリアルコンソール
|
||||
|
||||
@@ -212,7 +232,7 @@ settings-general-steamvr-trackers-chest = 胸
|
||||
settings-general-steamvr-trackers-feet = 足
|
||||
settings-general-steamvr-trackers-knees = 膝
|
||||
settings-general-steamvr-trackers-elbows = 肘
|
||||
settings-general-steamvr-trackers-hands = Hands
|
||||
settings-general-steamvr-trackers-hands = 手
|
||||
|
||||
## Tracker mechanics
|
||||
settings-general-tracker_mechanics = トラッカーメカニズム
|
||||
@@ -222,47 +242,48 @@ settings-general-tracker_mechanics-filtering-description =
|
||||
トラッカーのフィルタリングの種類を選択します。
|
||||
Predictionは動きを予測し、Smoothingは動きを滑らかにする。
|
||||
settings-general-tracker_mechanics-filtering-type = フィルタータイプ
|
||||
settings-general-tracker_mechanics-filtering-type-none = No filtering
|
||||
settings-general-tracker_mechanics-filtering-type-none = フィルター無し
|
||||
settings-general-tracker_mechanics-filtering-type-none-description = トラッカーの値をそのまま使用します。フィルタリングは行いません。
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing = Smoothing
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing = スムージング
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing-description = 動きを滑らかにしますが、若干の遅れが発生します
|
||||
settings-general-tracker_mechanics-filtering-type-prediction = Prediction
|
||||
settings-general-tracker_mechanics-filtering-type-prediction = プリディクション
|
||||
settings-general-tracker_mechanics-filtering-type-prediction-description = レイテンシーを減らし、動きをよりキビキビさせますが、ジッターが増加する場合があります。
|
||||
settings-general-tracker_mechanics-filtering-amount = 数値
|
||||
settings-general-tracker_mechanics-drift_compensation = Drift compensation
|
||||
settings-general-tracker_mechanics-drift_compensation = ドリフト補正
|
||||
# This cares about multilines
|
||||
settings-general-tracker_mechanics-drift_compensation-description =
|
||||
Compensates IMU yaw drift by applying an inverse rotation.
|
||||
Change amount of compensation and up to how many resets are taken into account.
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = Drift compensation
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = Compensation amount
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = Use up to x last resets
|
||||
逆回転をかけることで IMU のヨー軸ドリフトを補正します。
|
||||
補正量とリセット回数を変更します。
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = ドリフト補正
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = 補正量
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = 最大リセット回数
|
||||
|
||||
## FK settings
|
||||
settings-general-fk_settings = FK設定
|
||||
settings-general-fk_settings-leg_tweak = 脚の微調整
|
||||
settings-general-fk_settings-leg_tweak-description = フロアクリップは、床とのクリッピングを減らす、あるいはなくすことができますが、膝をついたときに問題が発生する可能性があります。スケーティング補正は足の滑りを補正できますが、特定の動作パターンでは精度が落ちることがあります。
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = フロアクリップ
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
settings-general-fk_settings-leg_tweak-skating_correction = スケーティング補正
|
||||
settings-general-fk_settings-leg_tweak-skating_correction-amount = Skating correction strength
|
||||
settings-general-fk_settings-arm_fk = アームFK
|
||||
settings-general-fk_settings-leg_tweak-skating_correction-amount = スケーティング補正の強さ
|
||||
settings-general-fk_settings-arm_fk = アームトラッキング
|
||||
settings-general-fk_settings-arm_fk-description = 腕の追従方法を変更する。
|
||||
settings-general-fk_settings-arm_fk-force_arms = Force arms from HMD
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = スケルトン設定
|
||||
settings-general-fk_settings-skeleton_settings-description = スケルトン設定のオン/オフを切り替えます。これらはオンのままにしておくことをお勧めします。
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Extended spine
|
||||
settings-general-fk_settings-skeleton_settings-extended_pelvis = Extended pelvis
|
||||
settings-general-fk_settings-skeleton_settings-extended_knees = Extended knee
|
||||
settings-general-fk_settings-vive_emulation-title = Vive emulation
|
||||
settings-general-fk_settings-vive_emulation-description = Emulate the waist tracker problems that Vive trackers have. This is a joke and makes tracking worse.
|
||||
settings-general-fk_settings-vive_emulation-label = Enable Vive emulation
|
||||
settings-general-fk_settings-vive_emulation-title = Viveエミュレーション
|
||||
settings-general-fk_settings-vive_emulation-description = Viveトラッカーが抱える腰トラッカーの問題をエミュレートします。
|
||||
settings-general-fk_settings-vive_emulation-label = Viveエミュレーションの有効化
|
||||
|
||||
## Gesture control settings (tracker tapping)
|
||||
settings-general-gesture_control = ジェスチャーコントロール
|
||||
@@ -272,17 +293,17 @@ settings-general-gesture_control-description = ダブルタップクイックリ
|
||||
# $amount (Number) - Amount of taps (touches to the tracker's case)
|
||||
settings-general-gesture_control-taps = { $amount ->
|
||||
[one] 1 tap
|
||||
*[other] { $amount } taps
|
||||
*[other] { $amount } タップ
|
||||
}
|
||||
settings-general-gesture_control-quickResetEnabled = Enable tap to quick reset
|
||||
settings-general-gesture_control-quickResetDelay = Quick reset delay
|
||||
settings-general-gesture_control-quickResetTaps = Taps for quick reset
|
||||
settings-general-gesture_control-resetEnabled = Enable tap to reset
|
||||
settings-general-gesture_control-resetDelay = Reset delay
|
||||
settings-general-gesture_control-resetTaps = Taps for reset
|
||||
settings-general-gesture_control-mountingResetEnabled = Enable tap to reset mounting
|
||||
settings-general-gesture_control-mountingResetDelay = Mounting reset delay
|
||||
settings-general-gesture_control-mountingResetTaps = Taps for mounting reset
|
||||
settings-general-gesture_control-quickResetEnabled = タップによるクイックリセットを有効にする
|
||||
settings-general-gesture_control-quickResetDelay = クイックリセットディレイ
|
||||
settings-general-gesture_control-quickResetTaps = タップによるクイックリセット
|
||||
settings-general-gesture_control-resetEnabled = タップによるリセットを有効にする
|
||||
settings-general-gesture_control-resetDelay = リセットディレイ
|
||||
settings-general-gesture_control-resetTaps = タップによるリセット
|
||||
settings-general-gesture_control-mountingResetEnabled = タップによるマウントリセットを有効にする
|
||||
settings-general-gesture_control-mountingResetDelay = マウントリセットディレイ
|
||||
settings-general-gesture_control-mountingResetTaps = タップによるマウントリセット
|
||||
|
||||
## Interface settings
|
||||
settings-general-interface = インターフェース
|
||||
@@ -310,31 +331,31 @@ settings-serial-serial_select = シリアルポートを選択
|
||||
settings-serial-auto_dropdown_item = 自動
|
||||
|
||||
## OSC router settings
|
||||
settings-osc-router = OSC router
|
||||
settings-osc-router = OSCルーター
|
||||
# This cares about multilines
|
||||
settings-osc-router-description =
|
||||
Forward OSC messages from another program.
|
||||
Useful for using another OSC program with VRChat for example.
|
||||
settings-osc-router-enable = Enable
|
||||
settings-osc-router-enable-description = Toggle the forwarding of messages.
|
||||
settings-osc-router-enable-label = Enable
|
||||
settings-osc-router-network = Network ports
|
||||
他のプログラムからの OSC メッセージを転送します。
|
||||
例えば、VRChat で他の OSC プログラムを使用する場合に便利です。
|
||||
settings-osc-router-enable = 有効
|
||||
settings-osc-router-enable-description = メッセージの転送を切り替えます。
|
||||
settings-osc-router-enable-label = 有効
|
||||
settings-osc-router-network = ネットワークポート
|
||||
# This cares about multilines
|
||||
settings-osc-router-network-description =
|
||||
Set the ports for listening and sending data.
|
||||
These can be the same as other ports used in the SlimeVR server.
|
||||
データのリスニングと送信のためのポートを設定します。
|
||||
これらはSlimeVRサーバーで使用する他のポートと同じでかまいません。
|
||||
settings-osc-router-network-port_in =
|
||||
.label = Port In
|
||||
.placeholder = Port in (default: 9002)
|
||||
.label = ポートイン
|
||||
.placeholder = ポートイン (デフォルト: 9002)
|
||||
settings-osc-router-network-port_out =
|
||||
.label = Port Out
|
||||
.placeholder = Port out (default: 9000)
|
||||
settings-osc-router-network-address = Network address
|
||||
settings-osc-router-network-address-description = Set the address to send out data at.
|
||||
settings-osc-router-network-address-placeholder = IPV4 address
|
||||
.label = ポートアウト
|
||||
.placeholder = ポートアウト (デフォルト: 9000)
|
||||
settings-osc-router-network-address = ネットワークアドレス
|
||||
settings-osc-router-network-address-description = データを送り出すアドレスを設定します。
|
||||
settings-osc-router-network-address-placeholder = IPV4アドレス
|
||||
|
||||
## OSC VRChat settings
|
||||
settings-osc-vrchat = VRChat OSC Trackers
|
||||
settings-osc-vrchat = VRChat OSCトラッカー
|
||||
# This cares about multilines
|
||||
settings-osc-vrchat-description =
|
||||
HMDのデータを受信して送信するためにVRChat固有の設定を変更する。
|
||||
@@ -351,7 +372,7 @@ settings-osc-vrchat-network-port_out =
|
||||
.label = ポートアウト
|
||||
.placeholder = ポートアウト (デフォルト: 9000)
|
||||
settings-osc-vrchat-network-address = ネットワークアドレス
|
||||
settings-osc-vrchat-network-address-description = VRChatにデータを送信するアドレスを選択してください(デバイスのwifi設定を確認してください)
|
||||
settings-osc-vrchat-network-address-description = VRChatにデータを送信するアドレスを選択してください(デバイスのWi-Fi設定を確認してください)
|
||||
settings-osc-vrchat-network-address-placeholder = VRChatのIPアドレス
|
||||
settings-osc-vrchat-network-trackers = トラッカー
|
||||
settings-osc-vrchat-network-trackers-description = データの送受信を切り替える。
|
||||
@@ -366,18 +387,18 @@ onboarding-skip = 設定をスキップする
|
||||
onboarding-continue = 続ける
|
||||
onboarding-wip = 実行中
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = 戻る
|
||||
onboarding-wifi_creds = WiFiの認証情報の入力
|
||||
onboarding-wifi_creds = Wi-Fi
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
トラッカーはこれらの認証情報を使ってwifiに接続します。
|
||||
トラッカーはこれらの認証情報を使ってWi-Fiに接続します。
|
||||
現在接続している認証情報を使用してください。
|
||||
onboarding-wifi_creds-skip = wifi設定をスキップする
|
||||
onboarding-wifi_creds-skip = Wi-Fi設定をスキップする
|
||||
onboarding-wifi_creds-submit = 実行!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
.placeholder = Enter SSID
|
||||
.label = Wi-Fi名
|
||||
.placeholder = Enter Wi-Fi名
|
||||
onboarding-wifi_creds-password =
|
||||
.label = Password
|
||||
.placeholder = Enter password
|
||||
@@ -388,11 +409,11 @@ onboarding-reset_tutorial = リセットチュートリアル
|
||||
onboarding-reset_tutorial-description = この機能は終了していません。続けるを押してください。
|
||||
|
||||
## Setup start
|
||||
onboarding-home = Welcome to SlimeVR
|
||||
onboarding-home = SlimeVRへようこそ
|
||||
# This cares about multilines and it's centered!!
|
||||
onboarding-home-description =
|
||||
Bringing full-body tracking
|
||||
to everyone
|
||||
フルボディトラッキングを実現する
|
||||
すべての人に!
|
||||
onboarding-home-start = セットアップ開始!
|
||||
|
||||
## Enter VR part of setup
|
||||
@@ -407,15 +428,15 @@ onboarding-done-description = フルトラをお楽しみください
|
||||
onboarding-done-close = ガイドを閉じる
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = WiFi認証に戻る
|
||||
onboarding-connect_tracker-back = Wi-Fi認証に戻る
|
||||
onboarding-connect_tracker-title = 接続中のトラッカー
|
||||
onboarding-connect_tracker-description-p0 = さあ、楽しい部分に移りましょう。すべてのトラッカーを接続します!
|
||||
onboarding-connect_tracker-description-p1 = まだ接続されていないトラッカーたちをUSBポートを通して接続するだけです。
|
||||
onboarding-connect_tracker-issue-serial = 接続に問題があります!
|
||||
onboarding-connect_tracker-usb = USBトラッカー
|
||||
onboarding-connect_tracker-connection_status-connecting = wifiの認証情報を送信中
|
||||
onboarding-connect_tracker-connection_status-connected = WiFiに接続されました
|
||||
onboarding-connect_tracker-connection_status-error = Wifiに接続できません
|
||||
onboarding-connect_tracker-connection_status-connecting = Wi-Fiの認証情報を送信中
|
||||
onboarding-connect_tracker-connection_status-connected = Wi-Fiに接続されました
|
||||
onboarding-connect_tracker-connection_status-error = Wi-Fiに接続できません
|
||||
onboarding-connect_tracker-connection_status-start_connecting = トラッカーを探しています
|
||||
onboarding-connect_tracker-connection_status-handshake = サーバーに接続されました
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -431,7 +452,7 @@ onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
onboarding-connect_tracker-next = すべてのトラッカーを接続しました
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Wifi認証に戻る
|
||||
onboarding-assign_trackers-back = Wi-Fi認証に戻る
|
||||
onboarding-assign_trackers-title = トラッカーを割り当てる
|
||||
onboarding-assign_trackers-description = どのトラッカーをどこに置くか選んでみましょう。トラッカーを配置したい場所をクリックしてください。
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
|
||||
@@ -24,7 +24,7 @@ body_part-RIGHT_HAND = 오른손
|
||||
body_part-RIGHT_UPPER_LEG = 오른쪽 다리 위
|
||||
body_part-RIGHT_LOWER_LEG = 오른쪽 다리 아래
|
||||
body_part-RIGHT_FOOT = 오른발
|
||||
body_part-RIGHT_CONTROLLER = Right controller
|
||||
body_part-RIGHT_CONTROLLER = 오른쪽 컨트롤러
|
||||
body_part-CHEST = 가슴
|
||||
body_part-WAIST = 허리
|
||||
body_part-HIP = 골반
|
||||
@@ -35,29 +35,30 @@ body_part-LEFT_HAND = 왼손
|
||||
body_part-LEFT_UPPER_LEG = 왼쪽 다리 위
|
||||
body_part-LEFT_LOWER_LEG = 왼쪽 다리 아래
|
||||
body_part-LEFT_FOOT = 왼발
|
||||
body_part-LEFT_CONTROLLER = Left controller
|
||||
body_part-LEFT_CONTROLLER = 왼쪽 컨트롤러
|
||||
|
||||
## Skeleton stuff
|
||||
skeleton_bone-NONE = None
|
||||
## Proportions
|
||||
skeleton_bone-NONE = 없음
|
||||
skeleton_bone-HEAD = 머리 밀림
|
||||
skeleton_bone-NECK = 목 길이
|
||||
skeleton_bone-CHEST = Chest Length
|
||||
skeleton_bone-CHEST_OFFSET = Chest Offset
|
||||
skeleton_bone-WAIST = Waist Length
|
||||
skeleton_bone-HIP = Hip Length
|
||||
skeleton_bone-CHEST = 가슴 길이
|
||||
skeleton_bone-CHEST_OFFSET = 가슴 오프셋
|
||||
skeleton_bone-WAIST = 허리 길이
|
||||
skeleton_bone-HIP = 골반 길이
|
||||
skeleton_bone-HIP_OFFSET = 골반 오프셋
|
||||
skeleton_bone-HIPS_WIDTH = 골반 너비
|
||||
skeleton_bone-UPPER_LEG = Upper Leg Length
|
||||
skeleton_bone-LOWER_LEG = Lower Leg Length
|
||||
skeleton_bone-UPPER_LEG = 위쪽 다리 길이
|
||||
skeleton_bone-LOWER_LEG = 아래쪽 다리 길이
|
||||
skeleton_bone-FOOT_LENGTH = 발 크기
|
||||
skeleton_bone-FOOT_SHIFT = 발 밀림
|
||||
skeleton_bone-SKELETON_OFFSET = 골격 오프셋
|
||||
skeleton_bone-SHOULDERS_DISTANCE = 어깨 거리
|
||||
skeleton_bone-SHOULDERS_WIDTH = 어깨 너비
|
||||
skeleton_bone-UPPER_ARM = 위팔 거리
|
||||
skeleton_bone-LOWER_ARM = 전완 길이
|
||||
skeleton_bone-UPPER_ARM = 위쪽 팔 거리
|
||||
skeleton_bone-LOWER_ARM = 아래쪽 팔 길이
|
||||
skeleton_bone-CONTROLLER_Y = 컨트롤러 Y축 거리
|
||||
skeleton_bone-CONTROLLER_Z = 컨트롤러 Z축 거리
|
||||
skeleton_bone-ELBOW_OFFSET = 팔꿈치 오프셋
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = 모든 신체 비율 리셋
|
||||
@@ -67,9 +68,9 @@ reset-quick = 퀵 리셋
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = 새로운 시리얼 디바이스를 찾았어요!
|
||||
serial_detection-new_device-p1 = WiFi 자격 증명을 입력해주세요!
|
||||
serial_detection-new_device-p1 = Wi-Fi 자격 증명을 입력해주세요!
|
||||
serial_detection-new_device-p2 = 원하는 작업을 선택하세요
|
||||
serial_detection-open_wifi = WiFi 연결
|
||||
serial_detection-open_wifi = Wi-Fi 연결
|
||||
serial_detection-open_serial = 시리얼 콘솔 열기
|
||||
serial_detection-submit = 저장!
|
||||
serial_detection-close = 닫기
|
||||
@@ -86,12 +87,28 @@ navbar-settings = 설정
|
||||
bvh-start_recording = BVH 기록
|
||||
bvh-recording = 기록중...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = SteamVR에서 오버레이 표시
|
||||
overlay-is_mirrored_label = 오버레이 반전
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = 오버레이
|
||||
widget-overlay-is_visible_label = SteamVR에서 오버레이 표시
|
||||
widget-overlay-is_mirrored_label = 오버레이 반전
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = 개발자 모드
|
||||
widget-developer_mode-high_contrast = 고대비
|
||||
widget-developer_mode-precise_rotation = 회전 자세히 보기
|
||||
widget-developer_mode-fast_data_feed = 빠른 데이터 피드
|
||||
widget-developer_mode-filter_slimes_and_hmd = 트래커와 VR 헤드셋만 보기
|
||||
widget-developer_mode-sort_by_name = 이름순으로 정렬
|
||||
widget-developer_mode-raw_slime_rotation = 원시 회전값 보기
|
||||
widget-developer_mode-more_info = 더 많은 정보 보기
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = 회전
|
||||
widget-imu_visualizer-rotation_raw = Raw
|
||||
widget-imu_visualizer-rotation_preview = 미리보기
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = No Status
|
||||
tracker-status-none = 알 수 없음
|
||||
tracker-status-busy = 바쁨
|
||||
tracker-status-error = 오류
|
||||
tracker-status-disconnected = 연결되지 않음
|
||||
@@ -103,6 +120,9 @@ tracker-table-column-name = 이름
|
||||
tracker-table-column-type = 타입
|
||||
tracker-table-column-battery = 배터리
|
||||
tracker-table-column-ping = Ping
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = 온도 °C
|
||||
tracker-table-column-linear-acceleration = X/Y/Z 가속도
|
||||
tracker-table-column-rotation = X/Y/Z 회전
|
||||
tracker-table-column-position = X/Y/Z 위치
|
||||
tracker-table-column-url = URL
|
||||
@@ -128,9 +148,9 @@ tracker-settings-assignment_section-edit = 위치 수정
|
||||
tracker-settings-mounting_section = 착용 방향
|
||||
tracker-settings-mounting_section-description = 트래커는 어디에 착용하나요?
|
||||
tracker-settings-mounting_section-edit = 방향 수정
|
||||
tracker-settings-drift_compensation_section = Allow drift compensation
|
||||
tracker-settings-drift_compensation_section-description = Should this tracker compensate for its drift when drift compensation is enabled?
|
||||
tracker-settings-drift_compensation_section-edit = Allow drift compensation
|
||||
tracker-settings-drift_compensation_section = 틀어짐 보정 사용
|
||||
tracker-settings-drift_compensation_section-description = 틀어짐 보정이 켜져 있을 때 이 트래커의 틀어짐을 보정할까요?
|
||||
tracker-settings-drift_compensation_section-edit = 틀어짐 보정 사용
|
||||
# The .<name> means it's an attribute and it's related to the top key.
|
||||
# In this case that is the settings for the assignment section.
|
||||
tracker-settings-name_section = 트래커 이름
|
||||
@@ -151,32 +171,32 @@ body_assignment_menu-unassign_tracker = 할당하지 않기
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Which tracker to assign to your
|
||||
tracker_selection_menu-NONE = Which tracker do you want to be unassigned?
|
||||
tracker_selection_menu-HEAD = { -tracker_selection-part } head?
|
||||
tracker_selection_menu-NECK = { -tracker_selection-part } neck?
|
||||
tracker_selection_menu-RIGHT_SHOULDER = { -tracker_selection-part } right shoulder?
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = { -tracker_selection-part } right upper arm?
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = { -tracker_selection-part } right lower arm?
|
||||
tracker_selection_menu-RIGHT_HAND = { -tracker_selection-part } right hand?
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = { -tracker_selection-part } right thigh?
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = { -tracker_selection-part } right ankle?
|
||||
tracker_selection_menu-RIGHT_FOOT = { -tracker_selection-part } right foot?
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = { -tracker_selection-part } right controller?
|
||||
tracker_selection_menu-CHEST = { -tracker_selection-part } chest?
|
||||
tracker_selection_menu-WAIST = { -tracker_selection-part } waist?
|
||||
tracker_selection_menu-HIP = { -tracker_selection-part } hip?
|
||||
tracker_selection_menu-LEFT_SHOULDER = { -tracker_selection-part } left shoulder?
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = { -tracker_selection-part } left upper arm?
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = { -tracker_selection-part } left lower arm?
|
||||
tracker_selection_menu-LEFT_HAND = { -tracker_selection-part } left hand?
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = { -tracker_selection-part } left thigh?
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = { -tracker_selection-part } left ankle?
|
||||
tracker_selection_menu-LEFT_FOOT = { -tracker_selection-part } left foot?
|
||||
tracker_selection_menu-LEFT_CONTROLLER = { -tracker_selection-part } left controller?
|
||||
-tracker_selection-part = 에 어떤 트래커를 할당할까요?
|
||||
tracker_selection_menu-NONE = 어떤 트래커를 할당 취소할까요?
|
||||
tracker_selection_menu-HEAD = 머리{ -tracker_selection-part }
|
||||
tracker_selection_menu-NECK = 목{ -tracker_selection-part }
|
||||
tracker_selection_menu-RIGHT_SHOULDER = 오른쪽 어께{ -tracker_selection-part }
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = 오른쪽 팔 위{ -tracker_selection-part }
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = 오른쪽 팔 아래{ -tracker_selection-part }
|
||||
tracker_selection_menu-RIGHT_HAND = 오른손{ -tracker_selection-part }
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = 오른쪽 다리 위{ -tracker_selection-part }
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = 오른쪽 다리 아래{ -tracker_selection-part }
|
||||
tracker_selection_menu-RIGHT_FOOT = 오른쪽 발{ -tracker_selection-part }
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = 오른쪽 컨트롤러{ -tracker_selection-part }
|
||||
tracker_selection_menu-CHEST = 가슴{ -tracker_selection-part }
|
||||
tracker_selection_menu-WAIST = 허리{ -tracker_selection-part }
|
||||
tracker_selection_menu-HIP = 골반{ -tracker_selection-part }
|
||||
tracker_selection_menu-LEFT_SHOULDER = 왼쪽 어께{ -tracker_selection-part }
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = 왼쪽 팔 위{ -tracker_selection-part }
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = 왼쪽 팔 아래{ -tracker_selection-part }
|
||||
tracker_selection_menu-LEFT_HAND = 왼손{ -tracker_selection-part }
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = 왼쪽 다리 위{ -tracker_selection-part }
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = 왼쪽 다리 아래{ -tracker_selection-part }
|
||||
tracker_selection_menu-LEFT_FOOT = 왼쪽 발{ -tracker_selection-part }
|
||||
tracker_selection_menu-LEFT_CONTROLLER = 왼쪽 컨트롤러{ -tracker_selection-part }
|
||||
|
||||
tracker_selection_menu-unassigned = 할당되지 않은 트래커
|
||||
tracker_selection_menu-assigned = 할당된 트래커
|
||||
@@ -229,24 +249,24 @@ settings-general-tracker_mechanics-filtering-type-smoothing-description = 움직
|
||||
settings-general-tracker_mechanics-filtering-type-prediction = Prediction
|
||||
settings-general-tracker_mechanics-filtering-type-prediction-description = 대기 시간이 줄어들고 움직임이 더 빨라지지만 지터가 증가할 수 있어요.
|
||||
settings-general-tracker_mechanics-filtering-amount = 강도
|
||||
settings-general-tracker_mechanics-drift_compensation = Drift compensation
|
||||
settings-general-tracker_mechanics-drift_compensation = 틀어짐 보정
|
||||
# This cares about multilines
|
||||
settings-general-tracker_mechanics-drift_compensation-description =
|
||||
Compensates IMU yaw drift by applying an inverse rotation.
|
||||
Change amount of compensation and up to how many resets are taken into account.
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = Drift compensation
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = Compensation amount
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = Use up to x last resets
|
||||
틀어지는 방향의 반대 방향으로 회전해서 IMU yaw 드리프트를 보정할 수 있어요.
|
||||
보정하는 강도와 감지할 최근 리셋 횟수를 설정할 수 있어요.
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = 틀어짐 보정
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = 보정 강도
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = 보정에 사용할 최근 리셋 횟수
|
||||
|
||||
## FK/Tracking settings
|
||||
settings-general-fk_settings = FK 설정
|
||||
settings-general-fk_settings-leg_tweak = 다리 보정
|
||||
settings-general-fk_settings-leg_tweak-description = 플로어 클립은 바닥과의 클리핑을 줄이거나 제거할 수 있지만 무릎을 꿇을 때 문제를 일으킬 수 있어요. 스케이팅 보정은 아이스 스케이팅을 보정하지만, 특정 움직임 패턴에서 정확도를 저하시킬 수 있어요.
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = 플로어 클립
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
@@ -255,14 +275,15 @@ settings-general-fk_settings-leg_tweak-skating_correction-amount = 스케이팅
|
||||
settings-general-fk_settings-arm_fk = 팔 운동학
|
||||
settings-general-fk_settings-arm_fk-description = 팔이 추적되는 방식을 변경할 수 있어요.
|
||||
settings-general-fk_settings-arm_fk-force_arms = 팔을 HMD에서만 받아오기
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = 골격 설정
|
||||
settings-general-fk_settings-skeleton_settings-description = 골격 설정을 설정하거나 해제해요. 이것들은 켜두는 게 좋아요.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = 척추 확장
|
||||
settings-general-fk_settings-skeleton_settings-extended_pelvis = 골반 확장
|
||||
settings-general-fk_settings-skeleton_settings-extended_knees = 무릎 확장
|
||||
settings-general-fk_settings-vive_emulation-title = Vive emulation
|
||||
settings-general-fk_settings-vive_emulation-description = Emulate the waist tracker problems that Vive trackers have. This is a joke and makes tracking worse.
|
||||
settings-general-fk_settings-vive_emulation-label = Enable Vive emulation
|
||||
settings-general-fk_settings-vive_emulation-title = VIVE 에뮬레이션
|
||||
settings-general-fk_settings-vive_emulation-description = 바이브 트래커가 가지고 있는 허리 트래커 문제를 따라해보세요! 사실 이건 장난이고 추적을 더 악화시켜요.
|
||||
settings-general-fk_settings-vive_emulation-label = VIVE 에뮬레이션 활성화
|
||||
|
||||
## Gesture control settings (tracker tapping)
|
||||
settings-general-gesture_control = 제스처 제어
|
||||
@@ -271,18 +292,17 @@ settings-general-gesture_control-description = 활성화하면 가장 높이 있
|
||||
# This is a unit: 3 taps, 2 taps, 1 tap
|
||||
# $amount (Number) - Amount of taps (touches to the tracker's case)
|
||||
settings-general-gesture_control-taps = { $amount ->
|
||||
[one] 1 tap
|
||||
*[other] { $amount } taps
|
||||
*[other] { $amount } 탭
|
||||
}
|
||||
settings-general-gesture_control-quickResetEnabled = Enable tap to quick reset
|
||||
settings-general-gesture_control-quickResetDelay = Quick reset delay
|
||||
settings-general-gesture_control-quickResetTaps = Taps for quick reset
|
||||
settings-general-gesture_control-resetEnabled = Enable tap to reset
|
||||
settings-general-gesture_control-resetDelay = Reset delay
|
||||
settings-general-gesture_control-resetTaps = Taps for reset
|
||||
settings-general-gesture_control-mountingResetEnabled = Enable tap to reset mounting
|
||||
settings-general-gesture_control-mountingResetDelay = Mounting reset delay
|
||||
settings-general-gesture_control-mountingResetTaps = Taps for mounting reset
|
||||
settings-general-gesture_control-quickResetEnabled = 탭해서 퀵 리셋 활성화
|
||||
settings-general-gesture_control-quickResetDelay = 퀵 리셋 딜레이
|
||||
settings-general-gesture_control-quickResetTaps = 탭해서 퀵 리셋
|
||||
settings-general-gesture_control-resetEnabled = 탭해서 리셋 활성화
|
||||
settings-general-gesture_control-resetDelay = 리셋 딜레이
|
||||
settings-general-gesture_control-resetTaps = 탭해서 리셋
|
||||
settings-general-gesture_control-mountingResetEnabled = 탭해서 착용 방향 정렬 활성화
|
||||
settings-general-gesture_control-mountingResetDelay = 착용 방향 정렬 딜레이
|
||||
settings-general-gesture_control-mountingResetTaps = 탭해서 착용 방향 정렬
|
||||
|
||||
## Interface settings
|
||||
settings-general-interface = 인터페이스
|
||||
@@ -366,21 +386,21 @@ onboarding-skip = 설정 건너뛰기
|
||||
onboarding-continue = 계속하기
|
||||
onboarding-wip = 아직 공사 중이에요
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = 처음으로 돌아가기
|
||||
onboarding-wifi_creds = WiFi 자격 증명을 입력하세요
|
||||
onboarding-wifi_creds = Wi-Fi 자격 증명을 입력하세요
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
트래커는 이 자격 증명을 사용하여 무선으로 연결해요
|
||||
지금 연결되어 있는 자격 증명을 사용해주세요
|
||||
onboarding-wifi_creds-skip = WiFi 설정 건너뛰기
|
||||
onboarding-wifi_creds-skip = Wi-Fi 설정 건너뛰기
|
||||
onboarding-wifi_creds-submit = 저장!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
.placeholder = Enter SSID
|
||||
.label = Wi-Fi 이름
|
||||
.placeholder = Wi-Fi 이름을 입력하세요
|
||||
onboarding-wifi_creds-password =
|
||||
.label = Password
|
||||
.placeholder = Enter password
|
||||
.label = 암호
|
||||
.placeholder = 암호를 입력하세요
|
||||
|
||||
## Mounting setup
|
||||
onboarding-reset_tutorial-back = 착용 방향 정렬로 돌아가기
|
||||
@@ -407,15 +427,15 @@ onboarding-done-description = 풀바디 트래킹을 즐기세요!
|
||||
onboarding-done-close = 마법사 닫기
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = WiFi 자격 증명으로 돌아가기
|
||||
onboarding-connect_tracker-back = Wi-Fi 자격 증명으로 돌아가기
|
||||
onboarding-connect_tracker-title = 트래커 연결
|
||||
onboarding-connect_tracker-description-p0 = 이제 모든 트래커를 연결하는 재미있는 부분으로 가봐요!
|
||||
onboarding-connect_tracker-description-p1 = 그냥 모든 트래커를 USB 포트에 연결하기만 하면 돼요
|
||||
onboarding-connect_tracker-issue-serial = 연결하는 데 문제가 생겼어요!
|
||||
onboarding-connect_tracker-usb = USB 트래커
|
||||
onboarding-connect_tracker-connection_status-connecting = WiFi 자격증명 전송 중
|
||||
onboarding-connect_tracker-connection_status-connected = WiFi 연결됨
|
||||
onboarding-connect_tracker-connection_status-error = Wifi에 연결할 수 없음
|
||||
onboarding-connect_tracker-connection_status-connecting = Wi-Fi 자격증명 전송 중
|
||||
onboarding-connect_tracker-connection_status-connected = Wi-Fi 연결됨
|
||||
onboarding-connect_tracker-connection_status-error = Wi-Fi에 연결할 수 없음
|
||||
onboarding-connect_tracker-connection_status-start_connecting = 트래커 찾는 중
|
||||
onboarding-connect_tracker-connection_status-handshake = 서버에 연결됨
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -424,23 +444,19 @@ onboarding-connect_tracker-connection_status-handshake = 서버에 연결됨
|
||||
# we use 0 in an explicit way because there is no plural rule in english for 0, so we directly say
|
||||
# if $amount is 0 then we say "No trackers connected"
|
||||
onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
[0] No trackers
|
||||
[one] 1 tracker
|
||||
*[other] { $amount } trackers
|
||||
} connected
|
||||
[0] 연결된 트래커가 없어요.
|
||||
*[other] 트래커 { $amount }개가 연결되었어요.
|
||||
}
|
||||
onboarding-connect_tracker-next = 모든 트래커를 잘 연결했어요
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = WiFi 자격 증명으로 돌아가기
|
||||
onboarding-assign_trackers-back = Wi-Fi 자격 증명으로 돌아가기
|
||||
onboarding-assign_trackers-title = 트래커 위치 지정
|
||||
onboarding-assign_trackers-description = 이제, 어떤 트래커가 어디에 있는지 선택할 시간이에요. 트래커를 배치할 위치를 클릭해보세요
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
# $assigned (Number) - Trackers that have been assigned a body part
|
||||
# $trackers (Number) - Trackers connected to the server
|
||||
onboarding-assign_trackers-assigned = { $assigned } of { $trackers ->
|
||||
[one] 1 tracker
|
||||
*[other] { $trackers } trackers
|
||||
} assigned
|
||||
onboarding-assign_trackers-assigned = 트래커 { $trackers }개 중 { $assigned }개 연결됨
|
||||
onboarding-assign_trackers-advanced = 고급 할당 위치 보기
|
||||
onboarding-assign_trackers-next = 모든 트래커를 배치했어요
|
||||
|
||||
@@ -503,8 +519,7 @@ onboarding-automatic_proportions-recording-steps-4 = 타이머가 종료될 때
|
||||
onboarding-automatic_proportions-recording-processing = 결과 처리 중
|
||||
# $time (Number) - Seconds left for the automatic calibration recording to finish (max 15)
|
||||
onboarding-automatic_proportions-recording-timer = { $time ->
|
||||
[one] 1 second left
|
||||
*[other] { $time } seconds left
|
||||
*[other] { $time } 초 남음
|
||||
}
|
||||
onboarding-automatic_proportions-verify_results-title = 결과를 확인하세요
|
||||
onboarding-automatic_proportions-verify_results-description = 아래 결과를 한번 보세요, 어때요?
|
||||
|
||||
540
gui/public/i18n/nl/translation.ftl
Normal file
540
gui/public/i18n/nl/translation.ftl
Normal file
@@ -0,0 +1,540 @@
|
||||
### SlimeVR complete GUI translations
|
||||
# Please developers (not translators) don't reuse a key inside another key
|
||||
# or concat text with a translation string in the code, use the appropiate
|
||||
# features like variables and selectors in each appropiate case!
|
||||
# And also comment the string if it's something not easy to translate so you help
|
||||
# translators on what it means
|
||||
|
||||
## Websocket (server) status
|
||||
websocket-connecting = Verbinden met de server
|
||||
websocket-connection_lost = Verbinding met de server verbroken. Opniew verbinding maken...
|
||||
|
||||
## Tips
|
||||
tips-find_tracker = Weet je niet welke tracker welke is? Schud een tracker en het corresponderende item zal worden gemarkeerd.
|
||||
tips-do_not_move_heels = Zorg ervoor dat je hielen tijdens het opnemen niet bewegen!
|
||||
|
||||
## Body parts
|
||||
body_part-NONE = Niet toegewezen
|
||||
body_part-HEAD = Hoofd
|
||||
body_part-NECK = Neck
|
||||
body_part-RIGHT_SHOULDER = Rechterschouder
|
||||
body_part-RIGHT_UPPER_ARM = Rechterbovenarm
|
||||
body_part-RIGHT_LOWER_ARM = Rechteronderarm
|
||||
body_part-RIGHT_HAND = Rechterhand
|
||||
body_part-RIGHT_UPPER_LEG = Rechterdij
|
||||
body_part-RIGHT_LOWER_LEG = Rechterenkel
|
||||
body_part-RIGHT_FOOT = Rechtervoet
|
||||
body_part-RIGHT_CONTROLLER = Rechtercontroller
|
||||
body_part-CHEST = Borst
|
||||
body_part-WAIST = Taille
|
||||
body_part-HIP = Heup
|
||||
body_part-LEFT_SHOULDER = Linkerschouder
|
||||
body_part-LEFT_UPPER_ARM = Linkerbovenarm
|
||||
body_part-LEFT_LOWER_ARM = Linkeronderarm
|
||||
body_part-LEFT_HAND = Linkerhand
|
||||
body_part-LEFT_UPPER_LEG = Linkerdij
|
||||
body_part-LEFT_LOWER_LEG = Linkerenkel
|
||||
body_part-LEFT_FOOT = Linkervoet
|
||||
body_part-LEFT_CONTROLLER = Linkercontroller
|
||||
|
||||
## Proportions
|
||||
skeleton_bone-NONE = Geen
|
||||
skeleton_bone-HEAD = Hoofdverschuiving
|
||||
skeleton_bone-NECK = Necklengte
|
||||
skeleton_bone-CHEST = Borstafstand
|
||||
skeleton_bone-CHEST_OFFSET = Borstoffset
|
||||
skeleton_bone-WAIST = Tailleafstand
|
||||
skeleton_bone-HIP = Heuplengte
|
||||
skeleton_bone-HIP_OFFSET = Heupoffset
|
||||
skeleton_bone-HIPS_WIDTH = Heupbreedte
|
||||
skeleton_bone-UPPER_LEG = Bovenbeenlengte
|
||||
skeleton_bone-LOWER_LEG = Onderbeenlengte
|
||||
skeleton_bone-FOOT_LENGTH = Voetlengte
|
||||
skeleton_bone-FOOT_SHIFT = Voetverschuiving
|
||||
skeleton_bone-SKELETON_OFFSET = Skelettenoffset
|
||||
skeleton_bone-SHOULDERS_DISTANCE = Schoudersafstand
|
||||
skeleton_bone-SHOULDERS_WIDTH = Schouderbreedte
|
||||
skeleton_bone-UPPER_ARM = Bovenarmlengte
|
||||
skeleton_bone-LOWER_ARM = Onderarmlengte
|
||||
skeleton_bone-CONTROLLER_Y = Controllerafstand Y
|
||||
skeleton_bone-CONTROLLER_Z = Controllerafstand Z
|
||||
skeleton_bone-ELBOW_OFFSET = Elleboogoffset
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Alle afmetingen resetten
|
||||
reset-full = Resetten
|
||||
reset-mounting = Bevestiging resetten
|
||||
reset-quick = Snel resetten
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = Nieuw serieel apparaat gedetecteerd!
|
||||
serial_detection-new_device-p1 = Voer je WiFi-inloggegevens in!
|
||||
serial_detection-new_device-p2 = Selecteer wat je wil doen
|
||||
serial_detection-open_wifi = Verbinden met WiFi
|
||||
serial_detection-open_serial = Open serieel console
|
||||
serial_detection-submit = Verzenden!
|
||||
serial_detection-close = Sluiten
|
||||
|
||||
## Navigation bar
|
||||
navbar-home = Startpagina
|
||||
navbar-body_proportions = Lichaams- verhoudingen
|
||||
navbar-trackers_assign = Tracker- toewijzing
|
||||
navbar-mounting = Bevestigings- kalibratie
|
||||
navbar-onboarding = Setupgids
|
||||
navbar-settings = Instellingen
|
||||
|
||||
## Bounding volume hierarchy recording
|
||||
bvh-start_recording = BVH opnemen
|
||||
bvh-recording = Opname bezig...
|
||||
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = Overlay
|
||||
widget-overlay-is_visible_label = Overlay in SteamVR weergeven
|
||||
widget-overlay-is_mirrored_label = Overlay weergeven als spiegel
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = Developer Mode
|
||||
widget-developer_mode-high_contrast = Hoog contrast
|
||||
widget-developer_mode-precise_rotation = Precieze rotatie
|
||||
widget-developer_mode-fast_data_feed = Snelle data feed
|
||||
widget-developer_mode-filter_slimes_and_hmd = Filter slimes en HMD
|
||||
widget-developer_mode-sort_by_name = Op naam sorteren
|
||||
widget-developer_mode-raw_slime_rotation = Ruwe rotatie
|
||||
widget-developer_mode-more_info = Meer informatie
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = Rotatie
|
||||
widget-imu_visualizer-rotation_raw = Rauw
|
||||
widget-imu_visualizer-rotation_preview = Preview
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = Geen status
|
||||
tracker-status-busy = Bezig
|
||||
tracker-status-error = Fout
|
||||
tracker-status-disconnected = Verbinding verbroken
|
||||
tracker-status-occluded = Verborgen
|
||||
tracker-status-ok = OK
|
||||
|
||||
## Tracker status columns
|
||||
tracker-table-column-name = Naam
|
||||
tracker-table-column-type = Type
|
||||
tracker-table-column-battery = Batterij
|
||||
tracker-table-column-ping = Ping
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = Temp. °C
|
||||
tracker-table-column-linear-acceleration = Accel. X/Y/Z
|
||||
tracker-table-column-rotation = Rotatie X/Y/Z
|
||||
tracker-table-column-position = Positie X/Y/Z
|
||||
tracker-table-column-url = URL
|
||||
|
||||
## Tracker rotation
|
||||
tracker-rotation-front = Voorzijde
|
||||
tracker-rotation-left = Links
|
||||
tracker-rotation-right = Rechts
|
||||
tracker-rotation-back = Achterzijde
|
||||
|
||||
## Tracker information
|
||||
tracker-infos-manufacturer = Fabrikant
|
||||
tracker-infos-display_name = Weergavenaam
|
||||
tracker-infos-custom_name = Aangepaste naam
|
||||
tracker-infos-url = Tracker URL
|
||||
|
||||
## Tracker settings
|
||||
tracker-settings-back = Terug naar trackerslijst
|
||||
tracker-settings-title = Trackersinstellingen
|
||||
tracker-settings-assignment_section = Toewijzing
|
||||
tracker-settings-assignment_section-description = Aan welk lichaamsdeel de tracker is toegewezen.
|
||||
tracker-settings-assignment_section-edit = Toewijzing bewerken
|
||||
tracker-settings-mounting_section = Bevestigingsorientatie
|
||||
tracker-settings-mounting_section-description = Hoe is de tracker georiënteerd?
|
||||
tracker-settings-mounting_section-edit = Bevestiging bewerken
|
||||
tracker-settings-drift_compensation_section = Laat drift compensatie toe
|
||||
tracker-settings-drift_compensation_section-description = Moet deze tracker compenseren voor drift wanneer drift compensatie is ingeschakeld?
|
||||
tracker-settings-drift_compensation_section-edit = Laat drift compensatie toe
|
||||
# The .<name> means it's an attribute and it's related to the top key.
|
||||
# In this case that is the settings for the assignment section.
|
||||
tracker-settings-name_section = Trackernaam
|
||||
tracker-settings-name_section-placeholder = NightyBeast's linkerbeen
|
||||
tracker-settings-name_section-description = Geef een schattige bijnaam :)
|
||||
|
||||
## Tracker part card info
|
||||
tracker-part_card-no_name = Geen naam
|
||||
tracker-part_card-unassigned = Niet toegewezen
|
||||
|
||||
## Body assignment menu
|
||||
body_assignment_menu = Waar wil je deze tracker bevestigen?
|
||||
body_assignment_menu-description = Kies een locatie waar je deze tracker wilt toewijzen. Alternatief kun je kiezen om alle trackers tegelijk te beheren in plaats van één voor één.
|
||||
body_assignment_menu-show_advanced_locations = Geavanceerde bevestigingslocaties weergeven
|
||||
body_assignment_menu-manage_trackers = Beheer alle trackers
|
||||
body_assignment_menu-unassign_tracker = Tracker niet toewijzen
|
||||
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Welke tracker wil je toewijzen aan je
|
||||
tracker_selection_menu-NONE = Van welke tracker will je de toewijzing ongedaan maken?
|
||||
tracker_selection_menu-HEAD = { -tracker_selection-part } hoofd?
|
||||
tracker_selection_menu-NECK = { -tracker_selection-part } nek?
|
||||
tracker_selection_menu-RIGHT_SHOULDER = { -tracker_selection-part } rechterschouder?
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = { -tracker_selection-part } rechterbovenarm?
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = { -tracker_selection-part } rechteronderarm?
|
||||
tracker_selection_menu-RIGHT_HAND = { -tracker_selection-part } rechterhand?
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = { -tracker_selection-part } rechterdij?
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = { -tracker_selection-part } rechterenkel?
|
||||
tracker_selection_menu-RIGHT_FOOT = { -tracker_selection-part } rechtervoet?
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = { -tracker_selection-part } rechtercontroller?
|
||||
tracker_selection_menu-CHEST = { -tracker_selection-part } borst?
|
||||
tracker_selection_menu-WAIST = { -tracker_selection-part } taille?
|
||||
tracker_selection_menu-HIP = { -tracker_selection-part } heup?
|
||||
tracker_selection_menu-LEFT_SHOULDER = { -tracker_selection-part } linkerschouder?
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = { -tracker_selection-part } linkerbovenarm?
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = { -tracker_selection-part } linkeronderarm?
|
||||
tracker_selection_menu-LEFT_HAND = { -tracker_selection-part } linkerhand?
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = { -tracker_selection-part } linkerdij?
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = { -tracker_selection-part } linkerenkel?
|
||||
tracker_selection_menu-LEFT_FOOT = { -tracker_selection-part } linkervoet?
|
||||
tracker_selection_menu-LEFT_CONTROLLER = { -tracker_selection-part } linkercontroller?
|
||||
|
||||
tracker_selection_menu-unassigned = Niet toegewezen trackers
|
||||
tracker_selection_menu-assigned = Toegewezen trackers
|
||||
tracker_selection_menu-dont_assign = Niet toewijzen
|
||||
|
||||
## Mounting menu
|
||||
mounting_selection_menu = Waar wil je deze tracker hebben bevestigd?
|
||||
mounting_selection_menu-close = Sluiten
|
||||
|
||||
## Sidebar settings
|
||||
settings-sidebar-title = Instellingen
|
||||
settings-sidebar-general = Algemeen
|
||||
settings-sidebar-tracker_mechanics = Trackersinstellingen
|
||||
settings-sidebar-fk_settings = FK-instellingen
|
||||
settings-sidebar-gesture_control = Tikbediening
|
||||
settings-sidebar-interface = Interface
|
||||
settings-sidebar-osc_router = OSC-router
|
||||
settings-sidebar-utils = Hulpmiddelen
|
||||
settings-sidebar-serial = Serieel console
|
||||
|
||||
## SteamVR settings
|
||||
settings-general-steamvr = SteamVR
|
||||
settings-general-steamvr-subtitle = SteamVR trackers
|
||||
# Not all translation keys support multiline, only the ones that specify it will actually
|
||||
# split it in lines (that also means you can split in lines however you want in those).
|
||||
# The first spaces (not tabs) for indentation will be ignored, just to make the file look nice when writing.
|
||||
# This one is one of this cases that cares about multilines
|
||||
settings-general-steamvr-description =
|
||||
Schakel specifieke SteamVR trackers in of uit.
|
||||
Handig voor games of apps die alleen bepaalde trackers ondersteunen.
|
||||
settings-general-steamvr-trackers-waist = Taille
|
||||
settings-general-steamvr-trackers-chest = Borst
|
||||
settings-general-steamvr-trackers-feet = Voeten
|
||||
settings-general-steamvr-trackers-knees = Knieën
|
||||
settings-general-steamvr-trackers-elbows = Ellebogen
|
||||
settings-general-steamvr-trackers-hands = Handen
|
||||
|
||||
## Tracker mechanics
|
||||
settings-general-tracker_mechanics = Tracker aanpassingen
|
||||
settings-general-tracker_mechanics-filtering = Filtering
|
||||
# This also cares about multilines
|
||||
settings-general-tracker_mechanics-filtering-description =
|
||||
Kies het type filter voor uw trackers.
|
||||
Voorspelling voorspelt beweging terwijl smoothing bewegingen vloeiender maakt.
|
||||
settings-general-tracker_mechanics-filtering-type = Filtering type
|
||||
settings-general-tracker_mechanics-filtering-type-none = Geen filtering
|
||||
settings-general-tracker_mechanics-filtering-type-none-description = Gebruik rotaties zoals ze zijn. Zal geen filtering uitvoeren.
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing = Smoothing
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing-description = Maakt bewegingen vloeiender, maar voegt enige latentie toe.
|
||||
settings-general-tracker_mechanics-filtering-type-prediction = Voorspelling
|
||||
settings-general-tracker_mechanics-filtering-type-prediction-description = Verlaagt latentie en maakt bewegingen snappier, maar kan jitter verhogen.
|
||||
settings-general-tracker_mechanics-filtering-amount = Hoeveelheid
|
||||
settings-general-tracker_mechanics-drift_compensation = Drift compensatie
|
||||
# This cares about multilines
|
||||
settings-general-tracker_mechanics-drift_compensation-description =
|
||||
Compenseert voor IMU yaw drift door de toevoeging van een omgekeerde rotatie.
|
||||
Veranderd de sterkte van de compensatie en hoeveel resets worden gebruikt.
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = Drift compensate
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = Compensatiesterkte
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = Gebruik de laatste x resets
|
||||
|
||||
## FK/Tracking settings
|
||||
settings-general-fk_settings = Tracking instellingen
|
||||
settings-general-fk_settings-leg_tweak = Aanpassingen van tracking gedrag voor benen
|
||||
settings-general-fk_settings-leg_tweak-description = Floor-clip verminderd de kans dat je voeten door de grond gaan, maar kan problemen veroorzaken als je op je knieën bent. Skating-correctie corrigeert ongewenst glijden van je voeten, maar kan de nauwkeurigheid in bepaalde bewegingspatronen verminderen.
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Floor-clip
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
settings-general-fk_settings-leg_tweak-skating_correction = Skating-correctie
|
||||
settings-general-fk_settings-leg_tweak-skating_correction-amount = Skating-correctie sterkte
|
||||
settings-general-fk_settings-arm_fk = Arm tracking
|
||||
settings-general-fk_settings-arm_fk-description = Verander de manier waarop de armen worden getrackt.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Dwing armen vanuit HMD
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = Skeleton instellingen
|
||||
settings-general-fk_settings-skeleton_settings-description = Schakel skeleton instellingen in of uit. Het is aanbevolen om deze aan te laten.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Uitgebreide rug
|
||||
settings-general-fk_settings-skeleton_settings-extended_pelvis = Uitgebreide bekken
|
||||
settings-general-fk_settings-skeleton_settings-extended_knees = Uitgebreide knieën
|
||||
settings-general-fk_settings-vive_emulation-title = Vive-emulatie
|
||||
settings-general-fk_settings-vive_emulation-description = Emuleer de problemen met de taille van Vive trackers. Dit is een mop en maakt tracking slechter.
|
||||
settings-general-fk_settings-vive_emulation-label = Vive-emulatie inschakelen
|
||||
|
||||
## Gesture control settings (tracker tapping)
|
||||
settings-general-gesture_control = Gesture control
|
||||
settings-general-gesture_control-subtitle = Op tik gebaseerde resets
|
||||
settings-general-gesture_control-description = Maakt het mogelijk om resets te activeren door op een tracker te tikken. De tracker het hoogst op je bovenlichaam wordt gebruikt voor Quick Reset, de tracker het hoogst op je linkerbeen voor Reset en de tracker het hoogst op je rechterbeen voor Mounting Reset. Het moet worden vermeld dat tikken binnen 0,6 seconden moeten gebeuren om geregistreerd te worden.
|
||||
# This is a unit: 3 taps, 2 taps, 1 tap
|
||||
# $amount (Number) - Amount of taps (touches to the tracker's case)
|
||||
settings-general-gesture_control-taps = { $amount ->
|
||||
[one] 1 tik
|
||||
*[other] { $amount } tikken
|
||||
}
|
||||
settings-general-gesture_control-quickResetEnabled = Activeer tikken voor snelle reset
|
||||
settings-general-gesture_control-quickResetDelay = Vertraging snelle reset
|
||||
settings-general-gesture_control-quickResetTaps = Hoeveelheid tikken voor snelle reset
|
||||
settings-general-gesture_control-resetEnabled = Activeer tikken voor reset
|
||||
settings-general-gesture_control-resetDelay = Vertraging reset
|
||||
settings-general-gesture_control-resetTaps = Hoeveelheid tikken voor reset
|
||||
settings-general-gesture_control-mountingResetEnabled = Activeer tikken voor bevestigingskalibratie
|
||||
settings-general-gesture_control-mountingResetDelay = Vertraging bevestigingskalibratie
|
||||
settings-general-gesture_control-mountingResetTaps = Hoeveelheid tikken voor bevestigingskalibratie
|
||||
|
||||
## Interface settings
|
||||
settings-general-interface = Interface
|
||||
settings-general-interface-dev_mode = Ontwikkelaarsmodus
|
||||
settings-general-interface-dev_mode-description = Deze modus kan nuttig zijn als u diepgaande gegevens nodig hebt of op een geavanceerd niveau wilt communiceren met aangesloten trackers.
|
||||
settings-general-interface-dev_mode-label = Ontwikkelaarsmodus
|
||||
settings-general-interface-serial_detection = Detectie van seriële apparaten
|
||||
settings-general-interface-serial_detection-description = Met deze optie verschijnt er elke keer dat u een nieuw serieel apparaat aansluit dat mogelijk een tracker is, een pop-up. Dit helpt bij het verbeteren van het instelproces van een tracker.
|
||||
settings-general-interface-serial_detection-label = Detectie van seriële apparaten
|
||||
settings-general-interface-lang = Selecteer taal
|
||||
settings-general-interface-lang-description = Verander de standaardtaal die u wilt gebruiken.
|
||||
settings-general-interface-lang-placeholder = Selecteer de te gebruiken taal
|
||||
|
||||
## Serial settings
|
||||
settings-serial = Seriele console
|
||||
# This cares about multilines
|
||||
settings-serial-description =
|
||||
Dit is een live-informatiefeed voor seriële communicatie.
|
||||
Kan nuttig zijn voor het debuggen van trackers.
|
||||
settings-serial-connection_lost = Verbinding met seriële poort verloren, opnieuw verbinden...
|
||||
settings-serial-reboot = Opnieuw opstarten
|
||||
settings-serial-factory_reset = Fabrieksinstellingen herstellen
|
||||
settings-serial-get_infos = Informatie ophalen
|
||||
settings-serial-serial_select = Selecteer een seriële poort
|
||||
settings-serial-auto_dropdown_item = Automatisch
|
||||
|
||||
## OSC router settings
|
||||
settings-osc-router = OSC-router
|
||||
# This cares about multilines
|
||||
settings-osc-router-description =
|
||||
Stuur OSC-berichten door vanuit een ander programma.
|
||||
Nuttig om bijvoorbeeld een ander OSC-programma te gebruiken met VRChat.
|
||||
settings-osc-router-enable = Inschakelen
|
||||
settings-osc-router-enable-description = Schakel het doorsturen van berichten in of uit.
|
||||
settings-osc-router-enable-label = Inschakelen
|
||||
settings-osc-router-network = Netwerkpoorten
|
||||
# This cares about multilines
|
||||
settings-osc-router-network-description =
|
||||
Stel de poorten in voor het verzenden en ontvangen van gegevens.
|
||||
Dit kunnen dezelfde poorten zijn als andere poorten die worden gebruikt in de SlimeVR-server.
|
||||
settings-osc-router-network-port_in =
|
||||
.label = Poort in
|
||||
.placeholder = Poort in (standaard: 9002)
|
||||
settings-osc-router-network-port_out =
|
||||
.label = Poort uit
|
||||
.placeholder = Poort uit (standaard: 9000)
|
||||
settings-osc-router-network-address = Netwerkadres
|
||||
settings-osc-router-network-address-description = Stel het adres in waarnaar gegevens moeten worden verzonden.
|
||||
settings-osc-router-network-address-placeholder = IPV4-adres
|
||||
|
||||
## OSC VRChat settings
|
||||
settings-osc-vrchat = VRChat OSC Trackers
|
||||
# This cares about multilines
|
||||
settings-osc-vrchat-description =
|
||||
Wijzig VRChat-specifieke instellingen om HMD-data te ontvangen en te verzenden
|
||||
trackergegevens voor FBT (werkt op Quest standalone).
|
||||
settings-osc-vrchat-enable = Inschakelen
|
||||
settings-osc-vrchat-enable-description = Schakel het verzenden en ontvangen van gegevens in en uit.
|
||||
settings-osc-vrchat-enable-label = Inschakelen
|
||||
settings-osc-vrchat-network = Netwerkpoorten
|
||||
settings-osc-vrchat-network-description = Stel de poorten in voor het zenden en ontvangen van OSC-gegevens naar VRChat.
|
||||
settings-osc-vrchat-network-port_in =
|
||||
.label = Poort In
|
||||
.placeholder = Poort in (standaard: 9001)
|
||||
settings-osc-vrchat-network-port_out =
|
||||
.label = Poort Out
|
||||
.placeholder = Poort uit (standaard: 9000)
|
||||
settings-osc-vrchat-network-address = Netwerkadres
|
||||
settings-osc-vrchat-network-address-description = Kies naar welk adres u gegevens naar VRChat wilt verzenden (controleer de wifi-instellingen op je apparaat).
|
||||
settings-osc-vrchat-network-address-placeholder = VRChat IP-adres
|
||||
settings-osc-vrchat-network-trackers = Trackers
|
||||
settings-osc-vrchat-network-trackers-description = Schakel het verzenden van specifieke trackers via OSC in en uit.
|
||||
settings-osc-vrchat-network-trackers-chest = Borst
|
||||
settings-osc-vrchat-network-trackers-waist = Taille
|
||||
settings-osc-vrchat-network-trackers-knees = Knieën
|
||||
settings-osc-vrchat-network-trackers-feet = Voeten
|
||||
settings-osc-vrchat-network-trackers-elbows = Ellebogen
|
||||
|
||||
## Setup/onboarding menu
|
||||
onboarding-skip = Setupgids overslaan
|
||||
onboarding-continue = Doorgaan
|
||||
onboarding-wip = WIP
|
||||
|
||||
## WiFi setup
|
||||
onboarding-wifi_creds-back = Ga terug naar de introductie
|
||||
onboarding-wifi_creds = Voer de WiFi-inloggegevens in
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
Deze gegevens worden gebruikt om de trackers draadloos te verbinden met de server.
|
||||
Gelieve de gegevens te gebruiken van het netwerk waarmee je momenteel bent verbonden.
|
||||
onboarding-wifi_creds-skip = WiFi-instellingen overslaan
|
||||
onboarding-wifi_creds-submit = Verzenden!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = WiFi naam
|
||||
.placeholder = Vul WiFi naam in
|
||||
onboarding-wifi_creds-password =
|
||||
.label = Paswoord
|
||||
.placeholder = Vul paswoord in
|
||||
|
||||
## Mounting setup
|
||||
onboarding-reset_tutorial-back = Ga terug naar de bevestigingskalibratie
|
||||
onboarding-reset_tutorial = Reset tutorial
|
||||
onboarding-reset_tutorial-description = Deze stap is nog niet afgewerkt, druk gewoon op doorgaan.
|
||||
|
||||
## Setup start
|
||||
onboarding-home = Welkom bij SlimeVR
|
||||
# This cares about multilines and it's centered!!
|
||||
onboarding-home-description =
|
||||
Maakt full-body tracking beschikbaar
|
||||
voor iedereen!
|
||||
onboarding-home-start = Laten we beginnen!
|
||||
|
||||
## Enter VR part of setup
|
||||
onboarding-enter_vr-back = Ga terug naar de sectie voor toewijzing van trackers
|
||||
onboarding-enter_vr-title = Tijd om VR in te gaan!
|
||||
onboarding-enter_vr-description = Doe al je trackers aan en ga dan in VR!
|
||||
onboarding-enter_vr-ready = Gereed!
|
||||
|
||||
## Setup done
|
||||
onboarding-done-title = Je bent klaar!
|
||||
onboarding-done-description = Geniet van je full-body ervaring
|
||||
onboarding-done-close = Sluit de gids
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = Ga terug naar de instellingen voor WiFi-configuratie
|
||||
onboarding-connect_tracker-title = Trackers verbinden
|
||||
onboarding-connect_tracker-description-p0 = Nu het leuke gedeelte, verbind al je trackers!
|
||||
onboarding-connect_tracker-description-p1 = Gebruik een USB-kabel om alle trackers te verbinden die nog niet verbonden zijn.
|
||||
onboarding-connect_tracker-issue-serial = Ik heb problemen met verbinden!
|
||||
onboarding-connect_tracker-usb = USB Tracker
|
||||
onboarding-connect_tracker-connection_status-connecting = Wifi-inloggegevens verzenden
|
||||
onboarding-connect_tracker-connection_status-connected = Verbonden via WiFi
|
||||
onboarding-connect_tracker-connection_status-error = Kan geen verbinding maken via WiFi
|
||||
onboarding-connect_tracker-connection_status-start_connecting = Zoeken naar trackers
|
||||
onboarding-connect_tracker-connection_status-handshake = Verbonden met de server
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
# More info on https://www.unicode.org/cldr/cldr-aux/charts/22/supplemental/language_plural_rules.html
|
||||
# English in this case only has 2 plural rules, which are "one" and "other",
|
||||
# we use 0 in an explicit way because there is no plural rule in english for 0, so we directly say
|
||||
# if $amount is 0 then we say "No trackers connected"
|
||||
onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
[0] Geen trackers
|
||||
[one] 1 tracker
|
||||
*[other] { $amount } trackers
|
||||
} verbonden
|
||||
onboarding-connect_tracker-next = Ik heb al mijn trackers verbonden
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Ga terug naar de instellingen voor WiFi-configuratie
|
||||
onboarding-assign_trackers-title = Trackers toewijzen
|
||||
onboarding-assign_trackers-description = Laten we de bevesteging van je trackers bepalen. Klik op de lichaamslocatie waar je een tracker wilt toewijzen.
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
# $assigned (Number) - Trackers that have been assigned a body part
|
||||
# $trackers (Number) - Trackers connected to the server
|
||||
onboarding-assign_trackers-assigned = { $assigned } van { $trackers ->
|
||||
[one] 1 tracker
|
||||
*[other] { $trackers } trackers
|
||||
} toegewezen
|
||||
onboarding-assign_trackers-advanced = Geavanceerde toewijzingslocaties weergeven
|
||||
onboarding-assign_trackers-next = Ik heb alle trackers toegewezen
|
||||
|
||||
## Tracker manual mounting setup
|
||||
onboarding-manual_mounting-back = Ga terug naar de VR sectie
|
||||
onboarding-manual_mounting = Handmatige bevestiging
|
||||
onboarding-manual_mounting-description = Klik op elke tracker en selecteer op welke manier ze zijn bevestigd
|
||||
onboarding-manual_mounting-auto_mounting = Automatische bevestiging
|
||||
onboarding-manual_mounting-next = Volgende stap
|
||||
|
||||
## Tracker automatic mounting setup
|
||||
onboarding-automatic_mounting-back = Ga terug naar de VR sectie
|
||||
onboarding-automatic_mounting-title = Bevestigingskalibratie
|
||||
onboarding-automatic_mounting-description = Om je trackers te laten werken, moet de rotatie worden ingesteld hoe deze zijn bevestigd op je lichaam.
|
||||
onboarding-automatic_mounting-manual_mounting = Bevestiging handmatig instellen
|
||||
onboarding-automatic_mounting-next = Volgende stap
|
||||
onboarding-automatic_mounting-prev_step = Vorige stap
|
||||
onboarding-automatic_mounting-done-title = Bevestigingsrotaties gekalibreerd.
|
||||
onboarding-automatic_mounting-done-description = Uw bevestigingskalibratie is compleet!
|
||||
onboarding-automatic_mounting-done-restart = Terug naar start
|
||||
onboarding-automatic_mounting-mounting_reset-title = Bevestiging kalibreren
|
||||
onboarding-automatic_mounting-mounting_reset-step-0 = 1. Ga staan in een "skie"-houding met gebogen benen, uw bovenlichaam naar voren gekanteld en armen gebogen.
|
||||
onboarding-automatic_mounting-mounting_reset-step-1 = 2. Druk op de knop "Bevestiging resetten" en wacht 3 seconden voordat de bevestigingsrotaties van de trackers opnieuw worden ingesteld.
|
||||
onboarding-automatic_mounting-preparation-title = Voorbereiding
|
||||
onboarding-automatic_mounting-preparation-step-0 = 1. Sta rechtop met uw armen langs uw zij.
|
||||
onboarding-automatic_mounting-preparation-step-1 = 2. Druk op de knop "Resetten" en wacht 3 seconden voordat de trackers opnieuw worden ingesteld.
|
||||
onboarding-automatic_mounting-put_trackers_on-title = Doe je trackers aan
|
||||
onboarding-automatic_mounting-put_trackers_on-description = Om bevestigingsrotaties te kalibreren, gaan we gebruik maken van de trackers die je net hebt toegewezen. Doe al je trackers aan, je kunt zien welke trackers welke zijn in de figuur rechts.
|
||||
onboarding-automatic_mounting-put_trackers_on-next = Ik heb al mijn trackers aan
|
||||
|
||||
## Tracker manual proportions setup
|
||||
onboarding-manual_proportions-back = Ga terug naar de reset tutorial
|
||||
onboarding-manual_proportions-title = Handmatige lichaamsverhoudingen
|
||||
onboarding-manual_proportions-precision = Precisie-aanpassing
|
||||
onboarding-manual_proportions-auto = Automatische kalibratie
|
||||
|
||||
## Tracker automatic proportions setup
|
||||
onboarding-automatic_proportions-back = Ga terug naar de reset tutorial
|
||||
onboarding-automatic_proportions-title = Meet je lichaam
|
||||
onboarding-automatic_proportions-description = Om SlimeVR-trackers te laten werken, moeten we de lengte van je botten weten. Deze korte kalibratie meet het voor je.
|
||||
onboarding-automatic_proportions-manual = Handmatige kalibratie
|
||||
onboarding-automatic_proportions-prev_step = Vorige stap
|
||||
onboarding-automatic_proportions-put_trackers_on-title = Doe je trackers aan
|
||||
onboarding-automatic_proportions-put_trackers_on-description = Om je verhoudingen te kalibreren, gaan we gebruik maken van de trackers die je net hebt toegewezen. Doe al je trackers aan, je kunt zien welke trackers welke zijn in de figuur rechts.
|
||||
onboarding-automatic_proportions-put_trackers_on-next = Ik heb al mijn trackers aan
|
||||
onboarding-automatic_proportions-preparation-title = Voorbereiding
|
||||
onboarding-automatic_proportions-preparation-description = Plaats een stoel recht achter je binnen je speelruimte. Zorg dat je klaar bent om te gaan zitten tijdens de autobone-configuratie.
|
||||
onboarding-automatic_proportions-preparation-next = Ik sta voor een stoel
|
||||
onboarding-automatic_proportions-start_recording-title = Zorg dat je klaar bent om te bewegen
|
||||
onboarding-automatic_proportions-start_recording-description = We gaan nu enkele specifieke houdingen en bewegingen opnemen. Deze worden in het volgende scherm geprompt. Zorg dat je klaar bent om te beginnen als de knop wordt ingedrukt!
|
||||
onboarding-automatic_proportions-start_recording-next = Start opname
|
||||
onboarding-automatic_proportions-recording-title = REC
|
||||
onboarding-automatic_proportions-recording-description-p0 = Opname bezig...
|
||||
onboarding-automatic_proportions-recording-description-p1 = Voer de onderstaande bewegingen uit:
|
||||
onboarding-automatic_proportions-recording-steps-0 = Buig een paar keer op je knieën.
|
||||
onboarding-automatic_proportions-recording-steps-1 = Ga zitten op een stoel en sta weer op.
|
||||
onboarding-automatic_proportions-recording-steps-2 = Draai je bovenlichaam naar links, buig dan naar rechts.
|
||||
onboarding-automatic_proportions-recording-steps-3 = Draai je bovenlichaam naar rechts, buig dan naar links.
|
||||
onboarding-automatic_proportions-recording-steps-4 = Wiebel rond tot de timer is afgelopen.
|
||||
onboarding-automatic_proportions-recording-processing = Resultaat verwerken
|
||||
# $time (Number) - Seconds left for the automatic calibration recording to finish (max 15)
|
||||
onboarding-automatic_proportions-recording-timer = { $time ->
|
||||
[one] 1 seconde resterend
|
||||
*[other] { $time } seconden resterend
|
||||
}
|
||||
onboarding-automatic_proportions-verify_results-title = Resultaten controleren
|
||||
onboarding-automatic_proportions-verify_results-description = Controleer de resultaten hieronder, zien ze er correct uit?
|
||||
onboarding-automatic_proportions-verify_results-results = Opnameresultaten
|
||||
onboarding-automatic_proportions-verify_results-processing = Resultaat verwerken
|
||||
onboarding-automatic_proportions-verify_results-redo = Opname opnieuw doen
|
||||
onboarding-automatic_proportions-verify_results-confirm = Ze zijn correct
|
||||
onboarding-automatic_proportions-done-title = Lichaam gemeten en opgeslagen.
|
||||
onboarding-automatic_proportions-done-description = Je kalibratie voor lichaamsverhoudingen is voltooid!
|
||||
|
||||
## Home
|
||||
home-no_trackers = Geen trackers gedetecteerd of toegewezen
|
||||
@@ -37,7 +37,7 @@ body_part-LEFT_LOWER_LEG = Lewe Podudzie
|
||||
body_part-LEFT_FOOT = Lewa Stopa
|
||||
body_part-LEFT_CONTROLLER = Left controller
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = Brak
|
||||
skeleton_bone-HEAD = Head Shift
|
||||
skeleton_bone-NECK = Długość Szyi
|
||||
@@ -58,6 +58,7 @@ skeleton_bone-UPPER_ARM = Długość Bicepsa
|
||||
skeleton_bone-LOWER_ARM = Długość PrzedRamienia
|
||||
skeleton_bone-CONTROLLER_Z = Controller Distance Z
|
||||
skeleton_bone-CONTROLLER_Y = Controller Distance Y
|
||||
skeleton_bone-ELBOW_OFFSET = Offset Łokcia
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Zresetuj wszystkie wymiary
|
||||
@@ -67,9 +68,9 @@ reset-quick = Szybki Reset
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = Wykryto Nowe Urządzenie.
|
||||
serial_detection-new_device-p1 = Wprowadź dane WiFi!
|
||||
serial_detection-new_device-p1 = Wprowadź dane Wi-Fi!
|
||||
serial_detection-new_device-p2 = Wybierz co chcesz z nim zrobić.
|
||||
serial_detection-open_wifi = Połącz z WiFi
|
||||
serial_detection-open_wifi = Połącz z Wi-Fi
|
||||
serial_detection-open_serial = Otwórz Konsole
|
||||
serial_detection-submit = Potwierdź!
|
||||
serial_detection-close = Zamknij
|
||||
@@ -86,9 +87,25 @@ navbar-settings = Ustawienia
|
||||
bvh-start_recording = Nagraj BVH
|
||||
bvh-recording = Nagrywam...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = Pokaż Overlay w SteamVR
|
||||
overlay-is_mirrored_label = Pokaż Overlay jako Lustro
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = Overlay
|
||||
widget-overlay-is_visible_label = Pokaż Overlay w SteamVR
|
||||
widget-overlay-is_mirrored_label = Pokaż Overlay jako Lustro
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = Tryb Dewelopera
|
||||
widget-developer_mode-high_contrast = High contrast
|
||||
widget-developer_mode-precise_rotation = Precise rotation
|
||||
widget-developer_mode-fast_data_feed = Fast data feed
|
||||
widget-developer_mode-filter_slimes_and_hmd = Filter slimes and HMD
|
||||
widget-developer_mode-sort_by_name = Sort by name
|
||||
widget-developer_mode-raw_slime_rotation = Raw rotation
|
||||
widget-developer_mode-more_info = More info
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = Rotation
|
||||
widget-imu_visualizer-rotation_raw = Raw
|
||||
widget-imu_visualizer-rotation_preview = Preview
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = Brak Statusu
|
||||
@@ -103,6 +120,9 @@ tracker-table-column-name = Nazwa
|
||||
tracker-table-column-type = Typ
|
||||
tracker-table-column-battery = Bateria
|
||||
tracker-table-column-ping = Ping
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = Temp. °C
|
||||
tracker-table-column-linear-acceleration = Accel. X/Y/Z
|
||||
tracker-table-column-rotation = Rotacja X/Y/Z
|
||||
tracker-table-column-position = Pozycja X/Y/Z
|
||||
tracker-table-column-url = URL
|
||||
@@ -151,7 +171,7 @@ body_assignment_menu-unassign_tracker = Usuń przydzielenie
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Which tracker to assign to your
|
||||
@@ -242,11 +262,11 @@ settings-general-tracker_mechanics-drift_compensation-max_resets-label = Use up
|
||||
settings-general-fk_settings = Tracking settings
|
||||
settings-general-fk_settings-leg_tweak = Leg tweaks
|
||||
settings-general-fk_settings-leg_tweak-description = Floor-clip can Reduce or even eliminates clipping with the floor but may cause problems when on your knees. Skating-correction corrects for ice skating, but can decrease accuracy in certain movement patterns.
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Floor clip
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
@@ -255,6 +275,7 @@ settings-general-fk_settings-leg_tweak-skating_correction-amount = Skating corre
|
||||
settings-general-fk_settings-arm_fk = Arm tracking
|
||||
settings-general-fk_settings-arm_fk-description = Change the way the arms are tracked.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Force arms from HMD
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = Skeleton settings
|
||||
settings-general-fk_settings-skeleton_settings-description = Toggle skeleton settings on or off. It is recommended to leave these on.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Extended spine
|
||||
@@ -351,7 +372,7 @@ settings-osc-vrchat-network-port_out =
|
||||
.label = Port Out
|
||||
.placeholder = Port out (default: 9000)
|
||||
settings-osc-vrchat-network-address = Network address
|
||||
settings-osc-vrchat-network-address-description = Choose which address to send out data to VRChat (check your wifi settings on your device).
|
||||
settings-osc-vrchat-network-address-description = Choose which address to send out data to VRChat (check your Wi-Fi settings on your device).
|
||||
settings-osc-vrchat-network-address-placeholder = VRChat ip address
|
||||
settings-osc-vrchat-network-trackers = Trackers
|
||||
settings-osc-vrchat-network-trackers-description = Toggle the sending of specific trackers via OSC.
|
||||
@@ -366,14 +387,14 @@ onboarding-skip = Pomiń wstępną konfiguracje
|
||||
onboarding-continue = Kontynuuj
|
||||
onboarding-wip = W trakcie prac
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = Cofnij się do początku
|
||||
onboarding-wifi_creds = Wpisz dane WiFi
|
||||
onboarding-wifi_creds = Wpisz dane Wi-Fi
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
Trackery będą używać tej sieci do łączenia się z serwerem
|
||||
proszę używać sieci do której jest się połączonym
|
||||
onboarding-wifi_creds-skip = Pomiń ustawienia WiFi
|
||||
onboarding-wifi_creds-skip = Pomiń ustawienia Wi-Fi
|
||||
onboarding-wifi_creds-submit = Potwierdź!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
@@ -407,15 +428,15 @@ onboarding-done-description = Ciesz się Full-Body
|
||||
onboarding-done-close = Zamknij Poradnik
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = Cofnij się do ustawień WiFi
|
||||
onboarding-connect_tracker-back = Cofnij się do ustawień Wi-Fi
|
||||
onboarding-connect_tracker-title = Połącz trackery
|
||||
onboarding-connect_tracker-description-p0 = Teraz czas na zabawe, połączenie wszystkich trackerów!
|
||||
onboarding-connect_tracker-description-p1 = Po prostu połącz wszystkie dotychczas nie połączone trackery za pomocą USB
|
||||
onboarding-connect_tracker-issue-serial = Mam problemy z połączeniem!
|
||||
onboarding-connect_tracker-usb = USB Tracker
|
||||
onboarding-connect_tracker-connection_status-connecting = Wysyłanie danych WiFi
|
||||
onboarding-connect_tracker-connection_status-connected = Połączono z WiFi
|
||||
onboarding-connect_tracker-connection_status-error = Nie można połączyć z Wifi
|
||||
onboarding-connect_tracker-connection_status-connecting = Wysyłanie danych Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-connected = Połączono z Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-error = Nie można połączyć z Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-start_connecting = Szukanie Trackerów
|
||||
onboarding-connect_tracker-connection_status-handshake = Połączono z serwerem
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -431,7 +452,7 @@ onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
onboarding-connect_tracker-next = Połączyłem już wszystkie trackery
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Cofnij się do ustawień WiFi
|
||||
onboarding-assign_trackers-back = Cofnij się do ustawień Wi-Fi
|
||||
onboarding-assign_trackers-title = Przydziel Trackery
|
||||
onboarding-assign_trackers-description = Wybierzmy gdzie idzie jaki tracker. Naciśnij gdzie chcesz go przydzielić
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
|
||||
@@ -37,7 +37,7 @@ body_part-LEFT_LOWER_LEG = Canela esquerda
|
||||
body_part-LEFT_FOOT = Pé esquerdo
|
||||
body_part-LEFT_CONTROLLER = Controle esquerdo
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = Nada
|
||||
skeleton_bone-HEAD = Deslocamento da Cabeça
|
||||
skeleton_bone-NECK = Tamanho do Pescoço
|
||||
@@ -58,6 +58,7 @@ skeleton_bone-UPPER_ARM = Tamanho do Braço Superior
|
||||
skeleton_bone-LOWER_ARM = Distância do Antebraço
|
||||
skeleton_bone-CONTROLLER_Y = Distância do Controle Y
|
||||
skeleton_bone-CONTROLLER_Z = Distância do Controle Z
|
||||
skeleton_bone-ELBOW_OFFSET = Compensação do Cotovelo
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Redefinir todas as proporções
|
||||
@@ -67,9 +68,9 @@ reset-quick = Reset Rápido
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = Novo dispositivo de serial detectado!
|
||||
serial_detection-new_device-p1 = Insira suas credenciais de wifi!
|
||||
serial_detection-new_device-p1 = Insira suas credenciais de Wi-Fi!
|
||||
serial_detection-new_device-p2 = Selecione o que quer fazer com ele
|
||||
serial_detection-open_wifi = Conectar ao WiFi
|
||||
serial_detection-open_wifi = Conectar ao Wi-Fi
|
||||
serial_detection-open_serial = Abrir o Console Serial
|
||||
serial_detection-submit = Enviar!
|
||||
serial_detection-close = Fechar
|
||||
@@ -86,9 +87,25 @@ navbar-settings = Opções
|
||||
bvh-start_recording = Gravar BVH
|
||||
bvh-recording = Gravando...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = Mostrar Overlay na SteamVR
|
||||
overlay-is_mirrored_label = Mostrar Overlay como espelho
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = Overlay
|
||||
widget-overlay-is_visible_label = Mostrar Overlay na SteamVR
|
||||
widget-overlay-is_mirrored_label = Mostrar Overlay como espelho
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = Modo de desenvolvedor
|
||||
widget-developer_mode-high_contrast = High contrast
|
||||
widget-developer_mode-precise_rotation = Precise rotation
|
||||
widget-developer_mode-fast_data_feed = Fast data feed
|
||||
widget-developer_mode-filter_slimes_and_hmd = Filter slimes and HMD
|
||||
widget-developer_mode-sort_by_name = Sort by name
|
||||
widget-developer_mode-raw_slime_rotation = Raw rotation
|
||||
widget-developer_mode-more_info = More info
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = Rotation
|
||||
widget-imu_visualizer-rotation_raw = Raw
|
||||
widget-imu_visualizer-rotation_preview = Preview
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = Sem Status
|
||||
@@ -103,6 +120,9 @@ tracker-table-column-name = Nome
|
||||
tracker-table-column-type = Tipo
|
||||
tracker-table-column-battery = Bateria
|
||||
tracker-table-column-ping = Ping
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = Temp. °C
|
||||
tracker-table-column-linear-acceleration = Accel. X/Y/Z
|
||||
tracker-table-column-rotation = Rotação X/Y/Z
|
||||
tracker-table-column-position = Posição X/Y/Z
|
||||
tracker-table-column-url = URL
|
||||
@@ -151,7 +171,7 @@ body_assignment_menu-unassign_tracker = Desatribuir tracker
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Which tracker to assign to your
|
||||
@@ -242,11 +262,11 @@ settings-general-tracker_mechanics-drift_compensation-max_resets-label = Use up
|
||||
settings-general-fk_settings = Opções de Tracker
|
||||
settings-general-fk_settings-leg_tweak = Ajustes de perna
|
||||
settings-general-fk_settings-leg_tweak-description = Atravessar o chão pode reduzir ou até eliminar o clipping(atravessar) com o chão porém pode causar problemas quando ajoelhado. Correção de Deslize corrige o ice skating(deslize dos trackers no chão), porém pode diminuir a precisão de certos padrões de movimento.
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Atravessar o chão
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
@@ -255,6 +275,7 @@ settings-general-fk_settings-leg_tweak-skating_correction-amount = Força da cor
|
||||
settings-general-fk_settings-arm_fk = Opções do Braço
|
||||
settings-general-fk_settings-arm_fk-description = Muda o jeito que os braços são rastreados.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Forçar braços do HMD
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = Opções do esqueleto
|
||||
settings-general-fk_settings-skeleton_settings-description = Ligar ou desligar opções do esqueleto. É recomendado deixar eles ligados.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Estender coluna
|
||||
@@ -351,7 +372,7 @@ settings-osc-vrchat-network-port_out =
|
||||
.label = Porta de saída
|
||||
.placeholder = Porta de saída (padrão: 9000)
|
||||
settings-osc-vrchat-network-address = Endereço de rede
|
||||
settings-osc-vrchat-network-address-description = Escolha qual o endereço para enviar dados para o VRChat (verifique as suas opções de wifi no seu dispositivo)
|
||||
settings-osc-vrchat-network-address-description = Escolha qual o endereço para enviar dados para o VRChat (verifique as suas opções de Wi-Fi no seu dispositivo)
|
||||
settings-osc-vrchat-network-address-placeholder = Endereço de ip do VRChat
|
||||
settings-osc-vrchat-network-trackers = Trackers
|
||||
settings-osc-vrchat-network-trackers-description = Ligar ou desligar o envio e recepção de dados.
|
||||
@@ -366,14 +387,14 @@ onboarding-skip = Pular configurações
|
||||
onboarding-continue = Continuar
|
||||
onboarding-wip = Trabalho em progresso
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = Voltar para introdução
|
||||
onboarding-wifi_creds = Insira as credenciais de WiFi
|
||||
onboarding-wifi_creds = Insira as credenciais de Wi-Fi
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
Os Trackers vão usar essas credenciais para conectar à rede sem fio
|
||||
Use as credenciais da rede em que você está atualmente conectado
|
||||
onboarding-wifi_creds-skip = Pular as configurações de WiFi
|
||||
onboarding-wifi_creds-skip = Pular as configurações de Wi-Fi
|
||||
onboarding-wifi_creds-submit = Enviar!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
@@ -407,15 +428,15 @@ onboarding-done-description = Aproveite sua experiência com full body
|
||||
onboarding-done-close = Fechar o guia
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = Voltar para as credenciais de WiFi
|
||||
onboarding-connect_tracker-back = Voltar para as credenciais de Wi-Fi
|
||||
onboarding-connect_tracker-title = Conectar os trackers
|
||||
onboarding-connect_tracker-description-p0 = Agora para a parte divertida, conectando todos os seus trackers!
|
||||
onboarding-connect_tracker-description-p1 = Simplesmente conecte todos que ainda não estão conectados, via porta USB.
|
||||
onboarding-connect_tracker-issue-serial = Estou tendo problemas para conectar!
|
||||
onboarding-connect_tracker-usb = Tracker USB
|
||||
onboarding-connect_tracker-connection_status-connecting = Enviando credenciais de wifi
|
||||
onboarding-connect_tracker-connection_status-connected = Conectado ao WiFi
|
||||
onboarding-connect_tracker-connection_status-error = Não é possível conectar ao WiFi
|
||||
onboarding-connect_tracker-connection_status-connecting = Enviando credenciais de Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-connected = Conectado ao Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-error = Não é possível conectar ao Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-start_connecting = Procurando por trackers
|
||||
onboarding-connect_tracker-connection_status-handshake = Conectado ao servidor
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -431,7 +452,7 @@ onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
onboarding-connect_tracker-next = Eu conectei todos os meus trackers
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Voltar para as credenciais de WiFi
|
||||
onboarding-assign_trackers-back = Voltar para as credenciais de Wi-Fi
|
||||
onboarding-assign_trackers-title = Atribuir trackers
|
||||
onboarding-assign_trackers-description = Vamos escolher onde cada tracker vai. Clique no local onde você quer colocar o tracker
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
@@ -516,4 +537,4 @@ onboarding-automatic_proportions-done-title = Corpo medido e salvo.
|
||||
onboarding-automatic_proportions-done-description = Sua calibragem de proporção de corpo está completa!
|
||||
|
||||
## Home
|
||||
home-no_trackers = Nenhum tracker detectado ou atribuído
|
||||
home-no_trackers = Nenhum tracker detectado ou atribuído
|
||||
|
||||
@@ -10,92 +10,109 @@ websocket-connecting = Đang kết nối với máy chủ
|
||||
websocket-connection_lost = Kết nối với máy chủ đã mất. Đang kết nối lại...
|
||||
|
||||
## Tips
|
||||
tips-find_tracker = Không rõ tracker nào? Lắc tracker và trong menu sẽ sáng lên.
|
||||
tips-do_not_move_heels = Hãy đảm bảo gót chân không cử động trong khi đo ghi!
|
||||
tips-find_tracker = Không rõ tracker nào đang được chọn? Di chuyển nó và trong menu sẽ sáng lên tracker đó
|
||||
tips-do_not_move_heels = Không di chuyển gót chân trong khi đo
|
||||
|
||||
## Body parts
|
||||
body_part-NONE = Chưa liên kết
|
||||
body_part-NONE = Chưa được gán
|
||||
body_part-HEAD = Đầu
|
||||
body_part-NECK = Cổ
|
||||
body_part-RIGHT_SHOULDER = Vai phải
|
||||
body_part-RIGHT_UPPER_ARM = Tay phải trên
|
||||
body_part-RIGHT_LOWER_ARM = Tay phải dưới
|
||||
body_part-RIGHT_UPPER_ARM = Bắp tay phải
|
||||
body_part-RIGHT_LOWER_ARM = Cẳng tay phải
|
||||
body_part-RIGHT_HAND = Tay phải
|
||||
body_part-RIGHT_UPPER_LEG = Chân phải trên
|
||||
body_part-RIGHT_LOWER_LEG = chân phải dưới
|
||||
body_part-RIGHT_UPPER_LEG = Bắp chân phải
|
||||
body_part-RIGHT_LOWER_LEG = Cẳng chân phải
|
||||
body_part-RIGHT_FOOT = Bàn chân phải
|
||||
body_part-RIGHT_CONTROLLER = Tay cầm phải
|
||||
body_part-RIGHT_CONTROLLER = Tay cầm bên phải
|
||||
body_part-CHEST = Ngực
|
||||
body_part-WAIST = Eo
|
||||
body_part-HIP = Hông
|
||||
body_part-LEFT_SHOULDER = Vai trái
|
||||
body_part-LEFT_UPPER_ARM = Tay trái trên
|
||||
body_part-LEFT_LOWER_ARM = tay trái dưới
|
||||
body_part-LEFT_UPPER_ARM = Bắp tay trái
|
||||
body_part-LEFT_LOWER_ARM = Cẳng tay trái
|
||||
body_part-LEFT_HAND = Tay trái
|
||||
body_part-LEFT_UPPER_LEG = Chân trái trên
|
||||
body_part-LEFT_LOWER_LEG = Chân trái dưới
|
||||
body_part-LEFT_UPPER_LEG = Bắp chân trái
|
||||
body_part-LEFT_LOWER_LEG = Cẳng chân trái
|
||||
body_part-LEFT_FOOT = Bàn chân trái
|
||||
body_part-LEFT_CONTROLLER = Tay cầm trái
|
||||
body_part-LEFT_CONTROLLER = Tay cầm bên trái
|
||||
|
||||
## Skeleton stuff
|
||||
skeleton_bone-NONE = Chưa liên kết
|
||||
skeleton_bone-HEAD = Đầu ca
|
||||
skeleton_bone-NECK = Cổ dài
|
||||
skeleton_bone-CHEST = Chest Length
|
||||
skeleton_bone-CHEST_OFFSET = Chest Offset
|
||||
skeleton_bone-WAIST = Waist Length
|
||||
skeleton_bone-HIP = Hip Length
|
||||
skeleton_bone-HIP_OFFSET = Lệc đo hông
|
||||
## Proportions
|
||||
skeleton_bone-NONE = Chưa được gán
|
||||
skeleton_bone-HEAD = Sai số đầu
|
||||
skeleton_bone-NECK = Chiều dài cổ
|
||||
skeleton_bone-CHEST = Khoảng cách ngực
|
||||
skeleton_bone-CHEST_OFFSET = Sai số ngực
|
||||
skeleton_bone-WAIST = Khoảng cách eo
|
||||
skeleton_bone-HIP = Khoảng cách hông
|
||||
skeleton_bone-HIP_OFFSET = Sai số hông
|
||||
skeleton_bone-HIPS_WIDTH = Chiều rộng hông
|
||||
skeleton_bone-UPPER_LEG = Upper Leg Length
|
||||
skeleton_bone-LOWER_LEG = Lower Leg Length
|
||||
skeleton_bone-FOOT_LENGTH = CHiều dài bàn chân
|
||||
skeleton_bone-FOOT_SHIFT = Lệch đo bàn chân
|
||||
skeleton_bone-SKELETON_OFFSET = Lệch đo thân
|
||||
skeleton_bone-UPPER_LEG = Chiều dài bắp chân
|
||||
skeleton_bone-LOWER_LEG = Chiều dài cẳng chân
|
||||
skeleton_bone-FOOT_LENGTH = Chiều dài bàn chân
|
||||
skeleton_bone-FOOT_SHIFT = Sai số bàn chân
|
||||
skeleton_bone-SKELETON_OFFSET = Sai số thân
|
||||
skeleton_bone-SHOULDERS_DISTANCE = Khoảng cách vai
|
||||
skeleton_bone-SHOULDERS_WIDTH = Chiều rộng vai
|
||||
skeleton_bone-UPPER_ARM = Chiều dài tay trên
|
||||
skeleton_bone-LOWER_ARM = khoảng cách cánh tay
|
||||
skeleton_bone-CONTROLLER_Y = Khoảng cách tay cầm Y
|
||||
skeleton_bone-CONTROLLER_Z = Khoảng cách tay cầm Z
|
||||
skeleton_bone-UPPER_ARM = Chiều dài bắp tay
|
||||
skeleton_bone-LOWER_ARM = Chiều dài cẳng tay
|
||||
skeleton_bone-CONTROLLER_Y = Khoảng cách tay cầm theo trục Y
|
||||
skeleton_bone-CONTROLLER_Z = Khoảng cách tay cầm theo trục Z
|
||||
skeleton_bone-ELBOW_OFFSET = Sai số khuỷu tay
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Reset tất cả bộ phận
|
||||
reset-full = Reset
|
||||
reset-mounting = Reset vị trí cài
|
||||
reset-quick = Reset nhanh
|
||||
reset-reset_all = Đặt lại tất cả bộ phận
|
||||
reset-full = Đặt lại
|
||||
reset-mounting = Đặt lại hướng gắn tracker
|
||||
reset-quick = Đặt lại nhanh
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = New serial device detected!
|
||||
serial_detection-new_device-p1 = Vui lòng nhập thông tin Wi-Fi!
|
||||
serial_detection-new_device-p2 = Vui lòng chọn những gì làm với nó
|
||||
serial_detection-open_wifi = Kết nối Wi-Fi
|
||||
serial_detection-open_serial = Mở Serial Console
|
||||
serial_detection-submit = Đăng lên!
|
||||
serial_detection-new_device-p0 = Tìm thấy thiết bị mới!
|
||||
serial_detection-new_device-p1 = Nhập thông tin Wi-Fi
|
||||
serial_detection-new_device-p2 = Chọn hành động cần thực hiện
|
||||
serial_detection-open_wifi = Kết nối đến Wi-Fi
|
||||
serial_detection-open_serial = Mở cổng Serial
|
||||
serial_detection-submit = Gửi
|
||||
serial_detection-close = Đóng
|
||||
|
||||
## Navigation bar
|
||||
navbar-home = Giao diện chính
|
||||
navbar-body_proportions = Bộ phận cơ thể
|
||||
navbar-trackers_assign = Giao bộ phận tracker
|
||||
navbar-mounting = Đo vị trí đặt
|
||||
navbar-onboarding = Trình hướng dẫn cài đặt
|
||||
navbar-home = Trang chủ
|
||||
navbar-body_proportions = Tỉ lệ cơ thể
|
||||
navbar-trackers_assign = Phân bố tracker
|
||||
navbar-mounting = Cân chỉnh hướng gắn tracker
|
||||
navbar-onboarding = Trình thiết lập
|
||||
navbar-settings = Cài đặt
|
||||
|
||||
## Bounding volume hierarchy recording
|
||||
bvh-start_recording = Ghi BVH
|
||||
bvh-recording = Đang ghi...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = Xem overlay trên SteamVR
|
||||
overlay-is_mirrored_label = Xem overlay trong gương
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = Overlay
|
||||
widget-overlay-is_visible_label = Xem overlay trên SteamVR
|
||||
widget-overlay-is_mirrored_label = Xem overlay trong gương
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = Chế độ nhà phát triển
|
||||
widget-developer_mode-high_contrast = Chế độ tương phản cao
|
||||
widget-developer_mode-precise_rotation = Hiển thị góc quay chính xác
|
||||
widget-developer_mode-fast_data_feed = Tăng tốc độ gửi dữ liệu
|
||||
widget-developer_mode-filter_slimes_and_hmd = Lọc dữ liệu tracker và kính
|
||||
widget-developer_mode-sort_by_name = Sắp xếp theo tên
|
||||
widget-developer_mode-raw_slime_rotation = Sử dụng giá trị góc quay thực cho tracker
|
||||
widget-developer_mode-more_info = Thêm thông tin
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = Góc quay
|
||||
widget-imu_visualizer-rotation_raw = Gốc
|
||||
widget-imu_visualizer-rotation_preview = Qua xử lí
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = Không có tình trạng
|
||||
tracker-status-none = Không có trạng thái
|
||||
tracker-status-busy = Bận
|
||||
tracker-status-error = Lỗi
|
||||
tracker-status-disconnected = Đã ngắt kết nối
|
||||
tracker-status-occluded = Bị tắc
|
||||
tracker-status-occluded = Nghẽn
|
||||
tracker-status-ok = Đã kết nối
|
||||
|
||||
## Tracker status columns
|
||||
@@ -103,258 +120,262 @@ tracker-table-column-name = Tên
|
||||
tracker-table-column-type = Loại
|
||||
tracker-table-column-battery = Pin
|
||||
tracker-table-column-ping = Ping
|
||||
tracker-table-column-rotation = Chiều chuyển X/Y/Z
|
||||
tracker-table-column-position = Vị trí X/Y/Z
|
||||
tracker-table-column-url = URL
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = Nhiệt độ (°C)
|
||||
tracker-table-column-linear-acceleration = Tốc độ X/Y/Z
|
||||
tracker-table-column-rotation = Góc quay X/Y/Z
|
||||
tracker-table-column-position = Tọa độ X/Y/Z
|
||||
tracker-table-column-url = Đường dẫn
|
||||
|
||||
## Tracker rotation
|
||||
tracker-rotation-front = Đằng trước
|
||||
tracker-rotation-left = Bên trái
|
||||
tracker-rotation-right = Bên phải
|
||||
tracker-rotation-back = Đằng sau
|
||||
tracker-rotation-front = Trước
|
||||
tracker-rotation-left = Trái
|
||||
tracker-rotation-right = Phải
|
||||
tracker-rotation-back = Sau
|
||||
|
||||
## Tracker information
|
||||
tracker-infos-manufacturer = Nhà sản xuất
|
||||
tracker-infos-display_name = Tên gọi
|
||||
tracker-infos-custom_name = Tên tự chọn
|
||||
tracker-infos-url = URL
|
||||
tracker-infos-display_name = Tên hiển thị
|
||||
tracker-infos-custom_name = Tên gọi
|
||||
tracker-infos-url = Đường dẫn
|
||||
|
||||
## Tracker settings
|
||||
tracker-settings-back = Quay lại danh sách tracker
|
||||
tracker-settings-title = Cài đặt tracker
|
||||
tracker-settings-assignment_section = Giao bộ phận
|
||||
tracker-settings-assignment_section-description = Thiết bị này được giao cho bộ phận nào.
|
||||
tracker-settings-assignment_section-edit = Chỉnh lại giao bộ phận
|
||||
tracker-settings-mounting_section = Vị trí đặt bộ phận
|
||||
tracker-settings-mounting_section-description = Tracker đặt ở đâu?
|
||||
tracker-settings-mounting_section-edit = Chỉnh lại chỗ đặt
|
||||
tracker-settings-drift_compensation_section = Allow drift compensation
|
||||
tracker-settings-drift_compensation_section-description = Should this tracker compensate for its drift when drift compensation is enabled?
|
||||
tracker-settings-drift_compensation_section-edit = Allow drift compensation
|
||||
tracker-settings-title = Cài đặt
|
||||
tracker-settings-assignment_section = Vị trí
|
||||
tracker-settings-assignment_section-description = Vị trí của tracker trên cơ thể
|
||||
tracker-settings-assignment_section-edit = Thay đổi vị trí
|
||||
tracker-settings-mounting_section = Vị trí đặt
|
||||
tracker-settings-mounting_section-description = Tracker được đặt ở đâu?
|
||||
tracker-settings-mounting_section-edit = Thay đổi chỗ đặt
|
||||
tracker-settings-drift_compensation_section = Cho phép bù trừ sai số
|
||||
tracker-settings-drift_compensation_section-description = Tracker này được phép bù trừ cho sai số của nó không?
|
||||
tracker-settings-drift_compensation_section-edit = Cho phép bù trừ sai số
|
||||
# The .<name> means it's an attribute and it's related to the top key.
|
||||
# In this case that is the settings for the assignment section.
|
||||
tracker-settings-name_section = Tên tracker
|
||||
tracker-settings-name_section-description = Hãy cho một tên đẹp :)
|
||||
tracker-settings-name_section-placeholder = Menaced's left leg
|
||||
tracker-settings-name_section-description = Đặt cho nó một cái tên đẹp :3
|
||||
tracker-settings-name_section-placeholder = Chân trái của JINODK
|
||||
|
||||
## Tracker part card info
|
||||
tracker-part_card-no_name = Không tên
|
||||
tracker-part_card-unassigned = Chưa giao vị trí
|
||||
tracker-part_card-unassigned = Chưa gán vị trí
|
||||
|
||||
## Body assignment menu
|
||||
body_assignment_menu = Bạn muốn giao tracker này cho bộ phận nào?
|
||||
body_assignment_menu-description = Chọn vị trí bạn muốn giao tracker cho. Ngoài ra, bạn có thể quản lí tất cả tracker cùng một lúc thay vì từng cái một.
|
||||
body_assignment_menu = Bạn muốn gán tracker này cho bộ phận nào?
|
||||
body_assignment_menu-description = Chọn vị trí bạn muốn gán tracker, ngoài ra bạn cũng có thể quản lí vị trí tất cả các tracker cùng một lúc
|
||||
body_assignment_menu-show_advanced_locations = Xem thêm vị trí đặt
|
||||
body_assignment_menu-manage_trackers = Quản lí tất cả tracker
|
||||
body_assignment_menu-unassign_tracker = Tracker chưa giao vị trí
|
||||
body_assignment_menu-unassign_tracker = Bỏ gán tracker
|
||||
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = Tracker nào để giao cho vị trí
|
||||
tracker_selection_menu-NONE = Bạn muốn giao cho tracker nào mà chua giao?
|
||||
-tracker_selection-part = Tracker nào cho vị trí
|
||||
tracker_selection_menu-NONE = Bạn muốn bỏ gán tracker nào?
|
||||
tracker_selection_menu-HEAD = { -tracker_selection-part } đầu?
|
||||
tracker_selection_menu-NECK = { -tracker_selection-part } cổ?
|
||||
tracker_selection_menu-RIGHT_SHOULDER = { -tracker_selection-part } vai phải?
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = { -tracker_selection-part } tay phải trên?
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = { -tracker_selection-part } tay phải dưới?
|
||||
tracker_selection_menu-RIGHT_UPPER_ARM = { -tracker_selection-part } bắp tay phải?
|
||||
tracker_selection_menu-RIGHT_LOWER_ARM = { -tracker_selection-part } cẳng tay phải?
|
||||
tracker_selection_menu-RIGHT_HAND = { -tracker_selection-part } tay phải?
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = { -tracker_selection-part } chân phải trên?
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = { -tracker_selection-part } chân phải dưới?
|
||||
tracker_selection_menu-RIGHT_UPPER_LEG = { -tracker_selection-part } bắp chân phải?
|
||||
tracker_selection_menu-RIGHT_LOWER_LEG = { -tracker_selection-part } cẳng chân phải?
|
||||
tracker_selection_menu-RIGHT_FOOT = { -tracker_selection-part } bàn chân phải?
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = { -tracker_selection-part } tay cầm phải?
|
||||
tracker_selection_menu-RIGHT_CONTROLLER = { -tracker_selection-part } tay cầm bên phải?
|
||||
tracker_selection_menu-CHEST = { -tracker_selection-part } ngực?
|
||||
tracker_selection_menu-WAIST = { -tracker_selection-part } eo?
|
||||
tracker_selection_menu-HIP = { -tracker_selection-part } hông?
|
||||
tracker_selection_menu-LEFT_SHOULDER = { -tracker_selection-part } vai trái?
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = { -tracker_selection-part } tay trái trên?
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = { -tracker_selection-part } tay trái dưới?
|
||||
tracker_selection_menu-LEFT_UPPER_ARM = { -tracker_selection-part } bắp tay trái?
|
||||
tracker_selection_menu-LEFT_LOWER_ARM = { -tracker_selection-part } cẳng tay trái?
|
||||
tracker_selection_menu-LEFT_HAND = { -tracker_selection-part } tay trái?
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = { -tracker_selection-part } chân trái trên?
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = { -tracker_selection-part } chân trái dưới?
|
||||
tracker_selection_menu-LEFT_UPPER_LEG = { -tracker_selection-part } bắp chân trái?
|
||||
tracker_selection_menu-LEFT_LOWER_LEG = { -tracker_selection-part } cẳng chân trái?
|
||||
tracker_selection_menu-LEFT_FOOT = { -tracker_selection-part } bàn chân trái?
|
||||
tracker_selection_menu-LEFT_CONTROLLER = { -tracker_selection-part } tay tráitrái?
|
||||
tracker_selection_menu-LEFT_CONTROLLER = { -tracker_selection-part } tay cầm bên trái?
|
||||
|
||||
tracker_selection_menu-unassigned = Chưa giao vị trí
|
||||
tracker_selection_menu-assigned = Đã giao vị trí
|
||||
tracker_selection_menu-dont_assign = Thoát và không giao
|
||||
tracker_selection_menu-unassigned = Chưa gán vị trí
|
||||
tracker_selection_menu-assigned = Đã gán vị trí
|
||||
tracker_selection_menu-dont_assign = Không gán
|
||||
|
||||
## Mounting menu
|
||||
mounting_selection_menu = Bạn muốn giao tracker này ở đâu?
|
||||
mounting_selection_menu = Bạn muốn gán tracker này cho bộ phận nào?
|
||||
mounting_selection_menu-close = Đóng
|
||||
|
||||
## Sidebar settings
|
||||
settings-sidebar-title = Cài đặt
|
||||
settings-sidebar-general = Cài đặt chung
|
||||
settings-sidebar-tracker_mechanics = Cơ khí tracker
|
||||
settings-sidebar-fk_settings = Cài đặt FK
|
||||
settings-sidebar-gesture_control = Gesture control
|
||||
settings-sidebar-tracker_mechanics = Cơ chế tracker
|
||||
settings-sidebar-fk_settings = Cài đặt tracker
|
||||
settings-sidebar-gesture_control = Cử chỉ điều khiển
|
||||
settings-sidebar-interface = Giao diện
|
||||
settings-sidebar-osc_router = OSC router
|
||||
settings-sidebar-utils = Hữu dụng
|
||||
settings-sidebar-serial = Bảng điều khiển Serial
|
||||
settings-sidebar-osc_router = Router OSC
|
||||
settings-sidebar-utils = Công cụ
|
||||
settings-sidebar-serial = Cổng Serial
|
||||
|
||||
## SteamVR settings
|
||||
settings-general-steamvr = SteamVR
|
||||
settings-general-steamvr-subtitle = SteamVR trackers
|
||||
settings-general-steamvr-subtitle = Tracker SteamVR
|
||||
# Not all translation keys support multiline, only the ones that specify it will actually
|
||||
# split it in lines (that also means you can split in lines however you want in those).
|
||||
# The first spaces (not tabs) for indentation will be ignored, just to make the file look nice when writing.
|
||||
# This one is one of this cases that cares about multilines
|
||||
settings-general-steamvr-description =
|
||||
Bặt hoặc tắt tracker SteamVR.
|
||||
Hữu dụng nếu bạn muốn điều khiển cách SlimeVR hoạt động.
|
||||
Bật hoặc tắt tracker SteamVR.
|
||||
Hữu dụng nếu game chỉ hỗ trợ số lượng tracker giới hạn.
|
||||
settings-general-steamvr-trackers-waist = Eo
|
||||
settings-general-steamvr-trackers-chest = Ngực
|
||||
settings-general-steamvr-trackers-feet = Bàn chân
|
||||
settings-general-steamvr-trackers-knees = Đầu gối (Chân)
|
||||
settings-general-steamvr-trackers-knees = Đầu gối
|
||||
settings-general-steamvr-trackers-elbows = Khuỷu tay
|
||||
settings-general-steamvr-trackers-hands = Hands
|
||||
settings-general-steamvr-trackers-hands = Tay
|
||||
|
||||
## Tracker mechanics
|
||||
settings-general-tracker_mechanics = Cơ khí tracker
|
||||
settings-general-tracker_mechanics-filtering = Lọc rung
|
||||
settings-general-tracker_mechanics = Cơ chế tracker
|
||||
settings-general-tracker_mechanics-filtering = Lọc nhiễu
|
||||
# This also cares about multilines
|
||||
settings-general-tracker_mechanics-filtering-description =
|
||||
Chọn kiểu lọc rung cho tracker.
|
||||
Dự đoán đoán cử động trong khi lọc rung cử động.
|
||||
Chọn kiểu lọc nhiễu cho tracker
|
||||
"Dự đoán" sẽ dự đoán chuyển động trong khi "Khử nhiễu" sẽ làm chuyển động mềm mại hơn
|
||||
settings-general-tracker_mechanics-filtering-type = Kiểu lọc
|
||||
settings-general-tracker_mechanics-filtering-type-none = Không lọc
|
||||
settings-general-tracker_mechanics-filtering-type-none-description = Để đo chiều chuyển y nguyên. Không sử dụlọclọc.
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing = Làm mượt
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing-description = Lọc cử động mượt nhưng tạo ít chậm rễ.
|
||||
settings-general-tracker_mechanics-filtering-type-none-description = Sử dụng giá trị thực, không áp dụng bất kì bộ lọc nào
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing = Khử nhiễu
|
||||
settings-general-tracker_mechanics-filtering-type-smoothing-description = Làm chuyển động mềm mại hơn nhưng có thể tăng độ trễ
|
||||
settings-general-tracker_mechanics-filtering-type-prediction = Dự đoán
|
||||
settings-general-tracker_mechanics-filtering-type-prediction-description = Giảm chậm trê và để cử động gọn hơn, nhưng có thể tăng độ rung.
|
||||
settings-general-tracker_mechanics-filtering-amount = Số luọng
|
||||
settings-general-tracker_mechanics-drift_compensation = Drift compensation
|
||||
settings-general-tracker_mechanics-filtering-type-prediction-description = Giảm độ trễ và làm chuyển động chân thật hơn, có thể khiến chuyển động không mượt mà
|
||||
settings-general-tracker_mechanics-filtering-amount = Mức độ lọc
|
||||
settings-general-tracker_mechanics-drift_compensation = Bù trừ sai số
|
||||
# This cares about multilines
|
||||
settings-general-tracker_mechanics-drift_compensation-description =
|
||||
Compensates IMU yaw drift by applying an inverse rotation.
|
||||
Change amount of compensation and up to how many resets are taken into account.
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = Drift compensation
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = Compensation amount
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = Use up to x last resets
|
||||
Bù trừ sai lệch trục ngang của cảm biến bằng cách thêm một sai lệch chống lại nó
|
||||
Thay đổi mức độ bù trừ và số lần đặt lại được áp dụng bù trừ
|
||||
settings-general-tracker_mechanics-drift_compensation-enabled-label = Bù trừ sai số
|
||||
settings-general-tracker_mechanics-drift_compensation-amount-label = Mức độ bù trừ
|
||||
settings-general-tracker_mechanics-drift_compensation-max_resets-label = Số lần đặt lại được áp dụng bù trừ
|
||||
|
||||
## FK/Tracking settings
|
||||
settings-general-fk_settings = Cài đặt FK
|
||||
settings-general-fk_settings-leg_tweak = Chỉnh chân
|
||||
settings-general-fk_settings-leg_tweak-description = Chỉnh chân có thể giảm hoặc loại bỏ chân đi xuyên sàn nhà nhưng có thể ảnh hưởng đầu gối. Sửa trượt sửa khi lướt, nhưng giảm độ chính xác ở một số cử động.
|
||||
# Floor clip:
|
||||
settings-general-fk_settings = Cài đặt nâng cao
|
||||
settings-general-fk_settings-leg_tweak = Chân
|
||||
settings-general-fk_settings-leg_tweak-description = "Ngăn xuyên sàn" có thể giảm thiểu khả năng chân xuống thấp hơn sàn sau khi đặt lại vị trí tracker, có thể gây vấn đề nếu đang đứng bằng đầu gối. "Sửa trượt" giúp giảm thiểu tình trạng chân có chuyển động nhỏ so với sàn khi đứng yên, có thể làm giảm độ chính xác với một số chuyển động cụ thể
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Xuyên sàn
|
||||
# Skating correction:
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = Ngăn xuyên sàn
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
settings-general-fk_settings-leg_tweak-skating_correction = Sửa trượt
|
||||
settings-general-fk_settings-leg_tweak-skating_correction-amount = Skating correction strength
|
||||
settings-general-fk_settings-arm_fk = Tay FK
|
||||
settings-general-fk_settings-arm_fk-description = Chỉnh cách tay được đo.
|
||||
settings-general-fk_settings-arm_fk-force_arms = Bắt tay từ kính thực tế ảo
|
||||
settings-general-fk_settings-skeleton_settings = Cài đặt cơ thể
|
||||
settings-general-fk_settings-skeleton_settings-description = Bật hoặc tắt hình cơ thể. Khuyên nên luôn để bật lựa chọn này.
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Xương sống mở rộng
|
||||
settings-general-fk_settings-skeleton_settings-extended_pelvis = Xuong chậu mở rộng
|
||||
settings-general-fk_settings-skeleton_settings-extended_knees = Đầu gối mở rộng
|
||||
settings-general-fk_settings-vive_emulation-title = Vive emulation
|
||||
settings-general-fk_settings-vive_emulation-description = Emulate the waist tracker problems that Vive trackers have. This is a joke and makes tracking worse.
|
||||
settings-general-fk_settings-vive_emulation-label = Enable Vive emulation
|
||||
settings-general-fk_settings-leg_tweak-skating_correction-amount = Mức độ sửa
|
||||
settings-general-fk_settings-arm_fk = Track cánh tay
|
||||
settings-general-fk_settings-arm_fk-description = Thay đổi cách cánh tay được track
|
||||
settings-general-fk_settings-arm_fk-force_arms = Lấy dữ liệu cánh tay từ kính
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = Cài đặt khung cơ thể
|
||||
settings-general-fk_settings-skeleton_settings-description = Bật hoặc tắt các cài đặt về khung cơ thể. Các lựa chọn này nên được giữ bật
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = Xương sống kéo dài
|
||||
settings-general-fk_settings-skeleton_settings-extended_pelvis = Xương chậu kéo dài
|
||||
settings-general-fk_settings-skeleton_settings-extended_knees = Đầu gối kéo dài
|
||||
settings-general-fk_settings-vive_emulation-title = Giả lập tracker Vive
|
||||
settings-general-fk_settings-vive_emulation-description = Giả lập cách tracker của Vive gặp vấn đề với việc theo dõi eo, đây là 1 tính năng được làm cho vui và sẽ làm giảm độ chính xác
|
||||
settings-general-fk_settings-vive_emulation-label = Giả lập tracker Vive
|
||||
|
||||
## Gesture control settings (tracker tapping)
|
||||
settings-general-gesture_control = Điều khiển cử chỉ
|
||||
settings-general-gesture_control-subtitle = Bấm hai lần để reset nhanh
|
||||
settings-general-gesture_control-description = Bật hoặc tắt reset nhanh. Khi bật bấm hai lần bất cứ đâu trên điểm cao nhất ở thân sẽ kích hoạt reset nhanh. Delay is the time between registering a tap and resetting.
|
||||
settings-general-gesture_control = Cử chỉ điều khiển
|
||||
settings-general-gesture_control-subtitle = Chạm để đặt lại
|
||||
settings-general-gesture_control-description = Cho phép chạm vào tracker để đặt lại vị trí, chạm hai lần vào tracker cao nhất ở thân để đặt lại nhanh, chạm hai lần vào tracker cao nhất ở chân trái để đặt lại, chạm hai lần vào tracker cao nhất ở chân phải để đặt lại vị trí gắn tracker. Cử chỉ chỉ được tiếp nhận khi thời gian giữa hai lần chạm ngắn hơn 0.6 giây.
|
||||
# This is a unit: 3 taps, 2 taps, 1 tap
|
||||
# $amount (Number) - Amount of taps (touches to the tracker's case)
|
||||
settings-general-gesture_control-taps = { $amount ->
|
||||
[one] 1 tap
|
||||
*[other] { $amount } lần
|
||||
*[other] { $amount } lần
|
||||
}
|
||||
settings-general-gesture_control-quickResetEnabled = Enable tap to quick reset
|
||||
settings-general-gesture_control-quickResetDelay = Quick reset delay
|
||||
settings-general-gesture_control-quickResetTaps = Taps for quick reset
|
||||
settings-general-gesture_control-resetEnabled = Enable tap to reset
|
||||
settings-general-gesture_control-resetDelay = Reset delay
|
||||
settings-general-gesture_control-resetTaps = Taps for reset
|
||||
settings-general-gesture_control-mountingResetEnabled = Enable tap to reset mounting
|
||||
settings-general-gesture_control-mountingResetDelay = Mounting reset delay
|
||||
settings-general-gesture_control-mountingResetTaps = Taps for mounting reset
|
||||
settings-general-gesture_control-quickResetEnabled = Chạm để đặt lại nhanh
|
||||
settings-general-gesture_control-quickResetDelay = Thời gian delay trước khi đặt lại nhanh
|
||||
settings-general-gesture_control-quickResetTaps = Số lần chạm cho đặt lại nhanh
|
||||
settings-general-gesture_control-resetEnabled = Chạm để đặt lại
|
||||
settings-general-gesture_control-resetDelay = Thời gian delay trước khi đặt lại
|
||||
settings-general-gesture_control-resetTaps = Số lần chạm cho đặt lại
|
||||
settings-general-gesture_control-mountingResetEnabled = Chạm để đặt lại hướng gắn tracker
|
||||
settings-general-gesture_control-mountingResetDelay = Thời gian delay trước khi đặt lại hướng gắn tracker
|
||||
settings-general-gesture_control-mountingResetTaps = Số lần chạm cho đặt lại hướng gắn tracker
|
||||
|
||||
## Interface settings
|
||||
settings-general-interface = Giao diện
|
||||
settings-general-interface-dev_mode = Chế độ nhà phát triển
|
||||
settings-general-interface-dev_mode-description = Chế độ này có thể hữu dụng nếu như bạn cần thông tin sâu hơn hoặc giao tiếp với tracker nâng cao
|
||||
settings-general-interface-dev_mode-description = Hữu dụng nếu cần thêm thông tin chi tiết của tracker hay can thiệp sâu hơn vào tracker
|
||||
settings-general-interface-dev_mode-label = Chế độ nhà phát triển
|
||||
settings-general-interface-serial_detection = Phát hiện thiết bị Serial
|
||||
settings-general-interface-serial_detection-description = Lựa chọn này sẽ hiển thị thông báo mỗi lần thiết bị Serial mà có thể là tracker.Lựa chọn này có thể giúp quá trình cài đạt tracker
|
||||
settings-general-interface-serial_detection-label = Phát hiện thiết bị Serial
|
||||
settings-general-interface-lang = Chọn ngôn ngữ (Change language)
|
||||
settings-general-interface-lang-description = Đổi ngôn ngữ cố định (Change the default language you want to use)
|
||||
settings-general-interface-serial_detection = Nhận dạng thiết bị Serial mới
|
||||
settings-general-interface-serial_detection-description = Hiển thị pop-up mỗi lần một thiết bị Serial mới được kết nối qua USB (có thể là tracker), giúp cải thiện quá trình thiết lập tracker
|
||||
settings-general-interface-serial_detection-label = Nhận dạng thiết bị Serial mới
|
||||
settings-general-interface-lang = Thay đổi ngôn ngữ (Change language)
|
||||
settings-general-interface-lang-description = Đổi ngôn ngữ hiển thị (Change the default language you want to use)
|
||||
settings-general-interface-lang-placeholder = Chọn ngôn ngữ để sử dụng (Select the language to use)
|
||||
|
||||
## Serial settings
|
||||
settings-serial = Bảng điều khiển serial
|
||||
settings-serial = Cổng Serial
|
||||
# This cares about multilines
|
||||
settings-serial-description =
|
||||
Đâu là thông tin trực tiếp về giao tiếp với Serial.
|
||||
Hữu dụng nếu muốn biết phần mềm firmware có vấn đề không.
|
||||
Đây là cổng giao tiếp Serial trực tiếp với tracker
|
||||
Hữu dụng nếu cần kiểm tra tracker có hoạt động như mong muốn hay không
|
||||
settings-serial-connection_lost = Kết nối đến Serial đã mất, đang kết nối lại...
|
||||
settings-serial-reboot = Khởi động lại
|
||||
settings-serial-factory_reset = Khôi phục cài đặt gối
|
||||
settings-serial-factory_reset = Khôi phục cài đặt gốc
|
||||
settings-serial-get_infos = Lấy thông tin
|
||||
settings-serial-serial_select = Chọn cổng Serial
|
||||
settings-serial-auto_dropdown_item = Tự động
|
||||
|
||||
## OSC router settings
|
||||
settings-osc-router = OSC router
|
||||
settings-osc-router = Router OSC
|
||||
# This cares about multilines
|
||||
settings-osc-router-description =
|
||||
Forward OSC messages from another program.
|
||||
Useful for using another OSC program with VRChat for example.
|
||||
settings-osc-router-enable = Enable
|
||||
settings-osc-router-enable-description = Toggle the forwarding of messages.
|
||||
settings-osc-router-enable-label = Enable
|
||||
settings-osc-router-network = Network ports
|
||||
Chuyển tiếp dữ liệu OSC từ phần mềm khác
|
||||
Hữu dụng cho việc sử dụng phần mềm OSC khác với VRChat, ...
|
||||
settings-osc-router-enable = Chuyển tiếp dữ liệu OSC
|
||||
settings-osc-router-enable-description = Cho phép chuyển tiếp dữ liệu OSC
|
||||
settings-osc-router-enable-label = Chuyển tiếp dữ liệu OSC
|
||||
settings-osc-router-network = Cổng mạng
|
||||
# This cares about multilines
|
||||
settings-osc-router-network-description =
|
||||
Set the ports for listening and sending data.
|
||||
These can be the same as other ports used in the SlimeVR server.
|
||||
Đặt cổng nhận và gửi dữ liệu OSC
|
||||
Có thể dùng chung cổng với server SlimeVR
|
||||
settings-osc-router-network-port_in =
|
||||
.label = Port In
|
||||
.placeholder = Port in (default: 9002)
|
||||
.label = Cổng vào
|
||||
.placeholder = Cổng vào (Mặc định: 9002)
|
||||
settings-osc-router-network-port_out =
|
||||
.label = Port Out
|
||||
.placeholder = Port out (default: 9000)
|
||||
settings-osc-router-network-address = Network address
|
||||
settings-osc-router-network-address-description = Set the address to send out data at.
|
||||
settings-osc-router-network-address-placeholder = IPV4 address
|
||||
.label = Cổng ra
|
||||
.placeholder = Cổng ra (Mặc định: 9000)
|
||||
settings-osc-router-network-address = Địa chỉ mạng
|
||||
settings-osc-router-network-address-description = Địa chỉ mạng mà SlimeVR sẽ gửi dữ liệu OSC đến
|
||||
settings-osc-router-network-address-placeholder = Địa chỉ IPv4
|
||||
|
||||
## OSC VRChat settings
|
||||
settings-osc-vrchat = VRChat OSC Trackers
|
||||
# This cares about multilines
|
||||
settings-osc-vrchat-description =
|
||||
Đổi cài đặt dành riêng cho VRChat để nhận thông tin từ kính thực tế ảo và gửi
|
||||
thông tin tracker để track toàn thân (Hoạt động trên Quest một mình standalone).
|
||||
settings-osc-vrchat-enable = Bật
|
||||
settings-osc-vrchat-enable-description = Chình gửi và nhận thông tin
|
||||
settings-osc-vrchat-enable-label = Bật
|
||||
Thay đổi các cài đặt liên quan đến VRChat để nhận dữ liệu từ kính và
|
||||
gửi dữ liệu tracker cho Full-body tracking (hoạt động với kính ở chế độ standalone)
|
||||
settings-osc-vrchat-enable = Dữ liệu OSC
|
||||
settings-osc-vrchat-enable-description = Cho phép nhận và gửi dữ liệu OSC
|
||||
settings-osc-vrchat-enable-label = Giao tiếp dữ liệu OSC
|
||||
settings-osc-vrchat-network = Cổng mạng
|
||||
settings-osc-vrchat-network-description = Chọn cổng mạng để nghe và gửi thông tin lên VRChat
|
||||
settings-osc-vrchat-network-description = Chọn cổng mạng để nhận và gửi dữ liệu OSC đến VRChat
|
||||
settings-osc-vrchat-network-port_in =
|
||||
.label = Cổng vào
|
||||
.placeholder = Cổng vào (Cố định: 9001)
|
||||
.placeholder = Cổng vào (Mặc định: 9001)
|
||||
settings-osc-vrchat-network-port_out =
|
||||
.label = Cổng ra
|
||||
.placeholder = Cổng ra (Cố định: 9000)
|
||||
.placeholder = Cổng ra (Mặc định: 9000)
|
||||
settings-osc-vrchat-network-address = Địa chỉ mạng
|
||||
settings-osc-vrchat-network-address-description = Chọn địa chỉ mạng nào để gứi lên VRChat (Hãy kiểm tra cài đặt Wi-Fi trên thiết bị để tìm cái này)
|
||||
settings-osc-vrchat-network-address-placeholder = Địa chỉ IP cho VRChat
|
||||
settings-osc-vrchat-network-trackers = Trackers
|
||||
settings-osc-vrchat-network-trackers-description = Chỉnh gửi và nhận thông tin
|
||||
settings-osc-vrchat-network-address-description = Địa chỉ mạng mà SlimeVR sẽ gửi dữ liệu OSC đến VRChat (có thể tìm thấy địa chỉ mạng trong menu cài đặt Wi-Fi)
|
||||
settings-osc-vrchat-network-address-placeholder = Địa chỉ IP của thiết bị chơi VRChat
|
||||
settings-osc-vrchat-network-trackers = Cấu hình Tracker
|
||||
settings-osc-vrchat-network-trackers-description = Chọn các tracker mà SlimeVR sẽ gửi dữ liệu OSC đến VRChat
|
||||
settings-osc-vrchat-network-trackers-chest = Ngực
|
||||
settings-osc-vrchat-network-trackers-waist = Eo
|
||||
settings-osc-vrchat-network-trackers-knees = Đầu gối
|
||||
@@ -364,156 +385,156 @@ settings-osc-vrchat-network-trackers-elbows = Khuỷu tay
|
||||
## Setup/onboarding menu
|
||||
onboarding-skip = Bỏ qua cài đặt
|
||||
onboarding-continue = Tiếp tục
|
||||
onboarding-wip = Đang làm dở (vui lòng quay lại sau update)
|
||||
onboarding-wip = Chưa hoàn thiện
|
||||
|
||||
## WiFi setup
|
||||
onboarding-wifi_creds-back = Quay lại đoạn giới thiệuthiệu
|
||||
onboarding-wifi_creds = Bỏ thông tin Wi-Fi ở đây
|
||||
onboarding-wifi_creds-back = Quay lại giới thiệu
|
||||
onboarding-wifi_creds = Nhập thông tin Wi-Fi
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
Tracker sẽ sử dụng thông tin sau để kết nối không dây
|
||||
vui lòng bỏ thông tin bạn muốn kết nối
|
||||
Tracker sẽ sử dụng thông tin này để kết nối đến mạng
|
||||
Hãy nhập thông tin mạng Wi-Fi bạn đang dùng
|
||||
onboarding-wifi_creds-skip = Bỏ qua cài đặt Wi-Fi
|
||||
onboarding-wifi_creds-submit = Thiết lập!
|
||||
onboarding-wifi_creds-submit = Gửi
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
.placeholder = Enter SSID
|
||||
.label = Tên hiển thị
|
||||
.placeholder = Nhập tên Wi-Fi
|
||||
onboarding-wifi_creds-password =
|
||||
.label = Password
|
||||
.placeholder = Enter password
|
||||
.label = Mật khẩu
|
||||
.placeholder = và mật khẩu
|
||||
|
||||
## Mounting setup
|
||||
onboarding-reset_tutorial-back = Quay lại đo đạt vị trí
|
||||
onboarding-reset_tutorial = Làm lại hướng dẫn
|
||||
onboarding-reset_tutorial-description = Tính năng này chưa hoàn thiện, vui lòng bấm tiếp tục và quay lại sau update
|
||||
onboarding-reset_tutorial-back = Quay lại cân chỉnh vị trí gắn tracker
|
||||
onboarding-reset_tutorial = Làm lại
|
||||
onboarding-reset_tutorial-description = Tính năng này chưa hoàn thiện, vui lòng bấm tiếp tục và quay lại sau
|
||||
|
||||
## Setup start
|
||||
onboarding-home = Chào mừng đến với SlimeVR!
|
||||
onboarding-home = Chào mừng bạn đến với SlimeVR!
|
||||
# This cares about multilines and it's centered!!
|
||||
onboarding-home-description =
|
||||
Đem đến đo toàn thân
|
||||
tới tất cả
|
||||
onboarding-home-start = Hãy bắt đầu cài đặt!
|
||||
Mang FBT đến
|
||||
với mọi người
|
||||
onboarding-home-start = Bắt đầu thiết lập!
|
||||
|
||||
## Enter VR part of setup
|
||||
onboarding-enter_vr-back = Quay lại giao bộ phận tracker
|
||||
onboarding-enter_vr-title = Đến giờ lên VR!
|
||||
onboarding-enter_vr-description = Đeo tất cả tracker và lên VR!
|
||||
onboarding-enter_vr-ready = Sẵn sàng!
|
||||
onboarding-enter_vr-back = Quay lại gán tracker
|
||||
onboarding-enter_vr-title = Chuẩn bị cho việc cân chỉnh trong VR
|
||||
onboarding-enter_vr-description = Đeo tất cả tracker và vào VR trước khi tiếp tục
|
||||
onboarding-enter_vr-ready = Sẵn sàng
|
||||
|
||||
## Setup done
|
||||
onboarding-done-title = Bạn đã hoàn thành cài đặt!
|
||||
onboarding-done-description = Hãy tận hưởng đo toàn thân
|
||||
onboarding-done-title = Hoàn thành!
|
||||
onboarding-done-description = Bạn đã hoàn tất quá trình thiết lập cơ bản
|
||||
onboarding-done-close = Đóng hướng dẫn
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = Quay lại tra thông tin Wi-Fi
|
||||
onboarding-connect_tracker-back = Quay lại cài đặt Wi-Fi
|
||||
onboarding-connect_tracker-title = Kết nối tracker
|
||||
onboarding-connect_tracker-description-p0 = Đến giờ đoạn hay nhất, kết nối tất cả tracker!
|
||||
onboarding-connect_tracker-description-p1 = Đơn thuần kết nối tất cả tracker chưa kết nối, qua cổng USB
|
||||
onboarding-connect_tracker-issue-serial = Mình có vấn đề kết nối!
|
||||
onboarding-connect_tracker-description-p0 = Cập nhật thông tin Wi-Fi cho tracker
|
||||
onboarding-connect_tracker-description-p1 = Hãy kết nối các tracker chưa thiết lập qua cổng USB
|
||||
onboarding-connect_tracker-issue-serial = Có vấn đề với việc kết nối? Kiểm tra thông tin qua cổng Serial
|
||||
onboarding-connect_tracker-usb = USB Tracker
|
||||
onboarding-connect_tracker-connection_status-connecting = Đang gửi thông tin Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-connected = Đã kết nối Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-error = Không thể kết nối Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-connected = Đã kết nối đến Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-error = Không thể kết nối đến Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-start_connecting = Đang tìm tracker
|
||||
onboarding-connect_tracker-connection_status-handshake = Đã kết nối với máy chủ
|
||||
onboarding-connect_tracker-connection_status-handshake = Đã kết nối đến máy chủ SlimeVR
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
# More info on https://www.unicode.org/cldr/cldr-aux/charts/22/supplemental/language_plural_rules.html
|
||||
# English in this case only has 2 plural rules, which are "one" and "other",
|
||||
# we use 0 in an explicit way because there is no plural rule in english for 0, so we directly say
|
||||
# if $amount is 0 then we say "No trackers connected"
|
||||
onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
[0] Không trackers
|
||||
[0] Không có tracker
|
||||
[one] 1 tracker
|
||||
*[other] { $amount } trackers
|
||||
*[other] { $amount } tracker
|
||||
} đã giao
|
||||
onboarding-connect_tracker-next = Tôi đã kết nối tất cả tracker
|
||||
onboarding-connect_tracker-next = Đã kết nối với tất cả tracker
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = Quay lại tra thông tin Wi-Fi
|
||||
onboarding-assign_trackers-title = Giao tracker
|
||||
onboarding-assign_trackers-description = Hãy chọn tracker nào nằm ở đâu. Chọn vị trí bạn muốn giao tracker cho
|
||||
onboarding-assign_trackers-back = Quay lại cài đặt Wi-Fi
|
||||
onboarding-assign_trackers-title = Gán tracker
|
||||
onboarding-assign_trackers-description = Chọn vị trí bạn muốn gán tracker bằng cách nhấn vào tên bộ phận muốn gán và chọn tracker
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
# $assigned (Number) - Trackers that have been assigned a body part
|
||||
# $trackers (Number) - Trackers connected to the server
|
||||
onboarding-assign_trackers-assigned = { $assigned } of { $trackers ->
|
||||
onboarding-assign_trackers-assigned = { $assigned } trên { $trackers ->
|
||||
[one] 1 tracker
|
||||
*[other] { $trackers } trackers
|
||||
*[other] { $trackers } tracker
|
||||
} đã giao
|
||||
onboarding-assign_trackers-advanced = Xem vị trí mở rộng
|
||||
onboarding-assign_trackers-advanced = Xem thêm vị trí đặt
|
||||
onboarding-assign_trackers-next = Hoàn thành
|
||||
|
||||
## Tracker manual mounting setup
|
||||
onboarding-manual_mounting-back = Quay lại đến vào VR
|
||||
onboarding-manual_mounting = Đặt thủ công
|
||||
onboarding-manual_mounting-description = Bấm từng tracker một và chọn xem nó được gắn theo chiều nào
|
||||
onboarding-manual_mounting-auto_mounting = Gắn tự động
|
||||
onboarding-manual_mounting-next = Bước tiếp theo
|
||||
onboarding-manual_mounting-back = Quay lại chuẩn bị cân chỉnh
|
||||
onboarding-manual_mounting = Cân chỉnh thủ công
|
||||
onboarding-manual_mounting-description = Chọn từng tracker và chọn hướng nó được gắn
|
||||
onboarding-manual_mounting-auto_mounting = Cân chỉnh tự động
|
||||
onboarding-manual_mounting-next = Tiếp tục
|
||||
|
||||
## Tracker automatic mounting setup
|
||||
onboarding-automatic_mounting-back = Quay lại đến vào VR
|
||||
onboarding-automatic_mounting-title = Đo vị trí đặt
|
||||
onboarding-automatic_mounting-description = Để SlimeVR hoạt động, bạn cần đạt chiều hướng quay của tracker để khớp với điểm đặt tracker trên cơ thể
|
||||
onboarding-automatic_mounting-manual_mounting = Đặt vị trí thủ công
|
||||
onboarding-automatic_mounting-next = Bước tiếp theo
|
||||
onboarding-automatic_mounting-prev_step = Bước trước
|
||||
onboarding-automatic_mounting-done-title = Hướng quay đã được đo.
|
||||
onboarding-automatic_mounting-back = Quay lại chuẩn bị cân chỉnh
|
||||
onboarding-automatic_mounting-title = Cân chỉnh hướng gắn
|
||||
onboarding-automatic_mounting-description = SlimeVR cần biết hướng gắn thực của tracker để hoạt động đúng, làm theo hướng dẫn để cân chỉnh hướng gắn tự động
|
||||
onboarding-automatic_mounting-manual_mounting = Cân chỉnh thủ công
|
||||
onboarding-automatic_mounting-next = Tiếp tục
|
||||
onboarding-automatic_mounting-prev_step = Quay lại
|
||||
onboarding-automatic_mounting-done-title = Đã cân chỉnh hướng gắn
|
||||
onboarding-automatic_mounting-done-description = Cài đặt vị trí đã hoàn thành!
|
||||
onboarding-automatic_mounting-done-restart = Quay lại bắt đầu
|
||||
onboarding-automatic_mounting-mounting_reset-title = Reset vị trí
|
||||
onboarding-automatic_mounting-mounting_reset-step-0 = 1. Ngồi xổm trong tư thế "skiing" với hai chân cong, thân trên nghiêng về phía trước và hai cánh tay cong.
|
||||
onboarding-automatic_mounting-mounting_reset-step-1 = 2. Nhấn nút "Reset Mounting" và đợi trong 3 giây trước khi các vòng quay giá đỡ của thiết bị theo dõi sẽ được đặt lại.
|
||||
onboarding-automatic_mounting-preparation-title = Chuẩn bị
|
||||
onboarding-automatic_mounting-preparation-step-0 = 1. Đứng thẳng với hai cánh tay sang hai bên.
|
||||
onboarding-automatic_mounting-preparation-step-1 = 2. Nhấn nút "Reset" và đợi trong 3 giây trước khi trình theo dõi sẽ đặt lại.
|
||||
onboarding-automatic_mounting-put_trackers_on-title = Hãy đeo tracker lên người
|
||||
onboarding-automatic_mounting-put_trackers_on-description = Để đo chiều quay của tracker, phần mềm sẽ sử dụng tracker mà bạn đã giao cho. Hãy đeo lên tất cả tracker, và xem cái nào là cái nào trên hình bên phải
|
||||
onboarding-automatic_mounting-put_trackers_on-next = Hoàn thành (Gắn xong)
|
||||
onboarding-automatic_mounting-done-restart = Thử lại
|
||||
onboarding-automatic_mounting-mounting_reset-title = Đặt lại hướng gắn
|
||||
onboarding-automatic_mounting-mounting_reset-step-0 = 1. Đứng khom người như tư thế trượt tuyết với đầu gối khom lại, thân trên hướng tới trước và hai tay co lại để giữ thăng bằng như hình bên
|
||||
onboarding-automatic_mounting-mounting_reset-step-1 = 2. Nhấn nút đặt lại và chờ 3 giây trước khi hệ thống cân chỉnh hướng gắn tracker
|
||||
onboarding-automatic_mounting-preparation-title = Chuẩn bị tư thế
|
||||
onboarding-automatic_mounting-preparation-step-0 = 1. Đứng thẳng với hai tay duỗi thẳng
|
||||
onboarding-automatic_mounting-preparation-step-1 = 2. Nhấn nút đặt lại và chờ 3 giây trước khi tracker được đặt lại.
|
||||
onboarding-automatic_mounting-put_trackers_on-title = Đeo tracker lên người
|
||||
onboarding-automatic_mounting-put_trackers_on-description = Để cân chỉnh hướng gắn của tracker, SlimeVR sẽ tiến hành đo góc nghiêng của tracker khi đang đeo để cân chỉnh hướng gắn, hãy đeo tracker theo đúng vị trí đã thiết lập
|
||||
onboarding-automatic_mounting-put_trackers_on-next = Tiếp tục
|
||||
|
||||
## Tracker manual proportions setup
|
||||
onboarding-manual_proportions-back = Quay lại hướng dẫn reset
|
||||
onboarding-manual_proportions-title = Cài bộ phận cơ thể thủ công
|
||||
onboarding-manual_proportions-precision = Chỉnh độ chính xác
|
||||
onboarding-manual_proportions-auto = Đo cơ thể tự động
|
||||
onboarding-manual_proportions-back = Quay lại cân chỉnh hướng gắn
|
||||
onboarding-manual_proportions-title = Đo kích thước cơ thể thủ công
|
||||
onboarding-manual_proportions-precision = Cân chỉnh cụ thể (giảm hệ số chỉnh)
|
||||
onboarding-manual_proportions-auto = Đo kích thước cơ thể tự động
|
||||
|
||||
## Tracker automatic proportions setup
|
||||
onboarding-automatic_proportions-back = Quay lại hướng dẫn reset
|
||||
onboarding-automatic_proportions-title = Đo cơ thể
|
||||
onboarding-automatic_proportions-description = Để SlimeVR hoạt động, phần mềm cần biết chiều dài của thân. Bước đo tự động này sẽ giúp bạn.
|
||||
onboarding-automatic_proportions-manual = Đo thủ công
|
||||
onboarding-automatic_proportions-prev_step = Bước trước
|
||||
onboarding-automatic_proportions-put_trackers_on-title = Đeo tất cả
|
||||
onboarding-automatic_proportions-put_trackers_on-description = Để đo bộ phận, phần mềm sẽ sử dụng tracker mà bạn đã giao cho. Hãy đeo lên tất cả tracker, và xem cái nào là cái nào trên hình bên phải.
|
||||
onboarding-automatic_proportions-put_trackers_on-next = Hoàn thành (Gắn xong)
|
||||
onboarding-automatic_proportions-back = Quay lại cân chỉnh hướng gắn
|
||||
onboarding-automatic_proportions-title = Đo kích thước cơ thể
|
||||
onboarding-automatic_proportions-description = Để tracker có vị trí chính xác, SlimeVR cần biết các chỉ số kích thước cơ thể, làm theo hướng dẫn để đo kích thước cơ thể tự động
|
||||
onboarding-automatic_proportions-manual = Đo kích thước cơ thể thủ công
|
||||
onboarding-automatic_proportions-prev_step = Quay lại
|
||||
onboarding-automatic_proportions-put_trackers_on-title = Đeo tracker lên người
|
||||
onboarding-automatic_proportions-put_trackers_on-description = Để đo kích thước cơ thể, SlimeVR sẽ sử dụng một thuật toán để dự đoán kích thước của các bộ phận, hãy đeo tracker theo đúng vị trí đã thiết lập như hình bên
|
||||
onboarding-automatic_proportions-put_trackers_on-next = Tiếp tục
|
||||
onboarding-automatic_proportions-preparation-title = Chuẩn bị
|
||||
onboarding-automatic_proportions-preparation-description = Đặt ghế đằng sau bạn thẳng trong khu vực chơi VR. Hãy chuẩn bị ngồi trong khi cài đặt đo thân tự động.
|
||||
onboarding-automatic_proportions-preparation-next = Tôi đang đứng trước ghế ngồi
|
||||
onboarding-automatic_proportions-start_recording-title = Chuẩn bị cử động
|
||||
onboarding-automatic_proportions-start_recording-description = Phần mềm sẽ ghi một số củ động cử chỉ. Bước này sẽ bắt đầu ở màn hình tiếp theo. Hãy chuẩn bị khi bấm bắt đầu
|
||||
onboarding-automatic_proportions-start_recording-next = Bắt đầu quay
|
||||
onboarding-automatic_proportions-recording-title = Quay
|
||||
onboarding-automatic_proportions-recording-description-p0 = Đang quay...
|
||||
onboarding-automatic_proportions-recording-description-p1 = Hãy cử động theo hướng dẫn sau:
|
||||
onboarding-automatic_proportions-recording-steps-0 = Cong đầu gối vài lần.
|
||||
onboarding-automatic_proportions-recording-steps-1 = Ngồi lên ghế rồi đứng lên.
|
||||
onboarding-automatic_proportions-recording-steps-2 = Vặn thân trên sang trái, sau đó uốn cong sang phải.
|
||||
onboarding-automatic_proportions-recording-steps-3 = Vặn thân trên sang phải, sau đó uốn cong sang trái.
|
||||
onboarding-automatic_proportions-recording-steps-4 = Đảo xung quanh cho đến khi bộ đếm thời gian kết thúc.
|
||||
onboarding-automatic_proportions-recording-processing = Đang xử lí kết quả
|
||||
onboarding-automatic_proportions-preparation-description = Chuẩn bị một chiếc ghế trong khu vực chơi vì quá trình đo sẽ yêu cầu đến việc ngồi xuống
|
||||
onboarding-automatic_proportions-preparation-next = Đã có ghế ngồi sau lưng
|
||||
onboarding-automatic_proportions-start_recording-title = Chuẩn bị đo
|
||||
onboarding-automatic_proportions-start_recording-description = Phần mềm sẽ đo một số chuyển động, cử chỉ cụ thể, hãy chuẩn bị cho việc di chuyển theo yêu cầu trong phần tiếp theo
|
||||
onboarding-automatic_proportions-start_recording-next = Bắt đầu
|
||||
onboarding-automatic_proportions-recording-title = REC
|
||||
onboarding-automatic_proportions-recording-description-p0 = Đang ghi...
|
||||
onboarding-automatic_proportions-recording-description-p1 = Thực hiện các thao tác sau:
|
||||
onboarding-automatic_proportions-recording-steps-0 = Uốn duỗi chân vài lần (squat)
|
||||
onboarding-automatic_proportions-recording-steps-1 = Ngồi lên ghế rồi đứng lên
|
||||
onboarding-automatic_proportions-recording-steps-2 = Vặn thân sang trái và uốn người sang phải
|
||||
onboarding-automatic_proportions-recording-steps-3 = Vặn thân sang phải và uốn người sang trái
|
||||
onboarding-automatic_proportions-recording-steps-4 = Làm thêm các chuyển động khác đến khi hết thời gian
|
||||
onboarding-automatic_proportions-recording-processing = Đang xử lí kết quả...
|
||||
# $time (Number) - Seconds left for the automatic calibration recording to finish (max 15)
|
||||
onboarding-automatic_proportions-recording-timer = { $time ->
|
||||
[one] 1 giây còn lại
|
||||
*[other] { $time } giây còn
|
||||
[one] 1 second
|
||||
*[other] còn lại { $time } giây
|
||||
}
|
||||
onboarding-automatic_proportions-verify_results-title = Xác nhận kết quả
|
||||
onboarding-automatic_proportions-verify_results-description = Kiểm tra kết quả dưới đây, nó có chính xác không?
|
||||
onboarding-automatic_proportions-verify_results-results = Đang ghi kết quả
|
||||
onboarding-automatic_proportions-verify_results-processing = Đang xử lí kết quả
|
||||
onboarding-automatic_proportions-verify_results-redo = Ghi lại
|
||||
onboarding-automatic_proportions-verify_results-confirm = Kết quả này chính xác!
|
||||
onboarding-automatic_proportions-done-title = Thân đã được đo và lưu.
|
||||
onboarding-automatic_proportions-done-description = Quá trình đo thân đã hoàn thành!
|
||||
onboarding-automatic_proportions-verify_results-title = Kiểm tra kết quả
|
||||
onboarding-automatic_proportions-verify_results-description = So sánh kết quả với chỉ số thực, Lưu ý: kết quả chỉ mang tính tương đối
|
||||
onboarding-automatic_proportions-verify_results-results = Kết quả đo
|
||||
onboarding-automatic_proportions-verify_results-processing = Đang chờ kết quả...
|
||||
onboarding-automatic_proportions-verify_results-redo = Thử lại
|
||||
onboarding-automatic_proportions-verify_results-confirm = Kết quả tương đối chính xác
|
||||
onboarding-automatic_proportions-done-title = Đã lưu chỉ số đo
|
||||
onboarding-automatic_proportions-done-description = Quá trình đo đã hoàn tất
|
||||
|
||||
## Home
|
||||
home-no_trackers = Không tracker nào được phát hiện hoặc giao vị trí
|
||||
home-no_trackers = Không tìm thấy tracker / Tracker chưa được gán
|
||||
|
||||
@@ -37,18 +37,18 @@ body_part-LEFT_LOWER_LEG = 左小腿
|
||||
body_part-LEFT_FOOT = 左脚
|
||||
body_part-LEFT_CONTROLLER = 左控制器
|
||||
|
||||
## Skeleton stuff
|
||||
## Proportions
|
||||
skeleton_bone-NONE = 无
|
||||
skeleton_bone-HEAD = 头部偏移
|
||||
skeleton_bone-NECK = 颈部长度
|
||||
skeleton_bone-CHEST = Chest Length
|
||||
skeleton_bone-CHEST_OFFSET = Chest Offset
|
||||
skeleton_bone-WAIST = Waist Length
|
||||
skeleton_bone-HIP = Hip Length
|
||||
skeleton_bone-CHEST = 胸部长度
|
||||
skeleton_bone-CHEST_OFFSET = 胸部偏移
|
||||
skeleton_bone-WAIST = 腰部长度
|
||||
skeleton_bone-HIP = 髋部长度
|
||||
skeleton_bone-HIP_OFFSET = 髋部偏移
|
||||
skeleton_bone-HIPS_WIDTH = 髋部宽度
|
||||
skeleton_bone-UPPER_LEG = Upper Leg Length
|
||||
skeleton_bone-LOWER_LEG = Lower Leg Length
|
||||
skeleton_bone-UPPER_LEG = 大腿长度
|
||||
skeleton_bone-LOWER_LEG = 小腿长度
|
||||
skeleton_bone-FOOT_LENGTH = 脚部长度
|
||||
skeleton_bone-FOOT_SHIFT = 脚部偏移
|
||||
skeleton_bone-SKELETON_OFFSET = 骨骼偏移
|
||||
@@ -58,18 +58,19 @@ skeleton_bone-UPPER_ARM = 上臂长度
|
||||
skeleton_bone-LOWER_ARM = 前臂距离
|
||||
skeleton_bone-CONTROLLER_Y = 控制器距离 Y
|
||||
skeleton_bone-CONTROLLER_Z = 控制器距离 Z
|
||||
skeleton_bone-ELBOW_OFFSET = 肘部偏移
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = 重置所有比例
|
||||
reset-reset_all = 重置身体比例
|
||||
reset-full = 重置
|
||||
reset-mounting = 重置佩戴
|
||||
reset-quick = 快速重置
|
||||
|
||||
## Serial detection stuff
|
||||
serial_detection-new_device-p0 = 检测到了新的串口设备!
|
||||
serial_detection-new_device-p1 = 输入你的 WiFi 凭据!
|
||||
serial_detection-new_device-p1 = 输入你的 Wi-Fi 凭据!
|
||||
serial_detection-new_device-p2 = 请选择你想对它做什么
|
||||
serial_detection-open_wifi = 连接到 WiFi
|
||||
serial_detection-open_wifi = 连接到 Wi-Fi
|
||||
serial_detection-open_serial = 打开串口控制台
|
||||
serial_detection-submit = 提交!
|
||||
serial_detection-close = 关闭
|
||||
@@ -86,9 +87,25 @@ navbar-settings = 设置
|
||||
bvh-start_recording = 录制 BVH 文件
|
||||
bvh-recording = 录制中...
|
||||
|
||||
## Overlay settings
|
||||
overlay-is_visible_label = 在 SteamVR 中显示覆盖层
|
||||
overlay-is_mirrored_label = 镜像显示覆盖层
|
||||
## Widget: Overlay settings
|
||||
widget-overlay = 覆盖层
|
||||
widget-overlay-is_visible_label = 在 SteamVR 中显示覆盖层
|
||||
widget-overlay-is_mirrored_label = 镜像显示覆盖层
|
||||
|
||||
## Widget: Developer settings
|
||||
widget-developer_mode = 开发者选项
|
||||
widget-developer_mode-high_contrast = 高对比度
|
||||
widget-developer_mode-precise_rotation = 显示精确旋转
|
||||
widget-developer_mode-fast_data_feed = 快速数据更新
|
||||
widget-developer_mode-filter_slimes_and_hmd = 对追踪器和HMD应用滤波
|
||||
widget-developer_mode-sort_by_name = 根据名称排序
|
||||
widget-developer_mode-raw_slime_rotation = 显示原始旋转
|
||||
widget-developer_mode-more_info = 显示更多信息
|
||||
|
||||
## Widget: IMU Visualizer
|
||||
widget-imu_visualizer = 旋转
|
||||
widget-imu_visualizer-rotation_raw = 原始旋转
|
||||
widget-imu_visualizer-rotation_preview = 预览
|
||||
|
||||
## Tracker status
|
||||
tracker-status-none = 无状态
|
||||
@@ -103,6 +120,9 @@ tracker-table-column-name = 名字
|
||||
tracker-table-column-type = 类型
|
||||
tracker-table-column-battery = 电量
|
||||
tracker-table-column-ping = 延迟
|
||||
tracker-table-column-tps = TPS
|
||||
tracker-table-column-temperature = 温度 °C
|
||||
tracker-table-column-linear-acceleration = 加速度 X/Y/Z
|
||||
tracker-table-column-rotation = 旋转 X/Y/Z
|
||||
tracker-table-column-position = 位置 X/Y/Z
|
||||
tracker-table-column-url = 地址
|
||||
@@ -142,7 +162,7 @@ tracker-part_card-no_name = 未命名
|
||||
tracker-part_card-unassigned = 未分配
|
||||
|
||||
## Body assignment menu
|
||||
body_assignment_menu = 你想把追踪器戴在哪里?
|
||||
body_assignment_menu = 你想将此追踪器戴在哪里?
|
||||
body_assignment_menu-description = 选择要将此追踪器分配到的位置,或者你也可以选择一次管理所有追踪器,而不是逐个管理。
|
||||
body_assignment_menu-show_advanced_locations = 显示高级分配位置
|
||||
body_assignment_menu-manage_trackers = 管理所有追踪器
|
||||
@@ -151,7 +171,7 @@ body_assignment_menu-unassign_tracker = 取消分配追踪器
|
||||
## Tracker assignment menu
|
||||
# A -translation_key (with a dash in the front) means that it's a label.
|
||||
# It can only be used in the translation file, it's nice for reusing names and that kind of stuff.
|
||||
#
|
||||
#
|
||||
# We are using it here because english doesn't require changing the text in each case but
|
||||
# maybe your language does.
|
||||
-tracker_selection-part = 哪个追踪器将被分配到你的
|
||||
@@ -183,7 +203,7 @@ tracker_selection_menu-assigned = 已分配的追踪器
|
||||
tracker_selection_menu-dont_assign = 不分配
|
||||
|
||||
## Mounting menu
|
||||
mounting_selection_menu = 你想把追踪器放在哪里?
|
||||
mounting_selection_menu = 你想将此追踪器戴在哪里?
|
||||
mounting_selection_menu-close = 关闭
|
||||
|
||||
## Sidebar settings
|
||||
@@ -242,11 +262,11 @@ settings-general-tracker_mechanics-drift_compensation-max_resets-label = 使用
|
||||
settings-general-fk_settings = FK 设置
|
||||
settings-general-fk_settings-leg_tweak = 腿部调整
|
||||
settings-general-fk_settings-leg_tweak-description = 本设置可以减少甚至消除脚部穿入地板的情况,但是当你跪在地上的时候可能产生一些问题. 脚滑矫正可以矫正一些脚滑溜冰的问题, 但是可能会降低某些动作的准确性。
|
||||
# Floor clip:
|
||||
# Floor clip:
|
||||
# why the name - came from the idea of noclip in video games, but is the opposite where clipping to the floor is a desired feature
|
||||
# definition - Prevents the foot trackers from going lower than they where when a reset was performed
|
||||
settings-general-fk_settings-leg_tweak-floor_clip = 地板限制
|
||||
# Skating correction:
|
||||
# Skating correction:
|
||||
# why the name - without this enabled the feet will often slide across the ground as if your skating across the ground,
|
||||
# since this largely prevents this it corrects for it hence skating correction (note this may be renamed to sliding correction)
|
||||
# definition - Guesses when each foot is in contact with the ground and uses that information to improve tracking
|
||||
@@ -255,6 +275,7 @@ settings-general-fk_settings-leg_tweak-skating_correction-amount = 脚滑矫正
|
||||
settings-general-fk_settings-arm_fk = 手臂 FK
|
||||
settings-general-fk_settings-arm_fk-description = 更改手臂的追踪方式。
|
||||
settings-general-fk_settings-arm_fk-force_arms = 强制从头显获得数据
|
||||
settings-general-fk_settings-arm_fk-i_pose = Use i-pose instead of t-pose
|
||||
settings-general-fk_settings-skeleton_settings = 骨架设置
|
||||
settings-general-fk_settings-skeleton_settings-description = 打开或关闭骨架设置。建议保持这些设置不变。
|
||||
settings-general-fk_settings-skeleton_settings-extended_spine = 脊柱延伸
|
||||
@@ -299,7 +320,7 @@ settings-general-interface-lang-placeholder = 选择要使用的语言
|
||||
settings-serial = 串口控制台
|
||||
# This cares about multilines
|
||||
settings-serial-description =
|
||||
这是用于串口通信的实时信息馈送。
|
||||
这里用于显示串口的实时信息流。
|
||||
如果你需要了解固件是否出现问题,这将会很有用。
|
||||
settings-serial-connection_lost = 串口连接丢失,正在重新连接..
|
||||
settings-serial-reboot = 重新启动
|
||||
@@ -350,7 +371,7 @@ settings-osc-vrchat-network-port_out =
|
||||
.label = 输出端口
|
||||
.placeholder = 输出端口(默认 9000)
|
||||
settings-osc-vrchat-network-address = 网络地址
|
||||
settings-osc-vrchat-network-address-description = 选择将数据发送到 VRChat 的地址(检查设备上的 WiFi 设置)
|
||||
settings-osc-vrchat-network-address-description = 选择将数据发送到 VRChat 的地址(检查设备上的 Wi-Fi 设置)
|
||||
settings-osc-vrchat-network-address-placeholder = VRChat IP 地址
|
||||
settings-osc-vrchat-network-trackers = 追踪器
|
||||
settings-osc-vrchat-network-trackers-description = 切换数据的发送和接收
|
||||
@@ -365,14 +386,14 @@ onboarding-skip = 跳过设置
|
||||
onboarding-continue = 继续
|
||||
onboarding-wip = 仍在开发中
|
||||
|
||||
## WiFi setup
|
||||
## Wi-Fi setup
|
||||
onboarding-wifi_creds-back = 返回简介
|
||||
onboarding-wifi_creds = 输入 WiFi 凭据
|
||||
onboarding-wifi_creds = 输入 Wi-Fi 凭据
|
||||
# This cares about multilines
|
||||
onboarding-wifi_creds-description =
|
||||
追踪器将使用这些凭据连接到 WiFi
|
||||
请使用当前连接到 WiFi 的凭据
|
||||
onboarding-wifi_creds-skip = 跳过 WiFi 设置
|
||||
追踪器将使用这些凭据连接到 Wi-Fi
|
||||
请使用当前连接到 Wi-Fi 的凭据
|
||||
onboarding-wifi_creds-skip = 跳过 Wi-Fi 设置
|
||||
onboarding-wifi_creds-submit = 提交!
|
||||
onboarding-wifi_creds-ssid =
|
||||
.label = SSID
|
||||
@@ -406,15 +427,15 @@ onboarding-done-description = 享受你的全身追踪体验吧
|
||||
onboarding-done-close = 关闭向导
|
||||
|
||||
## Tracker connection setup
|
||||
onboarding-connect_tracker-back = 返回到 WiFi 凭据设置
|
||||
onboarding-connect_tracker-back = 返回到 Wi-Fi 凭据设置
|
||||
onboarding-connect_tracker-title = 连接追踪器
|
||||
onboarding-connect_tracker-description-p0 = 来到了我第二喜欢的环节,连接所有的追踪器!
|
||||
onboarding-connect_tracker-description-p1 = 只需通过 USB 连接所有尚未连接的设备即可。
|
||||
onboarding-connect_tracker-issue-serial = QAQ 我在连接时遇到问题!
|
||||
onboarding-connect_tracker-usb = USB 追踪器
|
||||
onboarding-connect_tracker-connection_status-connecting = 正在发送 WiFi 凭据
|
||||
onboarding-connect_tracker-connection_status-connected = WiFi 已连接
|
||||
onboarding-connect_tracker-connection_status-error = 无法连接到 WiFi
|
||||
onboarding-connect_tracker-connection_status-connecting = 正在发送 Wi-Fi 凭据
|
||||
onboarding-connect_tracker-connection_status-connected = Wi-Fi 已连接
|
||||
onboarding-connect_tracker-connection_status-error = 无法连接到 Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-start_connecting = 寻找追踪器
|
||||
onboarding-connect_tracker-connection_status-handshake = 已连接到服务器
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
@@ -429,7 +450,7 @@ onboarding-connect_tracker-connected_trackers = { $amount ->
|
||||
onboarding-connect_tracker-next = 所有的追踪器都连接好了
|
||||
|
||||
## Tracker assignment setup
|
||||
onboarding-assign_trackers-back = 返回 WiFi 凭据设置
|
||||
onboarding-assign_trackers-back = 返回 Wi-Fi 凭据设置
|
||||
onboarding-assign_trackers-title = 分配追踪器
|
||||
onboarding-assign_trackers-description = 让我们选择哪个追踪器在哪里。单击要放置追踪器的部位
|
||||
# Look at translation of onboarding-connect_tracker-connected_trackers on how to use plurals
|
||||
|
||||
@@ -23,7 +23,7 @@ custom-protocol = ["tauri/custom-protocol"]
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1.2", features = [] }
|
||||
cfg_aliases = "0.1"
|
||||
shadow-rs = "0.19"
|
||||
shadow-rs = "0.20"
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1"
|
||||
@@ -36,10 +36,12 @@ clap-verbosity-flag = "2"
|
||||
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/tauri-plugin-window-state", rev = "refs/pull/52/head" }
|
||||
rand = "0.8.5"
|
||||
tempfile = "3"
|
||||
which = "4.3.0"
|
||||
which = "4.3"
|
||||
glob = "0.3"
|
||||
open = "3"
|
||||
shadow-rs = { version = "0.19", default-features = false }
|
||||
shadow-rs = { version = "0.20", default-features = false }
|
||||
const_format = "0.2.30"
|
||||
cfg-if = "1"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
win32job = "1"
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::io::Write;
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::process::CommandExt;
|
||||
use std::panic;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Child, Stdio};
|
||||
|
||||
use clap::Parser;
|
||||
@@ -15,7 +15,6 @@ use shadow_rs::shadow;
|
||||
use tauri::api::process::Command;
|
||||
use tauri::Manager;
|
||||
use tempfile::Builder;
|
||||
use which::which_all;
|
||||
|
||||
#[cfg(windows)]
|
||||
/// For Commands on Windows so they dont create terminals
|
||||
@@ -53,41 +52,25 @@ struct Cli {
|
||||
verbose: clap_verbosity_flag::Verbosity,
|
||||
}
|
||||
|
||||
fn is_valid_path(path: &PathBuf) -> bool {
|
||||
fn is_valid_path(path: &Path) -> bool {
|
||||
path.join("slimevr.jar").exists()
|
||||
}
|
||||
|
||||
fn get_launch_path(cli: Cli) -> Option<PathBuf> {
|
||||
if let Some(path) = cli.launch_from_path {
|
||||
if path.exists() && is_valid_path(&path) {
|
||||
return Some(path);
|
||||
}
|
||||
}
|
||||
|
||||
let path = env::current_dir().unwrap();
|
||||
if is_valid_path(&path) {
|
||||
return Some(path);
|
||||
}
|
||||
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
if is_valid_path(&path) {
|
||||
return Some(path);
|
||||
}
|
||||
|
||||
let path = PathBuf::from("/usr/share/slimevr/");
|
||||
if is_valid_path(&path) {
|
||||
return Some(path);
|
||||
}
|
||||
|
||||
// This is only for AppImage
|
||||
if let Some(appimage) = env::var_os("APPDIR") {
|
||||
let path = PathBuf::from(appimage);
|
||||
if is_valid_path(&path) {
|
||||
return Some(path);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
let paths = [
|
||||
cli.launch_from_path,
|
||||
// AppImage passes the fakeroot in `APPDIR` env var.
|
||||
env::var_os("APPDIR").map(|x| PathBuf::from(x)),
|
||||
env::current_dir().ok(),
|
||||
Some(PathBuf::from(env!("CARGO_MANIFEST_DIR"))),
|
||||
// For flatpak container
|
||||
Some(PathBuf::from("/app/share/slimevr/")),
|
||||
Some(PathBuf::from("/usr/share/slimevr/")),
|
||||
];
|
||||
paths
|
||||
.into_iter()
|
||||
.filter_map(|x| x)
|
||||
.find(|x| is_valid_path(x))
|
||||
}
|
||||
|
||||
fn spawn_java(java: &OsStr, java_version: &OsStr) -> std::io::Result<Child> {
|
||||
@@ -306,7 +289,23 @@ fn valid_java_paths() -> Vec<(OsString, i32)> {
|
||||
|
||||
// Otherwise check if anything else is a supported version
|
||||
let mut childs = vec![];
|
||||
for java in which_all(JAVA_BIN).unwrap() {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "macos")] {
|
||||
// TODO: Actually use macOS paths
|
||||
let libs = which::which_all(JAVA_BIN).unwrap();
|
||||
} else if #[cfg(unix)] {
|
||||
// Linux JVMs are saved on /usr/lib/jvm from what I found out,
|
||||
// there is usually a default dir and a default-runtime dir also which are linked
|
||||
// to the current default runtime and the current default JDK (I think it's JDK)
|
||||
let libs = glob::glob(concatcp!("/usr/lib/jvm/*/bin/", JAVA_BIN))
|
||||
.unwrap()
|
||||
.filter_map(|res| res.ok());
|
||||
} else {
|
||||
let libs = which::which_all(JAVA_BIN).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
for java in libs {
|
||||
let res = spawn_java(java.as_os_str(), java_version.as_os_str());
|
||||
|
||||
match res {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import classNames from 'classnames';
|
||||
import { ReactNode } from 'react';
|
||||
import { ResetType } from 'solarxr-protocol';
|
||||
import { useConfig } from '../hooks/config';
|
||||
import { useLayout } from '../hooks/layout';
|
||||
import { BVHButton } from './BVHButton';
|
||||
import { ResetButton } from './home/ResetButton';
|
||||
import { Navbar } from './Navbar';
|
||||
import { TopBar } from './TopBar';
|
||||
import { DeveloperModeWidget } from './widgets/DeveloperModeWidget';
|
||||
import { OverlayWidget } from './widgets/OverlayWidget';
|
||||
|
||||
export function MainLayoutRoute({
|
||||
@@ -19,6 +21,7 @@ export function MainLayoutRoute({
|
||||
}) {
|
||||
const { layoutHeight, ref } = useLayout<HTMLDivElement>();
|
||||
const { layoutWidth, ref: refw } = useLayout<HTMLDivElement>();
|
||||
const { config } = useConfig();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -59,6 +62,11 @@ export function MainLayoutRoute({
|
||||
<div className="w-full">
|
||||
<OverlayWidget></OverlayWidget>
|
||||
</div>
|
||||
{config?.debug && (
|
||||
<div className="w-full">
|
||||
<DeveloperModeWidget></DeveloperModeWidget>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -50,101 +50,101 @@ export function PersonFrontIcon({ width }: { width?: number }) {
|
||||
cx="139.004"
|
||||
cy="170"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_HAND]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="122"
|
||||
cy="93"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_UPPER_ARM]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="122"
|
||||
cy="93"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_SHOULDER]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="139.004"
|
||||
cy="170"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_LOWER_ARM]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="97.004"
|
||||
cy="360"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_LOWER_LEG]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="103.004"
|
||||
cy="260"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_UPPER_LEG]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="97.004"
|
||||
cy="360"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_FOOT]}
|
||||
/>
|
||||
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="26.004"
|
||||
cy="170"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.RIGHT_HAND]}
|
||||
/>
|
||||
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="43"
|
||||
cx="122"
|
||||
cy="93"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.RIGHT_UPPER_ARM]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="43"
|
||||
cx="122"
|
||||
cy="93"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.RIGHT_SHOULDER]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="26.004"
|
||||
cx="139.004"
|
||||
cy="170"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.RIGHT_LOWER_ARM]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="67.004"
|
||||
cx="97.004"
|
||||
cy="360"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.RIGHT_LOWER_LEG]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="103.004"
|
||||
cy="260"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.RIGHT_UPPER_LEG]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="97.004"
|
||||
cy="360"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.RIGHT_FOOT]}
|
||||
/>
|
||||
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="26.004"
|
||||
cy="170"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_HAND]}
|
||||
/>
|
||||
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="43"
|
||||
cy="93"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_UPPER_ARM]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="43"
|
||||
cy="93"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_SHOULDER]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="26.004"
|
||||
cy="170"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_LOWER_ARM]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="67.004"
|
||||
cy="360"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.LEFT_LOWER_LEG]}
|
||||
/>
|
||||
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="61.004"
|
||||
cy="260"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.RIGHT_UPPER_LEG]}
|
||||
id={BodyPart[BodyPart.LEFT_UPPER_LEG]}
|
||||
/>
|
||||
<circle
|
||||
className="body-part-circle"
|
||||
cx="67.004"
|
||||
cy="360"
|
||||
r={CIRCLE_RADIUS}
|
||||
id={BodyPart[BodyPart.RIGHT_FOOT]}
|
||||
id={BodyPart[BodyPart.LEFT_FOOT]}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
17
gui/src/components/commons/icon/WarningIcon.tsx
Normal file
17
gui/src/components/commons/icon/WarningIcon.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
export function WarningIcon(props: any) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
{...props}
|
||||
className={`w-7 h-7 ${props.className || ''}`}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -77,35 +77,35 @@ export function BodyAssignment({
|
||||
{advanced && (
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_SHOULDER]}
|
||||
role={BodyPart.RIGHT_SHOULDER}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_SHOULDER)}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_SHOULDER]}
|
||||
role={BodyPart.LEFT_SHOULDER}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_SHOULDER)}
|
||||
direction="right"
|
||||
/>
|
||||
)}
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_UPPER_ARM]}
|
||||
role={BodyPart.RIGHT_UPPER_ARM}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_UPPER_ARM)}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_UPPER_ARM]}
|
||||
role={BodyPart.LEFT_UPPER_ARM}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_UPPER_ARM)}
|
||||
direction="right"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_LOWER_ARM]}
|
||||
role={BodyPart.RIGHT_LOWER_ARM}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_LOWER_ARM)}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_LOWER_ARM]}
|
||||
role={BodyPart.LEFT_LOWER_ARM}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_LOWER_ARM)}
|
||||
direction="right"
|
||||
/>
|
||||
|
||||
{advanced && (
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_HAND]}
|
||||
role={BodyPart.RIGHT_HAND}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_HAND)}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_HAND]}
|
||||
role={BodyPart.LEFT_HAND}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_HAND)}
|
||||
direction="right"
|
||||
/>
|
||||
)}
|
||||
@@ -113,24 +113,24 @@ export function BodyAssignment({
|
||||
<div className="flex flex-col gap-2">
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_UPPER_LEG]}
|
||||
role={BodyPart.RIGHT_UPPER_LEG}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_UPPER_LEG)}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_UPPER_LEG]}
|
||||
role={BodyPart.LEFT_UPPER_LEG}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_UPPER_LEG)}
|
||||
direction="right"
|
||||
/>
|
||||
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_LOWER_LEG]}
|
||||
role={BodyPart.RIGHT_LOWER_LEG}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_LOWER_LEG)}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_LOWER_LEG]}
|
||||
role={BodyPart.LEFT_LOWER_LEG}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_LOWER_LEG)}
|
||||
direction="right"
|
||||
/>
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_FOOT]}
|
||||
role={BodyPart.RIGHT_FOOT}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_FOOT)}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_FOOT]}
|
||||
role={BodyPart.LEFT_FOOT}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_FOOT)}
|
||||
direction="right"
|
||||
/>
|
||||
</div>
|
||||
@@ -150,18 +150,18 @@ export function BodyAssignment({
|
||||
{advanced && (
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_SHOULDER]}
|
||||
role={BodyPart.LEFT_SHOULDER}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_SHOULDER)}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_SHOULDER]}
|
||||
role={BodyPart.RIGHT_SHOULDER}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_SHOULDER)}
|
||||
direction="left"
|
||||
/>
|
||||
)}
|
||||
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_UPPER_ARM]}
|
||||
role={BodyPart.LEFT_UPPER_ARM}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_UPPER_ARM)}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_UPPER_ARM]}
|
||||
role={BodyPart.RIGHT_UPPER_ARM}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_UPPER_ARM)}
|
||||
direction="left"
|
||||
/>
|
||||
</div>
|
||||
@@ -169,17 +169,17 @@ export function BodyAssignment({
|
||||
<div className="flex flex-col gap-2">
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_LOWER_ARM]}
|
||||
role={BodyPart.LEFT_LOWER_ARM}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_LOWER_ARM)}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_LOWER_ARM]}
|
||||
role={BodyPart.RIGHT_LOWER_ARM}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_LOWER_ARM)}
|
||||
direction="left"
|
||||
/>
|
||||
{advanced && (
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_HAND]}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_HAND)}
|
||||
role={BodyPart.LEFT_HAND}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_HAND]}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_HAND)}
|
||||
role={BodyPart.RIGHT_HAND}
|
||||
direction="left"
|
||||
/>
|
||||
)}
|
||||
@@ -204,24 +204,24 @@ export function BodyAssignment({
|
||||
<div className="flex flex-col gap-2">
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_UPPER_LEG]}
|
||||
role={BodyPart.LEFT_UPPER_LEG}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_UPPER_LEG)}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_UPPER_LEG]}
|
||||
role={BodyPart.RIGHT_UPPER_LEG}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_UPPER_LEG)}
|
||||
direction="left"
|
||||
/>
|
||||
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_LOWER_LEG]}
|
||||
role={BodyPart.LEFT_LOWER_LEG}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_LOWER_LEG)}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_LOWER_LEG]}
|
||||
role={BodyPart.RIGHT_LOWER_LEG}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_LOWER_LEG)}
|
||||
direction="left"
|
||||
/>
|
||||
<TrackerPartCard
|
||||
onlyAssigned={onlyAssigned}
|
||||
td={trackerPartGrouped[BodyPart.LEFT_FOOT]}
|
||||
role={BodyPart.LEFT_FOOT}
|
||||
onClick={() => onRoleSelected(BodyPart.LEFT_FOOT)}
|
||||
td={trackerPartGrouped[BodyPart.RIGHT_FOOT]}
|
||||
role={BodyPart.RIGHT_FOOT}
|
||||
onClick={() => onRoleSelected(BodyPart.RIGHT_FOOT)}
|
||||
direction="left"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import Quaternion from 'quaternion';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { AssignTrackerRequestT, BodyPart, RpcMessage } from 'solarxr-protocol';
|
||||
import { FlatDeviceTracker } from '../../../../hooks/app';
|
||||
import { useOnboarding } from '../../../../hooks/onboarding';
|
||||
import { useTrackers } from '../../../../hooks/tracker';
|
||||
import { useWebsocketAPI } from '../../../../hooks/websocket-api';
|
||||
import { QuaternionToQuatT } from '../../../../maths/quaternion';
|
||||
import { MountingOrientationDegreesToQuatT } from '../../../../maths/quaternion';
|
||||
import { ArrowLink } from '../../../commons/ArrowLink';
|
||||
import { Button } from '../../../commons/Button';
|
||||
import { TipBox } from '../../../commons/TipBox';
|
||||
@@ -41,13 +40,13 @@ export function ManualMountingPage() {
|
||||
[assignedTrackers]
|
||||
);
|
||||
|
||||
const onDirectionSelected = (mountingOrientation: number) => {
|
||||
const onDirectionSelected = (mountingOrientationDegrees: number) => {
|
||||
(trackerPartGrouped[selectedRole] || []).forEach((td) => {
|
||||
const assignreq = new AssignTrackerRequestT();
|
||||
|
||||
assignreq.bodyPosition = td.tracker.info?.bodyPart || BodyPart.NONE;
|
||||
assignreq.mountingOrientation = QuaternionToQuatT(
|
||||
Quaternion.fromEuler(0, +mountingOrientation, 0)
|
||||
assignreq.mountingOrientation = MountingOrientationDegreesToQuatT(
|
||||
mountingOrientationDegrees
|
||||
);
|
||||
assignreq.trackerId = td.tracker.trackerId;
|
||||
sendRPCPacket(RpcMessage.AssignTrackerRequest, assignreq);
|
||||
|
||||
@@ -54,6 +54,7 @@ interface SettingsForm {
|
||||
floorClip: boolean;
|
||||
skatingCorrection: boolean;
|
||||
viveEmulation: boolean;
|
||||
iPose: boolean;
|
||||
};
|
||||
tapDetection: {
|
||||
tapMountingResetEnabled: boolean;
|
||||
@@ -92,6 +93,7 @@ const defaultValues = {
|
||||
floorClip: false,
|
||||
skatingCorrection: false,
|
||||
viveEmulation: false,
|
||||
iPose: false,
|
||||
},
|
||||
filtering: { amount: 0.1, type: FilteringType.NONE },
|
||||
driftCompensation: {
|
||||
@@ -149,6 +151,7 @@ export function GeneralSettings() {
|
||||
toggles.extendedSpine = values.toggles.extendedSpine;
|
||||
toggles.forceArmsFromHmd = values.toggles.forceArmsFromHmd;
|
||||
toggles.viveEmulation = values.toggles.viveEmulation;
|
||||
toggles.iPose = values.toggles.iPose;
|
||||
legTweaks.correctionStrength = values.legTweaks.correctionStrength;
|
||||
|
||||
modelSettings.toggles = toggles;
|
||||
@@ -437,18 +440,16 @@ export function GeneralSettings() {
|
||||
)}
|
||||
</Typography>
|
||||
<div className="flex flex-col pt-2 pb-4">
|
||||
<Typography color="secondary">
|
||||
{l10n
|
||||
.getString(
|
||||
'settings-general-tracker_mechanics-drift_compensation-description'
|
||||
)
|
||||
.split('\n')
|
||||
.map((line, i) => (
|
||||
<Typography color="secondary" key={i}>
|
||||
{line}
|
||||
</Typography>
|
||||
))}
|
||||
</Typography>
|
||||
{l10n
|
||||
.getString(
|
||||
'settings-general-tracker_mechanics-drift_compensation-description'
|
||||
)
|
||||
.split('\n')
|
||||
.map((line, i) => (
|
||||
<Typography color="secondary" key={i}>
|
||||
{line}
|
||||
</Typography>
|
||||
))}
|
||||
</div>
|
||||
<CheckBox
|
||||
variant="toggle"
|
||||
@@ -555,6 +556,17 @@ export function GeneralSettings() {
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid sm:grid-cols-2 pb-5">
|
||||
<CheckBox
|
||||
variant="toggle"
|
||||
outlined
|
||||
control={control}
|
||||
name="toggles.iPose"
|
||||
label={l10n.getString(
|
||||
'settings-general-fk_settings-arm_fk-i_pose'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{config?.debug && (
|
||||
<>
|
||||
<Typography bold>
|
||||
@@ -758,76 +770,61 @@ export function GeneralSettings() {
|
||||
<Typography variant="main-title">
|
||||
{l10n.getString('settings-general-interface')}
|
||||
</Typography>
|
||||
<div className="gap-4 grid">
|
||||
<div className="grid sm:grid-cols-2">
|
||||
<div>
|
||||
<Typography bold>
|
||||
{l10n.getString('settings-general-interface-dev_mode')}
|
||||
</Typography>
|
||||
<div className="flex flex-col">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'settings-general-interface-dev_mode-description'
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="pt-2">
|
||||
<CheckBox
|
||||
variant="toggle"
|
||||
control={control}
|
||||
outlined
|
||||
name="interface.devmode"
|
||||
label={l10n.getString(
|
||||
'settings-general-interface-dev_mode-label'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid sm:grid-cols-2">
|
||||
<div>
|
||||
<Typography bold>
|
||||
{l10n.getString(
|
||||
'settings-general-interface-serial_detection'
|
||||
)}
|
||||
</Typography>
|
||||
<div className="flex flex-col">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'settings-general-interface-serial_detection-description'
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="pt-2">
|
||||
<CheckBox
|
||||
variant="toggle"
|
||||
control={control}
|
||||
outlined
|
||||
name="interface.watchNewDevices"
|
||||
label={l10n.getString(
|
||||
'settings-general-interface-serial_detection-label'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid sm:grid-cols-2">
|
||||
<div>
|
||||
<Typography bold>
|
||||
{l10n.getString('settings-general-interface-lang')}
|
||||
</Typography>
|
||||
<div className="flex flex-col">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'settings-general-interface-lang-description'
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="pt-2">
|
||||
<LangSelector />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Typography bold>
|
||||
{l10n.getString('settings-general-interface-dev_mode')}
|
||||
</Typography>
|
||||
<div className="flex flex-col pt-1 pb-2">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'settings-general-interface-dev_mode-description'
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="grid sm:grid-cols-2 pb-4">
|
||||
<CheckBox
|
||||
variant="toggle"
|
||||
control={control}
|
||||
outlined
|
||||
name="interface.devmode"
|
||||
label={l10n.getString(
|
||||
'settings-general-interface-dev_mode-label'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Typography bold>
|
||||
{l10n.getString('settings-general-interface-serial_detection')}
|
||||
</Typography>
|
||||
<div className="flex flex-col pt-1 pb-2">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'settings-general-interface-serial_detection-description'
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="grid sm:grid-cols-2 pb-4">
|
||||
<CheckBox
|
||||
variant="toggle"
|
||||
control={control}
|
||||
outlined
|
||||
name="interface.watchNewDevices"
|
||||
label={l10n.getString(
|
||||
'settings-general-interface-serial_detection-label'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Typography bold>
|
||||
{l10n.getString('settings-general-interface-lang')}
|
||||
</Typography>
|
||||
<div className="flex flex-col pt-1 pb-2">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString('settings-general-interface-lang-description')}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="grid sm:grid-cols-2 pb-4">
|
||||
<LangSelector />
|
||||
</div>
|
||||
</>
|
||||
</SettingsPageLayout>
|
||||
|
||||
@@ -3,11 +3,17 @@ import { Typography } from '../commons/Typography';
|
||||
|
||||
export function TrackerBattery({
|
||||
value,
|
||||
voltage,
|
||||
disabled,
|
||||
textColor = 'secondary',
|
||||
}: {
|
||||
value: number;
|
||||
voltage?: number | null;
|
||||
disabled?: boolean;
|
||||
textColor?: string;
|
||||
}) {
|
||||
const percent = value * 100;
|
||||
|
||||
return (
|
||||
<div className="flex gap-2">
|
||||
<div className="flex flex-col justify-around">
|
||||
@@ -15,9 +21,10 @@ export function TrackerBattery({
|
||||
</div>
|
||||
{!disabled && (
|
||||
<div className="w-10">
|
||||
<Typography color="secondary">
|
||||
{(value * 100).toFixed(0)} %
|
||||
</Typography>
|
||||
<Typography color={textColor}>{percent.toFixed(0)} %</Typography>
|
||||
{voltage && (
|
||||
<Typography color={textColor}>{voltage.toFixed(2)} V</Typography>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{disabled && (
|
||||
|
||||
@@ -44,10 +44,11 @@ function TrackerBig({
|
||||
/>
|
||||
)}
|
||||
<div className="flex gap-2">
|
||||
{device.hardwareStatus.rssi && device.hardwareStatus.ping && (
|
||||
{(device.hardwareStatus.rssi != null ||
|
||||
device.hardwareStatus.ping != null) && (
|
||||
<TrackerWifi
|
||||
rssi={device.hardwareStatus.rssi}
|
||||
ping={device.hardwareStatus.ping}
|
||||
rssi={device.hardwareStatus.rssi || 0}
|
||||
ping={device.hardwareStatus.ping || 0}
|
||||
disabled={tracker.status === TrackerStatusEnum.DISCONNECTED}
|
||||
></TrackerWifi>
|
||||
)}
|
||||
@@ -90,10 +91,11 @@ function TrackerSmol({
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col justify-center items-center">
|
||||
{device.hardwareStatus.rssi && device.hardwareStatus.ping && (
|
||||
{(device.hardwareStatus.rssi != null ||
|
||||
device.hardwareStatus.ping != null) && (
|
||||
<TrackerWifi
|
||||
rssi={device.hardwareStatus.rssi}
|
||||
ping={device.hardwareStatus.ping}
|
||||
rssi={device.hardwareStatus.rssi || 0}
|
||||
ping={device.hardwareStatus.ping || 0}
|
||||
disabled={tracker.status === TrackerStatusEnum.DISCONNECTED}
|
||||
></TrackerWifi>
|
||||
)}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { IPv4 } from 'ip-num/IPNumber';
|
||||
import Quaternion from 'quaternion';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useParams } from 'react-router-dom';
|
||||
@@ -7,8 +6,10 @@ import { AssignTrackerRequestT, BodyPart, RpcMessage } from 'solarxr-protocol';
|
||||
import { useDebouncedEffect } from '../../hooks/timeout';
|
||||
import { useTrackerFromId } from '../../hooks/tracker';
|
||||
import { useWebsocketAPI } from '../../hooks/websocket-api';
|
||||
import { DEG_TO_RAD, RAD_TO_DEG } from '../../maths/angle';
|
||||
import { FixEuler, GetYaw, QuaternionToQuatT } from '../../maths/quaternion';
|
||||
import {
|
||||
getYawInDegrees,
|
||||
MountingOrientationDegreesToQuatT,
|
||||
} from '../../maths/quaternion';
|
||||
import { ArrowLink } from '../commons/ArrowLink';
|
||||
import { Button } from '../commons/Button';
|
||||
import { FootIcon } from '../commons/icon/FootIcon';
|
||||
@@ -19,6 +20,10 @@ import { SingleTrackerBodyAssignmentMenu } from './SingleTrackerBodyAssignmentMe
|
||||
import { TrackerCard } from './TrackerCard';
|
||||
import { CheckBox } from '../commons/Checkbox';
|
||||
import { useLocalization } from '@fluent/react';
|
||||
import { IMUVisualizerWidget } from '../widgets/IMUVisualizerWidget';
|
||||
import { useConfig } from '../../hooks/config';
|
||||
import { WarningIcon } from '../commons/icon/WarningIcon';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export const rotationToQuatMap = {
|
||||
FRONT: 180,
|
||||
@@ -36,6 +41,7 @@ const rotationsLabels = {
|
||||
|
||||
export function TrackerSettingsPage() {
|
||||
const { l10n } = useLocalization();
|
||||
const { config } = useConfig();
|
||||
|
||||
const { sendRPCPacket } = useWebsocketAPI();
|
||||
const [firstLoad, setFirstLoad] = useState(false);
|
||||
@@ -59,18 +65,13 @@ export function TrackerSettingsPage() {
|
||||
|
||||
const tracker = useTrackerFromId(trackernum, deviceid);
|
||||
|
||||
const onDirectionSelected = (mountingOrientation: number) => {
|
||||
const onDirectionSelected = (mountingOrientationDegrees: number) => {
|
||||
if (!tracker) return;
|
||||
|
||||
const assignreq = new AssignTrackerRequestT();
|
||||
|
||||
assignreq.mountingOrientation = QuaternionToQuatT(
|
||||
Quaternion.fromEuler(
|
||||
0,
|
||||
0,
|
||||
FixEuler(+mountingOrientation) * DEG_TO_RAD,
|
||||
'XZY'
|
||||
)
|
||||
assignreq.mountingOrientation = MountingOrientationDegreesToQuatT(
|
||||
mountingOrientationDegrees
|
||||
);
|
||||
assignreq.bodyPosition = tracker?.tracker.info?.bodyPart || BodyPart.NONE;
|
||||
assignreq.trackerId = tracker?.tracker.trackerId;
|
||||
@@ -92,9 +93,9 @@ export function TrackerSettingsPage() {
|
||||
setSelectBodypart(false);
|
||||
};
|
||||
|
||||
const currRotation = useMemo(() => {
|
||||
const currRotationDegrees = useMemo(() => {
|
||||
return tracker?.tracker.info?.mountingOrientation
|
||||
? FixEuler(GetYaw(tracker.tracker.info?.mountingOrientation) * RAD_TO_DEG)
|
||||
? getYawInDegrees(tracker?.tracker.info?.mountingOrientation)
|
||||
: rotationToQuatMap.FRONT;
|
||||
}, [tracker?.tracker.info?.mountingOrientation]);
|
||||
|
||||
@@ -108,10 +109,9 @@ export function TrackerSettingsPage() {
|
||||
return;
|
||||
const assignreq = new AssignTrackerRequestT();
|
||||
assignreq.bodyPosition = tracker?.tracker.info?.bodyPart || BodyPart.NONE;
|
||||
assignreq.mountingOrientation = assignreq.mountingOrientation =
|
||||
QuaternionToQuatT(
|
||||
Quaternion.fromEuler(0, 0, FixEuler(+currRotation) * DEG_TO_RAD, 'XZY')
|
||||
);
|
||||
assignreq.mountingOrientation =
|
||||
MountingOrientationDegreesToQuatT(currRotationDegrees);
|
||||
|
||||
assignreq.displayName = trackerName;
|
||||
assignreq.trackerId = tracker?.tracker.trackerId;
|
||||
assignreq.allowDriftCompensation = allowDriftCompensation;
|
||||
@@ -162,7 +162,7 @@ export function TrackerSettingsPage() {
|
||||
onClose={() => setSelectRotation(false)}
|
||||
onDirectionSelected={onDirectionSelected}
|
||||
></MountingSelectionMenu>
|
||||
<div className="flex gap-2 md:h-full flex-wrap md:flex-row ">
|
||||
<div className="flex gap-2 md:h-full max-md:flex-wrap md:flex-row ">
|
||||
<div className="flex flex-col w-full md:max-w-xs gap-2">
|
||||
{tracker && (
|
||||
<TrackerCard
|
||||
@@ -222,6 +222,11 @@ export function TrackerSettingsPage() {
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
{tracker?.tracker && config?.debug && (
|
||||
<IMUVisualizerWidget
|
||||
tracker={tracker?.tracker}
|
||||
></IMUVisualizerWidget>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col flex-grow bg-background-70 rounded-lg p-5 gap-3">
|
||||
<ArrowLink to="/">
|
||||
@@ -241,8 +246,18 @@ export function TrackerSettingsPage() {
|
||||
</Typography>
|
||||
<div className="flex justify-between bg-background-80 w-full p-3 rounded-lg">
|
||||
<div className="flex gap-3 items-center">
|
||||
<FootIcon></FootIcon>
|
||||
<Typography>
|
||||
{tracker?.tracker.info?.bodyPart !== BodyPart.NONE && (
|
||||
<FootIcon></FootIcon>
|
||||
)}
|
||||
{tracker?.tracker.info?.bodyPart === BodyPart.NONE && (
|
||||
<WarningIcon className="text-yellow-300" />
|
||||
)}
|
||||
<Typography
|
||||
color={classNames({
|
||||
'text-yellow-300':
|
||||
tracker?.tracker.info?.bodyPart === BodyPart.NONE,
|
||||
})}
|
||||
>
|
||||
{l10n.getString(
|
||||
'body_part-' +
|
||||
BodyPart[tracker?.tracker.info?.bodyPart || BodyPart.NONE]
|
||||
@@ -270,7 +285,7 @@ export function TrackerSettingsPage() {
|
||||
<div className="flex gap-3 items-center">
|
||||
<FootIcon></FootIcon>
|
||||
<Typography>
|
||||
{l10n.getString(rotationsLabels[currRotation])}
|
||||
{l10n.getString(rotationsLabels[currRotationDegrees])}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="flex">
|
||||
@@ -284,31 +299,27 @@ export function TrackerSettingsPage() {
|
||||
</div>
|
||||
</div>
|
||||
{tracker?.tracker.info?.isImu && (
|
||||
<>
|
||||
<div className="flex flex-col gap-2 w-full mt-3">
|
||||
<Typography variant="section-title">
|
||||
{l10n.getString(
|
||||
'tracker-settings-drift_compensation_section'
|
||||
<div className="flex flex-col gap-2 w-full mt-3">
|
||||
<Typography variant="section-title">
|
||||
{l10n.getString('tracker-settings-drift_compensation_section')}
|
||||
</Typography>
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'tracker-settings-drift_compensation_section-description'
|
||||
)}
|
||||
</Typography>
|
||||
<div className="flex">
|
||||
<CheckBox
|
||||
variant="toggle"
|
||||
outlined
|
||||
name="allowDriftCompensation"
|
||||
control={control}
|
||||
label={l10n.getString(
|
||||
'tracker-settings-drift_compensation_section-edit'
|
||||
)}
|
||||
</Typography>
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'tracker-settings-drift_compensation_section-description'
|
||||
)}
|
||||
</Typography>
|
||||
<div className="flex">
|
||||
<CheckBox
|
||||
variant="toggle"
|
||||
outlined
|
||||
name="allowDriftCompensation"
|
||||
control={control}
|
||||
label={l10n.getString(
|
||||
'tracker-settings-drift_compensation_section-edit'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col gap-2 w-full mt-3">
|
||||
<Typography variant="section-title">
|
||||
|
||||
@@ -4,24 +4,31 @@ import { Typography } from '../commons/Typography';
|
||||
export function TrackerWifi({
|
||||
rssi,
|
||||
ping,
|
||||
rssiShowNumeric,
|
||||
disabled,
|
||||
textColor = 'secondary',
|
||||
}: {
|
||||
rssi: number;
|
||||
ping: number;
|
||||
rssiShowNumeric?: boolean;
|
||||
disabled?: boolean;
|
||||
textColor?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex gap-2">
|
||||
<div className="flex flex-col justify-around ">
|
||||
<div className="flex gap-2 whitespace-nowrap">
|
||||
<div className="flex flex-col justify-around">
|
||||
<WifiIcon value={rssi} disabled={disabled} />
|
||||
</div>
|
||||
{!disabled && (
|
||||
<div className="w-10">
|
||||
<Typography color="secondary">{ping} ms</Typography>
|
||||
<div className="w-12">
|
||||
<Typography color={textColor}>{ping} ms</Typography>
|
||||
{rssiShowNumeric && (
|
||||
<Typography color={textColor}>{rssi} dBm</Typography>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{disabled && (
|
||||
<div className="flex flex-col justify-center w-10">
|
||||
<div className="flex flex-col justify-center w-12">
|
||||
<div className="w-7 h-1 bg-background-30 rounded-full"></div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import classNames from 'classnames';
|
||||
import { IPv4 } from 'ip-num/IPNumber';
|
||||
import { MouseEventHandler, ReactNode, useState } from 'react';
|
||||
import { MouseEventHandler, ReactNode, useState, useMemo } from 'react';
|
||||
import {
|
||||
TrackerDataT,
|
||||
TrackerIdT,
|
||||
@@ -14,8 +14,45 @@ import { TrackerBattery } from './TrackerBattery';
|
||||
import { TrackerStatus } from './TrackerStatus';
|
||||
import { TrackerWifi } from './TrackerWifi';
|
||||
import { useLocalization } from '@fluent/react';
|
||||
import { formatVector3 } from '../utils/formatting';
|
||||
import { useConfig } from '../../hooks/config';
|
||||
|
||||
export function TrackerNameCol({ tracker }: { tracker: TrackerDataT }) {
|
||||
enum DisplayColumn {
|
||||
NAME,
|
||||
TYPE,
|
||||
BATTERY,
|
||||
PING,
|
||||
TPS,
|
||||
ROTATION,
|
||||
TEMPERATURE,
|
||||
LINEAR_ACCELERATION,
|
||||
POSITION,
|
||||
URL,
|
||||
}
|
||||
|
||||
const displayColumns: { [k: string]: boolean } = {
|
||||
[DisplayColumn.NAME]: true,
|
||||
[DisplayColumn.TYPE]: true,
|
||||
[DisplayColumn.BATTERY]: true,
|
||||
[DisplayColumn.PING]: true,
|
||||
[DisplayColumn.TPS]: true,
|
||||
[DisplayColumn.ROTATION]: true,
|
||||
[DisplayColumn.TEMPERATURE]: true,
|
||||
[DisplayColumn.LINEAR_ACCELERATION]: true,
|
||||
[DisplayColumn.POSITION]: true,
|
||||
[DisplayColumn.URL]: true,
|
||||
};
|
||||
|
||||
const isSlime = ({ device }: FlatDeviceTracker) =>
|
||||
device?.hardwareInfo?.manufacturer === 'SlimeVR';
|
||||
|
||||
const getDeviceName = ({ device }: FlatDeviceTracker) =>
|
||||
device?.customName?.toString() || '';
|
||||
|
||||
const getTrackerName = ({ tracker }: FlatDeviceTracker) =>
|
||||
tracker?.info?.customName?.toString() || '';
|
||||
|
||||
export function TrackerNameCell({ tracker }: { tracker: TrackerDataT }) {
|
||||
const { useName } = useTracker(tracker);
|
||||
|
||||
const name = useName();
|
||||
@@ -33,17 +70,28 @@ export function TrackerNameCol({ tracker }: { tracker: TrackerDataT }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function TrackerRotCol({ tracker }: { tracker: TrackerDataT }) {
|
||||
const { useRotationDegrees } = useTracker(tracker);
|
||||
export function TrackerRotCell({
|
||||
tracker,
|
||||
precise,
|
||||
color,
|
||||
referenceAdjusted,
|
||||
}: {
|
||||
tracker: TrackerDataT;
|
||||
precise?: boolean;
|
||||
color?: string;
|
||||
referenceAdjusted?: boolean;
|
||||
}) {
|
||||
const { useRawRotationEulerDegrees, useRefAdjRotationEulerDegrees } =
|
||||
useTracker(tracker);
|
||||
|
||||
const rot = useRotationDegrees();
|
||||
const rot = referenceAdjusted
|
||||
? useRefAdjRotationEulerDegrees()
|
||||
: useRawRotationEulerDegrees();
|
||||
|
||||
return (
|
||||
<Typography color="secondary">
|
||||
<Typography color={color}>
|
||||
<span className="whitespace-nowrap">
|
||||
{`${rot.pitch.toFixed(0)} / ${rot.yaw.toFixed(0)} / ${rot.roll.toFixed(
|
||||
0
|
||||
)}`}
|
||||
{formatVector3(rot, precise ? 2 : 0)}
|
||||
</span>
|
||||
</Typography>
|
||||
);
|
||||
@@ -90,7 +138,7 @@ export function RowContainer({
|
||||
'min-h-[50px] flex flex-col justify-center px-3',
|
||||
rounded === 'left' && 'rounded-l-lg',
|
||||
rounded === 'right' && 'rounded-r-lg',
|
||||
hover ? 'bg-background-50' : 'bg-background-60'
|
||||
hover ? 'bg-background-50 cursor-pointer' : 'bg-background-60'
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
@@ -108,168 +156,218 @@ export function TrackersTable({
|
||||
}) {
|
||||
const { l10n } = useLocalization();
|
||||
const [hoverTracker, setHoverTracker] = useState<TrackerIdT | null>(null);
|
||||
const { config } = useConfig();
|
||||
|
||||
const trackerEqual = (id: TrackerIdT | null) =>
|
||||
id?.trackerNum == hoverTracker?.trackerNum &&
|
||||
(!id?.deviceId || id.deviceId.id == hoverTracker?.deviceId?.id);
|
||||
|
||||
const filteringEnabled =
|
||||
config?.debug && config?.devSettings?.filterSlimesAndHMD;
|
||||
const sortingEnabled = config?.debug && config?.devSettings?.sortByName;
|
||||
// TODO: fix memo
|
||||
const filteredSortedTrackers = useMemo(() => {
|
||||
const list = filteringEnabled
|
||||
? flatTrackers.filter((t) => getDeviceName(t) === 'HMD' || isSlime(t))
|
||||
: flatTrackers;
|
||||
|
||||
if (sortingEnabled) {
|
||||
list.sort((a, b) => getTrackerName(a).localeCompare(getTrackerName(b)));
|
||||
}
|
||||
return list;
|
||||
}, [flatTrackers, filteringEnabled, sortingEnabled]);
|
||||
|
||||
const fontColor = config?.devSettings?.highContrast ? 'primary' : 'secondary';
|
||||
const moreInfo = config?.devSettings?.moreInfo;
|
||||
|
||||
const hasTemperature = !!filteredSortedTrackers.find(
|
||||
({ tracker }) => Number(tracker?.temp?.temp) != 0
|
||||
);
|
||||
displayColumns[DisplayColumn.TEMPERATURE] = hasTemperature || false;
|
||||
displayColumns[DisplayColumn.POSITION] = moreInfo || false;
|
||||
displayColumns[DisplayColumn.LINEAR_ACCELERATION] = moreInfo || false;
|
||||
displayColumns[DisplayColumn.URL] = moreInfo || false;
|
||||
const displayColumnsKeys = Object.keys(displayColumns).filter(
|
||||
(k) => displayColumns[k]
|
||||
);
|
||||
const firstColumnId = +displayColumnsKeys[0];
|
||||
const lastColumnId = +displayColumnsKeys[displayColumnsKeys.length - 1];
|
||||
|
||||
function column({
|
||||
id,
|
||||
label,
|
||||
labelClassName,
|
||||
row,
|
||||
}: {
|
||||
id: DisplayColumn;
|
||||
label: string;
|
||||
labelClassName?: string;
|
||||
row: (data: FlatDeviceTracker) => ReactNode | null;
|
||||
}) {
|
||||
let rounded: 'left' | 'right' | 'none' = 'none';
|
||||
if (firstColumnId === id) rounded = 'left';
|
||||
else if (lastColumnId === id) rounded = 'right';
|
||||
|
||||
if (!displayColumns[id]) return <></>;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('flex flex-col gap-1', {
|
||||
'flex-grow': lastColumnId === id,
|
||||
})}
|
||||
>
|
||||
<div className={`flex px-3 whitespace-nowrap ${labelClassName}`}>
|
||||
{label}
|
||||
</div>
|
||||
{filteredSortedTrackers.map((data, index) => (
|
||||
<RowContainer
|
||||
rounded={rounded}
|
||||
key={index}
|
||||
tracker={data.tracker}
|
||||
onClick={() => clickedTracker(data.tracker)}
|
||||
hover={trackerEqual(data.tracker.trackerId)}
|
||||
onMouseOver={() => setHoverTracker(data.tracker.trackerId)}
|
||||
onMouseOut={() => setHoverTracker(null)}
|
||||
>
|
||||
{row(data) || <></>}
|
||||
</RowContainer>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex w-full overflow-x-auto py-2">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex px-3">
|
||||
{l10n.getString('tracker-table-column-name')}
|
||||
</div>
|
||||
{flatTrackers.map(({ tracker }, index) => (
|
||||
<RowContainer
|
||||
key={index}
|
||||
rounded="left"
|
||||
tracker={tracker}
|
||||
onClick={() => clickedTracker(tracker)}
|
||||
hover={trackerEqual(tracker.trackerId)}
|
||||
onMouseOver={() => setHoverTracker(tracker.trackerId)}
|
||||
onMouseOut={() => setHoverTracker(null)}
|
||||
>
|
||||
<TrackerNameCol tracker={tracker}></TrackerNameCol>
|
||||
</RowContainer>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex px-3">
|
||||
{l10n.getString('tracker-table-column-type')}
|
||||
</div>
|
||||
{flatTrackers.map(({ device, tracker }, index) => (
|
||||
<RowContainer
|
||||
key={index}
|
||||
tracker={tracker}
|
||||
onClick={() => clickedTracker(tracker)}
|
||||
hover={trackerEqual(tracker.trackerId)}
|
||||
onMouseOver={() => setHoverTracker(tracker.trackerId)}
|
||||
onMouseOut={() => setHoverTracker(null)}
|
||||
>
|
||||
<Typography color="secondary">
|
||||
{device?.hardwareInfo?.manufacturer || '--'}
|
||||
</Typography>
|
||||
</RowContainer>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex px-3">
|
||||
{l10n.getString('tracker-table-column-battery')}
|
||||
</div>
|
||||
{flatTrackers.map(({ device, tracker }, index) => (
|
||||
<RowContainer
|
||||
key={index}
|
||||
tracker={tracker}
|
||||
onClick={() => clickedTracker(tracker)}
|
||||
hover={trackerEqual(tracker.trackerId)}
|
||||
onMouseOver={() => setHoverTracker(tracker.trackerId)}
|
||||
onMouseOut={() => setHoverTracker(null)}
|
||||
>
|
||||
{(device &&
|
||||
device.hardwareStatus &&
|
||||
device.hardwareStatus.batteryPctEstimate && (
|
||||
<TrackerBattery
|
||||
value={device.hardwareStatus.batteryPctEstimate / 100}
|
||||
disabled={tracker.status === TrackerStatusEnum.DISCONNECTED}
|
||||
/>
|
||||
)) || <></>}
|
||||
</RowContainer>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex px-3">
|
||||
{l10n.getString('tracker-table-column-ping')}
|
||||
</div>
|
||||
{flatTrackers.map(({ device, tracker }, index) => (
|
||||
<RowContainer
|
||||
key={index}
|
||||
tracker={tracker}
|
||||
onClick={() => clickedTracker(tracker)}
|
||||
hover={trackerEqual(tracker.trackerId)}
|
||||
onMouseOver={() => setHoverTracker(tracker.trackerId)}
|
||||
onMouseOut={() => setHoverTracker(null)}
|
||||
>
|
||||
{(device &&
|
||||
device.hardwareStatus &&
|
||||
device.hardwareStatus.rssi &&
|
||||
device.hardwareStatus.ping && (
|
||||
<TrackerWifi
|
||||
rssi={device.hardwareStatus.rssi}
|
||||
ping={device.hardwareStatus.ping}
|
||||
disabled={tracker.status === TrackerStatusEnum.DISCONNECTED}
|
||||
></TrackerWifi>
|
||||
)) || <></>}
|
||||
</RowContainer>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex px-3 whitespace-nowrap">
|
||||
{l10n.getString('tracker-table-column-rotation')}
|
||||
</div>
|
||||
{flatTrackers.map(({ tracker }, index) => (
|
||||
<RowContainer
|
||||
key={index}
|
||||
tracker={tracker}
|
||||
onClick={() => clickedTracker(tracker)}
|
||||
hover={trackerEqual(tracker.trackerId)}
|
||||
onMouseOver={() => setHoverTracker(tracker.trackerId)}
|
||||
onMouseOut={() => setHoverTracker(null)}
|
||||
>
|
||||
<TrackerRotCol tracker={tracker} />
|
||||
</RowContainer>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex px-3 whitespace-nowrap">
|
||||
{l10n.getString('tracker-table-column-position')}
|
||||
</div>
|
||||
{flatTrackers.map(({ tracker }, index) => (
|
||||
<RowContainer
|
||||
key={index}
|
||||
tracker={tracker}
|
||||
onClick={() => clickedTracker(tracker)}
|
||||
hover={trackerEqual(tracker.trackerId)}
|
||||
onMouseOver={() => setHoverTracker(tracker.trackerId)}
|
||||
onMouseOut={() => setHoverTracker(null)}
|
||||
>
|
||||
{(tracker.position && (
|
||||
<Typography color="secondary">
|
||||
<span className="whitespace-nowrap">
|
||||
{`${tracker.position?.x.toFixed(
|
||||
0
|
||||
)} / ${tracker.position?.y.toFixed(
|
||||
0
|
||||
)} / ${tracker.position?.z.toFixed(0)}`}
|
||||
</span>
|
||||
</Typography>
|
||||
)) || <></>}
|
||||
</RowContainer>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1 flex-grow">
|
||||
<div className="flex px-3">
|
||||
{l10n.getString('tracker-table-column-url')}
|
||||
</div>
|
||||
{column({
|
||||
id: DisplayColumn.NAME,
|
||||
label: l10n.getString('tracker-table-column-name'),
|
||||
row: ({ tracker }) => (
|
||||
<TrackerNameCell tracker={tracker}></TrackerNameCell>
|
||||
),
|
||||
})}
|
||||
|
||||
{flatTrackers.map(({ device, tracker }, index) => (
|
||||
<RowContainer
|
||||
key={index}
|
||||
rounded="right"
|
||||
{column({
|
||||
id: DisplayColumn.TYPE,
|
||||
label: l10n.getString('tracker-table-column-type'),
|
||||
row: ({ device }) => (
|
||||
<Typography color={fontColor}>
|
||||
{device?.hardwareInfo?.manufacturer || '--'}
|
||||
</Typography>
|
||||
),
|
||||
})}
|
||||
|
||||
{column({
|
||||
id: DisplayColumn.BATTERY,
|
||||
label: l10n.getString('tracker-table-column-battery'),
|
||||
row: ({ device, tracker }) =>
|
||||
device?.hardwareStatus?.batteryPctEstimate && (
|
||||
<TrackerBattery
|
||||
value={device.hardwareStatus.batteryPctEstimate / 100}
|
||||
voltage={device.hardwareStatus?.batteryVoltage}
|
||||
disabled={tracker.status === TrackerStatusEnum.DISCONNECTED}
|
||||
textColor={fontColor}
|
||||
/>
|
||||
),
|
||||
})}
|
||||
|
||||
{column({
|
||||
id: DisplayColumn.PING,
|
||||
label: l10n.getString('tracker-table-column-ping'),
|
||||
row: ({ device, tracker }) =>
|
||||
(device?.hardwareStatus?.rssi != null ||
|
||||
device?.hardwareStatus?.ping != null) && (
|
||||
<TrackerWifi
|
||||
rssi={device?.hardwareStatus?.rssi || 0}
|
||||
rssiShowNumeric
|
||||
ping={device?.hardwareStatus?.ping || 0}
|
||||
disabled={tracker.status === TrackerStatusEnum.DISCONNECTED}
|
||||
textColor={fontColor}
|
||||
></TrackerWifi>
|
||||
),
|
||||
})}
|
||||
|
||||
{column({
|
||||
id: DisplayColumn.TPS,
|
||||
label: l10n.getString('tracker-table-column-tps'),
|
||||
row: ({ device }) => (
|
||||
<Typography color={fontColor}>
|
||||
{(device?.hardwareStatus?.tps != null && (
|
||||
<>{device.hardwareStatus.tps || 0}</>
|
||||
)) || <></>}
|
||||
</Typography>
|
||||
),
|
||||
})}
|
||||
|
||||
{column({
|
||||
id: DisplayColumn.ROTATION,
|
||||
label: l10n.getString('tracker-table-column-rotation'),
|
||||
labelClassName: classNames({
|
||||
'w-44': config?.devSettings?.preciseRotation,
|
||||
'w-32': !config?.devSettings?.preciseRotation,
|
||||
}),
|
||||
row: ({ tracker }) => (
|
||||
<TrackerRotCell
|
||||
tracker={tracker}
|
||||
onClick={() => clickedTracker(tracker)}
|
||||
hover={trackerEqual(tracker.trackerId)}
|
||||
onMouseOver={() => setHoverTracker(tracker.trackerId)}
|
||||
onMouseOut={() => setHoverTracker(null)}
|
||||
>
|
||||
<Typography color="secondary">
|
||||
udp://
|
||||
{IPv4.fromNumber(
|
||||
device?.hardwareInfo?.ipAddress?.addr || 0
|
||||
).toString()}
|
||||
precise={config?.devSettings?.preciseRotation}
|
||||
referenceAdjusted={!config?.devSettings?.rawSlimeRotation}
|
||||
color={fontColor}
|
||||
/>
|
||||
),
|
||||
})}
|
||||
|
||||
{column({
|
||||
id: DisplayColumn.TEMPERATURE,
|
||||
label: l10n.getString('tracker-table-column-temperature'),
|
||||
row: ({ tracker }) =>
|
||||
tracker.temp?.temp != 0 && (
|
||||
<Typography color={fontColor}>
|
||||
<span className="whitespace-nowrap">
|
||||
{`${tracker.temp?.temp.toFixed(2)}`}
|
||||
</span>
|
||||
</Typography>
|
||||
</RowContainer>
|
||||
))}
|
||||
</div>
|
||||
),
|
||||
})}
|
||||
|
||||
{column({
|
||||
id: DisplayColumn.LINEAR_ACCELERATION,
|
||||
label: l10n.getString('tracker-table-column-linear-acceleration'),
|
||||
labelClassName: 'w-36',
|
||||
row: ({ tracker }) =>
|
||||
tracker.linearAcceleration && (
|
||||
<Typography color={fontColor}>
|
||||
<span className="whitespace-nowrap">
|
||||
{formatVector3(tracker.linearAcceleration, 1)}
|
||||
</span>
|
||||
</Typography>
|
||||
),
|
||||
})}
|
||||
|
||||
{column({
|
||||
id: DisplayColumn.POSITION,
|
||||
label: l10n.getString('tracker-table-column-position'),
|
||||
labelClassName: 'w-36',
|
||||
row: ({ tracker }) =>
|
||||
tracker.position && (
|
||||
<Typography color={fontColor}>
|
||||
<span className="whitespace-nowrap">
|
||||
{formatVector3(tracker.position, 1)}
|
||||
</span>
|
||||
</Typography>
|
||||
),
|
||||
})}
|
||||
|
||||
{column({
|
||||
id: DisplayColumn.URL,
|
||||
label: l10n.getString('tracker-table-column-url'),
|
||||
row: ({ device }) => (
|
||||
<Typography color={fontColor}>
|
||||
udp://
|
||||
{IPv4.fromNumber(
|
||||
device?.hardwareInfo?.ipAddress?.addr || 0
|
||||
).toString()}
|
||||
</Typography>
|
||||
),
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,3 +2,7 @@ import { BodyPart } from 'solarxr-protocol';
|
||||
|
||||
export const bodypartToString = (id: BodyPart) =>
|
||||
BodyPart[id].replace(/_/g, ' ');
|
||||
|
||||
type Vector3 = { x: number; y: number; z: number };
|
||||
export const formatVector3 = ({ x, y, z }: Vector3, precision = 0) =>
|
||||
`${x.toFixed(precision)} / ${y.toFixed(precision)} / ${z.toFixed(precision)}`;
|
||||
|
||||
83
gui/src/components/widgets/DeveloperModeWidget.tsx
Normal file
83
gui/src/components/widgets/DeveloperModeWidget.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useConfig } from '../../hooks/config';
|
||||
import { useWebsocketAPI } from '../../hooks/websocket-api';
|
||||
import { CheckBox } from '../commons/Checkbox';
|
||||
import { useLocalization } from '@fluent/react';
|
||||
import { Typography } from '../commons/Typography';
|
||||
|
||||
export interface DeveloperModeWidgetForm {
|
||||
highContrast: boolean;
|
||||
preciseRotation: boolean;
|
||||
fastDataFeed: boolean;
|
||||
filterSlimesAndHMD: boolean;
|
||||
sortByName: boolean;
|
||||
rawSlimeRotation: boolean;
|
||||
moreInfo: boolean;
|
||||
}
|
||||
|
||||
export function DeveloperModeWidget() {
|
||||
const { l10n } = useLocalization();
|
||||
const { config, setConfig } = useConfig();
|
||||
const { reconnect } = useWebsocketAPI();
|
||||
|
||||
const { reset, control, handleSubmit, watch } =
|
||||
useForm<DeveloperModeWidgetForm>({
|
||||
defaultValues: {
|
||||
highContrast: false,
|
||||
preciseRotation: false,
|
||||
fastDataFeed: false,
|
||||
filterSlimesAndHMD: false,
|
||||
sortByName: false,
|
||||
rawSlimeRotation: false,
|
||||
moreInfo: false,
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
reset(config?.devSettings || {});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const subscription = watch(() => handleSubmit(onSubmit)());
|
||||
return () => subscription.unsubscribe();
|
||||
}, []);
|
||||
|
||||
const onSubmit = async (formData: DeveloperModeWidgetForm) => {
|
||||
const needReconnect =
|
||||
config?.devSettings?.fastDataFeed !== formData.fastDataFeed;
|
||||
await setConfig({ devSettings: formData });
|
||||
if (needReconnect) reconnect();
|
||||
};
|
||||
|
||||
const makeToggle = ([name, label]: string[], index: number) => (
|
||||
<CheckBox
|
||||
key={index}
|
||||
control={control}
|
||||
variant="toggle"
|
||||
name={name}
|
||||
label={l10n.getString(`widget-developer_mode-${label}`)}
|
||||
></CheckBox>
|
||||
);
|
||||
|
||||
const toggles = {
|
||||
highContrast: 'high_contrast',
|
||||
preciseRotation: 'precise_rotation',
|
||||
fastDataFeed: 'fast_data_feed',
|
||||
filterSlimesAndHMD: 'filter_slimes_and_hmd',
|
||||
sortByName: 'sort_by_name',
|
||||
rawSlimeRotation: 'raw_slime_rotation',
|
||||
moreInfo: 'more_info',
|
||||
};
|
||||
|
||||
return (
|
||||
<form className="bg-background-60 flex flex-col w-full rounded-md px-2">
|
||||
<div className="mt-2 px-1">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString('widget-developer_mode')}
|
||||
</Typography>
|
||||
</div>
|
||||
{Object.entries(toggles).map(makeToggle)}
|
||||
</form>
|
||||
);
|
||||
}
|
||||
169
gui/src/components/widgets/IMUVisualizerWidget.tsx
Normal file
169
gui/src/components/widgets/IMUVisualizerWidget.tsx
Normal file
@@ -0,0 +1,169 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { TrackerDataT } from 'solarxr-protocol';
|
||||
import { useTracker } from '../../hooks/tracker';
|
||||
import { Typography } from '../commons/Typography';
|
||||
import { formatVector3 } from '../utils/formatting';
|
||||
import { Canvas, useThree } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
import { CanvasTexture, PerspectiveCamera } from 'three';
|
||||
import { Button } from '../commons/Button';
|
||||
import { QuatObject } from '../../maths/quaternion';
|
||||
import { useLocalization } from '@fluent/react';
|
||||
|
||||
const groundColor = '#4444aa';
|
||||
const R = '#f01662';
|
||||
const G = '#92ff1a';
|
||||
const B = '#00b0ff';
|
||||
|
||||
const scale = 1.4;
|
||||
const width = 2 * scale;
|
||||
const height = 1 * scale;
|
||||
const depth = 3 * scale;
|
||||
const defaultFaces = ['Right', 'Left', 'Top', 'Bottom', 'Back', 'Front'];
|
||||
const faceParams = [
|
||||
{ scaleX: depth, scaleY: height, color: R }, // left right
|
||||
{ scaleX: width, scaleY: depth, color: G }, // top bottom
|
||||
{ scaleX: width, scaleY: height, color: B }, // front back
|
||||
];
|
||||
|
||||
type FaceTypeProps = {
|
||||
index: number;
|
||||
scaleX: number;
|
||||
scaleY: number;
|
||||
resolution?: number;
|
||||
font?: string;
|
||||
opacity?: number;
|
||||
color?: string;
|
||||
hoverColor?: string;
|
||||
textColor?: string;
|
||||
strokeColor?: string;
|
||||
faces?: string[];
|
||||
};
|
||||
|
||||
const FaceMaterial = ({
|
||||
index,
|
||||
scaleX = 1,
|
||||
scaleY = 1,
|
||||
resolution = 128,
|
||||
font = 'bold 46px monospace',
|
||||
faces = defaultFaces,
|
||||
color = '#f0f0f0',
|
||||
textColor = 'black',
|
||||
strokeColor = 'black',
|
||||
opacity = 1,
|
||||
}: FaceTypeProps) => {
|
||||
const gl = useThree((state) => state.gl);
|
||||
const texture = useMemo(() => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = resolution * scaleX;
|
||||
canvas.height = resolution * scaleY;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const context = canvas.getContext('2d')!;
|
||||
context.fillStyle = color;
|
||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
context.strokeStyle = strokeColor;
|
||||
context.lineWidth = 2;
|
||||
context.strokeRect(0, 0, canvas.width, canvas.height);
|
||||
context.font = font;
|
||||
context.textAlign = 'center';
|
||||
context.fillStyle = textColor;
|
||||
context.fillText(
|
||||
faces[index].toUpperCase(),
|
||||
canvas.width / 2,
|
||||
canvas.height / 2 + 20
|
||||
);
|
||||
return new CanvasTexture(canvas);
|
||||
}, [index, faces, font, color, textColor, strokeColor]);
|
||||
return (
|
||||
<meshLambertMaterial
|
||||
map={texture}
|
||||
map-encoding={gl.outputEncoding}
|
||||
map-anisotropy={gl.capabilities.getMaxAnisotropy() || 1}
|
||||
attach={`material-${index}`}
|
||||
color={'white'}
|
||||
transparent
|
||||
opacity={opacity}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const FaceCube = (props: Partial<FaceTypeProps>) => (
|
||||
<mesh>
|
||||
{[...Array(6)].map((_, i) => (
|
||||
<FaceMaterial key={i} {...props} index={i} {...faceParams[(i / 2) | 0]} />
|
||||
))}
|
||||
<boxGeometry args={[width, height, depth]} />
|
||||
</mesh>
|
||||
);
|
||||
|
||||
function SceneRenderer({ x, y, z, w }: QuatObject) {
|
||||
return (
|
||||
<Canvas
|
||||
className="container"
|
||||
style={{ height: 200, background: 'transparent' }}
|
||||
onCreated={({ camera }) => {
|
||||
(camera as PerspectiveCamera).fov = 60;
|
||||
}}
|
||||
>
|
||||
<ambientLight intensity={0.5} />
|
||||
<spotLight position={[20, 20, 20]} angle={0.09} penumbra={1} />
|
||||
<group quaternion={new THREE.Quaternion(x, y, z, w)}>
|
||||
<FaceCube />
|
||||
<axesHelper args={[10]} />
|
||||
</group>
|
||||
|
||||
<mesh position={[0, -3, 0]} rotation={[-Math.PI / 2, 0, 0]}>
|
||||
<planeGeometry args={[50, 50, 10, 10]} />
|
||||
<meshBasicMaterial
|
||||
wireframe
|
||||
color={groundColor}
|
||||
transparent
|
||||
opacity={0.2}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
</Canvas>
|
||||
);
|
||||
}
|
||||
|
||||
export function IMUVisualizerWidget({ tracker }: { tracker: TrackerDataT }) {
|
||||
const { l10n } = useLocalization();
|
||||
const [enabled, setEnabled] = useState(false);
|
||||
const quat = tracker?.rotationIdentityAdjusted || new THREE.Quaternion();
|
||||
|
||||
const { useRawRotationEulerDegrees, useIdentAdjRotationEulerDegrees } =
|
||||
useTracker(tracker);
|
||||
|
||||
return (
|
||||
<div className="bg-background-70 flex flex-col p-3 rounded-lg gap-2">
|
||||
<Typography variant="section-title">
|
||||
{l10n.getString('widget-imu_visualizer')}
|
||||
</Typography>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString('widget-imu_visualizer-rotation_raw')}
|
||||
</Typography>
|
||||
<Typography>
|
||||
{formatVector3(useRawRotationEulerDegrees(), 2)}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString('widget-imu_visualizer-rotation_preview')}
|
||||
</Typography>
|
||||
<Typography>
|
||||
{formatVector3(useIdentAdjRotationEulerDegrees(), 2)}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
{!enabled && (
|
||||
<Button variant="secondary" onClick={() => setEnabled(true)}>
|
||||
{l10n.getString('widget-imu_visualizer-rotation_preview')}
|
||||
</Button>
|
||||
)}
|
||||
{enabled && <SceneRenderer {...quat}></SceneRenderer>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from '../../hooks/pubSub';
|
||||
import { CheckBox } from '../commons/Checkbox';
|
||||
import { useLocalization } from '@fluent/react';
|
||||
import { Typography } from '../commons/Typography';
|
||||
|
||||
export function OverlayWidget() {
|
||||
const { l10n } = useLocalization();
|
||||
@@ -64,17 +65,22 @@ export function OverlayWidget() {
|
||||
|
||||
return (
|
||||
<form className="bg-background-60 flex flex-col w-full rounded-md px-2">
|
||||
<div className="mt-2 px-1">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString('widget-overlay')}
|
||||
</Typography>
|
||||
</div>
|
||||
<CheckBox
|
||||
control={control}
|
||||
name="isVisible"
|
||||
variant="toggle"
|
||||
label={l10n.getString('overlay-is_visible_label')}
|
||||
label={l10n.getString('widget-overlay-is_visible_label')}
|
||||
></CheckBox>
|
||||
<CheckBox
|
||||
control={control}
|
||||
name="isMirrored"
|
||||
variant="toggle"
|
||||
label={l10n.getString('overlay-is_mirrored_label')}
|
||||
label={l10n.getString('widget-overlay-is_mirrored_label')}
|
||||
></CheckBox>
|
||||
</form>
|
||||
);
|
||||
|
||||
@@ -10,16 +10,14 @@ import {
|
||||
} from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
DataFeedConfigT,
|
||||
DataFeedMessage,
|
||||
DataFeedUpdateT,
|
||||
DeviceDataMaskT,
|
||||
DeviceDataT,
|
||||
StartDataFeedT,
|
||||
TrackerDataMaskT,
|
||||
TrackerDataT,
|
||||
} from 'solarxr-protocol';
|
||||
import { useConfig } from './config';
|
||||
import { useDataFeedConfig } from './datafeed-config';
|
||||
import { useWebsocketAPI } from './websocket-api';
|
||||
|
||||
export interface FlatDeviceTracker {
|
||||
@@ -52,6 +50,7 @@ export function useProvideAppContext(): AppContext {
|
||||
const { sendDataFeedPacket, useDataFeedPacket, isConnected } =
|
||||
useWebsocketAPI();
|
||||
const { config } = useConfig();
|
||||
const { dataFeedConfig } = useDataFeedConfig();
|
||||
const navigate = useNavigate();
|
||||
const [state, dispatch] = useReducer<Reducer<AppState, AppStateAction>>(
|
||||
reducer,
|
||||
@@ -62,24 +61,8 @@ export function useProvideAppContext(): AppContext {
|
||||
|
||||
useEffect(() => {
|
||||
if (isConnected) {
|
||||
const trackerData = new TrackerDataMaskT();
|
||||
trackerData.position = true;
|
||||
trackerData.rotation = true;
|
||||
trackerData.info = true;
|
||||
trackerData.status = true;
|
||||
trackerData.temp = true;
|
||||
|
||||
const dataMask = new DeviceDataMaskT();
|
||||
dataMask.deviceData = true;
|
||||
dataMask.trackerData = trackerData;
|
||||
|
||||
const config = new DataFeedConfigT();
|
||||
config.dataMask = dataMask;
|
||||
config.minimumTimeSinceLast = 100;
|
||||
config.syntheticTrackersMask = trackerData;
|
||||
|
||||
const startDataFeed = new StartDataFeedT();
|
||||
startDataFeed.dataFeeds = [config];
|
||||
startDataFeed.dataFeeds = [dataFeedConfig];
|
||||
sendDataFeedPacket(DataFeedMessage.StartDataFeed, startDataFeed);
|
||||
}
|
||||
}, [isConnected]);
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from '@tauri-apps/api/fs';
|
||||
|
||||
import { createContext, useContext, useRef, useState } from 'react';
|
||||
import { DeveloperModeWidgetForm } from '../components/widgets/DeveloperModeWidget';
|
||||
|
||||
export interface WindowConfig {
|
||||
width: number;
|
||||
@@ -20,6 +21,7 @@ export interface Config {
|
||||
lang: string;
|
||||
doneOnboarding: boolean;
|
||||
watchNewDevices: boolean;
|
||||
devSettings: DeveloperModeWidgetForm;
|
||||
}
|
||||
|
||||
export interface ConfigContext {
|
||||
|
||||
37
gui/src/hooks/datafeed-config.ts
Normal file
37
gui/src/hooks/datafeed-config.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {
|
||||
DataFeedConfigT,
|
||||
DeviceDataMaskT,
|
||||
TrackerDataMaskT,
|
||||
} from 'solarxr-protocol';
|
||||
import { useConfig } from './config';
|
||||
|
||||
export function useDataFeedConfig() {
|
||||
const { config } = useConfig();
|
||||
|
||||
const fastDataFeed = config?.debug && config?.devSettings?.fastDataFeed;
|
||||
const feedMaxTps = fastDataFeed ? 40 : 10;
|
||||
|
||||
const trackerData = new TrackerDataMaskT();
|
||||
trackerData.position = true;
|
||||
trackerData.rotation = true;
|
||||
trackerData.info = true;
|
||||
trackerData.status = true;
|
||||
trackerData.temp = true;
|
||||
trackerData.linearAcceleration = true;
|
||||
trackerData.rotationReferenceAdjusted = true;
|
||||
trackerData.rotationIdentityAdjusted = true;
|
||||
|
||||
const dataMask = new DeviceDataMaskT();
|
||||
dataMask.deviceData = true;
|
||||
dataMask.trackerData = trackerData;
|
||||
|
||||
const dataFeedConfig = new DataFeedConfigT();
|
||||
dataFeedConfig.dataMask = dataMask;
|
||||
dataFeedConfig.minimumTimeSinceLast = 1000 / feedMaxTps;
|
||||
dataFeedConfig.syntheticTrackersMask = trackerData;
|
||||
|
||||
return {
|
||||
dataFeedConfig,
|
||||
feedMaxTps,
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { BodyPart, TrackerDataT, TrackerStatus } from 'solarxr-protocol';
|
||||
import { RAD_TO_DEG } from '../maths/angle';
|
||||
import { QuaternionFromQuatT } from '../maths/quaternion';
|
||||
import {
|
||||
QuaternionFromQuatT,
|
||||
QuaternionToEulerDegrees,
|
||||
} from '../maths/quaternion';
|
||||
import { useAppContext } from './app';
|
||||
import { useLocalization } from '@fluent/react';
|
||||
import { useDataFeedConfig } from './datafeed-config';
|
||||
import { Quaternion, Vector3 } from 'three';
|
||||
import { Vector3FromVec3fT } from '../maths/vector3';
|
||||
|
||||
export function useTrackers() {
|
||||
const { trackers } = useAppContext();
|
||||
@@ -39,13 +44,7 @@ export function useTrackers() {
|
||||
|
||||
export function useTracker(tracker: TrackerDataT) {
|
||||
const { l10n } = useLocalization();
|
||||
const computeRot = (rot: { x: number; y: number; z: number; w: number }) =>
|
||||
QuaternionFromQuatT({
|
||||
x: rot.x || 0,
|
||||
y: rot.y || 0,
|
||||
z: rot.z || 0,
|
||||
w: rot.w || 1,
|
||||
}).toEuler();
|
||||
const { feedMaxTps } = useDataFeedConfig();
|
||||
|
||||
return {
|
||||
useName: () =>
|
||||
@@ -57,54 +56,61 @@ export function useTracker(tracker: TrackerDataT) {
|
||||
);
|
||||
return tracker.info?.displayName || 'NONE';
|
||||
}, [tracker.info]),
|
||||
useRotation: () =>
|
||||
useRawRotationEulerDegrees: () =>
|
||||
useMemo(
|
||||
() => computeRot(tracker.rotation || { x: 0, y: 0, z: 0, w: 1 }),
|
||||
() => QuaternionToEulerDegrees(tracker?.rotation),
|
||||
[tracker.rotation]
|
||||
),
|
||||
useRotationDegrees: () =>
|
||||
useMemo(() => {
|
||||
const { yaw, pitch, roll } = computeRot(
|
||||
tracker.rotation || { x: 0, y: 0, z: 0, w: 1 }
|
||||
);
|
||||
return {
|
||||
yaw: yaw * RAD_TO_DEG,
|
||||
pitch: pitch * RAD_TO_DEG,
|
||||
roll: roll * RAD_TO_DEG,
|
||||
};
|
||||
}, [tracker.rotation]),
|
||||
useRefAdjRotationEulerDegrees: () =>
|
||||
useMemo(
|
||||
() => QuaternionToEulerDegrees(tracker?.rotationReferenceAdjusted),
|
||||
[tracker.rotationReferenceAdjusted]
|
||||
),
|
||||
useIdentAdjRotationEulerDegrees: () =>
|
||||
useMemo(
|
||||
() => QuaternionToEulerDegrees(tracker?.rotationIdentityAdjusted),
|
||||
[tracker.rotationIdentityAdjusted]
|
||||
),
|
||||
useVelocity: () => {
|
||||
const previousRot = useRef<{
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
w: number;
|
||||
}>(tracker.rotation || { x: 0, y: 0, z: 0, w: 1 });
|
||||
const previousRot = useRef<Quaternion>(
|
||||
QuaternionFromQuatT(tracker.rotation)
|
||||
);
|
||||
const previousAcc = useRef<Vector3>(
|
||||
Vector3FromVec3fT(tracker.linearAcceleration)
|
||||
);
|
||||
const [velocity, setVelocity] = useState<number>(0);
|
||||
const [rots, setRotation] = useState<number[]>([]);
|
||||
const [deltas] = useState<number[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (tracker.rotation) {
|
||||
const rot = QuaternionFromQuatT(tracker.rotation).mul(
|
||||
QuaternionFromQuatT(previousRot.current).inverse()
|
||||
const rot = QuaternionFromQuatT(tracker.rotation).multiply(
|
||||
previousRot.current.clone().invert()
|
||||
);
|
||||
const dif = Math.min(1, (rot.x ** 2 + rot.y ** 2 + rot.z ** 2) * 2.5);
|
||||
// Use sum of rotation of last 3 frames (0.3sec) for smoother movement and better detection of slow movement.
|
||||
if (rots.length === 3) {
|
||||
rots.shift();
|
||||
const acc = Vector3FromVec3fT(tracker.linearAcceleration).sub(
|
||||
previousAcc.current
|
||||
);
|
||||
const dif = Math.min(
|
||||
1,
|
||||
(rot.x ** 2 + rot.y ** 2 + rot.z ** 2) * 2.5 +
|
||||
(acc.x ** 2 + acc.y ** 2 + acc.z ** 2) / 1000
|
||||
);
|
||||
// Use sum of the rotation and acceleration delta vector lengths over 0.3sec
|
||||
// for smoother movement and better detection of slow movement.
|
||||
if (deltas.length >= 0.3 * feedMaxTps) {
|
||||
deltas.shift();
|
||||
}
|
||||
rots.push(dif);
|
||||
setRotation(rots);
|
||||
deltas.push(dif);
|
||||
setVelocity(
|
||||
Math.min(
|
||||
1,
|
||||
Math.max(
|
||||
0,
|
||||
rots.reduce((a, b) => a + b)
|
||||
deltas.reduce((a, b) => a + b)
|
||||
)
|
||||
)
|
||||
);
|
||||
previousRot.current = tracker.rotation;
|
||||
previousRot.current = QuaternionFromQuatT(tracker.rotation);
|
||||
previousAcc.current = Vector3FromVec3fT(tracker.linearAcceleration);
|
||||
}
|
||||
}, [tracker.rotation]);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import { useInterval } from './timeout';
|
||||
export interface WebSocketApi {
|
||||
isConnected: boolean;
|
||||
isFirstConnection: boolean;
|
||||
reconnect: () => void;
|
||||
useRPCPacket: <T>(type: RpcMessage, callback: (packet: T) => void) => void;
|
||||
useDataFeedPacket: <T>(
|
||||
type: DataFeedMessage,
|
||||
@@ -51,9 +52,8 @@ export function useProvideWebsocketApi(): WebSocketApi {
|
||||
|
||||
useInterval(() => {
|
||||
if (webSocketRef.current && !isConnected) {
|
||||
disconnect();
|
||||
connect();
|
||||
console.log('Try reconnecting');
|
||||
console.log('Attempting to reconnect');
|
||||
reconnect();
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
@@ -102,8 +102,7 @@ export function useProvideWebsocketApi(): WebSocketApi {
|
||||
};
|
||||
|
||||
const sendRPCPacket = (type: RpcMessage, data: RPCPacketType): void => {
|
||||
if (!webSocketRef.current) throw new Error('No connection');
|
||||
|
||||
if (webSocketRef?.current?.readyState !== WebSocket.OPEN) return;
|
||||
const fbb = new Builder(1);
|
||||
|
||||
const message = new MessageBundleT();
|
||||
@@ -124,7 +123,7 @@ export function useProvideWebsocketApi(): WebSocketApi {
|
||||
type: DataFeedMessage,
|
||||
data: DataFeedPacketType
|
||||
): void => {
|
||||
if (!webSocketRef.current) throw new Error('No connection');
|
||||
if (webSocketRef?.current?.readyState !== WebSocket.OPEN) return;
|
||||
const fbb = new Builder(1);
|
||||
|
||||
const message = new MessageBundleT();
|
||||
@@ -143,7 +142,7 @@ export function useProvideWebsocketApi(): WebSocketApi {
|
||||
type: PubSubUnion,
|
||||
data: PubSubPacketType
|
||||
): void => {
|
||||
if (!webSocketRef.current) throw new Error('No connection');
|
||||
if (webSocketRef?.current?.readyState !== WebSocket.OPEN) return;
|
||||
const fbb = new Builder(1);
|
||||
|
||||
const message = new MessageBundleT();
|
||||
@@ -173,6 +172,15 @@ export function useProvideWebsocketApi(): WebSocketApi {
|
||||
webSocketRef.current.removeEventListener('open', onConnected);
|
||||
webSocketRef.current.removeEventListener('close', onConnectionClose);
|
||||
webSocketRef.current.removeEventListener('message', onMessage);
|
||||
if (isConnected) {
|
||||
setConnected(false);
|
||||
webSocketRef.current.close();
|
||||
}
|
||||
};
|
||||
|
||||
const reconnect = () => {
|
||||
disconnect();
|
||||
connect();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -185,6 +193,7 @@ export function useProvideWebsocketApi(): WebSocketApi {
|
||||
return {
|
||||
isConnected,
|
||||
isFirstConnection,
|
||||
reconnect,
|
||||
useDataFeedPacket: <T>(
|
||||
type: DataFeedMessage,
|
||||
callback: (packet: T) => void
|
||||
|
||||
@@ -19,6 +19,10 @@ export const langs = [
|
||||
name: '🇪🇪 Eesti',
|
||||
key: 'et',
|
||||
},
|
||||
{
|
||||
name: '🇩🇪 Deutsch',
|
||||
key: 'de',
|
||||
},
|
||||
{
|
||||
name: '🇫🇷 Français',
|
||||
key: 'fr',
|
||||
@@ -35,6 +39,10 @@ export const langs = [
|
||||
name: '🇰🇷 한국어',
|
||||
key: 'ko',
|
||||
},
|
||||
{
|
||||
name: '🇳🇱 Nederlands',
|
||||
key: 'nl',
|
||||
},
|
||||
{
|
||||
name: '🇵🇱 Polski',
|
||||
key: 'pl',
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
import Quaternion from 'quaternion';
|
||||
import { Euler, Quaternion } from 'three';
|
||||
import { QuatT } from 'solarxr-protocol';
|
||||
import { DEG_TO_RAD } from './angle';
|
||||
|
||||
export function QuaternionFromQuatT(q: {
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
w: number;
|
||||
}) {
|
||||
return new Quaternion(q.w, q.x, q.y, q.z);
|
||||
export type QuatObject = { x: number; y: number; z: number; w: number };
|
||||
|
||||
export function QuaternionFromQuatT(q?: QuatObject | null) {
|
||||
return q ? new Quaternion(q.x, q.y, q.z, q.w) : new Quaternion();
|
||||
}
|
||||
|
||||
export function QuaternionToQuatT(q: {
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
w: number;
|
||||
}) {
|
||||
export function QuaternionToQuatT(q: QuatObject) {
|
||||
const quat = new QuatT();
|
||||
|
||||
quat.x = q.x;
|
||||
quat.y = q.y;
|
||||
quat.z = q.z;
|
||||
@@ -25,39 +17,37 @@ export function QuaternionToQuatT(q: {
|
||||
return quat;
|
||||
}
|
||||
|
||||
export function FixEuler(yaw: number) {
|
||||
if (yaw > 180) {
|
||||
yaw *= -1;
|
||||
yaw += 180;
|
||||
}
|
||||
return Math.round(yaw);
|
||||
export function MountingOrientationDegreesToQuatT(
|
||||
mountingOrientationDegrees: number
|
||||
) {
|
||||
return QuaternionToQuatT(
|
||||
new Quaternion().setFromEuler(
|
||||
new Euler(0, +mountingOrientationDegrees * DEG_TO_RAD, 0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export function GetYaw(q: { x: number; y: number; z: number; w: number }) {
|
||||
const squareX = q.x * q.x,
|
||||
squareY = q.y * q.y,
|
||||
squareZ = q.z * q.z,
|
||||
squareW = q.w * q.w;
|
||||
const RAD_TO_DEG = 180 / Math.PI;
|
||||
|
||||
// This value is 1 if the quaternion is a unit (normalized) quaternion,
|
||||
// otherwise this will be a factor to compensate for the singularity pole checks
|
||||
const correctionFactor = squareX + squareY + squareZ + squareW;
|
||||
// This value is to test for a singularity, it will be 0.5 at the north singularity,
|
||||
// -0.5 at the south singularity, and anything else at any other value
|
||||
const singularityTest = q.x * q.y + q.z * q.w;
|
||||
export function getYawInDegrees(q?: QuatObject) {
|
||||
if (!q) return 0;
|
||||
|
||||
// Singularity cutoff points are 0.499 (86.3 degrees) to compensate for error
|
||||
if (singularityTest > 0.499 * correctionFactor) {
|
||||
// Handle the singularity at the attitude of 90 degrees (north pole)
|
||||
return 2 * Math.atan2(q.x, q.w);
|
||||
} else if (singularityTest < -0.499 * correctionFactor) {
|
||||
// Handle the singularity at the attitude of -90 degrees (south pole)
|
||||
return -2 * Math.atan2(q.x, q.w);
|
||||
}
|
||||
// X Y Z Result
|
||||
// back: 0 0 0 0
|
||||
// front: -180 0.. -180 180
|
||||
// left: 0 90 0 90
|
||||
// right: 0 -90 0 -90
|
||||
|
||||
// Otherwise calculate the yaw normally
|
||||
return Math.atan2(
|
||||
2 * q.y * q.w - 2 * q.x * q.z,
|
||||
squareX - squareY - squareZ + squareW
|
||||
);
|
||||
const angles = new Euler().setFromQuaternion(QuaternionFromQuatT(q));
|
||||
return angles.y | 0
|
||||
? Math.round(angles.y * RAD_TO_DEG)
|
||||
: Math.round(-angles.z * RAD_TO_DEG);
|
||||
}
|
||||
|
||||
export function QuaternionToEulerDegrees(q?: QuatObject | null) {
|
||||
const angles = { x: 0, y: 0, z: 0 };
|
||||
if (!q) return angles;
|
||||
|
||||
const a = new Euler().setFromQuaternion(new Quaternion(q.x, q.y, q.z, q.w));
|
||||
return { x: a.x * RAD_TO_DEG, y: a.y * RAD_TO_DEG, z: a.z * RAD_TO_DEG };
|
||||
}
|
||||
|
||||
16
gui/src/maths/vector3.ts
Normal file
16
gui/src/maths/vector3.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Vec3fT } from 'solarxr-protocol';
|
||||
import { Vector3 } from 'three';
|
||||
|
||||
export type Vector3Object = { x: number; y: number; z: number; };
|
||||
|
||||
export function Vector3FromVec3fT(vec?: Vector3Object | null) {
|
||||
return vec ? new Vector3(vec.x, vec.y, vec.z) : new Vector3();
|
||||
}
|
||||
|
||||
export function Vector3ToVec3fT(q: Vector3Object) {
|
||||
const vec = new Vec3fT();
|
||||
vec.x = q.x;
|
||||
vec.y = q.y;
|
||||
vec.z = q.z;
|
||||
return vec;
|
||||
}
|
||||
5216
package-lock.json
generated
5216
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.7.21"
|
||||
kotlin("jvm") version "1.8.0"
|
||||
application
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
id("com.diffplug.spotless") version "6.12.0"
|
||||
@@ -52,10 +52,11 @@ allprojects {
|
||||
dependencies {
|
||||
implementation(project(":solarxr-protocol"))
|
||||
|
||||
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
|
||||
// This dependency is used internally,
|
||||
// and not exposed to consumers on their own compile classpath.
|
||||
implementation("com.google.flatbuffers:flatbuffers-java:22.10.26")
|
||||
implementation("commons-cli:commons-cli:1.3.1")
|
||||
implementation("com.fasterxml.jackson.core:jackson-databind:2.12.6.1")
|
||||
implementation("com.fasterxml.jackson.core:jackson-databind:2.12.7.1")
|
||||
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.3")
|
||||
|
||||
implementation("com.github.jonpeterson:jackson-module-model-versioning:1.2.2")
|
||||
@@ -137,7 +138,7 @@ configure<com.diffplug.gradle.spotless.SpotlessExtension> {
|
||||
mapOf(
|
||||
"indent_size" to 4,
|
||||
"indent_style" to "tab",
|
||||
"max_line_length" to 88,
|
||||
// "max_line_length" to 88,
|
||||
"ktlint_experimental" to "enabled"
|
||||
)
|
||||
val ktlintVersion = "0.47.1"
|
||||
|
||||
@@ -45,9 +45,9 @@ import java.util.logging.Logger;
|
||||
* hypercomplex numbers. Quaternions extends a rotation in three dimensions to a
|
||||
* rotation in four dimensions. This avoids "gimbal lock" and allows for smooth
|
||||
* continuous rotation.
|
||||
*
|
||||
*
|
||||
* <code>Quaternion</code> is defined by four floating point numbers: {x y z w}.
|
||||
*
|
||||
*
|
||||
* @author Mark Powell
|
||||
* @author Joshua Slack
|
||||
*/
|
||||
@@ -239,10 +239,10 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
* angles (x,y,z) aka (pitch, yaw, rall)). Note that we are applying in
|
||||
* order: (y, z, x) aka (yaw, roll, pitch) but we've ordered them in x, y,
|
||||
* and z for convenience.
|
||||
*
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm</a>
|
||||
*
|
||||
*
|
||||
* @param xAngle the Euler pitch of rotation (in radians). (aka Attitude,
|
||||
* often rot around x)
|
||||
* @param yAngle the Euler yaw of rotation (in radians). (aka Heading, often
|
||||
@@ -283,10 +283,10 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
* angles (pitch, yaw, roll).<br/>
|
||||
* Note that the result is not always 100% accurate due to the implications
|
||||
* of euler angles.
|
||||
*
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm</a>
|
||||
*
|
||||
*
|
||||
* @param angles the float[] in which the angles should be stored, or null
|
||||
* if you want a new float[] to be created
|
||||
* @return the float[] in which the angles are stored (pitch, yaw, roll).
|
||||
@@ -327,7 +327,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
|
||||
/**
|
||||
* Returns Euler rotation angle around x axis (pitch).
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* @see #toAngles(float[])
|
||||
*/
|
||||
@@ -377,7 +377,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
|
||||
/**
|
||||
* Returns Euler rotation angle around z axis (roll).
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* @see #toAngles(float[])
|
||||
*/
|
||||
@@ -399,10 +399,10 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* <code>fromRotationMatrix</code> generates a quaternion from a supplied
|
||||
* matrix. This matrix is assumed to be a rotational matrix.
|
||||
*
|
||||
*
|
||||
* @param matrix the matrix that defines the rotation.
|
||||
*/
|
||||
public Quaternion fromRotationMatrix(Matrix3f matrix) {
|
||||
@@ -501,7 +501,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
* <code>toRotationMatrix</code> converts this quaternion to a rotational
|
||||
* matrix. Note: the result is created from a normalized version of this
|
||||
* quat.
|
||||
*
|
||||
*
|
||||
* @return the rotation matrix representation of this quaternion.
|
||||
*/
|
||||
public Matrix3f toRotationMatrix() {
|
||||
@@ -512,7 +512,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
/**
|
||||
* <code>toRotationMatrix</code> converts this quaternion to a rotational
|
||||
* matrix. The result is stored in result.
|
||||
*
|
||||
*
|
||||
* @param result The Matrix3f to store the result in.
|
||||
* @return the rotation matrix representation of this quaternion.
|
||||
*/
|
||||
@@ -557,7 +557,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
* matrix. The result is stored in result. 4th row and 4th column values are
|
||||
* untouched. Note: the result is created from a normalized version of this
|
||||
* quat.
|
||||
*
|
||||
*
|
||||
* @param result The Matrix4f to store the result in.
|
||||
* @return the rotation matrix representation of this quaternion.
|
||||
*/
|
||||
@@ -802,6 +802,38 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
return angle;
|
||||
}
|
||||
|
||||
public Quaternion align(Vector3f v1, Vector3f v2) {
|
||||
float aLenSq = v1.x * v1.x + v1.y * v1.y + v2.z * v2.z;
|
||||
float bLenSq = v2.x * v2.x + v2.y * v2.y + v2.z * v2.z;
|
||||
|
||||
float aLenSqInv = 1f / aLenSq;
|
||||
|
||||
float Rw = aLenSqInv * (x * v1.x + y * v1.y + z * v2.z);
|
||||
float Rx = aLenSqInv * (z * v1.y - w * v1.x - y * v2.z);
|
||||
float Ry = aLenSqInv * (x * v2.z - w * v1.y - z * v1.x);
|
||||
float Rz = aLenSqInv * (y * v1.x - w * v2.z - x * v1.y);
|
||||
|
||||
float Sw = -v2.x * Rx - v2.y * Ry - v2.z * Rz;
|
||||
float Sx = v2.x * Rw - v2.z * Ry + v2.y * Rz;
|
||||
float Sy = v2.y * Rw + v2.z * Rx - v2.x * Rz;
|
||||
float Sz = v2.z * Rw - v2.y * Rx + v2.x * Ry;
|
||||
|
||||
float mul = (float) Math.sqrt(aLenSqInv * bLenSq);
|
||||
|
||||
// (b*Q*a^-1 + len(b*a^-1)*Q)/2,
|
||||
// a and b are treated as pure imaginary Quaternions
|
||||
w = 0.5f * (Sw + mul * w);
|
||||
x = 0.5f * (Sx + mul * x);
|
||||
y = 0.5f * (Sy + mul * y);
|
||||
z = 0.5f * (Sz + mul * z);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f toAxis() {
|
||||
return new Vector3f(x, y, z);
|
||||
}
|
||||
|
||||
public float angleBetween(Quaternion q2) {
|
||||
float w = this.w * q2.w + this.x * q2.x + this.y * q2.y + this.z * q2.z;
|
||||
float x = this.w * q2.x - this.x * q2.w - this.y * q2.z + this.z * q2.y;
|
||||
@@ -903,7 +935,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
/**
|
||||
* Sets the values of this quaternion to the nlerp from itself to q2 by
|
||||
* blend.
|
||||
*
|
||||
*
|
||||
* @param q2
|
||||
* @param blend
|
||||
*/
|
||||
@@ -1251,7 +1283,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
/**
|
||||
* <code>mult</code> multiplies this quaternion by a parameter vector. The
|
||||
* result is returned as a new vector.
|
||||
*
|
||||
*
|
||||
* @param v the vector to multiply this quaternion by.
|
||||
* @param store the vector to store the result in. It IS safe for v and
|
||||
* store to be the same object.
|
||||
@@ -1374,7 +1406,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
/**
|
||||
* <code>mult</code> multiplies this quaternion by a parameter vector. The
|
||||
* result is returned as a new vector.
|
||||
*
|
||||
*
|
||||
* @param vx
|
||||
* @param vy
|
||||
* @param vz the vector to multiply this quaternion by.
|
||||
@@ -1494,9 +1526,9 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
/**
|
||||
* <code>inverse</code> returns the inverse of this quaternion as a new
|
||||
* quaternion. If this quaternion does not have an inverse (if its normal is
|
||||
* 0 or less), then null is returned.
|
||||
* 0 or less), then this quaternion is returned.
|
||||
*
|
||||
* @return the inverse of this quaternion or null if the inverse does not
|
||||
* @return the inverse of this quaternion or itself if the inverse does not
|
||||
* exist.
|
||||
*/
|
||||
public Quaternion inverse() {
|
||||
@@ -1512,9 +1544,9 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
/**
|
||||
* <code>inverse</code> returns the inverse of this quaternion. If this
|
||||
* quaternion does not have an inverse (if its normal is 0 or less), then
|
||||
* null is returned.
|
||||
* this quaternion is returned.
|
||||
*
|
||||
* @return the inverse of this quaternion or null if the inverse does not
|
||||
* @return the inverse of this quaternion or itself if the inverse does not
|
||||
* exist.
|
||||
*/
|
||||
public Quaternion inverse(Quaternion store) {
|
||||
@@ -1523,8 +1555,8 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
float invNorm = 1.0f / norm;
|
||||
return store.set(-x * invNorm, -y * invNorm, -z * invNorm, w * invNorm);
|
||||
}
|
||||
// return an invalid result to flag the error
|
||||
return null;
|
||||
// return itself since it has no inverse
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1614,11 +1646,11 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* <code>hashCode</code> returns the hash code value as an integer and is
|
||||
* supported for the benefit of hashing based collection classes such as
|
||||
* Hashtable, HashMap, HashSet etc.
|
||||
*
|
||||
*
|
||||
* @return the hashcode for this instance of Quaternion.
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@@ -1637,7 +1669,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
* <code>readExternal</code> builds a quaternion from an
|
||||
* <code>ObjectInput</code> object. <br>
|
||||
* NOTE: Used with serialization. Not to be called manually.
|
||||
*
|
||||
*
|
||||
* @param in the ObjectInput value to read from.
|
||||
* @throws IOException if the ObjectInput value has problems reading a
|
||||
* float.
|
||||
@@ -1654,7 +1686,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
* <code>writeExternal</code> writes this quaternion out to a
|
||||
* <code>ObjectOutput</code> object. NOTE: Used with serialization. Not to
|
||||
* be called manually.
|
||||
*
|
||||
*
|
||||
* @param out the object to write to.
|
||||
* @throws IOException if writing to the ObjectOutput fails.
|
||||
* @see java.io.Externalizable
|
||||
@@ -1696,7 +1728,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
/**
|
||||
* FIXME: This seems to have singularity type issues with angle == 0,
|
||||
* possibly others such as PI.
|
||||
*
|
||||
*
|
||||
* @param store A Quaternion to store our result in. If null, a new one is
|
||||
* created.
|
||||
* @return The store quaternion (or a new Quaterion, if store is null) that
|
||||
@@ -1737,7 +1769,7 @@ public final class Quaternion implements Cloneable, java.io.Serializable {
|
||||
* <p>
|
||||
* Based on implementation from here:
|
||||
* https://github.com/toji/gl-matrix/blob/f0583ef53e94bc7e78b78c8a24f09ed5e2f7a20c/src/gl-matrix/quat.js#L54
|
||||
*
|
||||
*
|
||||
* @param vec1
|
||||
* @param vec2
|
||||
* @return this quaternion
|
||||
|
||||
@@ -9,8 +9,10 @@ import com.jme3.math.Quaternion;
|
||||
import dev.slimevr.config.serializers.QuaternionDeserializer;
|
||||
import dev.slimevr.config.serializers.QuaternionSerializer;
|
||||
import io.eiren.util.ann.ThreadSafe;
|
||||
import io.eiren.util.logging.LogManager;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
|
||||
|
||||
public class ConfigManager {
|
||||
@@ -40,6 +42,9 @@ public class ConfigManager {
|
||||
} catch (FileNotFoundException e) {
|
||||
// Config file didn't exist, is not an error
|
||||
} catch (IOException e) {
|
||||
// Make a backup of the erroneous config
|
||||
backupConfig();
|
||||
// Re-throw the exception
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -48,14 +53,79 @@ public class ConfigManager {
|
||||
}
|
||||
}
|
||||
|
||||
@ThreadSafe
|
||||
public synchronized void saveConfig() {
|
||||
File cfgFile = new File(configPath);
|
||||
public void atomicMove(Path from, Path to) throws IOException {
|
||||
try {
|
||||
// Atomic move to overwrite
|
||||
Files.move(from, to, StandardCopyOption.ATOMIC_MOVE);
|
||||
} catch (AtomicMoveNotSupportedException | FileAlreadyExistsException e) {
|
||||
// Atomic move not supported or does not replace, try just replacing
|
||||
Files.move(from, to, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
|
||||
public void backupConfig() {
|
||||
Path cfgFile = Path.of(configPath);
|
||||
Path tmpBakCfgFile = Path.of(configPath + ".bak.tmp");
|
||||
Path bakCfgFile = Path.of(configPath + ".bak");
|
||||
|
||||
try {
|
||||
om.writeValue(cfgFile, this.vrConfig);
|
||||
Files
|
||||
.copy(
|
||||
cfgFile,
|
||||
tmpBakCfgFile,
|
||||
StandardCopyOption.REPLACE_EXISTING,
|
||||
StandardCopyOption.COPY_ATTRIBUTES
|
||||
);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
LogManager
|
||||
.severe(
|
||||
"Unable to make backup copy of config from \""
|
||||
+ cfgFile
|
||||
+ "\" to \""
|
||||
+ tmpBakCfgFile
|
||||
+ "\"",
|
||||
e
|
||||
);
|
||||
return; // Abort write
|
||||
}
|
||||
|
||||
try {
|
||||
atomicMove(tmpBakCfgFile, bakCfgFile);
|
||||
} catch (IOException e) {
|
||||
LogManager
|
||||
.severe(
|
||||
"Unable to move backup config from \""
|
||||
+ tmpBakCfgFile
|
||||
+ "\" to \""
|
||||
+ bakCfgFile
|
||||
+ "\"",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ThreadSafe
|
||||
public synchronized void saveConfig() {
|
||||
Path tmpCfgFile = Path.of(configPath + ".tmp");
|
||||
Path cfgFile = Path.of(configPath);
|
||||
|
||||
// Serialize config
|
||||
try {
|
||||
om.writeValue(tmpCfgFile.toFile(), this.vrConfig);
|
||||
} catch (IOException e) {
|
||||
LogManager.severe("Unable to write serialized config to \"" + tmpCfgFile + "\"", e);
|
||||
return; // Abort write
|
||||
}
|
||||
|
||||
// Overwrite old config
|
||||
try {
|
||||
atomicMove(tmpCfgFile, cfgFile);
|
||||
} catch (IOException e) {
|
||||
LogManager
|
||||
.severe(
|
||||
"Unable to move new config from \"" + tmpCfgFile + "\" to \"" + cfgFile + "\"",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ public class VRConfig {
|
||||
tracker.writeConfig(tc);
|
||||
}
|
||||
|
||||
public BridgeConfig getBrige(String bridgeKey) {
|
||||
public BridgeConfig getBridge(String bridgeKey) {
|
||||
BridgeConfig config = bridges.get(bridgeKey);
|
||||
if (config == null) {
|
||||
config = new BridgeConfig();
|
||||
|
||||
@@ -214,8 +214,10 @@ public class VRCOSCHandler implements OSCHandler {
|
||||
|
||||
// Send OSC data
|
||||
if (oscSender != null && oscSender.isConnected()) {
|
||||
int id = 0;
|
||||
for (int i = 0; i < shareableTrackers.size(); i++) {
|
||||
if (trackersEnabled[i]) {
|
||||
id++;
|
||||
// Send regular trackers' positions
|
||||
shareableTrackers.get(i).getPosition(vec);
|
||||
oscArgs.clear();
|
||||
@@ -223,7 +225,7 @@ public class VRCOSCHandler implements OSCHandler {
|
||||
oscArgs.add(vec.y);
|
||||
oscArgs.add(-vec.z);
|
||||
oscMessage = new OSCMessage(
|
||||
"/tracking/trackers/" + (i + 1) + "/position",
|
||||
"/tracking/trackers/" + id + "/position",
|
||||
oscArgs
|
||||
);
|
||||
try {
|
||||
@@ -250,7 +252,7 @@ public class VRCOSCHandler implements OSCHandler {
|
||||
oscArgs.add(floatBuf[2] * FastMath.RAD_TO_DEG);
|
||||
|
||||
oscMessage = new OSCMessage(
|
||||
"/tracking/trackers/" + (i + 1) + "/rotation",
|
||||
"/tracking/trackers/" + id + "/rotation",
|
||||
oscArgs
|
||||
);
|
||||
try {
|
||||
@@ -338,7 +340,7 @@ public class VRCOSCHandler implements OSCHandler {
|
||||
|
||||
/*
|
||||
* Apache Commons Math Copyright 2001-2022 The Apache Software Foundation
|
||||
*
|
||||
*
|
||||
* The code below includes code developed at The Apache Software Foundation
|
||||
* (http://www.apache.org/).
|
||||
*/
|
||||
|
||||
@@ -32,7 +32,7 @@ public abstract class SteamVRBridge extends ProtobufBridge<VRTracker> implements
|
||||
this.bridgeSettingsKey = bridgeSettingsKey;
|
||||
this.runnerThread = new Thread(this, threadName);
|
||||
this.shareableTrackers = shareableTrackers;
|
||||
this.config = server.getConfigManager().getVrConfig().getBrige(bridgeSettingsKey);
|
||||
this.config = server.getConfigManager().getVrConfig().getBridge(bridgeSettingsKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,7 +103,7 @@ public abstract class SteamVRBridge extends ProtobufBridge<VRTracker> implements
|
||||
device
|
||||
);
|
||||
|
||||
device.getTrackers().add(tracker);
|
||||
device.getTrackers().put(0, tracker);
|
||||
Main.getVrServer().getDeviceManager().addDevice(device);
|
||||
TrackerRole role = TrackerRole.getById(trackerAdded.getTrackerRole());
|
||||
if (role != null) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.slimevr.platform.linux;
|
||||
|
||||
import com.google.protobuf.CodedOutputStream;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import dev.slimevr.Main;
|
||||
import dev.slimevr.VRServer;
|
||||
@@ -82,6 +81,7 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
updateMessageQueue();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -98,8 +98,8 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
|
||||
try {
|
||||
int size = message.getSerializedSize() + 4;
|
||||
this.src.putInt(size);
|
||||
CodedOutputStream os = CodedOutputStream.newInstance(this.src);
|
||||
message.writeTo(os);
|
||||
byte[] serialized = message.toByteArray();
|
||||
this.src.put(serialized);
|
||||
this.src.flip();
|
||||
|
||||
while (this.src.hasRemaining()) {
|
||||
@@ -119,7 +119,8 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
|
||||
int read = channel.read(dst);
|
||||
boolean readAnything = false;
|
||||
// if buffer has 4 bytes at least, we got the message size!
|
||||
if (read > 0 && dst.remaining() >= 4) {
|
||||
// processs all messages
|
||||
while (dst.position() >= 4) {
|
||||
int messageLength = dst.get(0) | dst.get(1) << 8 | dst.get(2) << 16 | dst.get(3) << 24;
|
||||
if (messageLength > 1024) { // Overflow
|
||||
LogManager
|
||||
@@ -130,7 +131,7 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
|
||||
+ messageLength
|
||||
);
|
||||
socketError = true;
|
||||
} else if (dst.remaining() >= messageLength) {
|
||||
} else if (dst.position() >= messageLength) {
|
||||
// Parse the message (this reads the array directly from the
|
||||
// dst, so we need to move position ourselves)
|
||||
try {
|
||||
@@ -140,11 +141,15 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
LogManager.severe("Failed to read protocol message", e);
|
||||
}
|
||||
int originalpos = dst.position();
|
||||
dst.position(messageLength);
|
||||
dst.compact();
|
||||
// move position after compacting
|
||||
dst.position(originalpos - messageLength);
|
||||
readAnything = true;
|
||||
}
|
||||
} else if (read == -1) {
|
||||
}
|
||||
if (read == -1) {
|
||||
LogManager
|
||||
.info(
|
||||
"["
|
||||
|
||||
@@ -210,7 +210,7 @@ public class PoseFrameTracker implements Tracker, Iterable<TrackerFrame> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetFull(Quaternion reference) {
|
||||
public void resetFull(Quaternion reference, boolean tPose) {
|
||||
throw new UnsupportedOperationException("PoseFrameTracker does not implement calibration");
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public class PoseFrameTracker implements Tracker, Iterable<TrackerFrame> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetMounting(boolean reverseYaw) {
|
||||
public void resetMounting(boolean reverseYaw, boolean tPose) {
|
||||
throw new UnsupportedOperationException("PoseFrameTracker does not implement calibration");
|
||||
}
|
||||
|
||||
@@ -259,6 +259,11 @@ public class PoseFrameTracker implements Tracker, Iterable<TrackerFrame> {
|
||||
return frame != null && frame.hasData(TrackerFrameData.POSITION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAcceleration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComputed() {
|
||||
return true;
|
||||
|
||||
@@ -148,7 +148,7 @@ public final class TrackerFrame implements Tracker {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetFull(Quaternion reference) {
|
||||
public void resetFull(Quaternion reference, boolean tPose) {
|
||||
throw new UnsupportedOperationException("TrackerFrame does not implement calibration");
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ public final class TrackerFrame implements Tracker {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetMounting(boolean reverseYaw) {
|
||||
public void resetMounting(boolean reverseYaw, boolean tPose) {
|
||||
throw new UnsupportedOperationException("TrackerFrame does not implement calibration");
|
||||
}
|
||||
|
||||
@@ -194,6 +194,11 @@ public final class TrackerFrame implements Tracker {
|
||||
return hasData(TrackerFrameData.POSITION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAcceleration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComputed() {
|
||||
return true;
|
||||
|
||||
@@ -12,10 +12,10 @@ import java.io.*;
|
||||
|
||||
|
||||
public class BVHFileStream extends PoseDataStream {
|
||||
|
||||
private static final int LONG_MAX_VALUE_DIGITS = Long.toString(Long.MAX_VALUE).length();
|
||||
private static final float OFFSET_SCALE = 100f;
|
||||
private static final float POSITION_SCALE = 100f;
|
||||
|
||||
private BVHSettings bvhSettings = BVHSettings.DEFAULT;
|
||||
|
||||
private final BufferedWriter writer;
|
||||
private long frameCount = 0;
|
||||
private long frameCountOffset;
|
||||
@@ -31,16 +31,39 @@ public class BVHFileStream extends PoseDataStream {
|
||||
writer = new BufferedWriter(new OutputStreamWriter(outputStream), 4096);
|
||||
}
|
||||
|
||||
public BVHFileStream(OutputStream outputStream, BVHSettings bvhSettings) {
|
||||
this(outputStream);
|
||||
this.bvhSettings = bvhSettings;
|
||||
}
|
||||
|
||||
public BVHFileStream(File file) throws FileNotFoundException {
|
||||
super(file);
|
||||
writer = new BufferedWriter(new OutputStreamWriter(outputStream), 4096);
|
||||
}
|
||||
|
||||
public BVHFileStream(File file, BVHSettings bvhSettings) throws FileNotFoundException {
|
||||
this(file);
|
||||
this.bvhSettings = bvhSettings;
|
||||
}
|
||||
|
||||
public BVHFileStream(String file) throws FileNotFoundException {
|
||||
super(file);
|
||||
writer = new BufferedWriter(new OutputStreamWriter(outputStream), 4096);
|
||||
}
|
||||
|
||||
public BVHFileStream(String file, BVHSettings bvhSettings) throws FileNotFoundException {
|
||||
this(file);
|
||||
this.bvhSettings = bvhSettings;
|
||||
}
|
||||
|
||||
public BVHSettings getBvhSettings() {
|
||||
return bvhSettings;
|
||||
}
|
||||
|
||||
public void setBvhSettings(BVHSettings bvhSettings) {
|
||||
this.bvhSettings = bvhSettings;
|
||||
}
|
||||
|
||||
private String getBufferedFrameCount(long frameCount) {
|
||||
String frameString = Long.toString(frameCount);
|
||||
int bufferCount = LONG_MAX_VALUE_DIGITS - frameString.length();
|
||||
@@ -72,13 +95,28 @@ public class BVHFileStream extends PoseDataStream {
|
||||
return TransformNodeWrapper.wrapFullHierarchy(rootNode);
|
||||
}
|
||||
|
||||
private boolean isEndNode(TransformNodeWrapper node) {
|
||||
return node == null || (!bvhSettings.shouldWriteEndNodes() && node.children.isEmpty());
|
||||
}
|
||||
|
||||
private void writeNodeHierarchy(TransformNodeWrapper node) throws IOException {
|
||||
writeNodeHierarchy(node, 0);
|
||||
}
|
||||
|
||||
private void writeNodeHierarchy(TransformNodeWrapper node, int level) throws IOException {
|
||||
// Don't write end sites at populated nodes
|
||||
if (node.children.isEmpty() && node.getParent().children.size() > 1) {
|
||||
// Treat null as an end node, this allows for simply writing empty end
|
||||
// nodes
|
||||
boolean isEndNode = isEndNode(node);
|
||||
|
||||
// Don't write end sites at populated nodes, most BVH parsers don't like
|
||||
// this
|
||||
// Ex case caught: `joint{ joint{ end }, end, end }` outputs `joint{ end
|
||||
// }` instead
|
||||
// Ex case let through: `joint{ end }`
|
||||
boolean isSingleChild = node == null
|
||||
|| node.getParent() == null
|
||||
|| node.getParent().children.size() <= 1;
|
||||
if (isEndNode && !isSingleChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -86,7 +124,7 @@ public class BVHFileStream extends PoseDataStream {
|
||||
String nextIndentLevel = indentLevel + "\t";
|
||||
|
||||
// Handle ends
|
||||
if (node.children.isEmpty()) {
|
||||
if (isEndNode) {
|
||||
writer.write(indentLevel + "End Site\n");
|
||||
} else {
|
||||
writer.write((level > 0 ? indentLevel + "JOINT " : "ROOT ") + node.getName() + "\n");
|
||||
@@ -94,18 +132,19 @@ public class BVHFileStream extends PoseDataStream {
|
||||
writer.write(indentLevel + "{\n");
|
||||
|
||||
// Ignore the root offset and original root offset
|
||||
if (level > 0 && node.wrappedNode.getParent() != null) {
|
||||
if (level > 0 && node != null && node.wrappedNode.getParent() != null) {
|
||||
Vector3f offset = node.localTransform.getTranslation();
|
||||
float reverseMultiplier = node.hasReversedHierarchy() ? -1 : 1;
|
||||
float offsetScale = bvhSettings.getOffsetScale() * reverseMultiplier;
|
||||
writer
|
||||
.write(
|
||||
nextIndentLevel
|
||||
+ "OFFSET "
|
||||
+ offset.getX() * OFFSET_SCALE * reverseMultiplier
|
||||
+ offset.getX() * offsetScale
|
||||
+ " "
|
||||
+ offset.getY() * OFFSET_SCALE * reverseMultiplier
|
||||
+ offset.getY() * offsetScale
|
||||
+ " "
|
||||
+ offset.getZ() * OFFSET_SCALE * reverseMultiplier
|
||||
+ offset.getZ() * offsetScale
|
||||
+ "\n"
|
||||
);
|
||||
} else {
|
||||
@@ -113,7 +152,7 @@ public class BVHFileStream extends PoseDataStream {
|
||||
}
|
||||
|
||||
// Handle ends
|
||||
if (!node.children.isEmpty()) {
|
||||
if (!isEndNode) {
|
||||
// Only give position for root
|
||||
if (level > 0) {
|
||||
writer.write(nextIndentLevel + "CHANNELS 3 Zrotation Xrotation Yrotation\n");
|
||||
@@ -125,8 +164,14 @@ public class BVHFileStream extends PoseDataStream {
|
||||
);
|
||||
}
|
||||
|
||||
for (TransformNodeWrapper childNode : node.children) {
|
||||
writeNodeHierarchy(childNode, level + 1);
|
||||
// If the node has children
|
||||
if (!node.children.isEmpty()) {
|
||||
for (TransformNodeWrapper childNode : node.children) {
|
||||
writeNodeHierarchy(childNode, level + 1);
|
||||
}
|
||||
} else {
|
||||
// Write an empty end node
|
||||
writeNodeHierarchy(null, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,9 +260,6 @@ public class BVHFileStream extends PoseDataStream {
|
||||
rotBuf = inverseRootRot.mult(rotBuf, rotBuf);
|
||||
}
|
||||
|
||||
// Yaw (Z), roll (X), pitch (Y) (intrinsic)
|
||||
// angleBuf = rotBuf.toAngles(angleBuf);
|
||||
|
||||
// Roll (X), pitch (Y), yaw (Z) (intrinsic)
|
||||
angleBuf = quatToXyzAngles(rotBuf.normalizeLocal(), angleBuf);
|
||||
|
||||
@@ -235,7 +277,7 @@ public class BVHFileStream extends PoseDataStream {
|
||||
if (!node.children.isEmpty()) {
|
||||
Quaternion inverseRot = transform.getRotation().inverse();
|
||||
for (TransformNodeWrapper childNode : node.children) {
|
||||
if (childNode.children.isEmpty()) {
|
||||
if (isEndNode(childNode)) {
|
||||
// If it's an end node, skip
|
||||
continue;
|
||||
}
|
||||
@@ -258,13 +300,14 @@ public class BVHFileStream extends PoseDataStream {
|
||||
Vector3f rootPos = rootNode.worldTransform.getTranslation();
|
||||
|
||||
// Write root position
|
||||
float positionScale = bvhSettings.getPositionScale();
|
||||
writer
|
||||
.write(
|
||||
rootPos.getX() * POSITION_SCALE
|
||||
rootPos.getX() * positionScale
|
||||
+ " "
|
||||
+ rootPos.getY() * POSITION_SCALE
|
||||
+ rootPos.getY() * positionScale
|
||||
+ " "
|
||||
+ rootPos.getZ() * POSITION_SCALE
|
||||
+ rootPos.getZ() * positionScale
|
||||
+ " "
|
||||
);
|
||||
writeNodeHierarchyRotation(rootNode, null);
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package dev.slimevr.posestreamer;
|
||||
|
||||
public class BVHSettings {
|
||||
private float offsetScale = 100f;
|
||||
private float positionScale = 100f;
|
||||
private boolean writeEndNodes = false;
|
||||
|
||||
public static final BVHSettings DEFAULT = new BVHSettings();
|
||||
public static final BVHSettings BLENDER = new BVHSettings(DEFAULT)
|
||||
.setOffsetScale(1f)
|
||||
.setPositionScale(1f);
|
||||
|
||||
public BVHSettings() {
|
||||
}
|
||||
|
||||
public BVHSettings(BVHSettings source) {
|
||||
this.offsetScale = source.offsetScale;
|
||||
this.positionScale = source.positionScale;
|
||||
this.writeEndNodes = source.writeEndNodes;
|
||||
}
|
||||
|
||||
public float getOffsetScale() {
|
||||
return offsetScale;
|
||||
}
|
||||
|
||||
public BVHSettings setOffsetScale(float offsetScale) {
|
||||
this.offsetScale = offsetScale;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float getPositionScale() {
|
||||
return positionScale;
|
||||
}
|
||||
|
||||
public BVHSettings setPositionScale(float positionScale) {
|
||||
this.positionScale = positionScale;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean shouldWriteEndNodes() {
|
||||
return writeEndNodes;
|
||||
}
|
||||
|
||||
public BVHSettings setWriteEndNodes(boolean writeEndNodes) {
|
||||
this.writeEndNodes = writeEndNodes;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,6 @@ import java.util.List;
|
||||
public class DataFeedBuilder {
|
||||
|
||||
public static int createHardwareInfo(FlatBufferBuilder fbb, Device device) {
|
||||
Tracker tracker = device.getTrackers().get(0).get();
|
||||
|
||||
int nameOffset = device.getFirmwareVersion() != null
|
||||
? fbb.createString(device.getFirmwareVersion())
|
||||
: 0;
|
||||
@@ -74,6 +72,17 @@ public class DataFeedBuilder {
|
||||
return TrackerId.endTrackerId(fbb);
|
||||
}
|
||||
|
||||
public static int createQuat(FlatBufferBuilder fbb, Quaternion quaternion) {
|
||||
return Quat
|
||||
.createQuat(
|
||||
fbb,
|
||||
quaternion.getX(),
|
||||
quaternion.getY(),
|
||||
quaternion.getZ(),
|
||||
quaternion.getW()
|
||||
);
|
||||
}
|
||||
|
||||
public static int createTrackerInfos(FlatBufferBuilder fbb, boolean infoMask, Tracker tracker) {
|
||||
|
||||
if (!infoMask)
|
||||
@@ -102,18 +111,7 @@ public class DataFeedBuilder {
|
||||
|
||||
if (imuTracker.getMountingOrientation() != null) {
|
||||
Quaternion quaternion = imuTracker.getMountingOrientation();
|
||||
TrackerInfo
|
||||
.addMountingOrientation(
|
||||
fbb,
|
||||
Quat
|
||||
.createQuat(
|
||||
fbb,
|
||||
quaternion.getX(),
|
||||
quaternion.getY(),
|
||||
quaternion.getZ(),
|
||||
quaternion.getW()
|
||||
)
|
||||
);
|
||||
TrackerInfo.addMountingOrientation(fbb, createQuat(fbb, quaternion));
|
||||
}
|
||||
|
||||
TrackerInfo.addAllowDriftCompensation(fbb, imuTracker.getAllowDriftCompensation());
|
||||
@@ -133,16 +131,20 @@ public class DataFeedBuilder {
|
||||
|
||||
public static int createTrackerRotation(FlatBufferBuilder fbb, Tracker tracker) {
|
||||
Quaternion quaternion = new Quaternion();
|
||||
tracker.getRotation(quaternion);
|
||||
if (tracker instanceof IMUTracker imuTracker) {
|
||||
imuTracker.getRawRotation(quaternion);
|
||||
} else {
|
||||
tracker.getRotation(quaternion);
|
||||
}
|
||||
|
||||
return Quat
|
||||
.createQuat(
|
||||
fbb,
|
||||
quaternion.getX(),
|
||||
quaternion.getY(),
|
||||
quaternion.getZ(),
|
||||
quaternion.getW()
|
||||
);
|
||||
return createQuat(fbb, quaternion);
|
||||
}
|
||||
|
||||
public static int createTrackerAcceleration(FlatBufferBuilder fbb, Tracker tracker) {
|
||||
Vector3f accel = new Vector3f();
|
||||
tracker.getAcceleration(accel);
|
||||
|
||||
return Vec3f.createVec3f(fbb, accel.x, accel.y, accel.z);
|
||||
}
|
||||
|
||||
public static int createTrackerTemperature(FlatBufferBuilder fbb, Tracker tracker) {
|
||||
@@ -171,11 +173,28 @@ public class DataFeedBuilder {
|
||||
TrackerData.addPosition(fbb, DataFeedBuilder.createTrackerPosition(fbb, tracker));
|
||||
if (mask.getRotation() && tracker.hasRotation())
|
||||
TrackerData.addRotation(fbb, DataFeedBuilder.createTrackerRotation(fbb, tracker));
|
||||
if (mask.getLinearAcceleration() && tracker.hasAcceleration())
|
||||
TrackerData
|
||||
.addLinearAcceleration(
|
||||
fbb,
|
||||
DataFeedBuilder.createTrackerAcceleration(fbb, tracker)
|
||||
);
|
||||
if (mask.getTemp()) {
|
||||
int trackerTemperatureOffset = DataFeedBuilder.createTrackerTemperature(fbb, tracker);
|
||||
if (trackerTemperatureOffset != 0)
|
||||
TrackerData.addTemp(fbb, trackerTemperatureOffset);
|
||||
}
|
||||
if (tracker instanceof IMUTracker imuTracker) {
|
||||
Quaternion quaternion = new Quaternion();
|
||||
if (mask.getRotationReferenceAdjusted() && tracker.hasRotation()) {
|
||||
imuTracker.getRotation(quaternion);
|
||||
TrackerData.addRotationReferenceAdjusted(fbb, createQuat(fbb, quaternion));
|
||||
}
|
||||
if (mask.getRotationIdentityAdjusted() && tracker.hasRotation()) {
|
||||
imuTracker.getIdentityAdjustedRotation(quaternion);
|
||||
TrackerData.addRotationIdentityAdjusted(fbb, createQuat(fbb, quaternion));
|
||||
}
|
||||
}
|
||||
|
||||
return TrackerData.endTrackerData(fbb);
|
||||
}
|
||||
@@ -193,7 +212,7 @@ public class DataFeedBuilder {
|
||||
device
|
||||
.getTrackers()
|
||||
.forEach(
|
||||
(value) -> trackersOffsets
|
||||
(key, value) -> trackersOffsets
|
||||
.add(DataFeedBuilder.createTrackerData(fbb, mask.getTrackerData(), value))
|
||||
);
|
||||
|
||||
@@ -214,8 +233,13 @@ public class DataFeedBuilder {
|
||||
if (device.getTrackers().size() <= 0)
|
||||
return 0;
|
||||
|
||||
Tracker tracker = device.getTrackers().get(0).get();
|
||||
Tracker firstTracker = device.getTrackers().get(0);
|
||||
if (firstTracker == null) {
|
||||
// Not actually the "first" tracker, but do we care?
|
||||
firstTracker = device.getTrackers().entrySet().iterator().next().getValue();
|
||||
}
|
||||
|
||||
Tracker tracker = firstTracker.get();
|
||||
if (tracker == null)
|
||||
return 0;
|
||||
|
||||
@@ -315,14 +339,7 @@ public class DataFeedBuilder {
|
||||
|
||||
Bone.startBone(fbb);
|
||||
|
||||
var rotGOffset = Quat
|
||||
.createQuat(
|
||||
fbb,
|
||||
rotG.getX(),
|
||||
rotG.getY(),
|
||||
rotG.getZ(),
|
||||
rotG.getW()
|
||||
);
|
||||
var rotGOffset = createQuat(fbb, rotG);
|
||||
Bone.addRotationG(fbb, rotGOffset);
|
||||
var headPosGOffset = Vec3f.createVec3f(fbb, headPosG.x, headPosG.y, headPosG.z);
|
||||
Bone.addHeadPositionG(fbb, headPosGOffset);
|
||||
|
||||
@@ -153,7 +153,8 @@ public class RPCSettingsBuilder {
|
||||
config.getToggle(SkeletonConfigToggles.FORCE_ARMS_FROM_HMD),
|
||||
config.getToggle(SkeletonConfigToggles.FLOOR_CLIP),
|
||||
config.getToggle(SkeletonConfigToggles.SKATING_CORRECTION),
|
||||
config.getToggle(SkeletonConfigToggles.VIVE_EMULATION)
|
||||
config.getToggle(SkeletonConfigToggles.VIVE_EMULATION),
|
||||
config.getToggle(SkeletonConfigToggles.I_POSE)
|
||||
);
|
||||
int ratiosOffset = ModelRatios
|
||||
.createModelRatios(
|
||||
|
||||
@@ -273,6 +273,7 @@ public record RPCSettingsHandler(RPCHandler rpcHandler, ProtocolAPI api) {
|
||||
toggles.skatingCorrection()
|
||||
);
|
||||
cfg.setToggle(SkeletonConfigToggles.VIVE_EMULATION, toggles.viveEmulation());
|
||||
cfg.setToggle(SkeletonConfigToggles.I_POSE, toggles.iPose());
|
||||
}
|
||||
|
||||
if (ratios != null) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package dev.slimevr.vr;
|
||||
|
||||
import dev.slimevr.vr.trackers.Tracker;
|
||||
import io.eiren.util.collections.FastList;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ public class Device {
|
||||
private String firmwareVersion;
|
||||
private String manufacturer;
|
||||
|
||||
private final FastList<Tracker> trackers = new FastList<>();
|
||||
private final HashMap<Integer, Tracker> trackers = new HashMap<>();
|
||||
|
||||
public Device() {
|
||||
this.id = nextLocalDeviceId.incrementAndGet();
|
||||
@@ -58,7 +58,7 @@ public class Device {
|
||||
return null;
|
||||
}
|
||||
|
||||
public FastList<Tracker> getTrackers() {
|
||||
public HashMap<Integer, Tracker> getTrackers() {
|
||||
return trackers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ public class HumanSkeleton extends Skeleton implements SkeletonConfigCallback {
|
||||
protected boolean extendedPelvisModel;
|
||||
protected boolean extendedKneeModel;
|
||||
protected boolean forceArmsFromHMD;
|
||||
protected boolean iPose;
|
||||
// Values
|
||||
protected float waistFromChestHipAveraging;
|
||||
protected float waistFromChestLegsAveraging;
|
||||
@@ -1370,6 +1371,7 @@ public class HumanSkeleton extends Skeleton implements SkeletonConfigCallback {
|
||||
case SKATING_CORRECTION -> legTweaks.setSkatingReductionEnabled(newValue);
|
||||
case FLOOR_CLIP -> legTweaks.setFloorclipEnabled(newValue);
|
||||
case VIVE_EMULATION -> viveEmulation.setEnabled(newValue);
|
||||
case I_POSE -> iPose = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1742,7 +1744,7 @@ public class HumanSkeleton extends Skeleton implements SkeletonConfigCallback {
|
||||
|
||||
for (Tracker tracker : trackersToReset) {
|
||||
if (tracker != null) {
|
||||
tracker.resetFull(referenceRotation);
|
||||
tracker.resetFull(referenceRotation, !iPose);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1764,6 +1766,8 @@ public class HumanSkeleton extends Skeleton implements SkeletonConfigCallback {
|
||||
return position != null
|
||||
&& (position == TrackerPosition.LEFT_UPPER_LEG
|
||||
|| position == TrackerPosition.RIGHT_UPPER_LEG
|
||||
|| position == TrackerPosition.LEFT_UPPER_ARM
|
||||
|| position == TrackerPosition.RIGHT_UPPER_ARM
|
||||
|| position == TrackerPosition.LEFT_LOWER_ARM
|
||||
|| position == TrackerPosition.RIGHT_LOWER_ARM
|
||||
|| position == TrackerPosition.LEFT_HAND
|
||||
@@ -1778,7 +1782,7 @@ public class HumanSkeleton extends Skeleton implements SkeletonConfigCallback {
|
||||
|
||||
for (Tracker tracker : trackersToReset) {
|
||||
if (tracker != null && shouldResetMounting(tracker.getBodyPosition())) {
|
||||
tracker.resetMounting(shouldReverseYaw(tracker.getBodyPosition()));
|
||||
tracker.resetMounting(shouldReverseYaw(tracker.getBodyPosition()), !iPose);
|
||||
}
|
||||
}
|
||||
this.legTweaks.resetBuffer();
|
||||
|
||||
@@ -305,18 +305,22 @@ public class SkeletonConfig {
|
||||
-getOffset(SkeletonConfigOffsets.SHOULDERS_DISTANCE),
|
||||
0
|
||||
);
|
||||
case LEFT_UPPER_ARM, RIGHT_UPPER_ARM -> setNodeOffset(
|
||||
nodeOffset,
|
||||
0,
|
||||
-getOffset(SkeletonConfigOffsets.UPPER_ARM),
|
||||
0
|
||||
);
|
||||
case LEFT_LOWER_ARM, RIGHT_LOWER_ARM -> setNodeOffset(
|
||||
nodeOffset,
|
||||
0,
|
||||
getOffset(SkeletonConfigOffsets.LOWER_ARM),
|
||||
0
|
||||
);
|
||||
case LEFT_UPPER_ARM, RIGHT_UPPER_ARM -> {
|
||||
setNodeOffset(
|
||||
nodeOffset,
|
||||
0,
|
||||
-getOffset(SkeletonConfigOffsets.UPPER_ARM),
|
||||
0
|
||||
);
|
||||
}
|
||||
case LEFT_LOWER_ARM, RIGHT_LOWER_ARM -> {
|
||||
setNodeOffset(
|
||||
nodeOffset,
|
||||
0,
|
||||
-getOffset(SkeletonConfigOffsets.LOWER_ARM),
|
||||
0
|
||||
);
|
||||
}
|
||||
case LEFT_HAND, RIGHT_HAND -> setNodeOffset(
|
||||
nodeOffset,
|
||||
0,
|
||||
@@ -329,6 +333,14 @@ public class SkeletonConfig {
|
||||
getOffset(SkeletonConfigOffsets.CONTROLLER_Y),
|
||||
getOffset(SkeletonConfigOffsets.CONTROLLER_Z)
|
||||
);
|
||||
case LEFT_ELBOW_TRACKER, RIGHT_ELBOW_TRACKER -> {
|
||||
setNodeOffset(
|
||||
nodeOffset,
|
||||
0,
|
||||
-getOffset(SkeletonConfigOffsets.ELBOW_OFFSET),
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,12 @@ public enum SkeletonConfigOffsets {
|
||||
0.13f,
|
||||
new BoneType[] { BoneType.LEFT_CONTROLLER, BoneType.RIGHT_CONTROLLER,
|
||||
BoneType.LEFT_HAND, BoneType.RIGHT_HAND }
|
||||
),
|
||||
ELBOW_OFFSET(
|
||||
20,
|
||||
"elbowOffset",
|
||||
0.0f,
|
||||
new BoneType[] { BoneType.LEFT_ELBOW_TRACKER, BoneType.RIGHT_ELBOW_TRACKER }
|
||||
),;
|
||||
|
||||
public static final SkeletonConfigOffsets[] values = values();
|
||||
|
||||
@@ -6,43 +6,36 @@ import java.util.Map;
|
||||
|
||||
public enum SkeletonConfigToggles {
|
||||
|
||||
EXTENDED_SPINE_MODEL(1, "Extended spine model", "extendedSpine", true),
|
||||
EXTENDED_PELVIS_MODEL(2, "Extended pelvis model", "extendedPelvis", true),
|
||||
EXTENDED_KNEE_MODEL(3, "Extended knee model", "extendedKnee", true),
|
||||
FORCE_ARMS_FROM_HMD(4, "Force arms from HMD", "forceArmsFromHMD", true),
|
||||
FLOOR_CLIP(5, "Floor clip", "floorClip", true),
|
||||
SKATING_CORRECTION(6, "Skating correction", "skatingCorrection", true),
|
||||
VIVE_EMULATION(7, "Vive emulation", "viveEmulation", false),;
|
||||
EXTENDED_SPINE_MODEL(1, "extendedSpine", true),
|
||||
EXTENDED_PELVIS_MODEL(2, "extendedPelvis", true),
|
||||
EXTENDED_KNEE_MODEL(3, "extendedKnee", true),
|
||||
FORCE_ARMS_FROM_HMD(4, "forceArmsFromHMD", true),
|
||||
FLOOR_CLIP(5, "floorClip", true),
|
||||
SKATING_CORRECTION(6, "skatingCorrection", true),
|
||||
VIVE_EMULATION(7, "viveEmulation", false),
|
||||
I_POSE(8, "iPose", false),;
|
||||
|
||||
public static final SkeletonConfigToggles[] values = values();
|
||||
private static final Map<String, SkeletonConfigToggles> byStringVal = new HashMap<>();
|
||||
|
||||
private static final Map<Number, SkeletonConfigToggles> byIdVal = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (SkeletonConfigToggles configVal : values()) {
|
||||
byIdVal.put(configVal.id, configVal);
|
||||
byStringVal.put(configVal.stringVal.toLowerCase(), configVal);
|
||||
}
|
||||
}
|
||||
|
||||
public final int id;
|
||||
public final String stringVal;
|
||||
public final String configKey;
|
||||
public final boolean defaultValue;
|
||||
|
||||
SkeletonConfigToggles(int id, String stringVal, String configKey, boolean defaultValue) {
|
||||
SkeletonConfigToggles(int id, String configKey, boolean defaultValue) {
|
||||
this.id = id;
|
||||
this.stringVal = stringVal;
|
||||
this.configKey = configKey;
|
||||
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public static SkeletonConfigToggles getByStringValue(String stringVal) {
|
||||
return stringVal == null ? null : byStringVal.get(stringVal.toLowerCase());
|
||||
}
|
||||
|
||||
public static SkeletonConfigToggles getById(int id) {
|
||||
return byIdVal.get(id);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public class ComputedTracker implements Tracker, TrackerWithTPS {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetFull(Quaternion reference) {
|
||||
public void resetFull(Quaternion reference, boolean tPose) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,7 +115,7 @@ public class ComputedTracker implements Tracker, TrackerWithTPS {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetMounting(boolean reverseYaw) {
|
||||
public void resetMounting(boolean reverseYaw, boolean tPose) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,6 +151,11 @@ public class ComputedTracker implements Tracker, TrackerWithTPS {
|
||||
return hasPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAcceleration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComputed() {
|
||||
return true;
|
||||
|
||||
@@ -22,6 +22,10 @@ public class IMUTracker
|
||||
TrackerWithFiltering {
|
||||
|
||||
public static final float MAX_MAG_CORRECTION_ACCURACY = 5 * FastMath.RAD_TO_DEG;
|
||||
private static final Quaternion LEFT_TPOSE_OFFSET = new Quaternion()
|
||||
.fromAngles(0, 0, FastMath.HALF_PI);
|
||||
private static final Quaternion RIGHT_TPOSE_OFFSET = new Quaternion()
|
||||
.fromAngles(0, 0, -FastMath.HALF_PI);
|
||||
|
||||
// public final Vector3f gyroVector = new Vector3f();
|
||||
public final Vector3f accelVector = new Vector3f();
|
||||
@@ -32,10 +36,18 @@ public class IMUTracker
|
||||
public final UDPDevice device;
|
||||
public final int trackerNum;
|
||||
public final Vector3f rotVector = new Vector3f();
|
||||
public final Quaternion gyroFix = new Quaternion();
|
||||
public final Quaternion attachmentFix = new Quaternion();
|
||||
public final Quaternion mountRotFix = new Quaternion();
|
||||
public final Quaternion yawFix = new Quaternion();
|
||||
|
||||
// Reference adjustment quats
|
||||
private final Quaternion gyroFix = new Quaternion();
|
||||
private final Quaternion attachmentFix = new Quaternion();
|
||||
private final Quaternion yawMountRotFix = new Quaternion();
|
||||
private final Quaternion yawFix = new Quaternion();
|
||||
|
||||
// Zero-reference adjustment quats for IMU debugging
|
||||
private final Quaternion gyroFixNoMounting = new Quaternion();
|
||||
private final Quaternion attachmentFixNoMounting = new Quaternion();
|
||||
private final Quaternion yawFixZeroReference = new Quaternion();
|
||||
|
||||
protected final Quaternion correction = new Quaternion();
|
||||
protected final int trackerId;
|
||||
protected final String name;
|
||||
@@ -241,17 +253,20 @@ public class IMUTracker
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates reference-adjusted rotation (with full/quick reset) including
|
||||
* the mounting orientation (front, back, left, right) and mounting reset
|
||||
* adjustment. Also taking drift compensation into account.
|
||||
*
|
||||
* @param store Where to store the calculation result.
|
||||
*/
|
||||
@Override
|
||||
public boolean getRotation(Quaternion store) {
|
||||
if (movingAverage != null) {
|
||||
store.set(movingAverage.getFilteredQuaternion());
|
||||
} else {
|
||||
store.set(rotQuaternion);
|
||||
}
|
||||
getFilteredRotation(store);
|
||||
// correction.mult(store, store); // Correction is not used now to
|
||||
// prevent accidental errors while debugging other things
|
||||
store.multLocal(mountAdjust);
|
||||
adjustInternal(store);
|
||||
adjustToReference(store);
|
||||
if ((compensateDrift && allowDriftCompensation) && totalDriftTime > 0) {
|
||||
store
|
||||
.slerpLocal(
|
||||
@@ -264,6 +279,32 @@ public class IMUTracker
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates zero-reference-adjusted rotation (with full/quick reset). Same
|
||||
* as {@link #getRotation(Quaternion)}, except rotation is aligned to an
|
||||
* identity quaternion instead of HMD and does not include mounting reset
|
||||
* and mounting orientation adjustments. Does not take drift compensation
|
||||
* into account.
|
||||
*
|
||||
* This rotation can be used in visualizations for debugging purposes.
|
||||
*
|
||||
* @param store Where to store the calculation result.
|
||||
*/
|
||||
public boolean getIdentityAdjustedRotation(Quaternion store) {
|
||||
getFilteredRotation(store);
|
||||
adjustToIdentity(store);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean getFilteredRotation(Quaternion store) {
|
||||
if (movingAverage != null) {
|
||||
store.set(movingAverage.getFilteredQuaternion());
|
||||
} else {
|
||||
store.set(rotQuaternion);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRawRotation(Quaternion store) {
|
||||
store.set(rotQuaternion);
|
||||
@@ -275,12 +316,22 @@ public class IMUTracker
|
||||
// correction.mult(store, store); // Correction is not used now to
|
||||
// prevent accidental errors while debugging other things
|
||||
rot.multLocal(mountAdjust);
|
||||
adjustInternal(rot);
|
||||
adjustToReference(rot);
|
||||
return rot;
|
||||
}
|
||||
|
||||
private Quaternion getMountedAdjustedRotation() {
|
||||
Quaternion rot = new Quaternion(rotQuaternion);
|
||||
// correction.mult(store, store); // Correction is not used now to
|
||||
// prevent accidental errors while debugging other things
|
||||
rot.multLocal(mountAdjust);
|
||||
return rot;
|
||||
}
|
||||
|
||||
private Quaternion getMountedAdjustedDriftRotation() {
|
||||
Quaternion rot = new Quaternion(rotQuaternion);
|
||||
// correction.mult(store, store); // Correction is not used now to
|
||||
// prevent accidental errors while debugging other things
|
||||
rot.multLocal(mountAdjust);
|
||||
if ((compensateDrift && allowDriftCompensation) && totalDriftTime > 0) {
|
||||
rot
|
||||
@@ -354,11 +405,13 @@ public class IMUTracker
|
||||
* 0). This allows the tracker to be strapped to body at any pitch and roll.
|
||||
*/
|
||||
@Override
|
||||
public void resetFull(Quaternion reference) {
|
||||
public void resetFull(Quaternion reference, boolean tPose) {
|
||||
Quaternion rot = getAdjustedRawRotation();
|
||||
fixGyroscope(getMountedAdjustedRotation());
|
||||
fixAttachment(getMountedAdjustedRotation());
|
||||
fixYaw(reference);
|
||||
fixGyroscope(getMountedAdjustedRotation(), tPose);
|
||||
fixAttachment(getMountedAdjustedRotation(), tPose);
|
||||
makeIdentityAdjustmentQuatsFull();
|
||||
fixYaw(getMountedAdjustedRotation(), reference);
|
||||
makeIdentityAdjustmentQuatsYaw();
|
||||
calibrateMag();
|
||||
calculateDrift(rot);
|
||||
}
|
||||
@@ -373,51 +426,93 @@ public class IMUTracker
|
||||
@Override
|
||||
public void resetYaw(Quaternion reference) {
|
||||
Quaternion rot = getAdjustedRawRotation();
|
||||
fixYaw(reference);
|
||||
fixYaw(getMountedAdjustedRotation(), reference);
|
||||
makeIdentityAdjustmentQuatsYaw();
|
||||
calibrateMag();
|
||||
calculateDrift(rot);
|
||||
}
|
||||
|
||||
protected void adjustInternal(Quaternion store) {
|
||||
/**
|
||||
* Converts raw or filtered rotation into reference- and
|
||||
* mounting-reset-adjusted by applying quaternions produced after
|
||||
* {@link #resetFull(Quaternion, boolean)}, {@link #resetYaw(Quaternion)}
|
||||
* and {@link #resetMounting(boolean, boolean)}.
|
||||
*
|
||||
* @param store Raw or filtered rotation to mutate.
|
||||
*/
|
||||
protected void adjustToReference(Quaternion store) {
|
||||
gyroFix.mult(store, store);
|
||||
store.multLocal(attachmentFix);
|
||||
store.multLocal(mountRotFix);
|
||||
store.multLocal(yawMountRotFix);
|
||||
yawFix.mult(store, store);
|
||||
}
|
||||
|
||||
private void fixGyroscope(Quaternion sensorRotation) {
|
||||
sensorRotation.fromAngles(0, sensorRotation.getYaw(), 0);
|
||||
gyroFix.set(sensorRotation).inverseLocal();
|
||||
/**
|
||||
* Converts raw or filtered rotation into zero-reference-adjusted by
|
||||
* applying quaternions produced after
|
||||
* {@link #resetFull(Quaternion, boolean)}, {@link #resetYaw(Quaternion)}.
|
||||
*
|
||||
* @param store Raw or filtered rotation to mutate.
|
||||
*/
|
||||
protected void adjustToIdentity(Quaternion store) {
|
||||
gyroFixNoMounting.mult(store, store);
|
||||
store.multLocal(attachmentFixNoMounting);
|
||||
yawFixZeroReference.mult(store, store);
|
||||
}
|
||||
|
||||
private void fixAttachment(Quaternion sensorRotation) {
|
||||
private void fixGyroscope(Quaternion sensorRotation, boolean tPose) {
|
||||
sensorRotation = sensorRotation.clone();
|
||||
if (tPose)
|
||||
fixForTPose(sensorRotation);
|
||||
sensorRotation.fromAngles(0, sensorRotation.getYaw(), 0);
|
||||
gyroFix.set(sensorRotation.inverseLocal());
|
||||
}
|
||||
|
||||
private void fixAttachment(Quaternion sensorRotation, boolean tPose) {
|
||||
sensorRotation = sensorRotation.clone();
|
||||
gyroFix.mult(sensorRotation, sensorRotation);
|
||||
attachmentFix.set(sensorRotation).inverseLocal();
|
||||
if (tPose)
|
||||
fixForTPose(sensorRotation);
|
||||
attachmentFix.set(sensorRotation.inverseLocal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetMounting(boolean reverseYaw) {
|
||||
public void resetMounting(boolean reverseYaw, boolean tPose) {
|
||||
// Get the current calibrated rotation
|
||||
Quaternion buffer = getMountedAdjustedRotation();
|
||||
Quaternion buffer = getMountedAdjustedDriftRotation();
|
||||
gyroFix.mult(buffer, buffer);
|
||||
buffer.multLocal(attachmentFix);
|
||||
float yawAngle;
|
||||
|
||||
// Reset the vector for the rotation to point straight up
|
||||
rotVector.set(0f, 1f, 0f);
|
||||
// Rotate the vector by the quat, then flatten and normalize the vector
|
||||
buffer.multLocal(rotVector).setY(0f).normalizeLocal();
|
||||
|
||||
// Calculate the yaw angle using tan
|
||||
// Just use an angle offset of zero for unsolvable circumstances
|
||||
float yawAngle = FastMath.isApproxZero(rotVector.x) && FastMath.isApproxZero(rotVector.z)
|
||||
? 0f
|
||||
: FastMath.atan2(rotVector.x, rotVector.z);
|
||||
if (tPose && (isOnLeftArm() || isOnRightArm())) {
|
||||
// Find the global axis the tracker thinks it rotated about (should
|
||||
// be z), then projected on to the xz plane
|
||||
rotVector
|
||||
.set(
|
||||
((isOnLeftArm() ? LEFT_TPOSE_OFFSET : RIGHT_TPOSE_OFFSET)
|
||||
.mult(buffer)).toAxis()
|
||||
);
|
||||
yawAngle = FastMath
|
||||
.atan2(
|
||||
rotVector.cross(Vector3f.NEGATIVE_UNIT_Z).dot(Vector3f.UNIT_Y),
|
||||
rotVector.dot(Vector3f.NEGATIVE_UNIT_Z)
|
||||
);
|
||||
// TODO find out what what is causing arms to not work (yawFix?)
|
||||
} else {
|
||||
// Find the global axis the tracker thinks it rotated about (should
|
||||
// be z), then projected on to the xz plane
|
||||
rotVector.set(buffer.inverseLocal().toAxis());
|
||||
yawAngle = new Quaternion(0f, 0f, 0f, 1f)
|
||||
.align(rotVector, Vector3f.UNIT_X)
|
||||
.normalizeLocal()
|
||||
.getYaw();
|
||||
}
|
||||
|
||||
// Make an adjustment quaternion from the angle
|
||||
buffer.fromAngles(0f, reverseYaw ? yawAngle : yawAngle - FastMath.PI, 0f);
|
||||
|
||||
Quaternion lastRotAdjust = mountRotFix.clone();
|
||||
mountRotFix.set(buffer);
|
||||
Quaternion lastRotAdjust = yawMountRotFix.clone();
|
||||
yawMountRotFix.set(buffer);
|
||||
|
||||
// Get the difference from the last adjustment
|
||||
buffer.multLocal(lastRotAdjust.inverseLocal());
|
||||
@@ -425,19 +520,19 @@ public class IMUTracker
|
||||
yawFix.multLocal(buffer.inverseLocal());
|
||||
}
|
||||
|
||||
private void fixYaw(Quaternion reference) {
|
||||
private void fixYaw(Quaternion sensorRotation, Quaternion reference) {
|
||||
// Use only yaw HMD rotation
|
||||
Quaternion targetRotation = reference.clone();
|
||||
targetRotation.fromAngles(0, targetRotation.getYaw(), 0);
|
||||
reference = reference.clone();
|
||||
reference.fromAngles(0, reference.getYaw(), 0);
|
||||
|
||||
Quaternion sensorRotation = getMountedAdjustedRotation();
|
||||
sensorRotation = sensorRotation.clone();
|
||||
gyroFix.mult(sensorRotation, sensorRotation);
|
||||
sensorRotation.multLocal(attachmentFix);
|
||||
sensorRotation.multLocal(mountRotFix);
|
||||
sensorRotation.multLocal(yawMountRotFix);
|
||||
|
||||
sensorRotation.fromAngles(0, sensorRotation.getYaw(), 0);
|
||||
|
||||
yawFix.set(sensorRotation).inverseLocal().multLocal(targetRotation);
|
||||
yawFix.set(sensorRotation.inverseLocal().multLocal(reference));
|
||||
}
|
||||
|
||||
private void calibrateMag() {
|
||||
@@ -450,10 +545,10 @@ public class IMUTracker
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates 1 since last reset and store the data related to it in
|
||||
* Calculates drift since last reset and store the data related to it in
|
||||
* driftQuat, timeAtLastReset and timeForLastReset
|
||||
*/
|
||||
synchronized public void calculateDrift(Quaternion beforeQuat) {
|
||||
private void calculateDrift(Quaternion beforeQuat) {
|
||||
if (compensateDrift && allowDriftCompensation) {
|
||||
Quaternion rotQuat = getAdjustedRawRotation();
|
||||
|
||||
@@ -471,11 +566,10 @@ public class IMUTracker
|
||||
// Add new drift quaternion
|
||||
driftQuats
|
||||
.add(
|
||||
new Quaternion()
|
||||
.fromAngles(
|
||||
0f,
|
||||
rotQuat.mult(beforeQuat.inverse()).getYaw(),
|
||||
0f
|
||||
rotQuat
|
||||
.fromAngles(0, rotQuat.getYaw(), 0)
|
||||
.mult(
|
||||
beforeQuat.fromAngles(0, beforeQuat.getYaw(), 0).inverse()
|
||||
)
|
||||
);
|
||||
|
||||
@@ -512,23 +606,25 @@ public class IMUTracker
|
||||
averagedDriftQuat.fromAveragedQuaternions(driftQuats, driftWeights);
|
||||
|
||||
// Save tracker rotation and current time
|
||||
rotationSinceReset.set(rotQuat.mult(beforeQuat.inverse()));
|
||||
rotationSinceReset.set(driftQuats.getLatest());
|
||||
timeAtLastReset = System.currentTimeMillis();
|
||||
} else if (
|
||||
System.currentTimeMillis() - timeAtLastReset < DRIFT_COOLDOWN_MS
|
||||
&& driftQuats.size() > 0
|
||||
) {
|
||||
// Replace latest drift quaternion
|
||||
rotationSinceReset.multLocal(beforeQuat.mult(rotQuat.inverse()));
|
||||
rotationSinceReset
|
||||
.multLocal(
|
||||
rotQuat
|
||||
.fromAngles(0, rotQuat.getYaw(), 0)
|
||||
.mult(
|
||||
beforeQuat.fromAngles(0, beforeQuat.getYaw(), 0).inverse()
|
||||
)
|
||||
);
|
||||
driftQuats
|
||||
.set(
|
||||
driftQuats.size() - 1,
|
||||
new Quaternion()
|
||||
.fromAngles(
|
||||
0f,
|
||||
rotationSinceReset.inverse().getYaw(),
|
||||
0f
|
||||
)
|
||||
rotationSinceReset
|
||||
);
|
||||
|
||||
// Add drift time to total
|
||||
@@ -572,6 +668,25 @@ public class IMUTracker
|
||||
}
|
||||
}
|
||||
|
||||
private void makeIdentityAdjustmentQuatsFull() {
|
||||
Quaternion sensorRotation = new Quaternion();
|
||||
getRawRotation(sensorRotation);
|
||||
sensorRotation.fromAngles(0, sensorRotation.getYaw(), 0);
|
||||
gyroFixNoMounting.set(sensorRotation).inverseLocal();
|
||||
getRawRotation(sensorRotation);
|
||||
gyroFixNoMounting.mult(sensorRotation, sensorRotation);
|
||||
attachmentFixNoMounting.set(sensorRotation).inverseLocal();
|
||||
}
|
||||
|
||||
private void makeIdentityAdjustmentQuatsYaw() {
|
||||
Quaternion sensorRotation = new Quaternion();
|
||||
getRawRotation(sensorRotation);
|
||||
gyroFixNoMounting.mult(sensorRotation, sensorRotation);
|
||||
sensorRotation.multLocal(attachmentFixNoMounting);
|
||||
sensorRotation.fromAngles(0, sensorRotation.getYaw(), 0);
|
||||
yawFixZeroReference.set(sensorRotation).inverseLocal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate correction between normal and magnetometer readings up to
|
||||
* accuracy threshold
|
||||
@@ -581,6 +696,26 @@ public class IMUTracker
|
||||
// TODO Print "jump" length when correcting if it's more than 1 degree
|
||||
}
|
||||
|
||||
private void fixForTPose(Quaternion store) {
|
||||
if (isOnLeftArm()) {
|
||||
store.set(LEFT_TPOSE_OFFSET.mult(store));
|
||||
} else if (isOnRightArm()) {
|
||||
store.set(RIGHT_TPOSE_OFFSET.mult(store));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOnLeftArm() {
|
||||
return bodyPosition == TrackerPosition.LEFT_UPPER_ARM
|
||||
|| bodyPosition == TrackerPosition.LEFT_LOWER_ARM
|
||||
|| bodyPosition == TrackerPosition.LEFT_HAND;
|
||||
}
|
||||
|
||||
private boolean isOnRightArm() {
|
||||
return bodyPosition == TrackerPosition.RIGHT_UPPER_ARM
|
||||
|| bodyPosition == TrackerPosition.RIGHT_LOWER_ARM
|
||||
|| bodyPosition == TrackerPosition.RIGHT_HAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackerPosition getBodyPosition() {
|
||||
return bodyPosition;
|
||||
@@ -606,6 +741,11 @@ public class IMUTracker
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAcceleration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComputed() {
|
||||
return false;
|
||||
|
||||
@@ -34,11 +34,11 @@ public interface Tracker {
|
||||
|
||||
float getConfidenceLevel();
|
||||
|
||||
void resetFull(Quaternion reference);
|
||||
void resetFull(Quaternion reference, boolean tPose);
|
||||
|
||||
void resetYaw(Quaternion reference);
|
||||
|
||||
void resetMounting(boolean reverseYaw);
|
||||
void resetMounting(boolean reverseYaw, boolean tPose);
|
||||
|
||||
void tick();
|
||||
|
||||
@@ -52,6 +52,8 @@ public interface Tracker {
|
||||
|
||||
boolean hasPosition();
|
||||
|
||||
boolean hasAcceleration();
|
||||
|
||||
boolean isComputed();
|
||||
|
||||
int getTrackerId();
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
package dev.slimevr.vr.trackers;
|
||||
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Quaternion;
|
||||
import dev.slimevr.vr.Device;
|
||||
import io.eiren.util.BufferedTimer;
|
||||
|
||||
|
||||
public class VRTracker extends ComputedTracker {
|
||||
|
||||
private static final Quaternion LEFT_TPOSE_OFFSET = new Quaternion()
|
||||
.fromAngles(0, 0, FastMath.HALF_PI);
|
||||
private static final Quaternion RIGHT_TPOSE_OFFSET = new Quaternion()
|
||||
.fromAngles(0, 0, -FastMath.HALF_PI);
|
||||
protected BufferedTimer timer = new BufferedTimer(1f);
|
||||
public final Quaternion mountFix = new Quaternion();
|
||||
public final Quaternion attachmentFix = new Quaternion();
|
||||
public final Quaternion yawFix = new Quaternion();
|
||||
|
||||
public VRTracker(
|
||||
int id,
|
||||
@@ -23,6 +32,75 @@ public class VRTracker extends ComputedTracker {
|
||||
super(id, name, name, hasRotation, hasPosition, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRotation(Quaternion store) {
|
||||
store.set(rotation);
|
||||
// Don't adjust if tracker is HMD/Head (use raw rotation)
|
||||
if (super.getBodyPosition() != TrackerPosition.HMD)
|
||||
adjustInternal(store);
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO Reduce code duplication from IMUTracker.java
|
||||
// Refactor all tracker classes into one?
|
||||
protected void adjustInternal(Quaternion store) {
|
||||
store.multLocal(attachmentFix);
|
||||
store.multLocal(mountFix);
|
||||
yawFix.mult(store, store);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetFull(Quaternion reference, boolean tPose) {
|
||||
fixAttachment(rotation, reference, tPose);
|
||||
fixYaw(rotation, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetYaw(Quaternion reference) {
|
||||
fixYaw(rotation, reference);
|
||||
}
|
||||
|
||||
private void fixAttachment(Quaternion sensorRotation, Quaternion reference, boolean tPose) {
|
||||
mountFix.fromAngles(0, reference.getYaw(), 0);
|
||||
if (tPose)
|
||||
fixForTPose(sensorRotation);
|
||||
attachmentFix.set(sensorRotation.inverse());
|
||||
}
|
||||
|
||||
private void fixYaw(Quaternion sensorRotation, Quaternion reference) {
|
||||
// Use only yaw HMD rotation
|
||||
reference = reference.clone();
|
||||
reference.fromAngles(0, reference.getYaw(), 0);
|
||||
|
||||
sensorRotation = sensorRotation.clone();
|
||||
sensorRotation.multLocal(attachmentFix);
|
||||
sensorRotation.multLocal(mountFix);
|
||||
|
||||
sensorRotation.fromAngles(0, sensorRotation.getYaw(), 0);
|
||||
|
||||
yawFix.set(sensorRotation).inverseLocal().multLocal(reference);
|
||||
}
|
||||
|
||||
private void fixForTPose(Quaternion store) {
|
||||
if (isOnLeftArm()) {
|
||||
store.set(LEFT_TPOSE_OFFSET.mult(store));
|
||||
} else if (isOnRightArm()) {
|
||||
store.set(RIGHT_TPOSE_OFFSET.mult(store));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOnLeftArm() {
|
||||
return bodyPosition == TrackerPosition.LEFT_UPPER_ARM
|
||||
|| bodyPosition == TrackerPosition.LEFT_LOWER_ARM
|
||||
|| bodyPosition == TrackerPosition.LEFT_HAND;
|
||||
}
|
||||
|
||||
private boolean isOnRightArm() {
|
||||
return bodyPosition == TrackerPosition.RIGHT_UPPER_ARM
|
||||
|| bodyPosition == TrackerPosition.RIGHT_LOWER_ARM
|
||||
|| bodyPosition == TrackerPosition.RIGHT_HAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTPS() {
|
||||
return timer.getAverageFPS();
|
||||
|
||||
@@ -237,7 +237,7 @@ public class TrackersUDPServer extends Thread {
|
||||
Main.getVrServer()
|
||||
);
|
||||
|
||||
connection.getTrackers().add(imu);
|
||||
connection.getTrackers().put(trackerId, imu);
|
||||
trackersConsumer.accept(imu);
|
||||
LogManager
|
||||
.info(
|
||||
@@ -315,7 +315,7 @@ public class TrackersUDPServer extends Thread {
|
||||
parser.write(bb, conn, new UDPPacket1Heartbeat());
|
||||
socket.send(new DatagramPacket(rcvBuffer, bb.position(), conn.address));
|
||||
if (conn.lastPacket + 1000 < System.currentTimeMillis()) {
|
||||
for (Tracker value : conn.getTrackers()) {
|
||||
for (Tracker value : conn.getTrackers().values()) {
|
||||
IMUTracker tracker = (IMUTracker) value;
|
||||
if (tracker.getStatus() == TrackerStatus.OK)
|
||||
tracker.setStatus(TrackerStatus.DISCONNECTED);
|
||||
@@ -326,7 +326,7 @@ public class TrackersUDPServer extends Thread {
|
||||
}
|
||||
} else {
|
||||
conn.timedOut = false;
|
||||
for (Tracker value : conn.getTrackers()) {
|
||||
for (Tracker value : conn.getTrackers().values()) {
|
||||
IMUTracker tracker = (IMUTracker) value;
|
||||
if (tracker.getStatus() == TrackerStatus.DISCONNECTED)
|
||||
tracker.setStatus(TrackerStatus.OK);
|
||||
@@ -452,7 +452,7 @@ public class TrackersUDPServer extends Thread {
|
||||
break;
|
||||
UDPPacket10PingPong ping = (UDPPacket10PingPong) packet;
|
||||
if (connection.lastPingPacketId == ping.pingId) {
|
||||
for (Tracker t : connection.getTrackers()) {
|
||||
for (Tracker t : connection.getTrackers().values()) {
|
||||
IMUTracker imuTracker = (IMUTracker) t;
|
||||
imuTracker
|
||||
.setPing(
|
||||
@@ -485,7 +485,7 @@ public class TrackersUDPServer extends Thread {
|
||||
|
||||
if (connection.getTrackers().size() > 0) {
|
||||
|
||||
for (Tracker value : connection.getTrackers()) {
|
||||
for (Tracker value : connection.getTrackers().values()) {
|
||||
IMUTracker tr = (IMUTracker) value;
|
||||
tr.setBatteryVoltage(battery.voltage);
|
||||
tr.setBatteryLevel(battery.level * 100);
|
||||
@@ -549,7 +549,7 @@ public class TrackersUDPServer extends Thread {
|
||||
UDPPacket19SignalStrength signalStrength = (UDPPacket19SignalStrength) packet;
|
||||
|
||||
if (connection.getTrackers().size() > 0) {
|
||||
for (Tracker value : connection.getTrackers()) {
|
||||
for (Tracker value : connection.getTrackers().values()) {
|
||||
IMUTracker tr = (IMUTracker) value;
|
||||
tr.setSignalStrength(signalStrength.signalStrength);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ import dev.slimevr.NetworkProtocol;
|
||||
import dev.slimevr.vr.Device;
|
||||
import dev.slimevr.vr.trackers.IMUTracker;
|
||||
import dev.slimevr.vr.trackers.Tracker;
|
||||
import io.eiren.util.collections.FastList;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class UDPDevice extends Device {
|
||||
@@ -26,7 +26,7 @@ public class UDPDevice extends Device {
|
||||
public NetworkProtocol protocol = null;
|
||||
public int firmwareBuild = 0;
|
||||
public boolean timedOut = false;
|
||||
private final FastList<Tracker> trackers = new FastList<>();
|
||||
private final HashMap<Integer, Tracker> trackers = new HashMap<>();
|
||||
|
||||
public UDPDevice(SocketAddress address, InetAddress ipAddress) {
|
||||
this.address = address;
|
||||
@@ -77,13 +77,11 @@ public class UDPDevice extends Device {
|
||||
}
|
||||
|
||||
@Override
|
||||
public FastList<Tracker> getTrackers() {
|
||||
public HashMap<Integer, Tracker> getTrackers() {
|
||||
return this.trackers;
|
||||
}
|
||||
|
||||
public IMUTracker getTracker(int id) {
|
||||
if (id >= 0 && id < this.getTrackers().size())
|
||||
return (IMUTracker) this.getTrackers().get(id);
|
||||
return null;
|
||||
return (IMUTracker) this.getTrackers().get(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ public class ReferenceAdjustmentsTests {
|
||||
null
|
||||
);
|
||||
tracker.rotQuaternion.set(trackerQuat);
|
||||
tracker.resetFull(referenceQuat);
|
||||
tracker.resetFull(referenceQuat, false);
|
||||
Quaternion read = new Quaternion();
|
||||
assertTrue(tracker.getRotation(read), "Adjusted tracker didn't return rotation");
|
||||
|
||||
@@ -257,7 +257,7 @@ public class ReferenceAdjustmentsTests {
|
||||
null
|
||||
);
|
||||
tracker.rotQuaternion.set(trackerQuat);
|
||||
tracker.resetFull(referenceQuat);
|
||||
tracker.resetFull(referenceQuat, false);
|
||||
|
||||
// Use only yaw HMD rotation
|
||||
Quaternion targetTrackerRotation = new Quaternion(referenceQuat);
|
||||
|
||||
Submodule solarxr-protocol updated: e8f16f2a3d...deaf3af018
Reference in New Issue
Block a user