Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions gui/public/i18n/en/translation.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -639,8 +639,9 @@ settings-general-fk_settings-velocity_settings = Velocity Settings
settings-general-fk_settings-velocity_settings-description = Send derived velocity data to SteamVR. Required for Natural Locomotion support. May cause jitter in FBT.
settings-general-fk_settings-velocity_settings-send_derived_velocity = Send derived velocity to driver
settings-general-fk_settings-arm_fk = Arm tracking
settings-general-fk_settings-arm_fk-description = Force arms to be tracked from the headset (HMD) even if positional hand data is available.
settings-general-fk_settings-arm_fk-force_arms = Force arms from HMD
settings-general-fk_settings-arm_fk-description = Use forward kinematics to track arms between controller and HMD positional tracking. Otherwise, track arms from controllers alone.
settings-general-fk_settings-arm_fk-force_arms = Use forward kinematics (recommended)
settings-general-fk_settings-arm_fk-legacy = Tracking arms from controller alone is not recommended anymore!
settings-general-fk_settings-reset_settings = Reset settings
settings-general-fk_settings-reset_settings-reset_hmd_pitch-description = Reset the HMD's pitch (vertical rotation) upon doing a full reset. Useful if wearing an HMD on the forehead for VTubing or mocap. Do not enable for VR.
settings-general-fk_settings-reset_settings-reset_hmd_pitch = Reset HMD pitch
Expand Down Expand Up @@ -822,6 +823,9 @@ settings-osc-router-network-port_out =
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
settings-osc-router-external_tracking = External tracking
settings-osc-router-rescale_tracking = Rescale to avatar
settings-osc-router-rescale_tracking-description = Rescale external tracking routed through OSC to avatar scale as determined by the VRM loaded in VMC settings.

## OSC VRChat settings
settings-osc-vrchat = VRChat OSC Trackers
Expand Down Expand Up @@ -879,12 +883,13 @@ settings-osc-vmc-network-port_out =
settings-osc-vmc-network-address = Network address
settings-osc-vmc-network-address-description = Choose which address to send out data at via VMC.
settings-osc-vmc-network-address-placeholder = IPV4 address
settings-osc-vmc-vrm = VRM Model
settings-osc-vmc-vrm-description = Load a VRM model to allow head anchor and enable a higher compatibility with other applications.
settings-osc-vmc-vrm = VRM Avatar
settings-osc-vmc-vrm-description = Load a VRM avatar to allow for positioning using that avatars scale. Otherwise, alignment in external programs that use VMC might be wrong.
settings-osc-vmc-vrm-untitled_model = Untitled model
settings-osc-vmc-vrm-file_select = Drag & drop a model to use, or <u>browse</u>
settings-osc-vmc-vrm-required = Loading a VRM avatar is required for proper avatar positioning over VMC!
settings-osc-vmc-anchor_hip = Anchor at hips
settings-osc-vmc-anchor_hip-description = Anchor the tracking at the hips, useful for seated VTubing. If disabling, load a VRM model.
settings-osc-vmc-anchor_hip-description = Anchor the tracking at the hips, useful for seated VTubing. If disabled, load a VRM avatar to allow for proper positioning.
settings-osc-vmc-anchor_hip-label = Anchor at hips
settings-osc-vmc-mirror_tracking = Mirror tracking
settings-osc-vmc-mirror_tracking-description = Mirror the tracking horizontally.
Expand Down Expand Up @@ -977,8 +982,8 @@ onboarding-quiz-mocap_preferences-playspace-title = What is your playspace?
onboarding-quiz-mocap_preferences-playspace-desc = If standing, SlimeVR will try to track walking movement instead of anchoring you in one spot.
onboarding-quiz-mocap_preferences-playspace-sitting = Sitting
onboarding-quiz-mocap_preferences-playspace-standing = Standing
onboarding-quiz-mocap_preferences-vrm_model-title = Do you have a VRM model? (Optional)
onboarding-quiz-mocap_preferences-vrm_model-desc = Loading a VRM model will improve tracking quality and compatibility with applications that use VMC.
onboarding-quiz-mocap_preferences-vrm_model-title = Do you have a VRM avatar? (Optional)
onboarding-quiz-mocap_preferences-vrm_model-desc = Load a VRM avatar to allow for positioning using that avatars scale. Otherwise, alignment in external programs that use VMC might be wrong.
onboarding-quiz-mocap_preferences-head_tracker-title = Are you wearing a tracker or VR headset on your head?
onboarding-quiz-mocap_preferences-head_tracker-yes = Yes
onboarding-quiz-mocap_preferences-head_tracker-no = No
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,29 +31,28 @@ export function QuizMocapPosQuestion() {
id="onboarding-quiz-mocap_preferences-desc"
/>
</div>

<div className="flex flex-col gap-6">
<div className="flex gap-2 flex-col">
<div className="flex flex-col gap-2">
<Typography
variant="section-title"
id="onboarding-quiz-mocap_preferences-head_tracker-title"
id="onboarding-quiz-mocap_preferences-playspace-title"
/>
<Typography id="onboarding-quiz-mocap_preferences-playspace-desc" />
</div>
<div className="grid grid-cols-2 gap-4">
<QuizButton
active={headTracker}
onClick={() => setHeadTracker(true)}
icon={<HeadsetIcon width={50} />}
name="onboarding-quiz-mocap_preferences-head_tracker-yes"
active={playspace === 'sitting'}
onClick={() => setPlayspace('sitting')}
icon={<SittingIcon size={50} />}
name="onboarding-quiz-mocap_preferences-playspace-sitting"
/>
<QuizButton
active={!headTracker}
onClick={() => {
setHeadTracker(false);
setMocapPos(undefined);
}}
icon={<HeadsetIcon width={50} disabled />}
name="onboarding-quiz-mocap_preferences-head_tracker-no"
active={playspace === 'standing'}
onClick={() => setPlayspace('standing')}
icon={<HumanIcon width={50} />}
name="onboarding-quiz-mocap_preferences-playspace-standing"
/>
</div>
</div>
Expand All @@ -68,37 +67,40 @@ export function QuizMocapPosQuestion() {
/>
<Typography id="onboarding-quiz-mocap_preferences-vrm_model-desc" />
</div>
<VMCFileUpload />
<VMCFileUpload suggested={playspace !== 'sitting'} />
</div>
</div>

<div className="flex flex-col gap-6">
<div className="flex gap-2 flex-col">
<div className="flex flex-col gap-2">
<Typography
variant="section-title"
id="onboarding-quiz-mocap_preferences-head_tracker-title"
/>
</div>
<div className="grid grid-cols-2 gap-4">
<QuizButton
active={headTracker}
onClick={() => setHeadTracker(true)}
icon={<HeadsetIcon width={50} />}
name="onboarding-quiz-mocap_preferences-head_tracker-yes"
/>
<QuizButton
active={!headTracker}
onClick={() => {
setHeadTracker(false);
setMocapPos(undefined);
}}
icon={<HeadsetIcon width={50} disabled />}
name="onboarding-quiz-mocap_preferences-head_tracker-no"
/>
</div>
</div>
</div>

{headTracker && (
<>
<div className="flex flex-col gap-6">
<div className="flex gap-2 flex-col">
<div className="flex flex-col gap-2">
<Typography
variant="section-title"
id="onboarding-quiz-mocap_preferences-playspace-title"
/>
<Typography id="onboarding-quiz-mocap_preferences-playspace-desc" />
</div>
<div className="grid grid-cols-2 gap-4">
<QuizButton
active={playspace === 'sitting'}
onClick={() => setPlayspace('sitting')}
icon={<SittingIcon size={50} />}
name="onboarding-quiz-mocap_preferences-playspace-sitting"
/>
<QuizButton
active={playspace === 'standing'}
onClick={() => setPlayspace('standing')}
icon={<HumanIcon width={50} />}
name="onboarding-quiz-mocap_preferences-playspace-standing"
/>
</div>
</div>
</div>
<div className="flex flex-col gap-6">
<div className="flex gap-2 flex-col">
<div className="flex flex-col gap-2">
Expand All @@ -114,7 +116,7 @@ export function QuizMocapPosQuestion() {
icon={
<img
src="/images/quiz/quiz_mocap-pos_forehead.webp"
className="w-44"
className="w-20"
/>
}
name="onboarding-quiz-mocap_preferences-head_tracker_location-forehead"
Expand All @@ -125,7 +127,7 @@ export function QuizMocapPosQuestion() {
icon={
<img
src="/images/quiz/quiz_mocap-pos_face.webp"
className="w-44"
className="w-20"
/>
}
name="onboarding-quiz-mocap_preferences-head_tracker_location-face"
Expand Down
7 changes: 7 additions & 0 deletions gui/src/components/settings/pages/GeneralSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { WrenchIcon } from '@/components/commons/icon/WrenchIcons';
import { NumberSelector } from '@/components/commons/NumberSelector';
import { Radio } from '@/components/commons/Radio';
import { Typography } from '@/components/commons/Typography';
import { TipBox } from '@/components/commons/TipBox';
import {
SettingsPageLayout,
SettingsPagePaneLayout,
Expand Down Expand Up @@ -229,6 +230,7 @@ export function GeneralSettings() {

const {
trackers: { automaticTrackerToggle },
toggles: { forceArmsFromHmd },
} = watch();

const onSubmit = (values: SettingsForm) => {
Expand Down Expand Up @@ -924,6 +926,11 @@ export function GeneralSettings() {
)}
/>
</div>
{!forceArmsFromHmd && (
<TipBox>
{l10n.getString('settings-general-fk_settings-arm_fk-legacy')}
</TipBox>
)}

<div className="flex flex-col pt-2">
<Typography variant="section-title">
Expand Down
26 changes: 25 additions & 1 deletion gui/src/components/settings/pages/OSCRouterSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
SettingsPagePaneLayout,
} from '@/components/settings/SettingsPageLayout';
import { yupResolver } from '@hookform/resolvers/yup';
import { object } from 'yup';
import { boolean, object } from 'yup';
import {
OSCSettings,
useOscSettingsValidator,
Expand All @@ -28,6 +28,7 @@ import {
interface OSCRouterSettingsForm {
router: {
oscSettings: OSCSettings;
rescaleTracking: boolean;
};
}

Expand All @@ -39,6 +40,7 @@ const defaultValues = {
portOut: 9000,
address: '127.0.0.1',
},
rescaleTracking: false,
},
};

Expand All @@ -56,6 +58,7 @@ export function OSCRouterSettings() {
object({
router: object({
oscSettings: oscValidator,
rescaleTracking: boolean().required(),
}),
})
),
Expand All @@ -71,6 +74,7 @@ export function OSCRouterSettings() {
new OSCSettingsT(),
values.router.oscSettings
);
router.rescaleTracking = values.router.rescaleTracking;

settings.oscRouter = router;
}
Expand Down Expand Up @@ -102,6 +106,7 @@ export function OSCRouterSettings() {
formData.router.oscSettings.address =
settings.oscRouter.oscSettings.address.toString();
}
formData.router.rescaleTracking = settings.oscRouter.rescaleTracking;

reset(formData);
}
Expand Down Expand Up @@ -202,6 +207,25 @@ export function OSCRouterSettings() {
label=""
/>
</div>
<Typography variant="section-title">
{l10n.getString('settings-osc-router-external_tracking')}
</Typography>
<div className="flex flex-col pb-2">
<Typography>
{l10n.getString(
'settings-osc-router-rescale_tracking-description'
)}
</Typography>
</div>
<div className="grid grid-cols-2 gap-3 pb-5">
<CheckBox
variant="toggle"
outlined
control={control}
name="router.rescaleTracking"
label={l10n.getString('settings-osc-router-rescale_tracking')}
/>
</div>
</>
</SettingsPagePaneLayout>
</form>
Expand Down
68 changes: 39 additions & 29 deletions gui/src/components/settings/pages/VMCSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { FileInput } from '@/components/commons/FileInput';
import { VMCIcon } from '@/components/commons/icon/VMCIcon';
import { Input } from '@/components/commons/Input';
import { Typography } from '@/components/commons/Typography';
import { TipBox } from '@/components/commons/TipBox';
import { magic } from '@/utils/formatting';
import {
SettingsPageLayout,
Expand Down Expand Up @@ -50,7 +51,7 @@ const defaultValues = {
},
};

export function VMCFileUpload() {
export function VMCFileUpload({ suggested = false }) {
const { sendRPCPacket, useRPCPacket } = useWebsocketAPI();
const { l10n } = useLocalization();
const [modelName, setModelName] = useState<string | null>(null);
Expand Down Expand Up @@ -106,22 +107,29 @@ export function VMCFileUpload() {
});

return (
<FileInput
control={control}
name="vrmJson"
rules={{
required: false,
}}
value="help"
importedFileName={
// if modelname is an empty string, it's an untitled model
modelName === ''
? l10n.getString('settings-osc-vmc-vrm-untitled_model')
: modelName
}
label="settings-osc-vmc-vrm-file_select"
accept="model/gltf-binary, model/gltf+json, model/vrml, .vrm, .glb, .gltf"
/>
<>
{modelName === null && suggested && (
<Localized id="settings-osc-vmc-vrm-required">
<TipBox>Tip</TipBox>
</Localized>
)}
<FileInput
control={control}
name="vrmJson"
rules={{
required: false,
}}
value="help"
importedFileName={
// if modelname is an empty string, it's an untitled model
modelName === ''
? l10n.getString('settings-osc-vmc-vrm-untitled_model')
: modelName
}
label="settings-osc-vmc-vrm-file_select"
accept="model/gltf-binary, model/gltf+json, model/vrml, .vrm, .glb, .gltf"
/>
</>
);
}

Expand All @@ -145,6 +153,8 @@ export function VMCSettings() {
),
});

const anchorHip = watch('vmc.anchorHip');

const onSubmit = async (values: VMCSettingsForm) => {
const settings = new ChangeSettingsRequestT();

Expand Down Expand Up @@ -287,17 +297,6 @@ export function VMCSettings() {
label=""
/>
</div>
<Typography variant="section-title">
{l10n.getString('settings-osc-vmc-vrm')}
</Typography>
<div className="flex flex-col pb-2">
<Typography>
{l10n.getString('settings-osc-vmc-vrm-description')}
</Typography>
</div>
<div className="grid gap-3 pb-5">
<VMCFileUpload />
</div>
<Typography variant="section-title">
{l10n.getString('settings-osc-vmc-anchor_hip')}
</Typography>
Expand All @@ -315,6 +314,17 @@ export function VMCSettings() {
label={l10n.getString('settings-osc-vmc-anchor_hip-label')}
/>
</div>
<Typography variant="section-title">
{l10n.getString('settings-osc-vmc-vrm')}
</Typography>
<div className="flex flex-col pb-2">
<Typography>
{l10n.getString('settings-osc-vmc-vrm-description')}
</Typography>
</div>
<div className="grid gap-3 pb-5">
<VMCFileUpload suggested={!anchorHip} />
</div>
<Typography variant="section-title">
{l10n.getString('settings-osc-vmc-mirror_tracking')}
</Typography>
Expand Down Expand Up @@ -419,7 +429,7 @@ function getVRMName(data: any): string | null {

if (typeof name !== 'string') {
error(
`The name of the VRM model is not a string, instead it is a ${typeof name}`
`The name of the VRM avatar is not a string, instead it is a ${typeof name}`
);
return null;
}
Expand Down
Loading
Loading