|
|
@ -52,32 +52,6 @@ |
|
|
|
</a> |
|
|
|
</a> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
|
|
|
|
<div id="observablehq-numberOfPages-835aa7e9"></div> |
|
|
|
|
|
|
|
<div id="observablehq-result_as_html-ab4c1560"></div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script type="module"> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// just text |
|
|
|
|
|
|
|
import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@4/dist/runtime.js"; |
|
|
|
|
|
|
|
import define from "https://api.observablehq.com/@utopiah/from-pim-to-2d-to-3d-to-xr-explorations@2010.js?v=3"; |
|
|
|
|
|
|
|
import define2 from "https://api.observablehq.com/d/f219f0c440c6d5a2.js?v=3"; |
|
|
|
|
|
|
|
new Runtime().module(define, name => { |
|
|
|
|
|
|
|
if (name === "numberOfPages") return new Inspector(document.querySelector("#observablehq-numberOfPages-835aa7e9")); |
|
|
|
|
|
|
|
document.querySelector(".a-enter-vr").style.position = "fixed" |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// HTML with interactable input |
|
|
|
|
|
|
|
new Runtime().module(define2, name => { |
|
|
|
|
|
|
|
if (name === "viewof offsetExample") return new Inspector(document.querySelector("#observablehq-viewof-offsetExample-ab4c1560")); |
|
|
|
|
|
|
|
if (name === "result_as_html") return new Inspector(document.querySelector("#observablehq-result_as_html-ab4c1560")); |
|
|
|
|
|
|
|
return ["result_no_name","result"].includes(name); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
// setTimeout( _ => document.querySelector("#gui3d").setAttribute("html", "html:#observablehq-key;cursor:#cursor;" ) , 2000) |
|
|
|
|
|
|
|
// <a-entity id="gui3d" class="observableui" position="0 1.5 -.4"></a-entity> |
|
|
|
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script> |
|
|
|
<script> |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
/* |
|
|
@ -117,7 +91,7 @@ const zeroVector3 = new THREE.Vector3() |
|
|
|
var bbox = new THREE.Box3() |
|
|
|
var bbox = new THREE.Box3() |
|
|
|
bbox.min.copy( zeroVector3 ) |
|
|
|
bbox.min.copy( zeroVector3 ) |
|
|
|
bbox.max.copy( zeroVector3 ) |
|
|
|
bbox.max.copy( zeroVector3 ) |
|
|
|
var selectionBox = new THREE.BoundingBoxHelper( bbox.object3D, 0x0000ff); |
|
|
|
var selectionBox = new THREE.BoxHelper( bbox.object3D, 0x0000ff); |
|
|
|
var groupHelpers = [] |
|
|
|
var groupHelpers = [] |
|
|
|
var primaryPinchStarted = false |
|
|
|
var primaryPinchStarted = false |
|
|
|
var visible = true |
|
|
|
var visible = true |
|
|
@ -142,7 +116,7 @@ const url = "https://fabien.benetou.fr/PIMVRdata/CabinData?action=" |
|
|
|
var primarySide = 0 |
|
|
|
var primarySide = 0 |
|
|
|
const sides = ["right", "left"] |
|
|
|
const sides = ["right", "left"] |
|
|
|
var generators = "line-link-entities link screenstack dynamic-view selectionboxonpinches keyboard " |
|
|
|
var generators = "line-link-entities link screenstack dynamic-view selectionboxonpinches keyboard " |
|
|
|
+ "commands-from-external-json glossary timeline issues web-url background-via-url observableui hidableenvironmentfot fot" |
|
|
|
+ "commands-from-external-json glossary timeline issues web-url background-via-url hidableenvironmentfot fot" |
|
|
|
// could be an array proper completed on each relevant component registration |
|
|
|
// could be an array proper completed on each relevant component registration |
|
|
|
var heightAdjustableClasses = ["commands-from-external-json"] |
|
|
|
var heightAdjustableClasses = ["commands-from-external-json"] |
|
|
|
var pinches = [] // position, timestamp, primary vs secondary |
|
|
|
var pinches = [] // position, timestamp, primary vs secondary |
|
|
@ -443,74 +417,6 @@ source.onmessage = message => { |
|
|
|
// with token e.g JWT could also consider ~/.bashrc ~/.bin or ~/Prototypes as commands |
|
|
|
// with token e.g JWT could also consider ~/.bashrc ~/.bin or ~/Prototypes as commands |
|
|
|
// esp. those allowing to integrate with specific hardware |
|
|
|
// esp. those allowing to integrate with specific hardware |
|
|
|
|
|
|
|
|
|
|
|
// load as page loads |
|
|
|
|
|
|
|
// <a-text target observablecell="targetid:observablehq-numberOfPages-835aa7e9" position="0 1.55 -0.2" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
// interactive |
|
|
|
|
|
|
|
// <a-text target value="jxr obsv observablehq-numberOfPages-835aa7e9" position="0 1.55 -0.2" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function newNoteFromObservableCell( cell ){ |
|
|
|
|
|
|
|
var targetEl = document.querySelector("#"+cell) |
|
|
|
|
|
|
|
var potentialRes = document.querySelector("#observablehq-numberOfPages-835aa7e9>span") |
|
|
|
|
|
|
|
if (potentialRes && potentialRes.children[1]){ |
|
|
|
|
|
|
|
addNewNote( potentialRes.children[1].innerText ) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let observer = new MutationObserver(mutationRecords => { |
|
|
|
|
|
|
|
addNewNote( mutationRecords[0].addedNodes[0].children[1].innerText ) |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
observer.observe(targetEl, { |
|
|
|
|
|
|
|
childList: true, // observe direct children |
|
|
|
|
|
|
|
subtree: true, // and lower descendants too |
|
|
|
|
|
|
|
characterDataOldValue: true // pass old data to callback |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AFRAME.registerComponent('observablecell', { // non interactive mode |
|
|
|
|
|
|
|
schema: { |
|
|
|
|
|
|
|
targetid: {type: 'string'} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
init: function () { |
|
|
|
|
|
|
|
var el = this.el |
|
|
|
|
|
|
|
var targetEl = document.querySelector("#"+this.data.targetid) |
|
|
|
|
|
|
|
let observer = new MutationObserver(mutationRecords => { |
|
|
|
|
|
|
|
addNewNote( mutationRecords[0].addedNodes[0].children[1].innerText ) |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
observer.observe(targetEl, { |
|
|
|
|
|
|
|
childList: true, // observe direct children |
|
|
|
|
|
|
|
subtree: true, // and lower descendants too |
|
|
|
|
|
|
|
characterDataOldValue: true // pass old data to callback |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// might mess thing up on Quest somehow... like typing does not seem to work anymore since. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
|
|
const registerServiceWorker = async () => { |
|
|
|
|
|
|
|
if ('serviceWorker' in navigator) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
const registration = await navigator.serviceWorker.register( |
|
|
|
|
|
|
|
'sw-test/sw.js', |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
scope: '', |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
if (registration.installing) { |
|
|
|
|
|
|
|
console.log('Service worker installing'); |
|
|
|
|
|
|
|
} else if (registration.waiting) { |
|
|
|
|
|
|
|
console.log('Service worker installed'); |
|
|
|
|
|
|
|
} else if (registration.active) { |
|
|
|
|
|
|
|
console.log('Service worker active'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
console.error(`Registration failed with ${error}`); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2 modes : interact/display (see the .hidableenvironment class) |
|
|
|
// 2 modes : interact/display (see the .hidableenvironment class) |
|
|
|
// interact : small scale, 3D model of impact visible, keyboard visible, instruction visible |
|
|
|
// interact : small scale, 3D model of impact visible, keyboard visible, instruction visible |
|
|
|
// display : changeable scale, everything but content not visible |
|
|
|
// display : changeable scale, everything but content not visible |
|
|
@ -1150,8 +1056,6 @@ savingJSON = targets.map( e => { |
|
|
|
value : e.getAttribute("value"), |
|
|
|
value : e.getAttribute("value"), |
|
|
|
}) |
|
|
|
}) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
// load alt set of items e.g from https://observablehq.com/@utopiah/from-pim-to-2d-to-3d-to-xr-explorations |
|
|
|
|
|
|
|
// or https://fabien.benetou.fr/pub/home/pimxr-experimentation/sources.json |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// position should be configurable as rotation is handled by the OS |
|
|
|
// position should be configurable as rotation is handled by the OS |
|
|
|
|
|
|
|
|
|
|
@ -2178,7 +2082,7 @@ function changeColorLastId(){ |
|
|
|
if (id) document.querySelector("#"+id).setAttribute("color", "red") |
|
|
|
if (id) document.querySelector("#"+id).setAttribute("color", "red") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
AFRAME.registerComponent('thumbstick-shifting',{ |
|
|
|
AFRAME.registerComponent('thumbstick-shiftingDISABLED',{ |
|
|
|
/* illustrated in https://twitter.com/utopiah/status/1617460261111173121 */ |
|
|
|
/* illustrated in https://twitter.com/utopiah/status/1617460261111173121 */ |
|
|
|
init: function () { |
|
|
|
init: function () { |
|
|
|
this.el.addEventListener('thumbstickmoved', this.logThumbstick); |
|
|
|
this.el.addEventListener('thumbstickmoved', this.logThumbstick); |
|
|
@ -2201,21 +2105,21 @@ function stopDrawFromPenTip(){ |
|
|
|
clearInterval( drawingInterval ) |
|
|
|
clearInterval( drawingInterval ) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function drawIfPenTipPressed(){ |
|
|
|
function drawIfPenTipPressed(threshold=0.5){ |
|
|
|
[...document.querySelectorAll("[oculus-touch-controls]")].map( c => { |
|
|
|
[...AFRAME.scenes[0].querySelectorAll("[tracked-controls-webxr]")].map( c => { |
|
|
|
if ((c.components['tracked-controls-webxr'].buttonStates["7"]) > 0.5) { |
|
|
|
let component = c.components['tracked-controls-webxr'] |
|
|
|
let pos = c.getAttribute("position") |
|
|
|
if (component){ |
|
|
|
draw( position ) |
|
|
|
let value = component.buttonStates['7'] |
|
|
|
|
|
|
|
if (value && value.touched) { |
|
|
|
|
|
|
|
console.log(value.value, c.getAttribute("position"), c.getAttribute("rotation") ) |
|
|
|
|
|
|
|
if (value.value>threshold) draw(c.getAttribute("position")) // not exactly true : controller position, not tip position |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</script> |
|
|
|
</script> |
|
|
|
<div id="observablehq-key"> |
|
|
|
|
|
|
|
<div id="observablehq-viewof-offsetExample-ab4c1560"></div> |
|
|
|
|
|
|
|
<div id="observablehq-result_as_html-ab4c1560"></div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<button id=mainbutton style="z-index: 1; position: absolute; width:50%; margin: auto; text-align:center; top:45%; left:30%; height:30%;" onclick="startExperience()">Start the experience (hand tracking recommended)</button> |
|
|
|
<button id=mainbutton style="z-index: 1; position: absolute; width:50%; margin: auto; text-align:center; top:45%; left:30%; height:30%;" onclick="startExperience()">Start the experience (hand tracking recommended)</button> |
|
|
|
|
|
|
|
|
|
|
|
<a-scene cursor="rayOrigin: mouse" raycaster="objects: [html]; interval:100;" adjust-height-in-vr |
|
|
|
<a-scene cursor="rayOrigin: mouse" raycaster="objects: [html]; interval:100;" adjust-height-in-vr |
|
|
@ -2256,17 +2160,9 @@ function drawIfPenTipPressed(){ |
|
|
|
<a-entity hide-on-enter-ar="" id="environmentsky" class="hidableenvironment" gltf-model="../content/SourceCityToolkit/SKY_Market_day.glb" scale="1 1 1" position="17 -10 -4" rotation="0 0 0"></a-entity> |
|
|
|
<a-entity hide-on-enter-ar="" id="environmentsky" class="hidableenvironment" gltf-model="../content/SourceCityToolkit/SKY_Market_day.glb" scale="1 1 1" position="17 -10 -4" rotation="0 0 0"></a-entity> |
|
|
|
<a-text target value="instructions : \n--right pinch to move\n--left pinch to execute" position="0 1.65 -0.2" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="instructions : \n--right pinch to move\n--left pinch to execute" position="0 1.65 -0.2" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
|
|
|
|
<a-text target value="jxr addBlockCodeExample()" position="0 1.65 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="jxr location.reload()" position="0 1.65 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="jxr addAllPrimitives()" position="0 1.60 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="jxr startDrawFromPenTip()" position="0 1.45 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="jxr addCompoundPrimitiveExample()" position="0 1.55 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="jxr drawIfPenTipPressed()" position="0 1.40 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="jxr rescalePlace(1/10, 1)" position="0 1.50 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
<a-text target value="jxr rescalePlace()" position="0 1.45 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
<a-text target value="jxr tile_snapping_enabled = !tile_snapping_enabled" position="0 1.40 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
<a-text target id="getfromid_color" value="jxr changeColorLastId()" position="0 1.35 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
<a-text target id="getfromid_id" value="jxr getIdFromPick()" position="0 1.30 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
<a-text target id="locationreload" value="jxr location.reload()" position="0 1.20 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
<a-text target id="getfromclass_color" value="jxr changeColorLastClass()" position="0 1.15 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
<a-text target id="getfromclass_id" value="jxr getClassFromPick()" position="0 1.10 -0.1" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a-text target value="jxr pushLeftClass('tiles')" position=" -0.2 1.55 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="jxr pushLeftClass('tiles')" position=" -0.2 1.55 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="jxr pushRightClass('tiles')" position=" -0.2 1.50 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-text> |
|
|
|
<a-text target value="jxr pushRightClass('tiles')" position=" -0.2 1.50 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-text> |
|
|
|