Compare commits

..

108 Commits

Author SHA1 Message Date
Fabien Benetou 07644a6cd1 example of state per distance 1 year ago
Fabien Benetou 4fc5891c71 playgrou 1 year ago
Fabien Benetou 8d0f5e2756 annotation as component proper 1 year ago
Fabien Benetou 63bc7a02c5 ice map and annotation 1 year ago
Fabien Benetou 3aacf514d5 example with start and end blocks 1 year ago
Fabien Benetou 7a05cb826c example 1 year ago
Fabien Benetou e3e804f30c comments on user facing and post-it drop 1 year ago
Fabien Benetou 08eb53957b add events and right angle example for post it generator 1 year ago
Fabien Benetou 23d7f935df working example of thumb/index pull 1 year ago
Fabien Benetou 6ae4f08e57 example of touching with index to change entity 2 years ago
Fabien Benetou c8b3cb5741 move hands to see the tension 2 years ago
Fabien Benetou ec3fcfe28a draw with index tip preview 2 years ago
Fabien Benetou c43df10bf5 execute graph 2 years ago
Fabien Benetou 6ad5b4c4f0 fixed on editors connections and generateGraphFromEditors() 2 years ago
Fabien Benetou 5a2794401a addConnectorsToCodeEditor() and checkConnectors() 2 years ago
Fabien Benetou 7dbeeed9fd visual basis to start 2 years ago
Fabien Benetou 4418866691 editor prevent reflow and optional width 2 years ago
Fabien Benetou 547423ce17 merging editors 2 years ago
Fabien Benetou 808a7aedc5 hide source editor, might cause pinching conflicts 2 years ago
Fabien Benetou 110282218c split on pinch 2 years ago
Fabien Benetou 4153bccc1e moved editors set 2 years ago
Fabien Benetou 4d83424052 fixed length of sections and added addCodeMultipleEditors() 2 years ago
Fabien Benetou d407058a18 horizontal split with new editors, split full lines and vertical positioning 2 years ago
Fabien Benetou bcd14747c3 bug fix on empty lines (trimmed) causing infinite loop 2 years ago
Fabien Benetou 90050fa547 fixing gutters for code, example with syntax highligting 2 years ago
Fabien Benetou 2ec6f31ac8 synax highlight example on split multiple editor 2 years ago
Fabien Benetou 5240ab9ff9 split 2 years ago
Fabien Benetou b8cdd97aac removed single line testj 2 years ago
Fabien Benetou 6f7eb6b656 caesure 2 years ago
Fabien Benetou b71562cca1 basis 2 years ago
Fabien Benetou a8c55d1e3c rough desc 2 years ago
Fabien Benetou 6b483775e8 pulling element to hand 2 years ago
Fabien Benetou ba8013a38e extending piggybacking on target 2 years ago
Fabien Benetou 0abe363450 basic principle piggybacking on wristattached component 2 years ago
Fabien Benetou 4abc5ea939 fixed wrist attachement with new hand API (1.3 to 1.4) 2 years ago
Fabien Benetou 699dbcd6b9 using the proper name from new hand tracking API for rotation 2 years ago
Fabien Benetou de5c6a41bd rotation fixed, again, somehow (does not seem stable) 2 years ago
Fabien Benetou 4cf9c0b148 optimized model, AFrame version bump with rotation fixed 2 years ago
Fabien Benetou a817d54242 modified for offline mode 2 years ago
Fabien Benetou 841980a10c bringing a-console and shiki locally to better support offline mode 2 years ago
Fabien Benetou b0dbc6579d working code editor but not yet adding text/code in place 2 years ago
Fabien Benetou ebd1fb19ea meshes with physics 2 years ago
Fabien Benetou 1b2fa784e3 directly manipulable meshes 2 years ago
Fabien Benetou f6fb9ae4d1 meshing that can be stopped, restarted and content moved 2 years ago
Fabien Benetou 3b99a58287 meshing 2 years ago
Fabien Benetou 660cacab27 broken 2 years ago
Fabien Benetou a71be51ac5 working principle of showing anchors 2 years ago
Fabien Benetou 9ea1d0a71c example of combining default behaviors 2 years ago
Fabien Benetou 59d3e0c64d scaling continuation and hotfix on refresh from wiki page (throttling) 2 years ago
Fabien Benetou f1c7815557 scaling via left pinch while holding somethinmg 2 years ago
Fabien Benetou 737f36b4e6 periodic refresh of preview image 2 years ago
Fabien Benetou d5bc01251e send and refresh perspective image 2 years ago
Fabien Benetou c9f3e9c3ec updated submit.html with iframe preview and shareable link 2 years ago
Fabien Benetou 65d15d3266 matching room as wiki pages to be able to write from submit.html and read from index.html 2 years ago
Fabien Benetou de42d9be55 rotation centered on user but resetting on new pinch 2 years ago
Fabien Benetou 704b60b293 rotation example, not ideal because not centered on user 2 years ago
Fabien Benetou 834ffb4091 coherence in directions 2 years ago
Fabien Benetou 68b8ee8136 example of faster speed 2 years ago
Fabien Benetou a0bbdcfcd6 forward and sideways 2 years ago
Fabien Benetou aae734a20c moving backward only 2 years ago
Fabien Benetou 20181ae2c1 visual grid 2 years ago
Fabien Benetou 1bb95fa69c from primitive to instance (without instancing proper) 2 years ago
Fabien Benetou 1ce813ebac moving away from text for troika-text 2 years ago
Fabien Benetou 4f72cc08be more examples of nextMovementToPoints() usage 2 years ago
Fabien Benetou 9b776462c6 fixed draw() and works with nextMovementToPoints() 2 years ago
Fabien Benetou c8e2ad2e70 fixed pointsFromMovement and added example 2 years ago
Fabien Benetou 1a7c5a8f11 a-console component for easier feedback in HMD 2 years ago
Fabien Benetou 21c74453f2 drop zone as a sphere 2 years ago
Fabien Benetou 1cb5a25bd3 points from movement 2 years ago
Fabien Benetou cdb241ac8f generalized addBlockCodeExample with position and return element 2 years ago
Fabien Benetou 5ce4daa61e generalized addBlockCodeExample with position and return element 2 years ago
Fabien Benetou 1030436f74 generalized addBlockCodeExample with position and return element 2 years ago
Fabien Benetou a28612d4b7 generalized addBlockCodeExample 2 years ago
Fabien Benetou 1f8026d89c snap ghost preview 2 years ago
Fabien Benetou 407b3b494d next pinch applied (lack of feedback is confusing) 2 years ago
Fabien Benetou b31e925156 apply modifier to class 2 years ago
Fabien Benetou 9b5058389f modifier based on ID selected from last pick 2 years ago
Fabien Benetou 0572fe7294 removeOutlineFromEntity 2 years ago
Fabien Benetou 17afdd7855 addBlockCodeExample (just text for now, no snap) 2 years ago
Fabien Benetou 0e1f297ec0 cloning primitives 2 years ago
Fabien Benetou 89ee270eec snapping sound and fixed sky 2 years ago
Fabien Benetou 3e3e6fa602 refactoring and compound example 2 years ago
Fabien Benetou e6d068922b primitives 2 years ago
Fabien Benetou e3604cc7de snapping suggestions 2 years ago
Fabien Benetou 321f47bca5 merged screenshot, snapping to 10cm (invisible) grid 2 years ago
Fabien Benetou 5dd554f8ee working 2 years ago
Fabien Benetou 73c9a94ec5 being able to dyanmically change asset kits and sequentially load and use multiples 2 years ago
Fabien Benetou a49d200684 higher and lower level asset set considerations 2 years ago
Fabien Benetou 328e6e69ec cleaned up and added shifts 2 years ago
Fabien Benetou 6f8a451b77 event working 2 years ago
Fabien Benetou d71c932e50 grid to snap as searchable datastructure 2 years ago
Fabien Benetou 3327a0e523 Tile generation and scaling 2 years ago
Fabien Benetou 108d178a7d added rotation 2 years ago
Fabien Benetou 3cf9065603 sharing between friends (but without rotation) 2 years ago
Fabien Benetou a92aa271a0 send image and models too 2 years ago
Fabien Benetou f2fbaa2b37 loadFromMastodon() 2 years ago
Fabien Benetou fab5a00f38 higher permission required to create own streams for custom collections 2 years ago
Fabien Benetou fe6383f1f6 event based loading 2 years ago
Fabien Benetou 86b4f3ed9c removed descriptive comments and used code instead with ims() shorthand 2 years ago
Fabien Benetou 1c73d4ecb0 Friends list and message displayed in 3D/XR 2 years ago
Fabien Benetou ac94b9ab3c immers deeper integration 2 years ago
Fabien Benetou 16e72b5a23 Immers setup goals 2 years ago
Fabien Benetou c212277b9a working jxr teleport example but creating bug on pinching (parent pos) 2 years ago
Fabien Benetou ce7eccd0b7 fixed sa shorthand. Example of in VR doc 2 years ago
Fabien Benetou 9b2dd9284c loadCodeFromPage() as example 2 years ago
Fabien Benetou cd56f69d58 next page working 2 years ago
Fabien Benetou 133f0b040e small cleanup 2 years ago
Fabien Benetou 6f6f764063 add page sequence 2 years ago
  1. 62
      README.md
  2. 1708
      index.html
  3. 144
      index.js
  4. 3538
      jxr.js
  5. 28
      submit.html

@ -8,69 +8,7 @@ You can test it live at https://fabien.benetou.fr/pub/home/future_of_text_demo/e
See also the AR version https://video.benetou.fr/w/x7HeEBF9HGfdVyf7vWsKsQ See also the AR version https://video.benetou.fr/w/x7HeEBF9HGfdVyf7vWsKsQ
Note that the master branch is never the most up to date branch. Instead see https://git.benetou.fr/utopiah/text-code-xr-engine/branches for an overview. To explore branches in VR see https://fabien.benetou.fr/pub/home/future_of_text_demo/engine/branches.html
In order to have a better view of the different features accross branches see https://mastodon.pirateparty.be/web/@utopiah and https://twitter.com/utopiah/ which act as a kind of live documentation of the process.
![Manipulation prevew image](https://fabien.benetou.fr/pub/home/future_of_text_demo/content/primitives_manipulation.gif)
![Preview image](https://fabien.benetou.fr/pub/home/future_of_text_demo/content/engine-preview.png) ![Preview image](https://fabien.benetou.fr/pub/home/future_of_text_demo/content/engine-preview.png)
First communicated on https://twitter.com/utopiah/status/1531188862415929344 as way to work on (WebXR) code during a flight. First communicated on https://twitter.com/utopiah/status/1531188862415929344 as way to work on (WebXR) code during a flight.
## Minimalist example
See for details the [minimalist-template branch](https://git.benetou.fr/utopiah/text-code-xr-engine/src/branch/minimalist-template/index.html) and [deployment issue](https://git.benetou.fr/utopiah/text-code-xr-engine/issues/72).
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>JXR minimalist template</title>
<script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-troika-text/dist/aframe-troika-text.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/kylebakerio/a-console@1.0.2/a-console.js"></script>
<script src="https://fabien.benetou.fr/pub/home/future_of_text_demo/engine/jxr.js"></script>
<!-- use to define targets and left/right pinch interactions, respectively execute code and move targets -->
</head>
<body>
<div style="position:fixed;z-index:1; top: 0%; left: 0%; border-bottom: 70px solid transparent; border-left: 70px solid #eee;">
<a href="https://git.benetou.fr/utopiah/text-code-xr-engine/issues/">
<img style="position:fixed;left:10px;" title="code repository"
src="https://fabien.benetou.fr/pub/home/future_of_text_demo/engine/gitea_logo.svg">
</a>
</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>
<a-entity id="rig">
<a-entity id="player"
hud camera look-controls wasd-controls waistattach="target: .movebypinch" position="0 1.6 0"></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-troika-text value="SpaSca : Spatial Scaffolding" anchor="left" outline-width="5%" font="https://fabien.benetou.fr/pub/home/future_of_text_demo/content/ChakraPetch-Regular.ttf" position="-5.26197 6.54224 -1.81284"
scale="4 4 5" rotation="90 0 0" troika-text="outlineWidth: 0.01; strokeColor: #ffffff" material="flatShading: true; blending: additive; emissive: #c061cb"></a-troika-text>
<a-sky hide-on-enter-ar color="black"></a-sky>
<a-entity hide-on-enter-ar="" id="environmentsky" class="hidableenvironment" ></a-entity>
<a-troika-text anchor="left" target value="instructions : \n--right pinch to move\n--left pinch to execute" position="0 0.65 -0.2" 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-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>
</html>
```

File diff suppressed because it is too large Load Diff

@ -0,0 +1,144 @@
/* nodejs server to grab the current URL as tridactyl command and serve back page with content */
// mkdir tabs polydata
// autocmd TabEnter .* js fetch("http://localhost:7777/?url="+window.location.href)
// might be interesting to keep track of document.referrer too
// consider instead Firefox Account
const fs = require('fs');
const express = require('express')
const cors = require('cors')
const https = require('https')
const path = require('path')
const {execSync} = require('child_process');
const fetch = require('node-fetch');
const app = express()
app.use(cors())
app.get('/getpoly', function(req, res){
const polypath = "polydata"
const url = "https://static.poly.pizza/"
const extensions = [".glb",".webp"]
const filepath = path.join(__dirname, polypath, req.query.id+extensions[0])
if (!fs.existsSync(filepath)){
execSync("wget "+url+req.query.id+extensions[0], {cwd:path.join(__dirname,polypath)})
execSync("wget "+url+req.query.id+extensions[1], {cwd:path.join(__dirname,polypath)})
}
res.send("received");
});
app.get('/voiceinput', function(req, res){
console.log(req.query.keyword)
sseSend(req.query.keyword)
res.send("received");
});
app.get('/search', async function(req, res){
const response = await fetch('https://api.poly.pizza/v1/search/'+req.query.keyword, {
headers: {'x-auth-token': 'e821ece91d1a43c1ac70299368a72b8a'}
});
const data = await response.json();
res.json(data);
});
app.get('/cabin', function(req, res){
res.sendFile(path.join(__dirname, 'cabin.html'))
});
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, 'index.html'))
});
app.get('/tabs', function(req, res){
res.json({"files":fs.readdirSync("tabs")})
});
// resulting in possibly getting /static/screens/1652811988.png
app.get('/screens', function(req, res){
res.json({"files":fs.readdirSync("screens")})
});
const container = "docker run --rm -e UID=$(id -u) -e GID=$(id -g) "
// could try losing priviledges instead, if possible
fs.watch("cabin.html", (eventType, filename) => {
if (eventType == "change") sseSend(filename+" modified")
})
// SSE to force reload client-side
var connectedClients = []
function sseSend(data){
connectedClients.map( res => {
console.log("notifying client") // seems to be call very often (might try to send to closed clients?)
res.write(`data: ${JSON.stringify({status: data})}\n\n`);
})
}
app.get('/streaming', (req, res) => {
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Content-Type', 'text/event-stream');
//res.setHeader('Access-Control-Allow-Origin', '*');
// alread handled at the nginx level
res.setHeader('Connection', 'keep-alive');
res.setHeader('X-Accel-Buffering', 'no');
res.flushHeaders(); // flush the headers to establish SSE with client
res.write(`data: ${JSON.stringify({event: "userconnect"})}\n\n`); // res.write() instead of res.send()
connectedClients.push(res)
// If client closes connection, stop sending events
res.on('close', () => {
console.log('client dropped me');
res.end();
});
});
// consider instead CloudInit so that it can be delegated to another machine
// keeping a pool of available machine would start with a single one
// namely that it is possible to run multiple containers on 1 instance, simultaneously or not.
containersSupportedByLanguage = {
bash: "debian ",
julia: "julia julia -E ",
python: "python python -c ",
// avoided file specific languages
// could be done by writing to a file in the container e.g /tmp/file.c then passing it as parameter
}
app.get('/invitereload', function(req, res){
sseSend("reload")
res.json({"res":"reload requested"})
})
app.get('/command', function(req, res){
var req = req.query.command
var foundContainer = containersSupportedByLanguage[req.split(" ")[0]]
var code = req.split(" ").slice(1).join(" ")
if (foundContainer)
res.json({"res":execSync(container+foundContainer+code).toString()})
else
res.json({"res":"language not supported"})
});
// could specify name, it then contiue instance
// ~/.openai-codex-test-xr
// potential alt backend to generate
app.get('/currenturl', function(req, res){
// could instead be the webxr page
let now = + new Date()
fs.appendFile('currentURL.txt', now+" "+req.query.url+" "+req.query.referrer+"\n", function (err) { if (err) throw err; });
// could be JSON instead
res.json({"status":"test"})
});
app.use('/static', express.static(path.join(__dirname, '.')))
// including currentURL.txt
const port = 7777
app.listen(port, () =>
console.log('listening on port', port)
);

3538
jxr.js

File diff suppressed because it is too large Load Diff

@ -18,6 +18,12 @@ Examples, tap to add, optionally modify and send :
<li><a onclick=replaceWithThisText(this)>jxr toggleVisibilityEntitiesFromClass('fot')</a></li> <li><a onclick=replaceWithThisText(this)>jxr toggleVisibilityEntitiesFromClass('fot')</a></li>
</ul> </ul>
Share this URL to the browser using e.g <a id="shareablelink" href="https://hmd.link">hmd.link</a> on the same WiFi network.
<hr>
<iframe width="100%" id="pastcommands"></iframe>
<hr>
Remote preview, if available :<br/>
<img height="400px" id="remotepreview" />
<hr> <hr>
<br> <br>
Documentation as : Documentation as :
@ -29,13 +35,33 @@ Documentation as :
<li>open-source <a href=https://git.benetou.fr/utopiah/text-code-xr-engine/issues>code repository</a> of the code and to make your own suggestions via issues. </li> <li>open-source <a href=https://git.benetou.fr/utopiah/text-code-xr-engine/issues>code repository</a> of the code and to make your own suggestions via issues. </li>
<li><a href=qrcode.png>QRcode</a> of this page to share with others also on mobile.</li> <li><a href=qrcode.png>QRcode</a> of this page to share with others also on mobile.</li>
<li><a href=https://fabien.benetou.fr/pub/home/future_of_text_demo/engine/?background=../content/future_of_text_symposium/HORN-2001-FutureOfHumanCognomeCL.png&fontcolor=lightgray>background</a> as URL parameter. Feel free to use your own content.</li> <li><a href=https://fabien.benetou.fr/pub/home/future_of_text_demo/engine/?background=../content/future_of_text_symposium/HORN-2001-FutureOfHumanCognomeCL.png&fontcolor=lightgray>background</a> as URL parameter. Feel free to use your own content.</li>
<li>to create a room to work together in, add or change the ?roomname=<b>YourRoomName</b> in the browser URL
</ul> </ul>
<script> <script>
function replaceWithThisText(element){ function replaceWithThisText(element){
document.querySelector("textarea").value = element.innerText document.querySelector("textarea").value = element.innerText
} }
const url = 'https://fabien.benetou.fr/PIMVRdata/FoT?action=' let pagename
const queryString = window.location.search
const urlParams = new URLSearchParams(queryString)
let = forcedPagename = urlParams.get('roomname')
forcedPagename?pagename=forcedPagename:pagename='FoT'
const baseURL = 'https://fabien.benetou.fr/PIMVRdata/'+pagename
const url = baseURL+'?action='
document.getElementById("pastcommands").src = baseURL+'?action=source'
document.getElementById("shareablelink").href = "https://hmd.link/?https://fabien.benetou.fr/pub/home/future_of_text_demo/engine/?roomname="+pagename
function refreshPreview(){
document.getElementById("remotepreview").src = "https://fabien.benetou.fr/uploads/PIMVRdata/"+pagename+".jpg#"+Date.now()
}
// seems to get cached properly, i.e only transferring when update
setInterval( _ => refreshPreview(), 1000)
function sendtovr(cabin){ function sendtovr(cabin){
text = document.querySelector("textarea").value text = document.querySelector("textarea").value
document.querySelector("textarea").value = '' document.querySelector("textarea").value = ''

Loading…
Cancel
Save