|
|
|
@ -4,7 +4,6 @@ |
|
|
|
|
<head> |
|
|
|
|
<!-- Suggestions? https://git.benetou.fr/utopiah/text-code-xr-engine/issues/ --> |
|
|
|
|
|
|
|
|
|
<!--<script src='dependencies/aframe.min.js'></script>--> |
|
|
|
|
<script src='dependencies/aframe.offline.min.js'></script> |
|
|
|
|
<script src="dependencies/a-console.js"></script> |
|
|
|
|
<script src='dependencies/aframe-html.js'></script> |
|
|
|
@ -56,34 +55,6 @@ |
|
|
|
|
<img style='position:fixed;left:10px;' title='code repository' src='gitea_logo.svg'> |
|
|
|
|
</a> |
|
|
|
|
</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> |
|
|
|
|
/* |
|
|
|
|
|
|
|
|
@ -2202,7 +2173,7 @@ function highlight(code = `console.log("Here is your code."); var x = 5;`, langu |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
document.body.addEventListener( "highlighterready", (e) => { |
|
|
|
|
fetch("colorme.js").then(r=>r.text()).then( page => { addCodeEditor( page ) }) |
|
|
|
|
//fetch("colorme.js").then(r=>r.text()).then( page => { addCodeEditor( page ) }) |
|
|
|
|
}, false); |
|
|
|
|
|
|
|
|
|
function startExperience(){ |
|
|
|
@ -2989,21 +2960,21 @@ AFRAME.registerComponent('collider-check', { |
|
|
|
|
dependencies: ['raycaster'], |
|
|
|
|
|
|
|
|
|
init: function () { |
|
|
|
|
let worldPosition=new THREE.Vector3(); |
|
|
|
|
let v3 = new THREE.Vector3 |
|
|
|
|
let comeCloserInterval |
|
|
|
|
this.el.addEventListener('raycaster-intersection', function (e) { |
|
|
|
|
console.log('intersected') |
|
|
|
|
comeCloserInterval = setInterval( _=> { |
|
|
|
|
document.getElementById("leftHand").object3D.traverse( e => { if (e.name == "wrist") { |
|
|
|
|
worldPosition.copy(e.position);e.parent.updateMatrixWorld();e.parent.localToWorld(worldPosition) |
|
|
|
|
} }) |
|
|
|
|
e.detail.intersections[0]?.object.el.object3D.position.lerp(worldPosition, 0.1) |
|
|
|
|
}, 100) |
|
|
|
|
}); |
|
|
|
|
this.el.addEventListener('raycaster-intersection-cleared', function (e) { |
|
|
|
|
console.log('cleared') |
|
|
|
|
clearInterval( comeCloserInterval ) |
|
|
|
|
let c = e.detail.els[0].cloneNode() |
|
|
|
|
AFRAME.scenes[0].appendChild(c) |
|
|
|
|
let pos = e.detail.els[0].getAttribute("position").clone() |
|
|
|
|
console.log("found at", pos) |
|
|
|
|
let rig = document.getElementById("rig").getAttribute("position") |
|
|
|
|
if ( rig.distanceTo( pos ) == 0 ) rig.y++ // TODO doesn't work if the player itself moved |
|
|
|
|
pos.y = Array.from( document.querySelectorAll(".cubes") ) |
|
|
|
|
.filter( c => (c.getAttribute("position").x == pos.x && c.getAttribute("position").z == pos.z ) ) |
|
|
|
|
.sort( (b,a) => a.getAttribute("position").y - b.getAttribute("position").y )[0] |
|
|
|
|
.getAttribute("position").y + 1 |
|
|
|
|
console.log("adding at", pos) |
|
|
|
|
c.setAttribute("position", AFRAME.utils.coordinates.stringify( pos) ) |
|
|
|
|
c.setAttribute("material", "wireframe:true") |
|
|
|
|
c.classList.add("cubes") |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
@ -3020,17 +2991,16 @@ AFRAME.registerComponent('startfunctions', { |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
</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="display:none; 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 adjust-height-in-vr |
|
|
|
|
startfunctions |
|
|
|
|
snappable-cube-grid |
|
|
|
|
> |
|
|
|
|
<!-- screenstack dynamic-view selectionboxonpinches glossary timeline issues fot commands-from-external-json |
|
|
|
|
keyboard toolbox disable-components-via-url enable-components-via-url |
|
|
|
|
physics="debug:true" |
|
|
|
|
toolbox disable-components-via-url enable-components-via-url NOcommands-from-external-json keyboard > |
|
|
|
|
<!-- screenstack dynamic-view selectionboxonpinches glossary timeline issues fot |
|
|
|
|
cursor="rayOrigin: mouse" raycaster="objects: [html]; interval:100;" |
|
|
|
|
networked-scene="serverURL: https://naf.benetou.fr/; adapter: easyrtc; audio: true;" |
|
|
|
|
refresh-text-content-from-wiki-page="pagename:TestingPairCollaboration" |
|
|
|
|
--> |
|
|
|
@ -3048,14 +3018,24 @@ AFRAME.registerComponent('startfunctions', { |
|
|
|
|
<a-sound src="../content/street-crowd-ambience.mp3" autoplay=true loop=true volume=0.2></a-sound><!-- warning skipped on Quest, does autoplay there --> |
|
|
|
|
<a-sound id="snapping-sound" src="url(../content/magnets_snap.mp3)"></a-sound> |
|
|
|
|
<a-entity id="player" networked="template:#avatar-template;attachTemplateToLocal:false;" |
|
|
|
|
hud camera look-controls wasd-controls waistattach="target: .movebypinch" position="0 1.6 0"></a-entity> |
|
|
|
|
hud camera look-controls wasd-controls waistattach="target: .movebypinch" position="0 1.6 0"> |
|
|
|
|
<a-entity position=".5 0 0" collider-check raycaster="far:5; interval: 1000; objects: .cubes; showLine:true;" ></a-entity> |
|
|
|
|
</a-entity> |
|
|
|
|
<a-entity id="rightHand" pinchprimary hand-tracking-controls="hand: right;"></a-entity> |
|
|
|
|
<a-entity id="leftHand" pinchsecondary wristattachsecondary="target: #box" hand-tracking-controls="hand: left;"></a-entity> |
|
|
|
|
</a-entity> |
|
|
|
|
|
|
|
|
|
<a-box pressable start-on-press id="box" scale="0.05 0.05 0.05" color="pink"> |
|
|
|
|
<a-entity collider-check raycaster="objects: .collidable; showLine:true;" ></a-entity> |
|
|
|
|
</a-box> |
|
|
|
|
</a-box> |
|
|
|
|
<a-box class="cubes" color="red" position="0 0 -2"></a-box> |
|
|
|
|
<a-box class="cubes" color="red" position="1 0 -2"></a-box> |
|
|
|
|
<a-box class="cubes" color="red" position="-1 0 -2"></a-box> |
|
|
|
|
<a-box class="cubes" color="green" position="0 0 -1"></a-box> |
|
|
|
|
<a-box class="cubes" color="green" position="1 0 -1"></a-box> |
|
|
|
|
<a-box class="cubes" color="green" position="-1 0 -1"></a-box> |
|
|
|
|
<a-box class="cubes" color="blue" position="0 0 0"></a-box> |
|
|
|
|
<a-box class="cubes" color="blue" position="1 0 0"></a-box> |
|
|
|
|
<a-box class="cubes" color="blue" position="-1 0 0"></a-box> |
|
|
|
|
<!-- could attach functions here... BUT then they have to be activable with the other hand! --> |
|
|
|
|
<!-- visual reminders of shortcuts, a poster on the far left/right of keyboard shortcuts --> |
|
|
|
|
|
|
|
|
@ -3069,32 +3049,12 @@ AFRAME.registerComponent('startfunctions', { |
|
|
|
|
<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-troika-text anchor=left 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-troika-text> |
|
|
|
|
|
|
|
|
|
<a-troika-text anchor=left target value="jxr emptyPinchToMove()" position="0 1.65 -0.1" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
<a-troika-text anchor=left target value="jxr emptyPinchToMove()" position="0 1.35 -0.1" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
|
|
|
|
|
<a-troika-text anchor=left target id="locationreload" value="jxr location.reload()" position="0 1.20 -0.1" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
<a-troika-text anchor=left target id="makeAnchorsVisibleOnTargets" value="jxr makeAnchorsVisibleOnTargets()" position="0 1.05 -0.1" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
<a-troika-text anchor=left target id="startmesher" value="jxr startMesher()" position="0 1.00 -0.1" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
|
|
|
|
|
<a-troika-text anchor=left target value="jxr pushLeftClass('meshed')" position=" -0.2 1.55 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
<a-troika-text anchor=left target value="jxr pushRightClass('meshed')" position=" -0.2 1.50 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
<a-troika-text anchor=left target value="jxr pushUpClass('meshed')" position=" -0.2 1.45 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
<a-troika-text anchor=left target value="jxr pushDownClass('meshed')" position=" -0.2 1.40 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
<a-troika-text anchor=left target value="jxr pushBackClass('meshed')" position=" -0.2 1.35 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
<a-troika-text anchor=left target value="jxr pushFrontClass('meshed')" position=" -0.2 1.30 0.1" rotation="0 90 0" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
|
|
|
|
|
<!-- somehow disable hand interaction despite, according to the documentation, it should rely on world position |
|
|
|
|
<a-text target value="jxr qs #rig sa position 0 0 10" position="0 1.55 .5" rotation="0 180 0" scale="0.1 0.1 0.1"></a-text> |
|
|
|
|
--> |
|
|
|
|
<a-console position="0 1.1 -0.8" rotation="-45 0 0" font-size="34" height=0.5 skip-intro=true></a-console> |
|
|
|
|
|
|
|
|
|
<!-- Floor --> |
|
|
|
|
<a-plane rotation="-90 0 0" scale="5 5 5" position="0 1 0" opacity=.5 static-body></a-plane> |
|
|
|
|
<a-troika-text anchor=left target id="makeAnchorsVisibleOnTargets" value="jxr makeAnchorsVisibleOnTargets()" position="0 1.25 -0.1" scale="0.1 0.1 0.1"></a-troika-text> |
|
|
|
|
|
|
|
|
|
<!-- Immovable box --> |
|
|
|
|
<a-box static-body position="0 0.5 -5" width="3" height="1" depth="1"></a-box> |
|
|
|
|
|
|
|
|
|
<!-- Dynamic box --> |
|
|
|
|
<a-box dynamic-unless-picked position="0 1.4 -.3" target scale=".1 .1 .1"></a-box> |
|
|
|
|
<a-console position="0 1.1 -0.8" rotation="-45 0 0" font-size="34" height=0.5 skip-intro=true></a-console> |
|
|
|
|
|
|
|
|
|
</a-scene> |
|
|
|
|
</body> |
|
|
|
|