diff --git a/index.html b/index.html
index f2e321e..9b19bc2 100644
--- a/index.html
+++ b/index.html
@@ -33,203 +33,15 @@ setTimeout( _ => {
let rot = "0 0 0"
let positions = [ "-1 1 -3.5", "-1 2 -3.5", "0 0 -3.5", "0 1 -3.5", "1 0 -3.5", "-1 0 -3.5" ]
// triangle example, could be based on room boundaries instead
- positions.map( pos => {
- let el = document.createElement("a-entity")
- el.innerHTML = scaffoldingInnerHTMLTemplate
- AFRAME.scenes[0].appendChild(el)
- el.setAttribute("position", pos)
- el.setAttribute("rotation", rot)
- })
+ positions.map( pos => { addFromTemplate(pos, rot, scaffoldingInnerHTMLTemplate) })
}, 2000)
-var forceXaxis
-// setInterval( _ => console.log(forceXaxis), 1000)
-
-var translatingTargets = false
-var clearRot
-function toggleTranslateTargets(){
- translatingTargets = !translatingTargets
- let scene = AFRAME.scenes[0].object3D
- if (translatingTargets){
- let anchor = new THREE.Object3D()
- let latest = selectedElements[selectedElements.length-1].element
- latest.object3D.add( anchor )
- // also inherits rotation, could try cancel it as the opposite of latest rotation
- // might be easier to copy the position only every few ms instead
- anchor.position.sub( latest.object3D.position )
- //targets.map( t => anchor.attach(t.object3D) )
- // should attach all BUT the current moving entity!
- Array.from(document.querySelectorAll('.mab')).map( t => anchor.attach(t.object3D) )
- // they don't move... despite
- } else {
- clearInterval( clearRot )
- Array.from(document.querySelectorAll('.mab')).map( t => scene.attach(t.object3D) )
- //targets.map( t => scene.attach(t.object3D) )
- // could delete anchor, cleaner
- }
-}
-
-var attachToPlayer = false
-function toggleAttachToSelf(){
- attachToPlayer = !attachToPlayer
- attachToPlayer ? parent=document.querySelector("#player") : parent=AFRAME.scenes[0]
- targets.map( t => parent.object3D.attach(t.object3D) )
-}
-
-function checkIntersection(latest, nearby){
- //let latest = selectedElements[selectedElements.length-1].element
- //let nearby = getClosestTargetElements( latest.getAttribute('position') )
- // https://threejs.org/docs/?q=box#api/en/math/Box3.containsBox
- // https://threejs.org/docs/?q=box#api/en/math/Box3.expandByObject
- let a = new THREE.Box3().expandByObject( latest.object3D ) // consider mesh.geometry.computeBoundingBox() first
- let b = new THREE.Box3().expandByObject( nearby.object3D )
- console.log(a,b, a.containsBox(b))
- // testable as checkIntersection( document.querySelector("[color='yellow']"), document.querySelector("[color='purple']") )
- //
- //
-}
-
-setTimeout( _ => {
- let newPostIt = addNewNoteAsPostItNote("jxr console.log(222);", "0 1.2 -.5")
- .setAttribute("onreleased", "grammarBasedSnap()")
- let otherPostIt = addNewNoteAsPostItNote("jxr console.log(111);", "0 1.4 -.5")
- .setAttribute("onreleased", "grammarBasedSnap()")
- let postIt = addNewNoteAsPostItNote("hi this is a post-it note.", "0 1.6 -.5")
- .setAttribute("onreleased", "runClosestJXR(); grammarBasedSnap()") // dunno how to share the event context back here...
- // .setAttribute("onreleased", "snapNext()") // does NOT support multiple instances for now
- // see https://aframe.io/docs/1.5.0/core/component.html#multiple
- // maybe bind could help
-
- //let cloneMe = addNewNote('jxr clone me from corner', '0 0 .1', '1 1 1', 'cmd')
- // should rebind parent...
- //setTimeout( _ => { _ => cloneMe.object3D.parent = postIt.object3D }, 1000 )
- // should try object3D.attach() instead
- //.addEventListener('loaded',
- // entityIndexes( document.querySelector("[color='blue']").object3D.children[0] )
-}, 1000 )
-
-// e.g document.querySelector("[color='blue']").object3D.children[0]
-function entityIndexes(mesh){ // needs a mesh with a geometry, not a group
- // could also traverse
- let gp = mesh.geometry.attributes.position;
- let wPos = [];
- for(let i = 0;i < gp.count; i++){
- let p = new THREE.Vector3().fromBufferAttribute(gp, i); // set p from `position`
- mesh.localToWorld(p); // p has wordl coords
- wPos.push(p);
- }
- // many are duplicates, i.e a a cube will return 24 indexes (4 per 6 faces), not 8
- //let l = [...new Set(wPos)].length; console.log( l )
- [...new Set(wPos)].map( p => addNewNote("x", p))
- console.log( [...new Set(wPos)].length )
- // seems to add the duplicates again
- // try to "de-dup" via .distanceTo() below a threshold instead
-}
-
-
-function snapToGrid(gridSize=1){ // default as 1 decimeter
- let latest = selectedElements[selectedElements.length-1].element
- latest.setAttribute("rotation", "0 0 0")
- let pos = latest.getAttribute("position")
- pos.multiplyScalar(gridSize*10).round().divideScalar(gridSize*10)
- latest.setAttribute("position", pos )
-}
-
-// deeper question, making the rules themselves manipulable? JXR?
- // So the result of the grammar becomes manipulable, but could you make the rules of the grammar itself visual? Even manipulable?
- // could start by visualizing examples first e.g https://writer.com/wp-content/uploads/2024/03/grammar-1.webp
-function snapMAB(){
- // multibase arithmetic blocks aka MAB cf https://en.wikipedia.org/wiki/Base_ten_block
- let latest = selectedElements[selectedElements.length-1].element
- let nearby = getClosestTargetElements( latest.getAttribute('position') )
- let linked = []
- if (nearby.length>0){
- latest.setAttribute("rotation", AFRAME.utils.coordinates.stringify( nearby[0].el.getAttribute("rotation") ) )
- latest.setAttribute("position", AFRAME.utils.coordinates.stringify( nearby[0].el.getAttribute("position") ) )
- latest.object3D.translateX( 1/10 )
- linked.push( latest )
- linked.push( nearby[0].el )
- let overlap = Array.from( document.querySelectorAll(".mab") ).filter( e => e.object3D.position.distanceTo( latest.object3D.position ) < 0.01 && e!=latest )
- while (overlap.length > 0 ){
- latest.object3D.translateX( 1/10 )
- linked.push( overlap[0] )
- overlap = Array.from( document.querySelectorAll(".mab") ).filter( e => e.object3D.position.distanceTo( latest.object3D.position ) < 0.01 && e!=latest )
- }
- // do something special if it becomes 10, e.g become a single line, removing the "ridges"
- if (linked.length > 3)
- linked.map( e => Array.from( e.querySelectorAll("a-box") ).setAttribute("color", "orange") )
-
- // also need to go backward too to see if it's the latest added
- }
-}
-
-function snapRightOf(){
- let latest = selectedElements[selectedElements.length-1].element
- let nearby = getClosestTargetElements( latest.getAttribute('position') )
- if (nearby.length>0){
- latest.setAttribute("rotation", AFRAME.utils.coordinates.stringify( nearby[0].el.getAttribute("rotation") ) )
- latest.setAttribute("position", AFRAME.utils.coordinates.stringify( nearby[0].el.getAttribute("position") ) )
- latest.object3D.translateX( 1/10 )
- // somehow... works only the 2nd time, not the 1st?!
- }
-}
-
-function grammarBasedSnap(){
- // verify if snappable, e.g of same type (or not)
- // e.g check if both have .getAttribute('value').match(prefix) or not
- let latest = selectedElements[selectedElements.length-1].element
- let nearby = getClosestTargetElements( latest.getAttribute('position') )
- if (nearby.length>0){
- let closest = nearby[0].el
- let latestTypeJXR = latest.getAttribute('value').match(prefix)
- let closestTypeJXR = latest.getAttribute('value').match(prefix)
- latest.setAttribute("rotation", AFRAME.utils.coordinates.stringify( closest.getAttribute("rotation") ) )
- latest.setAttribute("position", AFRAME.utils.coordinates.stringify( closest.getAttribute("position") ) )
- if ( latestTypeJXR && closestTypeJXR )
- latest.object3D.translateX( 1/10 ) // same JXR type, snap close
- else
- latest.object3D.translateX( 2/10 ) // different types, snap away
- // somehow... works only the 2nd time, not the 1st?!
- }
-}
-
-function cloneTarget(target){
- let el = target.cloneNode(true)
- if (!el.id)
- el.id = "clone_" + crypto.randomUUID()
- else
- el.id += "_clone_" + crypto.randomUUID()
+function addFromTemplate(pos="0 0 0", rot="0 0 0", template=""){
+ let el = document.createElement("a-entity")
+ el.innerHTML = template
AFRAME.scenes[0].appendChild(el)
-}
-
-function deleteTarget(target){
- targets = targets.filter( e => e != target)
- target.remove()
-}
-
-function runClosestJXR(){
- // ideally this would come from event details
- let latest = selectedElements[selectedElements.length-1].element
- let nearby = getClosestTargetElements( latest.getAttribute('position') )
- // if (nearby.length>0){ interpretJXR( nearby[0].el.getAttribute("value") ) }
- nearby.map( n => interpretJXR( n.el.getAttribute("value") ) )
-}
-
-function notesFromArray(data, generatorName="", field="title", offset=1, step=1/10, depth=-.5 ){
- data.slice(0,maxItemsFromSources).map( (n,i) => {
- addNewNote( n[field], "0 "+(offset+i*step)+" "+depth, ".1 .1 .1", null, generatorName )
- .setAttribute("onreleased","spreadItemsFromCollection('getcsljson', 1.5)")
- })
-}
-
-function spreadItemsFromCollection( generatorName, offset=1, step=1/10, depth=-.5 ){
- getArrayFromClass(generatorName).sort((a,b)=>a.getAttribute('position').y-b.getAttribute('position').y).map( (n,i) => {
- n.setAttribute('position', "0 "+(offset+i*step)+" "+depth)
- n.setAttribute('rotation', "0 0 0") // could also be based on the average of all items, the first item, last one, etc
- // see also snap-on-pinchended component
- })
- let items = getArrayFromClass(generatorName).sort((b,a)=>a.getAttribute('position').y-b.getAttribute('position').y).map( n => n.getAttribute('value') )
- shareLiveEvent('modified list', items)
+ el.setAttribute("position", pos)
+ el.setAttribute("rotation", rot)
}
AFRAME.registerComponent('onemptypinch', { // changed from ondrop to be coherent with event name
@@ -255,39 +67,6 @@ AFRAME.registerComponent('onemptypinch', { // changed from ondrop to be coherent
}
})
-function onHoveredTeleport(){
- // iterate over targets
- // see instead of teleportable https://aframe.io/docs/1.5.0/components/cursor.html#configuring-the-cursor-through-the-raycaster-component
- Array.from( document.querySelectorAll("[teleporter]") ).map( target => {
- if ( target.states.includes( "cursor-hovered" ) ){
- target.setAttribute("material", "color", "magenta") // visited
- document.getElementById('rig').setAttribute('position', target.getAttribute("position") )
- }
- })
-}
-
-AFRAME.registerComponent('teleporter', {
- init: function(){
- this.el.setAttribute("opacity", .5)
- if (window.location.hash && document.querySelector(window.location.hash+"[teleporter]"))
- document.getElementById('rig').setAttribute('position', document.querySelector(window.location.hash+"[teleporter]").getAttribute("position") )
- },
- events: {
- mouseenter: function (e) { this.el.setAttribute("opacity", .8) },
- mouseleave: function (e) { this.el.setAttribute("opacity", .5) },
- click: function (e) {
- let posTarget = new THREE.Vector3()
- this.el.object3D.getWorldPosition( posTarget )
- console.log( posTarget)
- document.getElementById('rig').setAttribute('position', posTarget)
- // seems to work, maybe inteference with others teleporters activated unknowingly, e.g in succession
- }
- // this.el.getAttribute("position") ) }
- // does not get proper world position
- // makes it compatible with mouse on desktop ... but also somehow enable the wrist shortcut?!
- }
-});
-
AFRAME.registerComponent('scaffolding', {
init: function(){
console.log(this.el.innerHTML)
@@ -310,15 +89,6 @@ AFRAME.registerComponent('scaffolding', {
}
});
-let page = "Wiki.VirtualRealityInterface";
-let pageFromParam = AFRAME.utils.getUrlParameter('page')
-if (pageFromParam) page = pageFromParam
-setTimeout( _ => {
- Array.from( document.querySelectorAll("[value='"+page+"']") ).map( n =>
- n.setAttribute("onreleased", "console.log('dropped, should toggle display children,"+n.id+"')"));
- Array.from( document.querySelectorAll("[value='"+page+"']>a-sphere") ).map( n => n.setAttribute("color", "purple"))
-}, 5000)
-