"use strict"; (function() { Script.include([ "libraries/doppelganger.js?" + Math.random(), // "libraries/footMirroring.js?" + Math.random() ]); var CLINICIAN_SETTINGS_URL = Script.resolvePath("html/ClinicianSettings.html"); var STATS_URL = Script.resolvePath("html/Statistics.html"); var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); var buttonName = "session"; // matching location reserved in Desktop.qml var button = toolBar.addButton({ objectName: buttonName, imageURL: Script.resolvePath("assets/images/tools/clinic.svg"), visible: true, hoverState: 2, defaultState: 1, buttonState: 1, alpha: 0.9 }); var handlerId = 0; var propList = ["rightHandType","leftHandType", "leftFootType", "leftFootPosition", "leftFootRotation", "rightFootType", "rightFootPosition", "rightFootRotation"]; var ikTypes = { RotationAndPosition: 0, RotationOnly: 1, HmdHead: 2, HipsRelativeRotationAndPosition: 3, Off: 4 }; var dialogueWindowVisible = false; var dialog = new OverlayWebWindow('Clinician Settings', CLINICIAN_SETTINGS_URL, 800, 720, dialogueWindowVisible); function onClicked(){ if (dialogueWindowVisible) { dialog.setVisible(false); } else { dialog.setVisible(true); } } // Foot Mirror Handlers function animStateHandler(props) { return { leftFootType: ikTypes["Off"], rightFootType: ikTypes["Off"] }; } function mirrorFootPos(pos) { return {x: pos.x, y: (pos.y - 0.85)/2.4, z: -pos.z} } function offsetRot(q) { return {x: q.x, y: -q.y, z: -q.z, w: q.w}; } function offsetPos(p) { return {x: -p.x, y: (p.y - 0.85)/2.4, z: -p.z} } function updateFootPos() { MyAvatar.clearIKJointLimitHistory(); } function initFootMirroring() { Script.update.connect(updateFootPos); handlerId = MyAvatar.addAnimationStateHandler(function(props) { var pose = Controller.getPoseValue(Controller.Standard.LeftHand); return { rightHandType: ikTypes["Off"], leftHandType: ikTypes["Off"], leftFootPosition: offsetPos(pose.translation), leftFootRotation: offsetRot(pose.rotation), leftFootType: ikTypes["RotationAndPosition"], rightFootType: ikTypes["RotationAndPosition"], rightFootPosition: mirrorFootPos(pose.translation), //rightFootRotation: pose.rotation } }, propList); } function shutdown() { MyAvatar.removeAnimationStateHandler(handlerId); } // Hand Mirror Handlers function mirrorRot(q) { return {x: q.x, y: -q.y, z: -q.z, w: q.w}; } function mirrorPos(p, scale) { return {x: -p.x*scale, y: p.y, z: p.z} } var MAPPING_NAME = "com.highfidelity.mirrorMovement"; var mirrorMapping = Controller.newMapping(MAPPING_NAME); function mirrorMovement(side, scale) { // TODO: Disable it already set var controllerSide = (side === "left" ? Controller.Standard.LeftHand : Controller.Standard.RightHand); var mappedSide = (side === "left" ? Controller.Standard.RightHand : Controller.Standard.LeftHand); mirrorMapping.from(function(){ var pose = Controller.getPoseValue(controllerSide); pose.rotation = mirrorRot(pose.rotation); pose.translation = mirrorPos(pose.translation, scale); pose.velocity = mirrorPos(pose.velocity); pose.angularVelocity = mirrorPos(pose.angularVelocity); return pose; }).to(mappedSide); mirrorMapping.enable(); } // STATS WINDOW statsWindow = new OverlayWebWindow('Statistics', STATS_URL, 800, 700, false); statsWindow.webEventReceived.connect(function(message) { message.position = MyAvatar.position; message.leftHandPosition = MyAvatar.leftHandPose.translation; message.rightHandPosition = MyAvatar.rightHandPose.translation; var setStats = Script.setInterval(function() { statsWindow.emitScriptEvent(message); }, 1000); }); statsWindow.setVisible(false); dialog.webEventReceived.connect(function(data) { data = JSON.parse(data) if(data.type === "exportCSV" ) { statsWindow.emitWebEvent(data); statsWindow.setVisible(true); } else if(data.type === "limb") { if(data.value === "foot") { // print("debug............") initFootMirroring(); } } // else if (data.type === "doppelganger") { // // print("debug... ") // print("debug. " + TEST_MODEL_URL) // } else if(data.type === "amplification") { mirrorMovement(data.side, data.amplification) } else if (data.type === "side") { // TODO: if mapped then disable mirrorMovement(data.value) // mirrorMapping.disable(); // data.type = "update"; // dialog.emitScriptEvent(JSON.stringify(data)) } else if (data.type === "disableMirrroring") { print("disable..") // FIX: disable mapping mirrorMapping.disable(); // Disable Foot Animations MyAvatar.addAnimationStateHandler(animStateHandler, ["leftFootType", "rightFootType"]); // Move! // mirrorMovement(data.side) // data.type = "update"; // dialog.emitScriptEvent(JSON.stringify(data)) } else if (data.type === "update") { print("updating!") } }); function onDialogVisibilityChanged() { button.writeProperty('buttonState', dialog.visible ? 0 : 1); button.writeProperty('defaultState', dialog.visible ? 0 : 1); button.writeProperty('hoverState', dialog.visible ? 2 : 3); dialogueWindowVisible = dialog.visible; } onDialogVisibilityChanged(); button.clicked.connect(onClicked); dialog.visibleChanged.connect(onDialogVisibilityChanged) Script.scriptEnding.connect(function () { mirrorMapping.disable(); toolBar.removeButton(buttonName); button.clicked.disconnect(onClicked); Script.clearInterval(setStats); shutdown(); }); }());