Skip to content

Commit 4ad9d5c

Browse files
ButterscotchVImUrX
andauthored
Expand skeleton height config (#1156)
Co-authored-by: Uriel <imurx@proton.me>
1 parent 2c49d1d commit 4ad9d5c

27 files changed

+1215
-339
lines changed

gui/public/i18n/en/translation.ftl

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ reset-reset_all_warning =
122122
Are you sure you want to do this?
123123
reset-reset_all_warning-reset = Reset proportions
124124
reset-reset_all_warning-cancel = Cancel
125+
reset-reset_all_warning_default =
126+
<b>Warning:</b> You currently don't have your height defined, which
127+
will make the proportions be based on a default height.
128+
Are you sure you want to do this?
125129
126130
reset-full = Full Reset
127131
reset-mounting = Reset Mounting
@@ -962,6 +966,15 @@ onboarding-choose_proportions-manual_proportions = Manual proportions
962966
# Italicized text
963967
onboarding-choose_proportions-manual_proportions-subtitle = For small touches
964968
onboarding-choose_proportions-manual_proportions-description = This will let you adjust your proportions manually by modifying them directly
969+
onboarding-choose_proportions-scaled_proportions = Scaled proportions
970+
# Italized text
971+
onboarding-choose_proportions-scaled_proportions-subtitle = Recommended for new users
972+
# Multiline string
973+
onboarding-choose_proportions-scaled_proportions-description =
974+
This will scale the proportions of an average human body based on your height, this will help for basic full-body tracking.
975+
976+
<b>This requires having your headset (HMD) connected to SlimeVR and on your head!</b>
977+
onboarding-choose_proportions-scaled_proportions-button = Scaled proportions
965978
onboarding-choose_proportions-export = Export proportions
966979
onboarding-choose_proportions-import = Import proportions
967980
onboarding-choose_proportions-import-success = Imported
@@ -981,9 +994,11 @@ onboarding-automatic_proportions-title = Measure your body
981994
onboarding-automatic_proportions-description = For SlimeVR trackers to work, we need to know the length of your bones. This short calibration will measure it for you.
982995
onboarding-automatic_proportions-manual = Manual proportions
983996
onboarding-automatic_proportions-prev_step = Previous step
997+
984998
onboarding-automatic_proportions-put_trackers_on-title = Put on your trackers
985999
onboarding-automatic_proportions-put_trackers_on-description = To calibrate your proportions, we're gonna use the trackers you just assigned. Put on all your trackers, you can see which are which in the figure to the right.
9861000
onboarding-automatic_proportions-put_trackers_on-next = I have all my trackers on
1001+
9871002
onboarding-automatic_proportions-requirements-title = Requirements
9881003
# Each line of text is a different list item
9891004
onboarding-automatic_proportions-requirements-descriptionv2 =
@@ -993,23 +1008,38 @@ onboarding-automatic_proportions-requirements-descriptionv2 =
9931008
Your headset is reporting positional data to the SlimeVR server (this generally means having SteamVR running and connected to SlimeVR using SlimeVR's SteamVR driver).
9941009
Your tracking is working and is accurately representing your movements (ex. you have performed a full reset and they move the right direction when kicking, bending over, sitting, etc).
9951010
onboarding-automatic_proportions-requirements-next = I have read the requirements
996-
onboarding-automatic_proportions-check_height-title = Check your height
997-
onboarding-automatic_proportions-check_height-description = We use your height as a basis of our measurements by using the headset's (HMD) height as an approximation of your actual height, but it's better to check if they are right yourself!
1011+
1012+
onboarding-automatic_proportions-check_height-title-v2 = Measure your height
1013+
onboarding-automatic_proportions-check_height-description-v2 = Your headset (HMD) height should be slightly less than your full height, as headsets measure your eye height. This measurement will be used as a baseline for your body proportions.
9981014
# All the text is in bold!
999-
onboarding-automatic_proportions-check_height-calculation_warning = Please press the button while standing <u>upright</u> to calculate your height. You have 3 seconds after you press the button!
1015+
onboarding-automatic_proportions-check_height-calculation_warning-v2 = Start measuring while standing <u>upright</u> to calculate your height. Be careful to not raise your hands higher than your headset, as they may affect the measurement!
10001016
onboarding-automatic_proportions-check_height-guardian_tip = If you are using a standalone VR headset, make sure to have your guardian /
10011017
boundary turned on so that your height is correct!
1002-
onboarding-automatic_proportions-check_height-fetch_height = I'm standing!
10031018
# Context is that the height is unknown
10041019
onboarding-automatic_proportions-check_height-unknown = Unknown
10051020
# Shows an element below it
1006-
onboarding-automatic_proportions-check_height-hmd_height1 = Your HMD height is
1021+
onboarding-automatic_proportions-check_height-hmd_height2 = Your headset height is:
1022+
onboarding-automatic_proportions-check_height-measure-start = Start measuring
1023+
onboarding-automatic_proportions-check_height-measure-stop = Stop measuring
1024+
onboarding-automatic_proportions-check_height-measure-reset = Retry measuring
1025+
onboarding-automatic_proportions-check_height-next_step = Use headset height
1026+
1027+
onboarding-automatic_proportions-check_floor_height-title = Measure your floor height (optional)
1028+
onboarding-automatic_proportions-check_floor_height-description = In some cases, your floor height may not be set correctly by your headset, causing the headset height to be measured as higher than it should be. You can measure the "height" of your floor to correct your headset height.
1029+
# All the text is in bold!
1030+
onboarding-automatic_proportions-check_floor_height-calculation_warning = If you are sure that your floor height is correct, you can skip this step.
10071031
# Shows an element below it
1008-
onboarding-automatic_proportions-check_height-height1 = so your actual height is
1009-
onboarding-automatic_proportions-check_height-next_step = They are fine
1032+
onboarding-automatic_proportions-check_floor_height-floor_height = Your floor height is:
1033+
onboarding-automatic_proportions-check_floor_height-measure-start = Start measuring
1034+
onboarding-automatic_proportions-check_floor_height-measure-stop = Stop measuring
1035+
onboarding-automatic_proportions-check_floor_height-measure-reset = Retry measuring
1036+
onboarding-automatic_proportions-check_floor_height-skip_step = Skip step and save
1037+
onboarding-automatic_proportions-check_floor_height-next_step = Use floor height and save
1038+
10101039
onboarding-automatic_proportions-start_recording-title = Get ready to move
10111040
onboarding-automatic_proportions-start_recording-description = We're now going to record some specific poses and moves. These will be prompted in the next screen. Be ready to start when the button is pressed!
10121041
onboarding-automatic_proportions-start_recording-next = Start Recording
1042+
10131043
onboarding-automatic_proportions-recording-title = REC
10141044
onboarding-automatic_proportions-recording-description-p0 = Recording in progress...
10151045
onboarding-automatic_proportions-recording-description-p1 = Make the moves shown below:
@@ -1027,12 +1057,14 @@ onboarding-automatic_proportions-recording-timer = { $time ->
10271057
[one] 1 second left
10281058
*[other] { $time } seconds left
10291059
}
1060+
10301061
onboarding-automatic_proportions-verify_results-title = Verify results
10311062
onboarding-automatic_proportions-verify_results-description = Check the results below, do they look correct?
10321063
onboarding-automatic_proportions-verify_results-results = Recording results
10331064
onboarding-automatic_proportions-verify_results-processing = Processing the result
10341065
onboarding-automatic_proportions-verify_results-redo = Redo recording
10351066
onboarding-automatic_proportions-verify_results-confirm = They're correct
1067+
10361068
onboarding-automatic_proportions-done-title = Body measured and saved.
10371069
onboarding-automatic_proportions-done-description = Your body proportions' calibration is complete!
10381070
onboarding-automatic_proportions-error_modal-v2 =
@@ -1041,6 +1073,26 @@ onboarding-automatic_proportions-error_modal-v2 =
10411073
Please <docs>check the docs</docs> or join our <discord>Discord</discord> for help ^_^
10421074
onboarding-automatic_proportions-error_modal-confirm = Understood!
10431075
1076+
onboarding-automatic_proportions-smol_warning =
1077+
Your configured height of { $height } is smaller than the minimum accepted height of { $minHeight }.
1078+
<b>Please redo the measurements and ensure they are correct.</b>
1079+
onboarding-automatic_proportions-smol_warning-cancel = Go back
1080+
1081+
## Tracker scaled proportions setup
1082+
onboarding-scaled_proportions-title = Scaled proportions
1083+
onboarding-scaled_proportions-description = For SlimeVR trackers to work, we need to know the length of your bones. This will use an average proportion and scale it based on your height.
1084+
onboarding-scaled_proportions-manual_height-title = Configure your height
1085+
onboarding-scaled_proportions-manual_height-description = Your headset (HMD) height should be slightly less than your full height, as headsets measure your eye height. This height will be used as a baseline for your body proportions.
1086+
onboarding-scaled_proportions-manual_height-missing_steamvr = SteamVR is not currently connected to SlimeVR, so measurements can't be based on your headset. <b>Proceed at your own risk or check the docs!</b>
1087+
onboarding-scaled_proportions-manual_height-height = Your headset height is
1088+
onboarding-scaled_proportions-manual_height-next_step = Continue and save
1089+
1090+
## Tracker scaled proportions reset
1091+
onboarding-scaled_proportions-reset_proportion-title = Reset your body proportions
1092+
onboarding-scaled_proportions-reset_proportion-description = To set your body proportions based on your height, you need to now reset all of your proportions. This will clear any proportions you have configured and provide a baseline configuration.
1093+
onboarding-scaled_proportions-done-title = Body proportions set
1094+
onboarding-scaled_proportions-done-description = Your body proportions should now be configured based on your height.
1095+
10441096
## Home
10451097
home-no_trackers = No trackers detected or assigned
10461098

gui/src/App.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import { AppLayout } from './AppLayout';
5656
import { Preload } from './components/Preload';
5757
import { UnknownDeviceModal } from './components/UnknownDeviceModal';
5858
import { useDiscordPresence } from './hooks/discord-presence';
59+
import { ScaledProportionsPage } from './components/onboarding/pages/body-proportions/ScaledProportions';
5960
import { EmptyLayout } from './components/EmptyLayout';
6061
import { AdvancedSettings } from './components/settings/pages/AdvancedSettings';
6162
import { FirmwareUpdate } from './components/firmware-update/FirmwareUpdate';
@@ -162,6 +163,10 @@ function Layout() {
162163
path="body-proportions/manual"
163164
element={<ManualProportionsPage />}
164165
/>
166+
<Route
167+
path="body-proportions/scaled"
168+
element={<ScaledProportionsPage />}
169+
/>
165170
<Route path="done" element={<DonePage />} />
166171
</Route>
167172
<Route path="*" element={<TopBar></TopBar>}></Route>

gui/src/components/commons/NumberSelector.tsx

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Control, Controller } from 'react-hook-form';
22
import { Button } from './Button';
33
import { Typography } from './Typography';
4+
import { useCallback, useMemo } from 'react';
5+
import { useLocaleConfig } from '@/i18n/config';
46

57
export function NumberSelector({
68
label,
@@ -10,7 +12,9 @@ export function NumberSelector({
1012
min,
1113
max,
1214
step,
15+
doubleStep,
1316
disabled = false,
17+
showButtonWithNumber = false,
1418
}: {
1519
label?: string;
1620
valueLabelFormat?: (value: number) => string;
@@ -19,14 +23,36 @@ export function NumberSelector({
1923
min: number;
2024
max: number;
2125
step: number | ((value: number, add: boolean) => number);
26+
doubleStep?: number;
2227
disabled?: boolean;
28+
showButtonWithNumber?: boolean;
2329
}) {
30+
const { currentLocales } = useLocaleConfig();
31+
2432
const stepFn =
2533
typeof step === 'function'
2634
? step
2735
: (value: number, add: boolean) =>
2836
+(add ? value + step : value - step).toFixed(2);
2937

38+
const doubleStepFn = useCallback(
39+
(value: number, add: boolean) =>
40+
doubleStep === undefined
41+
? 0
42+
: +(add ? value + doubleStep : value - doubleStep).toFixed(2),
43+
[doubleStep]
44+
);
45+
46+
const decimalFormat = useMemo(
47+
() =>
48+
new Intl.NumberFormat(currentLocales, {
49+
style: 'decimal',
50+
maximumFractionDigits: 2,
51+
signDisplay: 'exceptZero',
52+
}),
53+
[currentLocales]
54+
);
55+
3056
return (
3157
<Controller
3258
control={control}
@@ -35,7 +61,19 @@ export function NumberSelector({
3561
<div className="flex flex-col gap-1 w-full">
3662
<Typography bold>{label}</Typography>
3763
<div className="flex gap-5 bg-background-60 p-2 rounded-lg">
38-
<div className="flex">
64+
<div className="flex gap-1">
65+
{doubleStep !== undefined && (
66+
<Button
67+
variant="tertiary"
68+
rounded
69+
onClick={() => onChange(doubleStepFn(value, false))}
70+
disabled={doubleStepFn(value, false) < min || disabled}
71+
>
72+
{showButtonWithNumber
73+
? decimalFormat.format(-doubleStep)
74+
: '--'}
75+
</Button>
76+
)}
3977
<Button
4078
variant="tertiary"
4179
rounded
@@ -48,7 +86,7 @@ export function NumberSelector({
4886
<div className="flex flex-grow justify-center items-center w-10 text-standard">
4987
{valueLabelFormat ? valueLabelFormat(value) : value}
5088
</div>
51-
<div className="flex">
89+
<div className="flex gap-1">
5290
<Button
5391
variant="tertiary"
5492
rounded
@@ -57,6 +95,18 @@ export function NumberSelector({
5795
>
5896
+
5997
</Button>
98+
{doubleStep !== undefined && (
99+
<Button
100+
variant="tertiary"
101+
rounded
102+
onClick={() => onChange(doubleStepFn(value, true))}
103+
disabled={doubleStepFn(value, true) > max || disabled}
104+
>
105+
{showButtonWithNumber
106+
? decimalFormat.format(doubleStep)
107+
: '++'}
108+
</Button>
109+
)}
60110
</div>
61111
</div>
62112
</div>

gui/src/components/onboarding/StepperSlider.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,30 +94,42 @@ export function StepDot({
9494
export function StepperSlider({
9595
variant,
9696
steps,
97+
back,
98+
forward,
9799
}: {
98100
variant: 'alone' | 'onboarding';
99101
steps: Step[];
102+
/**
103+
* Ran when step is 0 and `prevStep` is executed
104+
*/
105+
back?: () => void;
106+
/**
107+
* Ran when step is `steps.length - 1` and nextStep is executed
108+
*/
109+
forward?: () => void;
100110
}) {
101111
const ref = useRef<HTMLDivElement | null>(null);
102112
const { width } = useElemSize(ref);
103-
const [stepsContainers, setSteps] = useState(0);
104113
const [shouldAnimate, setShouldAnimate] = useState(true);
105114
const [step, setStep] = useState(0);
106115

107116
useEffect(() => {
108-
if (!ref.current) return;
109-
const stepsContainers =
110-
ref.current.getElementsByClassName('step-container');
111-
setSteps(stepsContainers.length);
112-
}, [ref]);
117+
setStep((x) => Math.min(x, steps.length - 1));
118+
}, [steps.length]);
113119

114120
const nextStep = () => {
115-
if (step + 1 === stepsContainers) return;
121+
if (step + 1 === steps.length) {
122+
forward?.();
123+
return;
124+
}
116125
setStep(step + 1);
117126
};
118127

119128
const prevStep = () => {
120-
if (step - 1 < 0) return;
129+
if (step - 1 < 0) {
130+
back?.();
131+
return;
132+
}
121133
setStep(step - 1);
122134
};
123135

@@ -168,7 +180,7 @@ export function StepperSlider({
168180
</div>
169181
</div>
170182
<div className="flex justify-center items-center gap-2">
171-
{Array.from({ length: stepsContainers }).map((_, index) => (
183+
{Array.from({ length: steps.length }).map((_, index) => (
172184
<div key={index} className="flex items-center gap-2">
173185
{index !== 0 && (
174186
<div className="w-5 h-1 bg-background-50 rounded-full"></div>

0 commit comments

Comments
 (0)