From 04d78b7e476588e857d078bc40885fdf9b80390a Mon Sep 17 00:00:00 2001 From: Fabien Benetou Date: Sun, 18 Feb 2024 15:21:25 +0100 Subject: [PATCH] share live event for supervisor --- index.html | 131 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 35 deletions(-) diff --git a/index.html b/index.html index 59d3559..cdd4df9 100644 --- a/index.html +++ b/index.html @@ -98,6 +98,34 @@ function manualAnimate(selector="#biggu"){ ) } +// see https://biggu-backend-collab.glitch.me/ to insure steps are done correctly +function shareLiveEvent(eventName, server='https://biggu-backend-collab.glitch.me/'){ + if (eventName.length > 0) fetch(server+'/newevent/'+eventName) +} +// should then become a container hosted on benetou.fr + +function saveTargets(server='https://biggu-backend-collab.glitch.me/'){ + // might try to generate a hash as ID, should be reproducible though + let data = [] + Array.from( document.querySelectorAll("[target]") ) + .filter( el => el.id != '') + .map( el => { + // limited to location/position for now as that's only what target does modify + if( hasBeenManipulated(el.getAttribute('position')) || hasBeenManipulated(el.getAttribute('rotation')) ) + data.push({id:el.id, position:el.getAttribute('position'), rotation:el.getAttribute('rotation')}) + }) + if (data.length > 0) fetch(server+'/save?data='+JSON.stringify(data)) + return data +} + +function animateThenIdle(mainCharacter, animationName, timeScale='1'){ + mainCharacter.setAttribute('animation-mixer', "clip:"+animationName+";loop:once; timeScale:"+timeScale) + mainCharacter.addEventListener('animation-finished', _ => { + mainCharacter.setAttribute('animation-mixer', "clip:bigguaction_idle; loop:true;") + }) + // could return the animation duration or an event when done +} + function checkExerciseCompletion(targetNumber=2){ const instructions = document.querySelector("#instructions>a-troika-text") let counter = 0 @@ -107,22 +135,19 @@ function checkExerciseCompletion(targetNumber=2){ if (f.object3D.position.distanceTo( document.querySelector('#plate').object3D.position ) < .3 ) counter++ }) if (counter == targetNumber) { instructions.emit('win') - mainCharacter.setAttribute('animation-mixer', "clip:bigguaction_win;loop:once") - mainCharacter.addEventListener('animation-finished', _ => { - mainCharacter.setAttribute('animation-mixer', "clip:bigguaction_idle; loop:true;") - }) + shareLiveEvent('win') + document.getElementById("biggubravojulia").play() + animateThenIdle(mainCharacter, 'bigguaction_win') } else { + document.getElementById("biggucontinu").play() instructions.emit('failed', {counter:counter}) - mainCharacter.setAttribute('animation-mixer', "clip:bigguaction_yes;loop:once") - mainCharacter.addEventListener('animation-finished', _ => { - mainCharacter.setAttribute('animation-mixer', "clip:bigguaction_idle; loop:true;") - }) + shareLiveEvent('failed'+' '+counter) + animateThenIdle(mainCharacter, 'bigguaction_yes') // anims = [ "bigguaction_no", "Bigguaction_pl", "bigguaction_pr", "bigguaction_talk", "bigguaction_win", "bigguaction_win", "bigguaction_yes" ] - } } - +// much too complex AFRAME.registerComponent('exercise', { schema: { instructions: {type: 'string'}, @@ -160,8 +185,45 @@ AFRAME.registerComponent('exercise', { } }) +// for more complete supervision consider remote scrcpy +AFRAME.registerComponent('start-with-supervision', { + init: function(){ + const server='https://biggu-backend-collab.glitch.me' + // CORS enabled needed + const source = new EventSource(server+'/events'); + + source.addEventListener('message', message => { + console.log('Got', message); + if (message.data == '"start-with-supervision"') startExercise() + }) + } +}) + +function startExercise(){ + document.getElementById("exerciseA").setAttribute("visible", false) + // hide everything until this is done, otherwise overwhelming + const mainCharacter = document.getElementById("biggu") + setTimeout(_=>{ + document.getElementById("biggucestmoi").play() + // works in XR on headset, not on desktop (needs user action) + animateThenIdle(mainCharacter, 'bigguaction_talk', .5) + },1000) + // should focus on learning pinch (thumb and index) before doing the exercise itself + setTimeout(_=>{ + document.getElementById("exerciseA").setAttribute("visible", true) + document.getElementById("bigguinstructions").play() + animateThenIdle(mainCharacter, 'bigguaction_talk', .5) + },5000) +} + +AFRAME.registerComponent('warmup', { + init: function(){ + startExercise() + } +}) + -
@@ -171,7 +233,7 @@ AFRAME.registerComponent('exercise', { - + - + + + +