mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 12:37:51 +02:00
beta
Uses valid track points Relocated to /developer Better UI Settings persistance
This commit is contained in:
parent
6ba8d1ef72
commit
d0226a3b05
8 changed files with 552 additions and 767 deletions
|
@ -1,240 +0,0 @@
|
||||||
var LEFT_HAND_INDEX = 0;
|
|
||||||
var RIGHT_HAND_INDEX = 1;
|
|
||||||
var LEFT_FOOT_INDEX = 2;
|
|
||||||
var RIGHT_FOOT_INDEX = 3;
|
|
||||||
var HIPS_INDEX = 4;
|
|
||||||
var SPINE2_INDEX = 5;
|
|
||||||
|
|
||||||
var HAND_SMOOTHING_TRANSLATION = 0.3;
|
|
||||||
var HAND_SMOOTHING_ROTATION = 0.15;
|
|
||||||
var FOOT_SMOOTHING_TRANSLATION = 0.3;
|
|
||||||
var FOOT_SMOOTHING_ROTATION = 0.15;
|
|
||||||
var TORSO_SMOOTHING_TRANSLATION = 0.3;
|
|
||||||
var TORSO_SMOOTHING_ROTATION = 0.16;
|
|
||||||
|
|
||||||
var mappingJson = {
|
|
||||||
name: "com.highfidelity.testing.exponentialFilterApp",
|
|
||||||
channels: [
|
|
||||||
{
|
|
||||||
from: "Standard.LeftHand",
|
|
||||||
to: "Actions.LeftHand",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: HAND_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: HAND_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.RightHand",
|
|
||||||
to: "Actions.RightHand",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: HAND_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: HAND_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.LeftFoot",
|
|
||||||
to: "Actions.LeftFoot",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: FOOT_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: FOOT_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.RightFoot",
|
|
||||||
to: "Actions.RightFoot",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: FOOT_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: FOOT_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.Hips",
|
|
||||||
to: "Actions.Hips",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: TORSO_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: TORSO_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.Spine2",
|
|
||||||
to: "Actions.Spine2",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: TORSO_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: TORSO_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// tablet app boiler plate
|
|
||||||
//
|
|
||||||
|
|
||||||
var TABLET_BUTTON_NAME = "EXPFILT";
|
|
||||||
var HTML_URL = Script.resolvePath("./index.html");
|
|
||||||
|
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
|
||||||
var tabletButton = tablet.addButton({
|
|
||||||
text: TABLET_BUTTON_NAME,
|
|
||||||
icon: Script.getExternalPath(Script.ExternalPaths.HF_Public, "/tony/icons/tpose-i.svg"),
|
|
||||||
activeIcon: Script.getExternalPath(Script.ExternalPaths.HF_Public, "/tony/icons/tpose-a.svg")
|
|
||||||
});
|
|
||||||
|
|
||||||
tabletButton.clicked.connect(function () {
|
|
||||||
if (shown) {
|
|
||||||
tablet.gotoHomeScreen();
|
|
||||||
} else {
|
|
||||||
tablet.gotoWebScreen(HTML_URL);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var shown = false;
|
|
||||||
|
|
||||||
function onScreenChanged(type, url) {
|
|
||||||
if (type === "Web" && url === HTML_URL) {
|
|
||||||
tabletButton.editProperties({isActive: true});
|
|
||||||
if (!shown) {
|
|
||||||
// hook up to event bridge
|
|
||||||
tablet.webEventReceived.connect(onWebEventReceived);
|
|
||||||
shownChanged(true);
|
|
||||||
}
|
|
||||||
shown = true;
|
|
||||||
} else {
|
|
||||||
tabletButton.editProperties({isActive: false});
|
|
||||||
if (shown) {
|
|
||||||
// disconnect from event bridge
|
|
||||||
tablet.webEventReceived.disconnect(onWebEventReceived);
|
|
||||||
shownChanged(false);
|
|
||||||
}
|
|
||||||
shown = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTranslation(i) {
|
|
||||||
return mappingJson.channels[i].filters[0].translation;
|
|
||||||
}
|
|
||||||
function setTranslation(i, value) {
|
|
||||||
mappingJson.channels[i].filters[0].translation = value;
|
|
||||||
mappingChanged();
|
|
||||||
}
|
|
||||||
function getRotation(i) {
|
|
||||||
return mappingJson.channels[i].filters[0].rotation;
|
|
||||||
}
|
|
||||||
function setRotation(i, value) {
|
|
||||||
mappingJson.channels[i].filters[0].rotation = value; mappingChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWebEventReceived(msg) {
|
|
||||||
msg = JSON.parse(msg);
|
|
||||||
if (msg.name === "init-complete") {
|
|
||||||
var values = [
|
|
||||||
{name: "enable-filtering", val: filterEnabled ? "on" : "off", checked: false},
|
|
||||||
{name: "left-hand-translation", val: getTranslation(LEFT_HAND_INDEX), checked: false},
|
|
||||||
{name: "left-hand-rotation", val: getRotation(LEFT_HAND_INDEX), checked: false},
|
|
||||||
{name: "right-hand-translation", val: getTranslation(RIGHT_HAND_INDEX), checked: false},
|
|
||||||
{name: "right-hand-rotation", val: getRotation(RIGHT_HAND_INDEX), checked: false},
|
|
||||||
{name: "left-foot-translation", val: getTranslation(LEFT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "left-foot-rotation", val: getRotation(LEFT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "right-foot-translation", val: getTranslation(RIGHT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "right-foot-rotation", val: getRotation(RIGHT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "hips-translation", val: getTranslation(HIPS_INDEX), checked: false},
|
|
||||||
{name: "hips-rotation", val: getRotation(HIPS_INDEX), checked: false},
|
|
||||||
{name: "spine2-translation", val: getTranslation(SPINE2_INDEX), checked: false},
|
|
||||||
{name: "spine2-rotation", val: getRotation(SPINE2_INDEX), checked: false}
|
|
||||||
];
|
|
||||||
tablet.emitScriptEvent(JSON.stringify(values));
|
|
||||||
} else if (msg.name === "enable-filtering") {
|
|
||||||
if (msg.val === "on") {
|
|
||||||
filterEnabled = true;
|
|
||||||
} else if (msg.val === "off") {
|
|
||||||
filterEnabled = false;
|
|
||||||
}
|
|
||||||
mappingChanged();
|
|
||||||
} else if (msg.name === "left-hand-translation") {
|
|
||||||
setTranslation(LEFT_HAND_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "left-hand-rotation") {
|
|
||||||
setRotation(LEFT_HAND_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "right-hand-translation") {
|
|
||||||
setTranslation(RIGHT_HAND_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "right-hand-rotation") {
|
|
||||||
setRotation(RIGHT_HAND_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "left-foot-translation") {
|
|
||||||
setTranslation(LEFT_FOOT_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "left-foot-rotation") {
|
|
||||||
setRotation(LEFT_FOOT_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "right-foot-translation") {
|
|
||||||
setTranslation(RIGHT_FOOT_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "right-foot-rotation") {
|
|
||||||
setRotation(RIGHT_FOOT_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "hips-translation") {
|
|
||||||
setTranslation(HIPS_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "hips-rotation") {
|
|
||||||
setRotation(HIPS_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "spine2-translation") {
|
|
||||||
setTranslation(SPINE2_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "spine2-rotation") {
|
|
||||||
setRotation(SPINE2_INDEX, Number(msg.val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tablet.screenChanged.connect(onScreenChanged);
|
|
||||||
|
|
||||||
function shutdownTabletApp() {
|
|
||||||
tablet.removeButton(tabletButton);
|
|
||||||
if (shown) {
|
|
||||||
tablet.webEventReceived.disconnect(onWebEventReceived);
|
|
||||||
tablet.gotoHomeScreen();
|
|
||||||
}
|
|
||||||
tablet.screenChanged.disconnect(onScreenChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// end tablet app boiler plate
|
|
||||||
//
|
|
||||||
|
|
||||||
var filterEnabled = true;
|
|
||||||
var mapping;
|
|
||||||
function mappingChanged() {
|
|
||||||
if (mapping) {
|
|
||||||
mapping.disable();
|
|
||||||
}
|
|
||||||
if (filterEnabled) {
|
|
||||||
mapping = Controller.parseMapping(JSON.stringify(mappingJson));
|
|
||||||
mapping.enable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function shownChanged(newShown) {
|
|
||||||
if (newShown) {
|
|
||||||
mappingChanged();
|
|
||||||
} else {
|
|
||||||
mapping.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mappingChanged();
|
|
||||||
|
|
||||||
Script.scriptEnding.connect(function() {
|
|
||||||
if (mapping) {
|
|
||||||
mapping.disable();
|
|
||||||
}
|
|
||||||
tablet.removeButton(tabletButton);
|
|
||||||
});
|
|
|
@ -1,65 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Document</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body{
|
|
||||||
/* margin:0; */
|
|
||||||
display:flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.container-1{
|
|
||||||
margin-bottom:1rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="left-hand-cnt" data-name="left-hand" class="container-1">
|
|
||||||
<span>Left Hand</span>
|
|
||||||
<input data-name="value" type="number">
|
|
||||||
<input data-name="state" type="checkbox">
|
|
||||||
<button>Apply</button>
|
|
||||||
</div>
|
|
||||||
<div id="right-hand-cnt" data-name="right-hand" class="container-1">
|
|
||||||
<span>Right Hand</span>
|
|
||||||
<input data-name="value" type="number">
|
|
||||||
<input data-name="state" type="checkbox">
|
|
||||||
<button>Apply</button>
|
|
||||||
</div>
|
|
||||||
<div id="left-foot-cnt" data-name="left-foot" class="container-1">
|
|
||||||
<span>Left Foot</span>
|
|
||||||
<input data-name="value" type="number">
|
|
||||||
<input data-name="state" type="checkbox">
|
|
||||||
<button>Apply</button>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const qs = (target) => document.querySelector(target);
|
|
||||||
const qsa = (target) => document.querySelectorAll(target);
|
|
||||||
|
|
||||||
qsa('.container-1 button').forEach(item => item.addEventListener('click', (event) => {
|
|
||||||
let data_bundle = {
|
|
||||||
target: event.target.parentNode.dataset.name,
|
|
||||||
value: event.target.parentNode.querySelector(`[data-name='value']`).value,
|
|
||||||
state: event.target.parentNode.querySelector(`[data-name='state']`).checked
|
|
||||||
}
|
|
||||||
console.log(JSON.stringify(data_bundle))
|
|
||||||
|
|
||||||
_sendMessage({name: `enable-filtering`, val: 'on'})
|
|
||||||
_sendMessage({name: `${data_bundle.target}-rotation`, val: data_bundle.value})
|
|
||||||
_sendMessage({name: `${data_bundle.target}-translation`, val: data_bundle.value})
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Emit messages to the script backend
|
|
||||||
function _sendMessage(message) {
|
|
||||||
EventBridge.emitWebEvent(JSON.stringify(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</html>
|
|
|
@ -1,222 +0,0 @@
|
||||||
var LEFT_HAND_INDEX = 0;
|
|
||||||
var RIGHT_HAND_INDEX = 1;
|
|
||||||
var LEFT_FOOT_INDEX = 2;
|
|
||||||
var RIGHT_FOOT_INDEX = 3;
|
|
||||||
var HIPS_INDEX = 4;
|
|
||||||
var SPINE2_INDEX = 5;
|
|
||||||
|
|
||||||
var mappingJson = {
|
|
||||||
name: "com.highfidelity.testing.accelerationTest",
|
|
||||||
channels: [
|
|
||||||
{
|
|
||||||
from: "Standard.LeftHand",
|
|
||||||
to: "Actions.LeftHand",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "accelerationLimiter",
|
|
||||||
rotationAccelerationLimit: 2000.0,
|
|
||||||
translationAccelerationLimit: 100.0,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.RightHand",
|
|
||||||
to: "Actions.RightHand",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "accelerationLimiter",
|
|
||||||
rotationAccelerationLimit: 2000.0,
|
|
||||||
translationAccelerationLimit: 100.0,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.LeftFoot",
|
|
||||||
to: "Actions.LeftFoot",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "accelerationLimiter",
|
|
||||||
rotationAccelerationLimit: 2000.0,
|
|
||||||
translationAccelerationLimit: 100.0,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.RightFoot",
|
|
||||||
to: "Actions.RightFoot",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "accelerationLimiter",
|
|
||||||
rotationAccelerationLimit: 2000.0,
|
|
||||||
translationAccelerationLimit: 100.0,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.Hips",
|
|
||||||
to: "Actions.Hips",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "accelerationLimiter",
|
|
||||||
rotationAccelerationLimit: 2000.0,
|
|
||||||
translationAccelerationLimit: 100.0,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.Spine2",
|
|
||||||
to: "Actions.Spine2",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "accelerationLimiter",
|
|
||||||
rotationAccelerationLimit: 2000.0,
|
|
||||||
translationAccelerationLimit: 100.0,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// tablet app boiler plate
|
|
||||||
//
|
|
||||||
|
|
||||||
var TABLET_BUTTON_NAME = "ACCFILT";
|
|
||||||
var HTML_URL = Script.getExternalPath(Script.ExternalPaths.HF_Public, "/tony/html/accelerationFilterApp.html?2");
|
|
||||||
|
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
|
||||||
var tabletButton = tablet.addButton({
|
|
||||||
text: TABLET_BUTTON_NAME,
|
|
||||||
icon: Script.getExternalPath(Script.ExternalPaths.HF_Public, "/tony/icons/tpose-i.svg"),
|
|
||||||
activeIcon: Script.getExternalPath(Script.ExternalPaths.HF_Public, "/tony/icons/tpose-a.svg")
|
|
||||||
});
|
|
||||||
|
|
||||||
tabletButton.clicked.connect(function () {
|
|
||||||
if (shown) {
|
|
||||||
tablet.gotoHomeScreen();
|
|
||||||
} else {
|
|
||||||
tablet.gotoWebScreen(HTML_URL);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var shown = false;
|
|
||||||
|
|
||||||
function onScreenChanged(type, url) {
|
|
||||||
if (type === "Web" && url === HTML_URL) {
|
|
||||||
tabletButton.editProperties({isActive: true});
|
|
||||||
if (!shown) {
|
|
||||||
// hook up to event bridge
|
|
||||||
tablet.webEventReceived.connect(onWebEventReceived);
|
|
||||||
shownChanged(true);
|
|
||||||
}
|
|
||||||
shown = true;
|
|
||||||
} else {
|
|
||||||
tabletButton.editProperties({isActive: false});
|
|
||||||
if (shown) {
|
|
||||||
// disconnect from event bridge
|
|
||||||
tablet.webEventReceived.disconnect(onWebEventReceived);
|
|
||||||
shownChanged(false);
|
|
||||||
}
|
|
||||||
shown = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTranslationAccelerationLimit(i) {
|
|
||||||
return mappingJson.channels[i].filters[0].translationAccelerationLimit;
|
|
||||||
}
|
|
||||||
function setTranslationAccelerationLimit(i, value) {
|
|
||||||
mappingJson.channels[i].filters[0].translationAccelerationLimit = value;
|
|
||||||
mappingChanged();
|
|
||||||
}
|
|
||||||
function getRotationAccelerationLimit(i) {
|
|
||||||
return mappingJson.channels[i].filters[0].rotationAccelerationLimit;
|
|
||||||
}
|
|
||||||
function setRotationAccelerationLimit(i, value) {
|
|
||||||
mappingJson.channels[i].filters[0].rotationAccelerationLimit = value; mappingChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWebEventReceived(msg) {
|
|
||||||
if (msg.name === "init-complete") {
|
|
||||||
var values = [
|
|
||||||
{name: "left-hand-translation-acceleration-limit", val: getTranslationAccelerationLimit(LEFT_HAND_INDEX), checked: false},
|
|
||||||
{name: "left-hand-rotation-acceleration-limit", val: getRotationAccelerationLimit(LEFT_HAND_INDEX), checked: false},
|
|
||||||
{name: "right-hand-translation-acceleration-limit", val: getTranslationAccelerationLimit(RIGHT_HAND_INDEX), checked: false},
|
|
||||||
{name: "right-hand-rotation-acceleration-limit", val: getRotationAccelerationLimit(RIGHT_HAND_INDEX), checked: false},
|
|
||||||
{name: "left-foot-translation-acceleration-limit", val: getTranslationAccelerationLimit(LEFT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "left-foot-rotation-acceleration-limit", val: getRotationAccelerationLimit(LEFT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "right-foot-translation-acceleration-limit", val: getTranslationAccelerationLimit(RIGHT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "right-foot-rotation-acceleration-limit", val: getRotationAccelerationLimit(RIGHT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "hips-translation-acceleration-limit", val: getTranslationAccelerationLimit(HIPS_INDEX), checked: false},
|
|
||||||
{name: "hips-rotation-acceleration-limit", val: getRotationAccelerationLimit(HIPS_INDEX), checked: false},
|
|
||||||
{name: "spine2-translation-acceleration-limit", val: getTranslationAccelerationLimit(SPINE2_INDEX), checked: false},
|
|
||||||
{name: "spine2-rotation-acceleration-limit", val: getRotationAccelerationLimit(SPINE2_INDEX), checked: false}
|
|
||||||
];
|
|
||||||
tablet.emitScriptEvent(JSON.stringify(values));
|
|
||||||
} else if (msg.name === "left-hand-translation-acceleration-limit") {
|
|
||||||
setTranslationAccelerationLimit(LEFT_HAND_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "left-hand-rotation-acceleration-limit") {
|
|
||||||
setRotationAccelerationLimit(LEFT_HAND_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "right-hand-translation-acceleration-limit") {
|
|
||||||
setTranslationAccelerationLimit(RIGHT_HAND_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "right-hand-rotation-acceleration-limit") {
|
|
||||||
setRotationAccelerationLimit(RIGHT_HAND_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "left-foot-translation-acceleration-limit") {
|
|
||||||
setTranslationAccelerationLimit(LEFT_FOOT_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "left-foot-rotation-acceleration-limit") {
|
|
||||||
setRotationAccelerationLimit(LEFT_FOOT_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "right-foot-translation-acceleration-limit") {
|
|
||||||
setTranslationAccelerationLimit(RIGHT_FOOT_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "right-foot-rotation-acceleration-limit") {
|
|
||||||
setRotationAccelerationLimit(RIGHT_FOOT_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "hips-translation-acceleration-limit") {
|
|
||||||
setTranslationAccelerationLimit(HIPS_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "hips-rotation-acceleration-limit") {
|
|
||||||
setRotationAccelerationLimit(HIPS_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "spine2-translation-acceleration-limit") {
|
|
||||||
setTranslationAccelerationLimit(SPINE2_INDEX, parseInt(msg.val, 10));
|
|
||||||
} else if (msg.name === "spine2-rotation-acceleration-limit") {
|
|
||||||
setRotationAccelerationLimit(SPINE2_INDEX, parseInt(msg.val, 10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tablet.screenChanged.connect(onScreenChanged);
|
|
||||||
|
|
||||||
function shutdownTabletApp() {
|
|
||||||
tablet.removeButton(tabletButton);
|
|
||||||
if (shown) {
|
|
||||||
tablet.webEventReceived.disconnect(onWebEventReceived);
|
|
||||||
tablet.gotoHomeScreen();
|
|
||||||
}
|
|
||||||
tablet.screenChanged.disconnect(onScreenChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// end tablet app boiler plate
|
|
||||||
//
|
|
||||||
|
|
||||||
var mapping;
|
|
||||||
function mappingChanged() {
|
|
||||||
if (mapping) {
|
|
||||||
mapping.disable();
|
|
||||||
}
|
|
||||||
mapping = Controller.parseMapping(JSON.stringify(mappingJson));
|
|
||||||
mapping.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
function shownChanged(newShown) {
|
|
||||||
if (newShown) {
|
|
||||||
mappingChanged();
|
|
||||||
} else {
|
|
||||||
mapping.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mappingChanged();
|
|
||||||
|
|
||||||
Script.scriptEnding.connect(function() {
|
|
||||||
if (mapping) {
|
|
||||||
mapping.disable();
|
|
||||||
}
|
|
||||||
tablet.removeButton(tabletButton);
|
|
||||||
});
|
|
||||||
|
|
254
scripts/developer/characterSmoothing/characterSmoothing.js
Executable file
254
scripts/developer/characterSmoothing/characterSmoothing.js
Executable file
|
@ -0,0 +1,254 @@
|
||||||
|
// TODO: Good UI
|
||||||
|
// TODO: Script optimization
|
||||||
|
// TODO: AccelerationLimiter choice?
|
||||||
|
// TODO: Force limit values on smoothing_settings.targets to 0 though 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copyright 2023 Overte e.V.
|
||||||
|
|
||||||
|
// Start everything at no smoothing.
|
||||||
|
// Ideally the miniscule about of smoothing that is actually still there should be sufficient.
|
||||||
|
let smoothing_settings = {
|
||||||
|
enabled: false,
|
||||||
|
targets: {
|
||||||
|
left_hand: {
|
||||||
|
transform: 1,
|
||||||
|
rotation: 1,
|
||||||
|
},
|
||||||
|
right_hand: {
|
||||||
|
transform: 1,
|
||||||
|
rotation: 1,
|
||||||
|
},
|
||||||
|
left_foot: {
|
||||||
|
transform: 1,
|
||||||
|
rotation: 1,
|
||||||
|
},
|
||||||
|
right_foot: {
|
||||||
|
transform: 1,
|
||||||
|
rotation: 1,
|
||||||
|
},
|
||||||
|
hips: {
|
||||||
|
transform: 1,
|
||||||
|
rotation: 1,
|
||||||
|
},
|
||||||
|
spine2: {
|
||||||
|
transform: 1,
|
||||||
|
rotation: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let mappingJson = {
|
||||||
|
name: "org.overte.controllers.smoothing",
|
||||||
|
channels: [
|
||||||
|
{
|
||||||
|
from: "Standard.LeftHand",
|
||||||
|
to: "Actions.LeftHand",
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
type: "exponentialSmoothing",
|
||||||
|
translation: smoothing_settings.targets.left_hand.transform,
|
||||||
|
rotation: smoothing_settings.targets.left_hand.rotation,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "Standard.RightHand",
|
||||||
|
to: "Actions.RightHand",
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
type: "exponentialSmoothing",
|
||||||
|
translation:
|
||||||
|
smoothing_settings.targets.right_hand.transform,
|
||||||
|
rotation: smoothing_settings.targets.right_hand.rotation,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "Standard.LeftFoot",
|
||||||
|
to: "Actions.LeftFoot",
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
type: "exponentialSmoothing",
|
||||||
|
translation: smoothing_settings.targets.left_foot.transform,
|
||||||
|
rotation: smoothing_settings.targets.left_foot.rotation,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "Standard.RightFoot",
|
||||||
|
to: "Actions.RightFoot",
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
type: "exponentialSmoothing",
|
||||||
|
translation:
|
||||||
|
smoothing_settings.targets.right_foot.transform,
|
||||||
|
rotation: smoothing_settings.targets.right_foot.rotation,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "Standard.Hips",
|
||||||
|
to: "Actions.Hips",
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
type: "exponentialSmoothing",
|
||||||
|
translation: smoothing_settings.targets.hips.transform,
|
||||||
|
rotation: smoothing_settings.targets.hips.rotation,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: "Standard.Spine2",
|
||||||
|
to: "Actions.Spine2",
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
type: "exponentialSmoothing",
|
||||||
|
translation: smoothing_settings.targets.spine2.transform,
|
||||||
|
rotation: smoothing_settings.targets.spine2.rotation,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
let mapping;
|
||||||
|
|
||||||
|
// Build tablet
|
||||||
|
const HTML_URL = Script.resolvePath("./index.html");
|
||||||
|
let shown = false;
|
||||||
|
let tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
|
let tabletButton = tablet.addButton({
|
||||||
|
text: "CHR",
|
||||||
|
// TODO: Icon
|
||||||
|
icon: Script.resolvePath("./img/icon.png"),
|
||||||
|
});
|
||||||
|
tabletButton.clicked.connect(() => {
|
||||||
|
if (shown) tablet.gotoHomeScreen();
|
||||||
|
else tablet.gotoWebScreen(HTML_URL);
|
||||||
|
});
|
||||||
|
|
||||||
|
function onScreenChanged(type, url) {
|
||||||
|
if (type === "Web" && url === HTML_URL) {
|
||||||
|
tabletButton.editProperties({ isActive: true });
|
||||||
|
|
||||||
|
if (!shown) {
|
||||||
|
// hook up to event bridge
|
||||||
|
tablet.webEventReceived.connect(onWebEventReceived);
|
||||||
|
shownChanged(true);
|
||||||
|
}
|
||||||
|
// FIXME: Works, just need to wait for response before we send data
|
||||||
|
Script.setTimeout(() => {
|
||||||
|
_sendMessage({
|
||||||
|
action: "load_listings",
|
||||||
|
data: smoothing_settings,
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
shown = true;
|
||||||
|
} else {
|
||||||
|
tabletButton.editProperties({ isActive: false });
|
||||||
|
|
||||||
|
if (shown) {
|
||||||
|
// disconnect from event bridge
|
||||||
|
tablet.webEventReceived.disconnect(onWebEventReceived);
|
||||||
|
shownChanged(false);
|
||||||
|
}
|
||||||
|
shown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tablet.screenChanged.connect(onScreenChanged);
|
||||||
|
|
||||||
|
function shutdownTabletApp() {
|
||||||
|
tablet.removeButton(tabletButton);
|
||||||
|
if (shown) {
|
||||||
|
tablet.webEventReceived.disconnect(onWebEventReceived);
|
||||||
|
tablet.gotoHomeScreen();
|
||||||
|
}
|
||||||
|
tablet.screenChanged.disconnect(onScreenChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onWebEventReceived(msg) {
|
||||||
|
msg = JSON.parse(msg);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// Toggle smoothing
|
||||||
|
// if (msg.action === "set_state") {
|
||||||
|
// smoothing_settings.enabled = msg.value ? true : false;
|
||||||
|
// mappingChanged();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Adjust a target's rotation and transform values
|
||||||
|
if (msg.action === "new_settings") {
|
||||||
|
|
||||||
|
smoothing_settings = msg.data
|
||||||
|
mappingChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mappingChanged() {
|
||||||
|
Settings.setValue("smoothing_settings", smoothing_settings);
|
||||||
|
|
||||||
|
if (mapping) mapping.disable();
|
||||||
|
|
||||||
|
if (smoothing_settings.enabled) {
|
||||||
|
mapping = Controller.parseMapping(JSON.stringify(mappingJson));
|
||||||
|
mapping.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function shownChanged(newShown) {
|
||||||
|
if (newShown) mappingChanged();
|
||||||
|
else if (mapping) mapping.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(function () {
|
||||||
|
if (mapping) mapping.disable();
|
||||||
|
tablet.removeButton(tabletButton);
|
||||||
|
});
|
||||||
|
|
||||||
|
function _sendMessage(message) {
|
||||||
|
message = JSON.stringify(message);
|
||||||
|
tablet.emitScriptEvent(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load settings
|
||||||
|
smoothing_settings = Settings.getValue(
|
||||||
|
"smoothing_settings",
|
||||||
|
smoothing_settings
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: Does script init work?
|
||||||
|
// Settings.setValue(
|
||||||
|
// "smoothing_settings",
|
||||||
|
// {
|
||||||
|
// enabled: false,
|
||||||
|
// targets: {
|
||||||
|
// left_hand: {
|
||||||
|
// transform: 1,
|
||||||
|
// rotation: 1,
|
||||||
|
// },
|
||||||
|
// right_hand: {
|
||||||
|
// transform: 1,
|
||||||
|
// rotation: 1,
|
||||||
|
// },
|
||||||
|
// left_foot: {
|
||||||
|
// transform: 1,
|
||||||
|
// rotation: 1,
|
||||||
|
// },
|
||||||
|
// right_foot: {
|
||||||
|
// transform: 1,
|
||||||
|
// rotation: 1,
|
||||||
|
// },
|
||||||
|
// hips: {
|
||||||
|
// transform: 1,
|
||||||
|
// rotation: 1,
|
||||||
|
// },
|
||||||
|
// spine2: {
|
||||||
|
// transform: 1,
|
||||||
|
// rotation: 1,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
mappingChanged();
|
80
scripts/developer/characterSmoothing/index.css
Normal file
80
scripts/developer/characterSmoothing/index.css
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
body {
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
body .container-1 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
body .container-1 .title {
|
||||||
|
background-color: #262626;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
padding: 0.2rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body .container-1 .list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
padding: 1rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #131313;
|
||||||
|
}
|
||||||
|
body .container-1 .list .option {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
body .container-1 .list .option * {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
body .container-1 .list .option div {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
body .container-1 .list .option input {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
body .button-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
background-color: #131313;
|
||||||
|
padding: 0.5rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 1rem;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
body .button-container button {
|
||||||
|
width: 100%;
|
||||||
|
height: 35px;
|
||||||
|
background-color: #505186;
|
||||||
|
border: 0;
|
||||||
|
color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
body .button-container button:hover,
|
||||||
|
body .button-container button:focus {
|
||||||
|
filter: brightness(60%);
|
||||||
|
}
|
||||||
|
body .button-container button:active {
|
||||||
|
filter: brightness(40%);
|
||||||
|
}
|
||||||
|
body .button-container .active {
|
||||||
|
background-color: #277727;
|
||||||
|
}
|
||||||
|
body .button-container .unactive {
|
||||||
|
background-color: #771d1d;
|
||||||
|
}
|
120
scripts/developer/characterSmoothing/index.html
Executable file
120
scripts/developer/characterSmoothing/index.html
Executable file
|
@ -0,0 +1,120 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<link rel="stylesheet" href="index.css"/>
|
||||||
|
<title>Character Smoothing</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="target-list"></div>
|
||||||
|
|
||||||
|
<div class="button-container">
|
||||||
|
<button id="apply-settings">
|
||||||
|
<span>Apply</span>
|
||||||
|
</button>
|
||||||
|
<!-- <button id="toggle-smooth-active" class="unactive">
|
||||||
|
<span>Enable</span>
|
||||||
|
</button> -->
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<template id="target-listing">
|
||||||
|
<div data-name="left-hand" class="container-1">
|
||||||
|
<div class="title">Left Hand</div>
|
||||||
|
<div class="list">
|
||||||
|
<div class="option">
|
||||||
|
<div>Transform</div>
|
||||||
|
<input min="0" max="1" step="0.01" data-name="value" data-target="transform" type="number"/>
|
||||||
|
</div>
|
||||||
|
<div class="option">
|
||||||
|
<div>Rotation</div>
|
||||||
|
<input min="0" max="1" step="0.01" data-name="value" data-target="rotation" type="number"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let smoothing_settings = {};
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
const qs = (target) => document.querySelector(target);
|
||||||
|
const qsa = (target) => document.querySelectorAll(target);
|
||||||
|
|
||||||
|
// Emit messages to the script backend
|
||||||
|
function _sendMessage(message) {
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
// Handle new messages
|
||||||
|
EventBridge.scriptEventReceived.connect((message) => {
|
||||||
|
message = JSON.parse(message);
|
||||||
|
newMessage(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
qsa("button").forEach((button) => button.addEventListener("click", (event) => event.target.blur()));
|
||||||
|
|
||||||
|
function newMessage(message) {
|
||||||
|
if (message.action === "load_listings")
|
||||||
|
buildTargetListings(message.data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// We supply a list of targets we allow adjustments for from the script.
|
||||||
|
// Using that list we generate the listings on the app view
|
||||||
|
function buildTargetListings(target_list) {
|
||||||
|
smoothing_settings = target_list;
|
||||||
|
|
||||||
|
// Clear all existing listings (if any)
|
||||||
|
qsa("body .container-1").forEach((item) => item.remove());
|
||||||
|
|
||||||
|
// Build list
|
||||||
|
Object.keys(smoothing_settings.targets).forEach((target) => {
|
||||||
|
let template = qs("#target-listing").content.cloneNode(true);
|
||||||
|
template.querySelector(".container-1").dataset.name = target;
|
||||||
|
|
||||||
|
template.querySelector(".container-1 .title").innerText = _formatName(target);
|
||||||
|
template.querySelector(".container-1 [data-target='transform']").value = smoothing_settings.targets[target].transform;
|
||||||
|
template.querySelector(".container-1 [data-target='rotation']").value = smoothing_settings.targets[target].rotation;
|
||||||
|
|
||||||
|
qs("#target-list").appendChild(template);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
qs('#apply-settings').addEventListener('click', updateSettings)
|
||||||
|
|
||||||
|
function updateSettings() {
|
||||||
|
qsa(".container-1").forEach((listing) => {
|
||||||
|
let target_name = listing.dataset.name;
|
||||||
|
let target_rotation = listing.querySelector('[data-target="rotation"]').value;
|
||||||
|
let target_transform = listing.querySelector('[data-target="transform"]').value;
|
||||||
|
|
||||||
|
smoothing_settings.targets[target_name] = {
|
||||||
|
transform: target_transform,
|
||||||
|
rotation: target_rotation
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_sendMessage({action: 'new_settings', data: smoothing_settings})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pretty formats a string for visual display
|
||||||
|
function _formatName(string) {
|
||||||
|
let string_parts = [];
|
||||||
|
let return_string = "";
|
||||||
|
|
||||||
|
string = string.replace("_", " ");
|
||||||
|
|
||||||
|
string_parts = string.split(" ");
|
||||||
|
|
||||||
|
string_parts.forEach((word) => {
|
||||||
|
return_string += word.charAt(0).toUpperCase() + word.slice(1)
|
||||||
|
});
|
||||||
|
|
||||||
|
return return_string;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
98
scripts/developer/characterSmoothing/index.scss
Normal file
98
scripts/developer/characterSmoothing/index.scss
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
body {
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.container-1 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
background-color: #262626;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
|
||||||
|
padding: 0.2rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
padding: 1rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
background-color: #131313;
|
||||||
|
|
||||||
|
.option {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
background-color: #131313;
|
||||||
|
padding: 0.5rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 1rem;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
height: 35px;
|
||||||
|
background-color: #505186;
|
||||||
|
border: 0;
|
||||||
|
color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover,
|
||||||
|
button:focus {
|
||||||
|
filter: brightness(60%);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
filter: brightness(40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
background-color: #277727;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unactive {
|
||||||
|
background-color: #771d1d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,240 +0,0 @@
|
||||||
var LEFT_HAND_INDEX = 0;
|
|
||||||
var RIGHT_HAND_INDEX = 1;
|
|
||||||
var LEFT_FOOT_INDEX = 2;
|
|
||||||
var RIGHT_FOOT_INDEX = 3;
|
|
||||||
var HIPS_INDEX = 4;
|
|
||||||
var SPINE2_INDEX = 5;
|
|
||||||
|
|
||||||
var HAND_SMOOTHING_TRANSLATION = 0.3;
|
|
||||||
var HAND_SMOOTHING_ROTATION = 0.15;
|
|
||||||
var FOOT_SMOOTHING_TRANSLATION = 0.3;
|
|
||||||
var FOOT_SMOOTHING_ROTATION = 0.15;
|
|
||||||
var TORSO_SMOOTHING_TRANSLATION = 0.3;
|
|
||||||
var TORSO_SMOOTHING_ROTATION = 0.16;
|
|
||||||
|
|
||||||
var mappingJson = {
|
|
||||||
name: "com.highfidelity.testing.exponentialFilterApp",
|
|
||||||
channels: [
|
|
||||||
{
|
|
||||||
from: "Standard.LeftHand",
|
|
||||||
to: "Actions.LeftHand",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: HAND_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: HAND_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.RightHand",
|
|
||||||
to: "Actions.RightHand",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: HAND_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: HAND_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.LeftFoot",
|
|
||||||
to: "Actions.LeftFoot",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: FOOT_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: FOOT_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.RightFoot",
|
|
||||||
to: "Actions.RightFoot",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: FOOT_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: FOOT_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.Hips",
|
|
||||||
to: "Actions.Hips",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: TORSO_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: TORSO_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: "Standard.Spine2",
|
|
||||||
to: "Actions.Spine2",
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
type: "exponentialSmoothing",
|
|
||||||
translation: TORSO_SMOOTHING_TRANSLATION,
|
|
||||||
rotation: TORSO_SMOOTHING_ROTATION
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// tablet app boiler plate
|
|
||||||
//
|
|
||||||
|
|
||||||
var TABLET_BUTTON_NAME = "EXPFILT";
|
|
||||||
var HTML_URL = Script.getExternalPath(Script.ExternalPaths.HF_Public, "/tony/html/exponentialFilterApp.html?7");
|
|
||||||
|
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
|
||||||
var tabletButton = tablet.addButton({
|
|
||||||
text: TABLET_BUTTON_NAME,
|
|
||||||
icon: Script.getExternalPath(Script.ExternalPaths.HF_Public, "/tony/icons/tpose-i.svg"),
|
|
||||||
activeIcon: Script.getExternalPath(Script.ExternalPaths.HF_Public, "/tony/icons/tpose-a.svg")
|
|
||||||
});
|
|
||||||
|
|
||||||
tabletButton.clicked.connect(function () {
|
|
||||||
if (shown) {
|
|
||||||
tablet.gotoHomeScreen();
|
|
||||||
} else {
|
|
||||||
tablet.gotoWebScreen(HTML_URL);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var shown = false;
|
|
||||||
|
|
||||||
function onScreenChanged(type, url) {
|
|
||||||
if (type === "Web" && url === HTML_URL) {
|
|
||||||
tabletButton.editProperties({isActive: true});
|
|
||||||
if (!shown) {
|
|
||||||
// hook up to event bridge
|
|
||||||
tablet.webEventReceived.connect(onWebEventReceived);
|
|
||||||
shownChanged(true);
|
|
||||||
}
|
|
||||||
shown = true;
|
|
||||||
} else {
|
|
||||||
tabletButton.editProperties({isActive: false});
|
|
||||||
if (shown) {
|
|
||||||
// disconnect from event bridge
|
|
||||||
tablet.webEventReceived.disconnect(onWebEventReceived);
|
|
||||||
shownChanged(false);
|
|
||||||
}
|
|
||||||
shown = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTranslation(i) {
|
|
||||||
return mappingJson.channels[i].filters[0].translation;
|
|
||||||
}
|
|
||||||
function setTranslation(i, value) {
|
|
||||||
mappingJson.channels[i].filters[0].translation = value;
|
|
||||||
mappingChanged();
|
|
||||||
}
|
|
||||||
function getRotation(i) {
|
|
||||||
return mappingJson.channels[i].filters[0].rotation;
|
|
||||||
}
|
|
||||||
function setRotation(i, value) {
|
|
||||||
mappingJson.channels[i].filters[0].rotation = value; mappingChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWebEventReceived(msg) {
|
|
||||||
if (msg.name === "init-complete") {
|
|
||||||
var values = [
|
|
||||||
{name: "enable-filtering", val: filterEnabled ? "on" : "off", checked: false},
|
|
||||||
{name: "left-hand-translation", val: getTranslation(LEFT_HAND_INDEX), checked: false},
|
|
||||||
{name: "left-hand-rotation", val: getRotation(LEFT_HAND_INDEX), checked: false},
|
|
||||||
{name: "right-hand-translation", val: getTranslation(RIGHT_HAND_INDEX), checked: false},
|
|
||||||
{name: "right-hand-rotation", val: getRotation(RIGHT_HAND_INDEX), checked: false},
|
|
||||||
{name: "left-foot-translation", val: getTranslation(LEFT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "left-foot-rotation", val: getRotation(LEFT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "right-foot-translation", val: getTranslation(RIGHT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "right-foot-rotation", val: getRotation(RIGHT_FOOT_INDEX), checked: false},
|
|
||||||
{name: "hips-translation", val: getTranslation(HIPS_INDEX), checked: false},
|
|
||||||
{name: "hips-rotation", val: getRotation(HIPS_INDEX), checked: false},
|
|
||||||
{name: "spine2-translation", val: getTranslation(SPINE2_INDEX), checked: false},
|
|
||||||
{name: "spine2-rotation", val: getRotation(SPINE2_INDEX), checked: false}
|
|
||||||
];
|
|
||||||
tablet.emitScriptEvent(JSON.stringify(values));
|
|
||||||
} else if (msg.name === "enable-filtering") {
|
|
||||||
if (msg.val === "on") {
|
|
||||||
filterEnabled = true;
|
|
||||||
} else if (msg.val === "off") {
|
|
||||||
filterEnabled = false;
|
|
||||||
}
|
|
||||||
mappingChanged();
|
|
||||||
} else if (msg.name === "left-hand-translation") {
|
|
||||||
setTranslation(LEFT_HAND_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "left-hand-rotation") {
|
|
||||||
setRotation(LEFT_HAND_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "right-hand-translation") {
|
|
||||||
setTranslation(RIGHT_HAND_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "right-hand-rotation") {
|
|
||||||
setRotation(RIGHT_HAND_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "left-foot-translation") {
|
|
||||||
setTranslation(LEFT_FOOT_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "left-foot-rotation") {
|
|
||||||
setRotation(LEFT_FOOT_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "right-foot-translation") {
|
|
||||||
setTranslation(RIGHT_FOOT_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "right-foot-rotation") {
|
|
||||||
setRotation(RIGHT_FOOT_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "hips-translation") {
|
|
||||||
setTranslation(HIPS_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "hips-rotation") {
|
|
||||||
setRotation(HIPS_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "spine2-translation") {
|
|
||||||
setTranslation(SPINE2_INDEX, Number(msg.val));
|
|
||||||
} else if (msg.name === "spine2-rotation") {
|
|
||||||
setRotation(SPINE2_INDEX, Number(msg.val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tablet.screenChanged.connect(onScreenChanged);
|
|
||||||
|
|
||||||
function shutdownTabletApp() {
|
|
||||||
tablet.removeButton(tabletButton);
|
|
||||||
if (shown) {
|
|
||||||
tablet.webEventReceived.disconnect(onWebEventReceived);
|
|
||||||
tablet.gotoHomeScreen();
|
|
||||||
}
|
|
||||||
tablet.screenChanged.disconnect(onScreenChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// end tablet app boiler plate
|
|
||||||
//
|
|
||||||
|
|
||||||
var filterEnabled = true;
|
|
||||||
var mapping;
|
|
||||||
function mappingChanged() {
|
|
||||||
if (mapping) {
|
|
||||||
mapping.disable();
|
|
||||||
}
|
|
||||||
if (filterEnabled) {
|
|
||||||
mapping = Controller.parseMapping(JSON.stringify(mappingJson));
|
|
||||||
mapping.enable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function shownChanged(newShown) {
|
|
||||||
if (newShown) {
|
|
||||||
mappingChanged();
|
|
||||||
} else {
|
|
||||||
mapping.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mappingChanged();
|
|
||||||
|
|
||||||
Script.scriptEnding.connect(function() {
|
|
||||||
if (mapping) {
|
|
||||||
mapping.disable();
|
|
||||||
}
|
|
||||||
tablet.removeButton(tabletButton);
|
|
||||||
});
|
|
||||||
|
|
Loading…
Reference in a new issue