mirror of
https://github.com/SlimeVR/SlimeVR-Server.git
synced 2026-04-06 02:01:58 +02:00
Full height for manual configuration (#1329)
Co-authored-by: lucas lelievre <loucass003@gmail.com>
This commit is contained in:
@@ -130,14 +130,13 @@ skeleton_bone-ELBOW_OFFSET = Elbow Offset
|
||||
|
||||
## Tracker reset buttons
|
||||
reset-reset_all = Reset all proportions
|
||||
reset-reset_all_warning =
|
||||
<b>Warning:</b> This will reset your proportions to being just based on your height.
|
||||
reset-reset_all_warning-v2 =
|
||||
<b>Warning:</b> Your proportions will be reset to defaults scaled to your configured height.
|
||||
Are you sure you want to do this?
|
||||
reset-reset_all_warning-reset = Reset proportions
|
||||
reset-reset_all_warning-cancel = Cancel
|
||||
reset-reset_all_warning_default =
|
||||
<b>Warning:</b> You currently don't have your height defined, which
|
||||
will make the proportions be based on a default height.
|
||||
reset-reset_all_warning_default-v2 =
|
||||
<b>Warning:</b> Your height has not been configured, your proportions will be reset to defaults with the default height.
|
||||
Are you sure you want to do this?
|
||||
|
||||
reset-full = Full Reset
|
||||
@@ -1078,9 +1077,10 @@ onboarding-automatic_proportions-smol_warning-cancel = Go back
|
||||
onboarding-scaled_proportions-title = Scaled proportions
|
||||
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.
|
||||
onboarding-scaled_proportions-manual_height-title = Configure your height
|
||||
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.
|
||||
onboarding-scaled_proportions-manual_height-description-v2 = This height will be used as a baseline for your body proportions.
|
||||
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>
|
||||
onboarding-scaled_proportions-manual_height-height = Your headset height is
|
||||
onboarding-scaled_proportions-manual_height-height-v2 = Your full height is
|
||||
onboarding-scaled_proportions-manual_height-estimated_height = Your estimated headset height is:
|
||||
onboarding-scaled_proportions-manual_height-next_step = Continue and save
|
||||
|
||||
## Tracker scaled proportions reset
|
||||
|
||||
@@ -55,8 +55,8 @@ export function ProportionsResetModal({
|
||||
<Localized
|
||||
id={
|
||||
usingDefaultHeight
|
||||
? 'reset-reset_all_warning_default'
|
||||
: 'reset-reset_all_warning'
|
||||
? 'reset-reset_all_warning_default-v2'
|
||||
: 'reset-reset_all_warning-v2'
|
||||
}
|
||||
elems={{ b: <b></b> }}
|
||||
>
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Typography } from '@/components/commons/Typography';
|
||||
import { Localized, useLocalization } from '@fluent/react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useLocaleConfig } from '@/i18n/config';
|
||||
import { useHeightContext } from '@/hooks/height';
|
||||
import { EYE_HEIGHT_TO_HEIGHT_RATIO, useHeightContext } from '@/hooks/height';
|
||||
import { useInterval } from '@/hooks/timeout';
|
||||
import { TooSmolModal } from './TooSmolModal';
|
||||
|
||||
@@ -137,7 +137,8 @@ export function CheckFloorHeightStep({
|
||||
</Typography>
|
||||
<Typography>
|
||||
{mFormat.format(
|
||||
((hmdHeight ?? 0) - (floorHeight ?? 0)) / 0.936
|
||||
((hmdHeight ?? 0) - (floorHeight ?? 0)) /
|
||||
EYE_HEIGHT_TO_HEIGHT_RATIO
|
||||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Typography } from '@/components/commons/Typography';
|
||||
import { Localized, useLocalization } from '@fluent/react';
|
||||
import { useMemo } from 'react';
|
||||
import { useLocaleConfig } from '@/i18n/config';
|
||||
import { useHeightContext } from '@/hooks/height';
|
||||
import { EYE_HEIGHT_TO_HEIGHT_RATIO, useHeightContext } from '@/hooks/height';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import {
|
||||
ChangeSettingsRequestT,
|
||||
@@ -36,12 +36,13 @@ export function ManualHeightStep({
|
||||
const { state } = useOnboarding();
|
||||
const { l10n } = useLocalization();
|
||||
const { setHmdHeight } = useHeightContext();
|
||||
const { control, handleSubmit, formState } = useForm<HeightForm>({
|
||||
const { control, handleSubmit, formState, watch } = useForm<HeightForm>({
|
||||
defaultValues: { height: 1.5 },
|
||||
});
|
||||
const { sendRPCPacket } = useWebsocketAPI();
|
||||
const { currentLocales } = useLocaleConfig();
|
||||
const { statuses } = useStatusContext();
|
||||
const height = watch('height');
|
||||
|
||||
const missingSteamConnection = useMemo(
|
||||
() =>
|
||||
@@ -65,13 +66,14 @@ export function ManualHeightStep({
|
||||
);
|
||||
|
||||
const submitHmdHeight = (values: HeightForm) => {
|
||||
setHmdHeight(values.height);
|
||||
const newHeight = values.height * EYE_HEIGHT_TO_HEIGHT_RATIO;
|
||||
setHmdHeight(newHeight);
|
||||
const settingsRequest = new ChangeSettingsRequestT();
|
||||
settingsRequest.modelSettings = new ModelSettingsT(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new SkeletonHeightT(values.height, 0)
|
||||
new SkeletonHeightT(newHeight, 0)
|
||||
);
|
||||
sendRPCPacket(RpcMessage.ChangeSettingsRequest, settingsRequest);
|
||||
nextStep();
|
||||
@@ -92,7 +94,7 @@ export function ManualHeightStep({
|
||||
<div>
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(
|
||||
'onboarding-scaled_proportions-manual_height-description'
|
||||
'onboarding-scaled_proportions-manual_height-description-v2'
|
||||
)}
|
||||
</Typography>
|
||||
{missingSteamConnection && (
|
||||
@@ -112,7 +114,7 @@ export function ManualHeightStep({
|
||||
control={control}
|
||||
name="height"
|
||||
label={l10n.getString(
|
||||
'onboarding-scaled_proportions-manual_height-height'
|
||||
'onboarding-scaled_proportions-manual_height-height-v2'
|
||||
)}
|
||||
valueLabelFormat={(value) =>
|
||||
isNaN(value)
|
||||
@@ -128,6 +130,16 @@ export function ManualHeightStep({
|
||||
doubleStep={0.1}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col self-center items-center justify-center">
|
||||
<Typography>
|
||||
{l10n.getString(
|
||||
'onboarding-scaled_proportions-manual_height-estimated_height'
|
||||
)}
|
||||
</Typography>
|
||||
<Typography>
|
||||
{mFormat.format(height * EYE_HEIGHT_TO_HEIGHT_RATIO)}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -56,3 +56,8 @@ export function useHeightContext() {
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
// The headset height is not the full height! This value compensates for the
|
||||
// offset from the headset height to the user full height
|
||||
// From Drillis and Contini (1966)
|
||||
export const EYE_HEIGHT_TO_HEIGHT_RATIO = 0.936;
|
||||
|
||||
@@ -27,10 +27,9 @@ class BodyProportionError : IAutoBoneError {
|
||||
}
|
||||
|
||||
companion object {
|
||||
// TODO hip tracker stuff... Hip tracker should be around 3 to 5
|
||||
// centimeters.
|
||||
// The headset height is not the full height! This value compensates for the
|
||||
// offset from the headset height to the user height
|
||||
// offset from the headset height to the user full height
|
||||
// From Drillis and Contini (1966)
|
||||
@JvmField
|
||||
var eyeHeightToHeightRatio = 0.936f
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import dev.slimevr.protocol.rpc.setup.RPCUtil.getLocalIp
|
||||
import dev.slimevr.protocol.rpc.status.RPCStatusHandler
|
||||
import dev.slimevr.protocol.rpc.trackingpause.RPCTrackingPause
|
||||
import dev.slimevr.tracking.processor.config.SkeletonConfigOffsets
|
||||
import dev.slimevr.tracking.trackers.TrackerPosition
|
||||
import dev.slimevr.tracking.trackers.TrackerPosition.Companion.getByBodyPart
|
||||
import dev.slimevr.tracking.trackers.TrackerStatus
|
||||
import dev.slimevr.tracking.trackers.TrackerUtils.getTrackerForSkeleton
|
||||
@@ -490,7 +491,8 @@ class RPCHandler(private val api: ProtocolAPI) : ProtocolHandler<RpcMessageHeade
|
||||
.createHeightResponse(
|
||||
fbb,
|
||||
posTrackers.minOf { it.position.y },
|
||||
posTrackers.maxOf { it.position.y },
|
||||
posTrackers.find { it.trackerPosition == TrackerPosition.HEAD }?.position?.y
|
||||
?: posTrackers.maxOf { it.position.y },
|
||||
)
|
||||
} else {
|
||||
HeightResponse
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.slimevr.tracking.processor.config
|
||||
|
||||
import dev.slimevr.VRServer.Companion.instance
|
||||
import dev.slimevr.VRServer.Companion.instanceInitialized
|
||||
import dev.slimevr.autobone.AutoBone
|
||||
import dev.slimevr.autobone.errors.BodyProportionError.Companion.proportionLimitMap
|
||||
import dev.slimevr.config.ConfigManager
|
||||
@@ -409,14 +410,14 @@ class SkeletonConfigManager(
|
||||
|
||||
// Remove from config to use default if they change in the future.
|
||||
Arrays.fill(changedToggles, false)
|
||||
for (value in SkeletonConfigToggles.values) {
|
||||
instance.configManager
|
||||
.vrConfig
|
||||
.skeleton
|
||||
.getToggles()
|
||||
.remove(value.configKey)
|
||||
// Set default in skeleton
|
||||
setToggle(value, value.defaultValue)
|
||||
if (instanceInitialized) {
|
||||
for (value in SkeletonConfigToggles.values) {
|
||||
instance.configManager
|
||||
.vrConfig
|
||||
.skeleton
|
||||
.getToggles()
|
||||
.remove(value.configKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,14 +433,14 @@ class SkeletonConfigManager(
|
||||
|
||||
// Remove from config to use default if they change in the future.
|
||||
Arrays.fill(changedValues, false)
|
||||
for (value in SkeletonConfigValues.values) {
|
||||
instance.configManager
|
||||
.vrConfig
|
||||
.skeleton
|
||||
.getValues()
|
||||
.remove(value.configKey)
|
||||
// Set default in skeleton
|
||||
setValue(value, value.defaultValue)
|
||||
if (instanceInitialized) {
|
||||
for (value in SkeletonConfigValues.values) {
|
||||
instance.configManager
|
||||
.vrConfig
|
||||
.skeleton
|
||||
.getValues()
|
||||
.remove(value.configKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,6 +516,8 @@ class SkeletonConfigManager(
|
||||
}
|
||||
|
||||
fun save() {
|
||||
require(instanceInitialized) { "VRServer instance is not initialized, config cannot be saved." }
|
||||
|
||||
val skeletonConfig = instance.configManager
|
||||
.vrConfig
|
||||
.skeleton
|
||||
|
||||
Reference in New Issue
Block a user