-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into ext-index-json
- Loading branch information
Showing
198 changed files
with
17,219 additions
and
5,191 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
name: Publish | ||
|
||
on: | ||
push: | ||
branches: ["master"] | ||
pull_request: | ||
|
||
permissions: | ||
pages: write | ||
id-token: write | ||
|
||
jobs: | ||
publish: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: 18 | ||
- run: npm i && node build.js | ||
- uses: actions/upload-pages-artifact@v1 | ||
with: | ||
path: build | ||
if: github.ref == 'refs/heads/master' && github.event_name == 'push' | ||
- uses: actions/deploy-pages@v2 | ||
if: github.ref == 'refs/heads/master' && github.event_name == 'push' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,9 @@ | ||
node_modules | ||
.DS_Store | ||
<<<<<<< HEAD | ||
package-lock.json | ||
.DS_Store | ||
build/ | ||
======= | ||
.DS_Store | ||
.vscode | ||
>>>>>>> master |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
const _ = require('lodash'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const EXTENSIONS_DIR = path.join(__dirname, 'extensions'); | ||
const OUT_DIR = path.join(__dirname, 'build'); | ||
|
||
const extensions = fs.readdirSync(EXTENSIONS_DIR).map(readExtension); | ||
|
||
try { fs.mkdirSync(OUT_DIR); } catch {} | ||
|
||
fs.writeFileSync(path.join(OUT_DIR, 'index.html'), renderTemplate('index.html', { extensions })); | ||
fs.copyFileSync('index.js', path.join(OUT_DIR, 'index.js')); | ||
|
||
// ------------------------------------------ | ||
|
||
function readExtension(name) { | ||
const dirpath = path.join(EXTENSIONS_DIR, name); | ||
const settings = JSON.parse(fs.readFileSync(path.join(dirpath, 'extension.json'), 'utf8')); | ||
const description = settings['description']; | ||
let linkUrl = ""; | ||
let scriptUrl = `https://extensions.netsblox.org/extensions/${name}/index.js`; | ||
|
||
if (!settings['useDev']) { | ||
linkUrl = `https://editor.netsblox.org/?extensions=[%22${scriptUrl}%22]#`; | ||
} else { | ||
linkUrl = `https://dev.netsblox.org/?extensions=[%22${scriptUrl}%22]#`; | ||
} | ||
|
||
return { | ||
name, | ||
displayName : settings['customName'] ?? name, | ||
description, | ||
linkUrl, | ||
scriptUrl, | ||
}; | ||
} | ||
|
||
function renderTemplate(name, data) { | ||
return _.template(fs.readFileSync(name, 'utf8'))(data).trim(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"description": "Use QR codes to pin sprites to the world!", | ||
"useDev": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
(async function () { | ||
|
||
let videoMirrored = false; | ||
|
||
const dictionaries = ['APRILTAG_16h5', 'APRILTAG_16h5_mini','APRILTAG_16h5_duo']; | ||
|
||
const localhost = window.location.search.includes('localhost'); | ||
const root = localhost? 'http://localhost:8000/' : 'https://extensions.netsblox.org/'; | ||
|
||
const rendererURL = root + 'extensions/AugmentedReality/js/renderModule.mjs'; | ||
const tagURL = root + 'extensions/AugmentedReality/js/tagHandler.mjs'; | ||
|
||
const renderModule = await import(rendererURL); | ||
const tagModule = await import(tagURL); | ||
|
||
function snapify(value) { | ||
if (Array.isArray(value)) { | ||
const res = []; | ||
for (const item of value) res.push(snapify(item)); | ||
return new List(res); | ||
} else if (typeof(value) === 'object') { | ||
const res = []; | ||
for (const key in value) res.push(new List([key, snapify(value[key])])); | ||
return new List(res); | ||
} else return value; | ||
} | ||
|
||
class AugmentedReality extends Extension { | ||
constructor(ide) { | ||
super('AugmentedReality'); | ||
this.ide = ide; | ||
} | ||
|
||
onOpenRole() { | ||
videoMirrored = this.ide.stage.mirrorVideo; | ||
} | ||
|
||
getMenu() { return { | ||
|
||
'Code Generator': function () { | ||
new ArucoGenMorph().popUp(world); | ||
}, | ||
|
||
}; } | ||
|
||
getCategories() { return []; } | ||
|
||
getPalette() { | ||
const blocks = [ | ||
new Extension.Palette.Block('ARCodeTracker'), | ||
new Extension.Palette.Block('ARCodeRender'), | ||
'-', | ||
new Extension.Palette.Block('ARCodeFlag'), | ||
new Extension.Palette.Block('ARCodeVisibleArray'), | ||
'-', | ||
new Extension.Palette.Block('ARCodeSetDictionary'), | ||
new Extension.Palette.Block('ARCodeDictionary').withWatcherToggle(), | ||
'-', | ||
new Extension.Palette.Block('ARCodeFlipVideo'), | ||
new Extension.Palette.Block('ARCodeFlipped').withWatcherToggle(), | ||
'-' | ||
]; | ||
return [ | ||
new Extension.PaletteCategory('sensing', blocks, SpriteMorph), | ||
new Extension.PaletteCategory('sensing', blocks, StageMorph), | ||
]; | ||
} | ||
|
||
getBlocks() { | ||
function block(name, type, category, spec, defaults, action) { | ||
return new Extension.Block(name, type, category, spec, defaults, action).for(SpriteMorph, StageMorph) | ||
} | ||
return [ | ||
block('ARCodeTracker', 'reporter', 'sensing', 'find AR code %s', [], function (image) { | ||
return this.runAsyncFn(async () => { | ||
|
||
image = image?.contents || image; | ||
if (!image || typeof(image) !== 'object' || !image.width || !image.height) | ||
throw TypeError('Expected an image as input'); | ||
|
||
const coordinates = await tagModule.getCoordinates(image); | ||
const res = await tagModule.transformCoordinates(coordinates, image); | ||
|
||
return snapify(res); | ||
|
||
}, { args: [], timeout: 10000 }); | ||
}), | ||
|
||
|
||
block('ARCodeRender', 'reporter', 'sensing', 'render %model on %s', ['box'], function (model, image) { | ||
return this.runAsyncFn(async () => { | ||
|
||
image = image?.contents || image; | ||
if (!image || typeof(image) !== 'object' || !image.width || !image.height){ | ||
throw TypeError('Expected an image as input'); | ||
} | ||
const res = await renderModule.renderScene(image, model); | ||
|
||
return new Costume(res); | ||
|
||
}, { args: [], timeout: 10000 }); | ||
}), | ||
|
||
|
||
block('ARCodeFlag', 'predicate', 'sensing', 'AR code %n visible in %s ?', [], function (value, image) { | ||
return this.runAsyncFn(async () => { | ||
|
||
image = image?.contents || image; | ||
if (!image || typeof(image) !== 'object' || !image.width || !image.height){ | ||
throw TypeError('Expected an image as input'); | ||
} | ||
|
||
console.log(value); | ||
value = value?.contents || value; | ||
|
||
if(typeof(value) === 'number'){ | ||
const temp = Array(); | ||
temp.push(value); | ||
value = temp; | ||
} | ||
if (!value || !value.length){ | ||
throw TypeError('Expected number or list'); | ||
} | ||
|
||
for(let i = 0; i < value.length; i++){ | ||
if(typeof(value[i]) === 'string' && !(value[i] = parseInt(value[i]))){ | ||
throw TypeError('list elements must be numbers'); | ||
} | ||
} | ||
|
||
const visible = await tagModule.isTagVisible(image, value); | ||
|
||
return snapify(visible); | ||
|
||
}, { args: [], timeout: 10000 }); | ||
}), | ||
|
||
|
||
block('ARCodeVisibleArray', 'reporter', 'sensing', 'All AR codes visible in %s', [], function (image) { | ||
return this.runAsyncFn(async () => { | ||
|
||
image = image?.contents || image; | ||
if (!image || typeof(image) !== 'object' || !image.width || !image.height){ | ||
throw TypeError('Expected an image as input'); | ||
} | ||
|
||
const visible = await tagModule.getVisibleTags(image); | ||
|
||
return snapify(visible); | ||
|
||
}, { args: [], timeout: 10000 }); | ||
}), | ||
|
||
|
||
block('ARCodeSetDictionary', 'command', 'sensing', 'set dictionary to %dictionaries', ['APRILTAG_16h5'], function (dict) { | ||
return this.runAsyncFn(async () => { | ||
|
||
console.log(dict, dictionaries.indexOf(dict) ); | ||
if(dictionaries.indexOf(dict) === -1){ | ||
return new Error(dict, 'is not a valid dictionary.'); | ||
} | ||
|
||
tagModule.setDictionary(dict) | ||
|
||
}, { args: [], timeout: 10000 }); | ||
}), | ||
|
||
|
||
block('ARCodeDictionary', 'reporter', 'sensing', 'dictionary', [], function () { | ||
return tagModule.getDictionary(); | ||
}), | ||
|
||
|
||
block('ARCodeFlipVideo', 'command', 'sensing', 'flip video', [], function () { | ||
return this.runAsyncFn(async () => { | ||
|
||
world.children[0].stage.mirrorVideo = !world.children[0].stage.mirrorVideo; | ||
videoMirrored = world.children[0].stage.mirrorVideo; | ||
|
||
}, { args: [], timeout: 10000 }); | ||
}), | ||
|
||
|
||
block('ARCodeFlipped', 'reporter', 'sensing', 'flipped?', [], function () { | ||
|
||
videoMirrored = world.children[0].stage.mirrorVideo; | ||
return snapify(videoMirrored); | ||
}) | ||
]; | ||
} | ||
|
||
|
||
getLabelParts() { | ||
function identityMap(s) { | ||
const res = {}; | ||
for (const x of s) res[x] = x; | ||
return res; | ||
} | ||
|
||
function unionMaps(maps) { | ||
const res = {}; | ||
for (const map of maps) { | ||
for (const key in map) res[key] = map[key]; | ||
} | ||
return res; | ||
} | ||
return [ | ||
new Extension.LabelPart('model', () => new InputSlotMorph( | ||
null, // text | ||
false, // numeric | ||
identityMap(['box', 'drum', 'piano']), | ||
true | ||
)), | ||
new Extension.LabelPart('dictionaries', () => new InputSlotMorph( | ||
null, // text | ||
false, // numeric | ||
identityMap(dictionaries), | ||
true | ||
)), | ||
]; | ||
} | ||
} | ||
|
||
const sources = [root + 'extensions/AugmentedReality/js/ui-morphs.js']; | ||
|
||
for(const source of sources){ | ||
const script = document.createElement('script'); | ||
script.class = 'ARUIScripts'; | ||
script.type = 'text/javascript'; | ||
script.src = source; | ||
script.async = false; | ||
script.crossOrigin = 'anonymous'; | ||
document.body.appendChild(script); | ||
} | ||
|
||
NetsBloxExtensions.register(AugmentedReality); | ||
disableRetinaSupport(); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import {OneEuroFilter} from 'https://esm.run/@david18284/[email protected]'; | ||
|
||
class singleExpFilter { | ||
constructor(startVals, alpha) { | ||
this.oldVals = startVals; | ||
this.a = alpha; | ||
} | ||
|
||
filter(...args) { | ||
const res = new Array(); | ||
const diff = this.oldVals.length - args.length; | ||
if(diff < 0){ | ||
for(let i = args.length; i > this.oldVals.length; i--){ | ||
this.oldVals.push(args[i-1]); | ||
console.log(this.oldVals) | ||
} | ||
} | ||
|
||
for(let i = 0; i < args.length; i++){ | ||
const newVal = (this.a * this.oldVals[i]) + ((1 - this.a) * args[i]); | ||
res.push(newVal); | ||
} | ||
this.oldVals = res; | ||
|
||
return res; | ||
} | ||
} | ||
|
||
export {singleExpFilter, OneEuroFilter} |
Oops, something went wrong.