work in progress [might break]

This commit is contained in:
Leon van Kammen 2024-03-05 11:56:06 +00:00
parent 490ff2937d
commit 6f8403da9d
7 changed files with 94 additions and 24 deletions

View File

@ -18,13 +18,13 @@
light="defaultLightsEnabled: false">
<a-entity id="player" movement-controls touch-controls wasd-controls="fly:false" look-controls>
<a-entity camera="fov:90" position="0 1.6 0" id="camera"></a-entity>
<a-entity id="left-hand" laser-controls="hand: left" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor">
<a-entity id="left-hand" hand-tracking-controls="hand:left" laser-controls="hand: left" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor" xrf-pinchmove="rig: #player">
<a-entity rotation="-35 0 0" position="0 0.1 0" id="navigator">
<a-entity id="back" xrf-button="label: <; width:0.05; action: history.back()" position="-0.025 0 0" class="ray"></a-entity>
<a-entity id="next" xrf-button="label: >; width:0.05; action: history.forward()" position=" 0.025 0 0" class="ray"></a-entity>
</a-entity>
</a-entity>
<a-entity id="right-hand" laser-controls="hand: right" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor"></a-entity>
<a-entity id="right-hand" hand-tracking-controls="hand:right" laser-controls="hand: right" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor"></a-entity>
</a-entity>
<a-entity id="home" xrf="index.glb" xrf-menu></a-entity>
@ -73,8 +73,7 @@
<!-- everything below is completely optional and not part of the spec -->
<script src="./../../../dist/aframe-blink-controls.min.js"></script> <!-- teleporting using controllers -->
<script src="https://cdn.jsdelivr.net/npm/handy-work@3.1.9/build/handy-controls.min.js"></script> <!-- hand controllers -->
<script src="./../../../dist/aframe-blink-controls.min.js"></script> <!-- teleporting using controllers -->
<script src="./../../../dist/xrfragment.plugin.p2p.js"></script> <!-- serverless p2p connectivity -->
<script src="./../../../dist/xrfragment.plugin.matrix.js"></script> <!-- matrix connectivity -->
<script src="./../../../dist/xrfragment.plugin.frontend.js"></script> <!-- menu + chat interface -->

View File

@ -139,14 +139,14 @@ window.AFRAME.registerComponent('xrf', {
let {mesh,clickHandler} = opts;
let createEl = function(c){
let el = document.createElement("a-entity")
el.setAttribute("xrf-get",c.name ) // turn into AFRAME entity
el.setAttribute("xrf-get",c.name ) // turn into AFRAME entity
el.setAttribute("pressable", '' ) // detect click via hand-detection
el.setAttribute("class","ray") // expose to raycaster
el.setAttribute("pressable", '') // detect hand-controller click
// respond to cursor via laser-controls (https://aframe.io/docs/1.4.0/components/laser-controls.html)
el.addEventListener("click", clickHandler )
el.addEventListener("mouseenter", mesh.userData.XRF.href.selected(true) )
el.addEventListener("mouseleave", mesh.userData.XRF.href.selected(false) )
el.addEventListener("pressedstarted", clickHandler )
el.addEventListener("pressedended", clickHandler )
$('a-scene').appendChild(el)
}
createEl(mesh)

View File

@ -0,0 +1,51 @@
// this makes WebXR hand controls able to click things (by touching it)
AFRAME.registerComponent('pressable', {
schema: {
pressDistance: {
default: 0.01
}
},
init: function() {
this.worldPosition = new THREE.Vector3();
this.handWorldPosition = new THREE.Vector3();
this.handEls = document.querySelectorAll('[hand-tracking-controls]');
this.pressed = false;
},
tick: function() {
var handEls = this.handEls;
var handEl;
var distance;
for (var i = 0; i < handEls.length; i++) {
handEl = handEls[i];
let indexTipPosition = handEl.components['hand-tracking-controls'].indexTipPosition
handEl.object3D.localToWorld( this.handWorldPosition )
this.handWorldPosition.add( indexTipPosition )
distance = this.calculateFingerDistance(this.handWorldPosition);
if( xrf.debug == 10 && this.el.id == "xrf-button_teleport_me_down_there" ){ debugger }
if (distance < this.data.pressDistance && distance !== 0.0 ) {
if (!this.pressed) {
this.el.emit('pressedstarted');
}
this.pressed = true;
return;
}
}
if (this.pressed) {
this.el.emit('pressedended');
}
this.pressed = false;
},
calculateFingerDistance: function(fingerPosition) {
var el = this.el;
//worldPosition.copy(el.object3D.position);
el.object3D.updateMatrixWorld();
el.object3D.localToWorld(this.worldPosition);
if( xrf.debug == 10 && this.el.id == "xrf-button_teleport_me_down_there" ){ debugger }
return this.worldPosition.distanceTo(fingerPosition);
}
});

View File

@ -37,10 +37,11 @@ window.AFRAME.registerComponent('xrf-get', {
mesh.scale.copy(world.scale)
mesh.setRotationFromQuaternion(world.quat);
}else{
// lets create a dummy add function so that the mesh won't get reparented
// lets create a dummy add function so that the mesh won't get reparented during setObject3D
this.el.object3D.add = (a) => a
}
this.el.setObject3D('mesh',mesh)
this.el.object3D = mesh //setObject3D('mesh',mesh)
if( !this.el.id ) this.el.setAttribute("id",`xrf-${mesh.name}`)
}else console.warn("xrf-get ignore: "+JSON.stringify(this.data))
}, evt && evt.timeout ? evt.timeout: 500)

View File

@ -0,0 +1,28 @@
// poor man's way to move forward using hand gesture pinch
window.AFRAME.registerComponent('xrf-pinchmove', {
schema:{
rig: {type: "selector"}
},
init: function(){
this.el.addEventListener("pinchended", () => {
// get the cameras world direction
let direction = new THREE.Vector3()
this.el.sceneEl.camera.getWorldDirection(direction);
// multiply the direction by a "speed" factor
direction.multiplyScalar(0.4)
// get the current position
var pos = player.getAttribute("position")
// add the direction vector
pos.x += direction.x
pos.z += direction.z
// set the new position
this.data.rig.setAttribute("position", pos);
// !!! NOTE - it would be more efficient to do the
// position change on the players THREE.Object:
// `player.object3D.position.add(direction)`
// but it would break "getAttribute("position")
})
},
})

View File

@ -38,19 +38,6 @@ xrf.detectCameraRig = function(opts){
}
}
xrf.roundrobin = (frag, store) => {
if( !frag.args || frag.args.length == 0 ) return 0
if( !store.rr ) store.rr = {}
let label = frag.fragment
if( store.rr[label] ) return store.rr[label].next()
store.rr[label] = frag.args
store.rr[label].next = () => {
store.rr[label].index = (store.rr[label].index + 1) % store.rr[label].length
return store.rr[label].index
}
return store.rr[label].index = 0
}
xrf.stats = () => {
// bookmarklet from https://github.com/zlgenuine/threejs_stats
(function(){

View File

@ -35,7 +35,11 @@ xrf.frag.href = function(v, opts){
let click = mesh.userData.XRF.href.exec = (e) => {
if( !mesh.material.visible ) return // ignore invisible nodes
if( !mesh.material || !mesh.material.visible ) return // ignore invisible nodes
if( e.type == "pressedended" && !e.detail ){
console.dir(e)
return
}
// bubble up!
mesh.traverseAncestors( (n) => n.userData && n.userData.href && n.dispatchEvent({type:e.type,data:{}}) )
@ -59,7 +63,7 @@ xrf.frag.href = function(v, opts){
}
let selected = mesh.userData.XRF.href.selected = (state) => () => {
if( !mesh.material.visible && !mesh.isSRC ) return // ignore invisible nodes
if( (!mesh.material && !mesh.material.visible) && !mesh.isSRC ) return // ignore invisible nodes
if( mesh.selected == state ) return // nothing changed
xrf.interactive.objects.map( (o) => {