Skip to content

Instantly share code, notes, and snippets.

@kevint2u
Created April 23, 2014 06:14
Show Gist options
  • Save kevint2u/11204396 to your computer and use it in GitHub Desktop.
Save kevint2u/11204396 to your computer and use it in GitHub Desktop.
[wearscript] AR script 2
<html style="width:100%; height:100%; overflow:hidden">
<head>
<!-- You can include external scripts here like so... -->
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.0/zepto.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>-->
</head>
<body style="width:100%; height:100%; overflow:hidden; margin:0">
<canvas id="canvas" width="640" height="360" style="display:block"></canvas>
<script>
// Constants
var DBG = true;
var i = 0;
var secondLineText = "Second line";
var wakeTime;
var timeDeltaText = "";
var wakeInterval = 300000;
var timeNow = new Date().getTime();
var tillNextWake = Math.floor(wakeInterval / 1000);
var deltasMaxLength = 10;
var timeDeltas = [];
var woken;
var timeDeltaTitleText = "Between Last Wakes:";
var batteryLevelText = "Battery level: ";
var showDashboard = true;
var cameraCB;
var showImageInterval = 10000;
var pauseFudgeFactor = 500;
var videoLength = 10;
// AUXILIARY FUNCTIONS
function drawModeName(name) {
upperBase = 40;
context.fillStyle = "rgb(200,200,200)";
context.font = '28pt Calibri';
context.textAlign = 'left';
context.fillText(name, 10, upperBase);
}
function drawSecondLine(name) {
upperBase = 90;
context.fillStyle = "rgb(200,200,200)";
context.font = '28pt Calibri';
context.textAlign = 'left';
context.fillText(name, 10, upperBase);
}
function drawTextLine(text, _number) {
var number = _number;
if ( number === undefined ) {
console.log("No number given, setting to 0");
number = 0;
}
baseline = 40 + 50 * number;
context.fillStyle = "rgb(200,200,200)";
context.font = '28pt Calibri';
context.textAlign = 'left';
context.fillText(text, 10, baseline);
}
function clearCanvas() {
context.fillStyle = "rgb(0, 0, 0)";
context.fillRect(0, 0, 640, 360);
}
Date.prototype.today = function () {
return ((this.getDate() < 10)?"0":"") + this.getDate() +"/"+(((this.getMonth()+1) < 10)?"0":"") + (this.getMonth()+1) +"/"+ this.getFullYear();
}
Date.prototype.timeNow = function () {
return ((this.getHours() < 10)?"0":"") + this.getHours() +":"+ ((this.getMinutes() < 10)?"0":"") + this.getMinutes() +":"+ ((this.getSeconds() < 10)?"0":"") + this.getSeconds();
}
// MAIN
function draw() {
if (showDashboard) {
clearCanvas();
drawTextLine(firstLineText, 0 );
drawTextLine(secondLineText, 1 );
drawTextLine(tillNextWake, 2 );
drawTextLine(timeDeltaTitleText, 3 );
drawTextLine(timeDeltaText, 4 );
drawTextLine(batteryLevelText, 5 );
}
// list of last times
// drawModeName("" + i);
// drawSecondLine(secondLineText);
}
currentTimeString = function () {
return new Date().today() + " @ " + new Date().timeNow();
}
timeString = function(date) {
return date.today() + " @ " + date.timeNow();
}
function server() {
if (!DBG) WS.serverConnect('0.0.0.0', null);
WS.log('Welcome to WearScript');
WS.say('Welcome to WearScript');
WS.sound('SUCCESS');
WS.dataLog(true, false, 1);
WS.sensorOn("battery", 1, function (data) {
console.log("Got battery callback");
console.log(JSON.stringify(data));
batteryLevelText = "Battery Level: " + Math.round(data.values[0] * 100) + "%";
if (Math.round(data.values[0] * 100) <= 20) WS.say("Low battery.");
batteryLevelText += " @ " + new Date(parseInt(data.timestamp * 1000)).timeNow();
});
clearCanvas();
drawModeName("Rock and roll");
var updateCurrentTime = function() {
var date = new Date();
timeNow = date.getTime();
tillNextWake = "Till Next Wake: " + Math.ceil((wakeInterval - (timeNow - wakeTime)) / 1000);
//firstLineText = currentTimeString();
firstLineText = timeString(date);
draw();
}
var updateWakeTime = function () {
if (wakeTime != undefined) {
woken = true;
}
var date = new Date();
lastWakeTime = wakeTime;
wakeTime = date.getTime();
wakeTimeString = timeString(date);
wakeTimeDelta = wakeTime - lastWakeTime;
if (woken) {
timeDeltas.unshift(Math.floor(wakeTimeDelta / 1000));
if (timeDeltas.length > deltasMaxLength) timeDeltas.pop();
}
timeDeltaText = JSON.stringify(timeDeltas);
secondLineText = "Last Wake: " + currentTimeString();
//thirdLineText = "Time since last wake: ";
//secondLineText = "current time";
draw();
}
updateCurrentTime();
updateWakeTime();
// WS.cameraOn(0.5, 480, 640, cameraCB);
setInterval(updateCurrentTime, 1000);
var img = new Image();
img.onload = function() {
context.drawImage(img, 0, 0);
}
cameraCB = function(data) {
WS.log("Got camera callback.");
showDashboard = false;
WS.cameraOff();
//context.drawImage(img, 0, 0);
img.src = 'data:image/jpg;base64,' + data;
setTimeout(function() {
showDashboard = true;
//WS.liveCardCreate(true, .45);
WS.activityDestroy();
}, showImageInterval);
//WS.say("Creating live card");
//WS.liveCardDestroy();
}
var periodic = function() {
WS.say("Cheese balls");
WS.wake();
WS.activityCreate();
WS.displayWebView();
// secondLineText = "LastWake: " + new Date().today() + " @ " + new Date().timeNow();
updateWakeTime();
WSRAW.recordWSVideo(videoLength);
WS.activityDestroy();
//setTimeout(function() {WS.cameraOn(0.5, 480, 640, cameraCB);}, pauseFudgeFactor);
}
setInterval( periodic, wakeInterval );
// Below this are more examples, uncomment to use them
WS.liveCardCreate(true, .2);
WSRAW.recordWSVideo(videoLength);
/*
var tree = new WS.Cards();
tree.add('Body text', 'Footer text', function () {WS.say('selected')}, function () {WS.say('tapped')}, 'Menu0', function () {WS.say('menu0')}, 'Menu1', function () {WS.say('menu1')});
tree.add('Body text', 'Footer text', (new WS.Cards()).add('Child0', '0').add('Child1', '1'));
WS.cardTree(tree);
WS.displayCardTree();
*/
/*
WS.speechRecognize('Say Something', function (data) {
WS.log('speech: ' + data);
WS.say('you said ' + data);
});
*/
//WS.cameraPhoto();
//WS.cameraVideo();
//WS.cameraOff();
//WS.shutdown();
}
function main() {
if (WS.scriptVersion(1)) return;
context = document.getElementById('canvas').getContext("2d");
WS.serverConnect('{{WSUrl}}', server);
}
window.onload = main;
</script>
</body>
</html>
<html style="width:100%; height:100%; overflow:hidden">
<body style="width:100%; height:100%; overflow:hidden; margin:0">
<canvas id="offscreen" width="640" height="360" style="display:hidden"></canvas>
<script>
function drawCircle(x, y,tag) {
var width = 640;
var height = 360;
var c = document.getElementById("offscreen");
var ctx = c.getContext("2d");
ctx.fillStyle = 'black'
ctx.fillRect(0, 0, width, height);
for (var i = 0; i < 50; i++) {
ctx.beginPath();
ctx.arc(x,y,10+15*i,0,2*Math.PI);
ctx.closePath();
ctx.strokeStyle = 'red'
ctx.stroke();
}
ctx.font="20px Georgia";
ctx.fillStyle="white"
ctx.fillText(tag,x,y);
var dataURL = c.toDataURL();
return dataURL; // Need to strip prefix?
}
function rangeToTag(t) {
// Crude distance estimation, based on the focal length of the glass
// camera and the diagonal distance of the AR fiducial. This is only valid
// when looking *head-on* at the the fiducial marker.
var x0 = t[1];
var y0 = t[2];
var x1 = t[5];
var y1 = t[6];
var distPx = Math.sqrt((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1));
var focalLengthPx = 2968.5/8; // Focal length, for 640x360 view
var distMeters = 0.287; // Diagonal size of AR tags printed out.
var rangeMeters = distMeters * focalLengthPx / distPx;
return rangeMeters;
}
function printTagName(x,y,tag) {
var width = 640;
var height = 360;
WS.log("Tag" + tag);
var c = document.getElementById("offscreen");
var ctx = c.getContext("2d");
ctx.font="20px Georgia";
ctx.fillStyle="blue"
ctx.fillText(tag,x,y);
}
function getData() {
var c = document.getElementById("offscreen");
var ctx = c.getContext("2d");
var dataURL = c.toDataURL();
return dataURL; // Need to strip prefix?
}
function printClear() {
var width = 640;
var height = 360;
var c = document.getElementById("offscreen");
var ctx = c.getContext("2d");
ctx.fillStyle = 'blue'
ctx.fillRect(0, 0, width, height);
var dataURL = c.toDataURL();
return dataURL;
}
function setImage(imageb64) {
var imageObj = new Image();
imageObj.onload = function() {
var c = document.getElementById("offscreen");
var ctx = c.getContext("2d");
ctx.drawImage(imageObj, 0, 0);
};
imageObj.src = 'data:image/jpg;base64,' + imageb64;
}
function cb(h) {
WS.log(h)
}
function HMultPoint(a, b) {
var c = [0, 0, 0];
c[2] = a[6] * b[0] + a[7] * b[1] + a[8];
c[0] = (a[0] * b[0] + a[1] * b[1] + a[2]) / c[2];
c[1] = (a[3] * b[0] + a[4] * b[1] + a[5]) / c[2];
return [c[0], c[1]];
}
function server() {
WS.cameraOn(1, 360, 640);
WS.displaywarpView();
var arModel = 'kYKia3eApG5hbWW4cGljYXJ1cy5BUk1hcmtlckRldGVjdG9y';
WS.cvInit(function () {
WS.log('inited');
var model = new WS.PicarusModel(arModel, function () {
WS.say('Loaded');
model.processWarpTargets(function (tags) {
tags = msgpack.unpack(tags)[0];
WS.log('Got tags: ' + JSON.stringify(tags));
var numTags = tags.length / 9;
WS.say('Got ' + numTags + ' tags')
//printClear();
//if (tags.length) {
//WS.say(tags[0].length + " tags. Range, " + Math.round(rangeToTag(tags[0])*10)/10. + " meters.");
console.log('hi');
for(var cnt=0; cnt < numTags; cnt++) {
var t = tags.slice(cnt * 9, (cnt + 1) * 9)
var x = (t[1] + t[3] + t[5] + t[7]) / 4;
var y = (t[2] + t[4] + t[6] + t[8]) / 4;
console.log(x);
console.log(y);
printTagName(x, y,t[0]);
}
WSRAW.warpSetOverlay(getData().split(',')[1]);
});
});
});
/*WS.subscribe('warptags:sample', function (channel, tags) {
})*/
function sample() {
WS.warpPreviewSampleGlass(function (data) {
WS.log('got data');
setImage(data);
});
}
WS.dataLog(false, true, .15);
WS.gestureCallback('onGesture', function (gesture) {
if (gesture === 'TAP') {
WS.sound('SUCCESS');
sample();
}
});
}
function main() {
if (WS.scriptVersion(1)) return;
WS.serverConnect('{{WSUrl}}', 'server');
}
window.onload = main;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment