didier

mise à jour arcs_browser, amélioration de la gestion des chemins

......@@ -46,7 +46,10 @@ module.exports = function (grunt) {
'src/application.js',
'src/arcs_module.js',
'src/exports.js'
]
],
'build/arcs_browser.js': [
'src/arcs_browser.js'
],
}
}
},
......@@ -90,6 +93,6 @@ module.exports = function (grunt) {
// Default task(s).
grunt.registerTask('default', ['jsdoc']);
grunt.registerTask('default', ['concat','uglify']);
grunt.registerTask('lint', ['jslint']);
};
......
{
"name": "ARCS",
"version": "0.1.0",
"description": "Augmented Reality Component System in web browser and node environment",
"main": "build/arcs.js",
"keywords": [
"Augmented",
"Reality"
],
"author": "Jean-Yves Didier",
"license": "GPL",
"dependencies": {
"requirejs": "*",
"three.js": "*",
"aruco": "https://js-aruco.googlecode.com/svn/trunk/src/aruco.js",
"cv": "https://js-aruco.googlecode.com/svn/trunk/src/cv.js"
}
}
......@@ -37,6 +37,7 @@ ARCS.isInRequire = function () {
return (typeof define === 'function' && define.amd);
};
/******************************************************************************
* Component implementation
* ***************************************************************************/
......
/*! ARCS 2014-08-22 */
/*! ARCS 2014-08-23 */
var ARCS=ARCS||{};if(ARCS.isInNode=function(){return"function"==typeof require&&require.resolve},ARCS.isInRequire=function(){return"function"==typeof define&&define.amd},ARCS.Component={SourceIsNotComponent:{message:"Source is not a component"},UndefinedSignal:{message:"Signal is not defined"},UndefinedSlot:{message:"Slot is not defined"},create:function(a,b,c){return void 0===a.prototype?(console.error("Cannot create such a component"),0):(a.prototype.slots=[],a.prototype.signals={},a.slotList=function(){return a.prototype.slots},a.prototype.slotList=function(){return a.prototype.slots},a.prototype.signalList=function(){var b,c=[];for(b in a.prototype.signals)c.push(b);return c},a.signalList=function(){return a.prototype.signalList()},a.prototype.emit=function(a){var b,c,d,e=Array.prototype.slice.call(arguments,1);for(b in this.signals[a])c=this.signals[a][b].func,d=this.signals[a][b].obj,c.apply(d,e)},a.slot=function(b,c){var d;if(b instanceof Array)for(d=0;d<b.length;d++)a.prototype.slots.push(b[d]);else a.prototype.slots.push(b),void 0!==c&&(a.prototype[b]=c)},a.signal=function(b){var c;if(b instanceof Array)for(c=0;c<b.length;c++)a.prototype.signals[b[c]]=1;else a.prototype.signals[b]=1},void 0!==b&&a.slot(b),void 0!==c&&a.signal(c),a)},check:function(a){return void 0===a.prototype?!1:void 0===a.prototype.signals||void 0===a.prototype.slots?!1:!0},connect:function(a,b,c,d){var e,f;if(void 0===a.signals)throw ARCS.Component.SourceIsNotComponent;if(void 0===a.signals[b])throw ARCS.Component.UndefinedSignal;if(void 0===c[d])throw ARCS.Component.UndefinedSlot;if(!a.hasOwnProperty("signals")){e=a.signals,a.signals={};for(f in e)a.signals[f]=[]}a.signals[b].push({obj:c,func:c[d]})},disconnect:function(a,b,c,d){var e;for(e=0;e<a.signals[b].length;e++)a.signals[b][e].obj===c&&a.signals[b][e].func===c[d]&&(a.signals[b].splice(e,1),e--)},invoke:function(a,b,c){var d=a[b];d.apply(a,c)},config:function(a,b){"function"==typeof a.config&&a.config(b)}},ARCS.Invocation=function(a,b,c){this.invoke=function(){var d=a[b];d.apply(a,c)}},ARCS.Invocation.cast=function(a,b){return new ARCS.Invocation(b[a.destination],a.slot,a.value)},ARCS.Connection=function(a,b,c,d){this.connect=function(){ARCS.Component.connect(a,b,c,d)},this.disconnect=function(){ARCS.Component.disconnect(a,b,c,d)}},ARCS.Connection.cast=function(a,b){return new ARCS.Connection(b[a.source],a.signal,b[a.destination],a.slot)},ARCS.Sheet=function(a){var b,c,d,e,f,g=[],h=[],i=[],j=[];b=function(){var a;for(a=0;a<g.length;a++)g[a].invoke()},c=function(){var a;for(a=0;a<h.length;a++)h[a].invoke()},d=function(){var a;for(a=0;a<i.length;a++)i[a].invoke()},e=function(){var a;for(a=0;a<j.length;a++)j[a].connect()},f=function(){var a;for(a=0;a<j.length;a++)j[a].disconnect()},this.activate=function(){b(),e(),c()},this.deactivate=function(){f(),d()},this.import=function(b){var c=0,d=ARCS.Invocation.cast,e=ARCS.Connection.cast;for(c=0;c<b.preconnections.length;c++)g.push(d(b.preconnections[c],a));for(c=0;c<b.postconnections.length;c++)h.push(d(b.postconnections[c],a));for(c=0;c<b.cleanups.length;c++)i.push(d(b.cleanups[c],a));for(c=0;c<b.connections.length;c++)j.push(e(b.connections[c],a))}},ARCS.Statemachine=function(a){var b="",c="",d={},e="";void 0!==a&&(b=a.initial,c=a.final,d=a.transitions,e=""),this.setInitialState=function(a){b=a,e=b},this.setFinalState=function(a){c=a},this.addTransition=function(a,b,c){d[a][b]=c},this.setToken=function(a){void 0!==d[e]&&void 0!==d[e][a]&&(e=d[e][a],this.emit("requestSheet",e),e===c&&this.emit("requestTermination"))},this.setTransitions=function(a){d=a},this.start=function(){e=b,this.emit("requestSheet",e)}},ARCS.Component.create(ARCS.Statemachine),ARCS.Statemachine.slot("setToken"),ARCS.Statemachine.signal("requestSheet"),ARCS.Statemachine.signal("requestTermination"),ARCS.Application=function(){var a,b,c,d={},e={},f={},g=[],h=[],i={},j=this,k=!1,l="";i.StateMachine=ARCS.Statemachine,a=function(){var a;if(ARCS.Application.currentApplication=j,ARCS.isInNode())for(a=0;a<g.length;a++)require("./"+g[a]+".js");else require(g)},this.loadLibrary=function(a,b){ARCS.Application.currentApplication=j,ARCS.isInNode()?(require("./"+a+".js"),void 0!==b&&b()):require(a,function(){void 0!==b&&b()})},this.getFactoryList=function(){return Object.keys(i)},this.getSheetList=function(){return Object.keys(e)},this.getFactory=function(a){return i[a]},this.getSheet=function(a){return e[a]},this.getComponentList=function(){return Object.keys(d)},this.getComponent=function(a){return d[a]},this.addSheet=function(a,b){e[a]=b},this.addComponent=function(a,b){d[a]=b},this.removeSheet=function(a){delete e[a]},this.removeComponent=function(a){delete d[a]},c=function(){var a,c=Object.keys(d);for(a=0;a<c.length;a++)if(void 0===i[d[c[a]].type])return;k=!1,console.log("[ARCS] All factories are operational !"),b()},b=function(){var a,b,c,g,h,k=Object.keys(d);for(a=0;a<k.length;a++)b=i[d[k[a]].type],c=new b(d[k[a]].value),d[k[a]]=c;for(g=d[f],f=g,h=Object.keys(e),a=0;a<h.length;a++)g=new ARCS.Sheet(d),g.import(e[h[a]],d),e[h[a]]=g;ARCS.Component.connect(f,"requestSheet",j,"setSheet"),ARCS.Component.connect(f,"requestTermination",j,"finish"),f.start()},this.setSheet=function(a){l&&e[l].deactivate(),l=a,e[l].activate()},this.finish=function(){l&&e[l].deactivate()},this.import=function(a){g=a.context.libraries,d=a.context.components,e=a.sheets,f=a.controller},this.setFactory=function(a,b){i[a]=b,k&&c()},this.setDependency=function(a){h[a]={}},this.start=function(){k=!0,a()}},ARCS.Application.setFactory=function(a,b,c){ARCS.Component.check(c)?a.setFactory(b,c):console.warn("[ARCS]",b,"is not a factory for an ARCS component.")},ARCS.Application.setDependency=function(a,b){a.setDependency(b)},ARCS.Component.create(ARCS.Application),ARCS.Application.slot("setSheet"),ARCS.Application.slot("finish"),arcs_module=function(a,b){var c,d,e=[],f=0;for("undefined"!=typeof module&&module.parent.exports&&(ARCS=module.exports),e[0]=ARCS,void 0===b&&(b=[]),c=function(b){var c,d;if(c="function"==typeof a?a.apply(this,b):a,void 0===c)throw new Error("[ARCS] Your module is undefined. Did you forget to export components?\nCode of module follows:\n"+a);for(d in c)ARCS.Application.setFactory(ARCS.Application.currentApplication,d,c[d])},d=0;d<b.length;d++)ARCS.isInNode()?e[d]=require(b[d]):(actualDep=b[d],void 0!==actualDep.name&&(shimConfig={shim:{}},shimConfig.shim[actualDep.name]={exports:actualDep.exports},void 0!==actualDep.deps&&(shimConfig.shim[actualDep.name].deps=actualDep.deps),require.config(shimConfig),actualDep=actualDep.name),require([actualDep],function(a){f++,e[f]=a,f>=b.length&&c(e)},function(a){console.error(JSON.stringify(a))}));(ARCS.isInNode()||0===b.length)&&c(e)},!ARCS.isInNode())var exports={};exports.Component=ARCS.Component,exports.Connection=ARCS.Connection,exports.Invocation=ARCS.Invocation,exports.Statemachine=ARCS.Statemachine,exports.Sheet=ARCS.Sheet,exports.Application=ARCS.Application,exports.isInNode=ARCS.isInNode,exports.isInRequire=ARCS.isInRequire,ARCS.isInRequire()&&define(exports);
\ No newline at end of file
......
arcs_module(
function (ARCS) {
var Animator;
Animator = ARCS.Component.create(
function() {
var paused = false;
var self=this;
var tick = function () {
if (paused === false) {
requestAnimationFrame(tick);
self.emit("onAnimationFrame");
}
}
this.start = function () {
paused = false;
tick();
};
this.stop = function () {
paused = true;
};
},
['start','stop'],
'onAnimationFrame'
);
return {Animator: Animator};
}
);
\ No newline at end of file
arcs_module(
function (ARCS, CV, AR) {
var ARUCODetector;
ARUCODetector = ARCS.Component.create(
function() {
var detector ;
detector = new AR.Detector();
this.detect = function (image) {
var markers = detector.detect(image);
this.emit("onMarkers",markers);
};
},
'detect',
['onMarkers']
);
return {ARUCODetector: ARUCODetector};
},
[
{name:"deps/cv/index.js", exports:"CV"},
{name:"deps/aruco/index.js", exports:"AR"}
]
);
\ No newline at end of file
arcs_module(
function(ARCS, three) {
var ARViewer;
ARViewer = ARCS.Component.create(
function () {
var container, sourceAspectRatio;
var renderer, scene2d, scene3d, camera2d, camera3d, videoSource, videoTexture;
var aspectRatioKept = true;
this.setWidgets = function(cName,vName) {
container = document.getElementById(cName);
videoSource = document.getElementById(vName);
var containerStyle = window.getComputedStyle(container);
var videoStyle = window.getComputedStyle(videoSource);
sourceAspectRatio = parseInt(videoStyle.width) / parseInt(videoStyle.height);
container.width = parseInt(containerStyle.width);
container.height = parseInt(containerStyle.height);
renderer = new THREE.WebGLRenderer();
renderer.setClearColorHex(0x000000, 1);
renderer.setSize(container.width, container.height);
container.appendChild(renderer.domElement);
scene2d = new THREE.Scene();
camera2d = new THREE.OrthographicCamera(-0.5, 0.5, 0.5, -0.5);
scene2d.add(camera2d);
scene3d = new THREE.Scene();
var theta = 30; //2*Math.atan2(container.height/2,focalLength)*180/3.14159265;
camera3d = new THREE.PerspectiveCamera(theta, container.width / container.height, 1, 1000);
scene3d.add(camera3d);
var _light = new THREE.DirectionalLight(0xffffff);
_light.position.set(0,5,5);
scene3d.add(_light);
videoTexture = new THREE.Texture(videoSource);
var geometry = new THREE.PlaneGeometry(1.0, 1.0, 0.0);
var material = new THREE.MeshBasicMaterial( {map: videoTexture, depthTest: false, depthWrite: false} );
var mesh = new THREE.Mesh(geometry, material);
var textureObject = new THREE.Object3D();
textureObject.position.z = -1;
textureObject.add(mesh);
scene2d.add(textureObject);
updateAspectRatio();
};
this.setFocal = function (focal) {
var theta = 2*Math.atan2(container.height/2,focal)*180/3.14159265;
camera3d.fov = theta;
camera3d.updateProjectionMatrix();
};
this.setSize = function(width, height) {
var W = width|0;
var H = height|0;
container.width = width;
container.height = height;
renderer.setSize(W,H);
updateAspectRatio();
/*camera3d.aspect = width/height;
camera3d.updateProjectionMatrix();
camera2d.aspect = width / height;
camera2d.updateProjectionMatrix();*/
};
this.keepAspectRatio = function (b) {
aspectRatioKept = b;
};
var updateAspectRatio = function () {
var cAspectRatio = container.width / container.height;
var actualWidth, actualHeight;
var xoff, yoff;
if (aspectRatioKept == true) {
// cameras have the source aspect ratio
camera2d.aspect = sourceAspectRatio;
camera2d.updateProjectionMatrix();
camera3d.aspect = sourceAspectRatio;
camera3d.updateProjectionMatrix();
// then, we should adjust viewport accordingly.
if (cAspectRatio > sourceAspectRatio) {
actualHeight = container.height;
actualWidth = actualHeight * sourceAspectRatio;
} else {
actualWidth = container.width;
actualHeight = actualWidth / sourceAspectRatio;
}
xoff = (container.width - actualWidth) / 2 ;
yoff = (container.height - actualHeight) / 2;
renderer.setViewport(xoff, yoff, actualWidth, actualHeight);
} else {
// for 3D camera, we will have to recompute the actual
// aspect ratio.
// but first reset viewport, just in case
renderer.setViewport(0, 0, container.width, container.height);
camera2d.aspect = cAspectRatio ;
camera2d.updateProjectionMatrix();
camera3d.aspect = cAspectRatio / sourceAspectRatio;
camera3d.updateProjectionMatrix();
}
};
this.addScene = function (scene) {
scene3d.add(scene);
};
this.removeScene = function (scene) {
scene3d.remove(scene);
};
this.render = function () {
videoTexture.needsUpdate = true;
renderer.autoClear = false;
renderer.clear();
renderer.render(scene2d, camera2d);
renderer.render(scene3d, camera3d);
};
},
['setWidgets','setFocal','setSize','addScene','removeScene','render','keepAspectRatio'],
[]
);
return {ARViewer: ARViewer};
},
[ 'deps/three.min.js']
);
\ No newline at end of file
/* ugly hack in order to display data in web page instead of console */
arcs_module(
function(ARCS) {
var Console;
Console = ARCS.Component.create(
function (id) {
if (id === undefined) {
return ;
}
window.console = {
timeRef: new Date().getTime(),
output : document.getElementById(id),
display: function(color,args) {
var s = document.createElement("span");
s.style.color=color;
var elapsed = (new Date().getTime() - this.timeRef);
s.innerHTML = '<span class="marker">' + (elapsed/1000).toFixed(3) + '</span>' + Array.prototype.join.call(args, ' ');
output.appendChild(s);
output.appendChild(document.createElement("br"));
},
log: function () {
this.display('green',arguments);
},
error: function () {
this.display('red',arguments);
},
warn: function () {
this.display('orange',arguments);
}
};
}
);
return { Console: Console};
}
);
\ No newline at end of file
/**
* Example of component declarations inside a module.
* You may look at the definitions of the following components:
* {@link Loop}
* @file
*/
arcs_module(function (ARCS) {
var Loop, DisplayInt, Sum;
/** @exports loop */
//console.log("loop: ", ARCS);
/**
* @class Loop
* @classdesc loop component creation using a compact style.
* This component iterates for a given number of times
*/
Loop = ARCS.Component.create(
function () {
/**
* Sets the number of times the component should iterate.
* It starts the iterations. At each iteration, a signal newIteration is
* emitted, then, at the end of the iterations, a signal sendToken is
* eventually triggered.
* @param n {numeric} number of iterations
* @function Loop#setIterations
*/
this.setIterations = function (n) {
var i;
for (i = 0; i < n; i++) {
console.log("Loop : emitting ", i);
this.emit("newIteration", i);
}
this.emit("sendToken", "end");
};
},
"setIterations", //slotList
["sendToken", "newIteration"] // signalList
);
/**
* @class DisplayInt
* @classdesc displayInt component creation using a variation with defined slots
* in the constructor (a slot is a function). DisplayInt will display an integer
* received on its display slot.
*/
DisplayInt = function () {
/**
* @param n {numeric} number to display
* @function DisplayInt#display
*/
this.display = function (n) {
console.log(" DisplayInt : " + n);
};
};
ARCS.Component.create(DisplayInt);
DisplayInt.slot("display");
/**
* @class Sum
* @classdec Sum is a component summing integers passed to its slot "add"
* and the result is sent back by signal "sum".
* This component is declared in two different phases: declaration of the
* constructor and declaration of the slot "add".
*/
Sum = function () {
this.total = 0;
};
ARCS.Component.create(Sum);
/**
* This slot adds its parameter to its internal sum and send it back by using
* the signal "sum".
* @param n {integer} add n to the internal sum of the component.
* @function Sum.add
*/
Sum.slot("add", function (n) {
this.total = this.total + n;
this.emit("sum", this.total); //console.log(" Total : " + this.total);
});
Sum.signal("sum");
// the anonymous function must return the components in one object:
// keys are factory names, value are actual constructors modified by
// ARCS.Component.create
return {Loop: Loop, DisplayInt: DisplayInt, Sum: Sum};
});
arcs_module(
function (ARCS, POS) {
var MarkerLocator;
MarkerLocator = ARCS.Component.create(
function () {
var square_pose = new POS.SquareFiducial();
this.setFocalLength = function (focalLength) {
square_pose.setFocalLength(focalLength);
};
this.setModelSize = function (modelSize) {
square_pose.setModelSize(modelSize);
};
this.setImageSource = function (id) {
var imageSource = document.getElementById(id);
if (id === undefined) {
return;
}
var imageSourceStyle = window.getComputedStyle(imageSource);
square_pose.setImageSize(parseInt(imageSourceStyle.width),parseInt( imageSourceStyle.height));
};
this.locateMarkers = function (markers) {
var k, pose;
for (k=0; k < markers.length; k++) {
corners = markers[k].corners;
markers[k].pose = square_pose.pose(corners);
}
this.emit("onLocatedMarkers",markers);
};
},
['locateMarkers','setFocalLength','setModelSize','setImageSource'],
['onLocatedMarkers']
);
return { MarkerLocator: MarkerLocator };
},
[ {name: "deps/pose/square_pose.js", exports: "POS"} ]
);
\ No newline at end of file
arcs_module(
function(ARCS) {
var MessageBox;
MessageBox = ARCS.Component.create(
function() {
var widget;
this.setWidget = function (wName) {
widget = document.getElementById(wName);
};
this.displayMessage = function (message) {
if (widget === undefined)
return ;
widget.innerHTML = message;
widget.style.display = 'block';
};
this.hide = function () {
if (widget !== undefined) {
widget.style.display = 'none';
}
};
},
['setWidget','displayMessage','hide'],
[]
);
return { MessageBox: MessageBox };
}
);
\ No newline at end of file
arcs_module(
function(ARCS) {
var Notificator;
Notificator = ARCS.Component.create(
function () {
var notificationZone;
var self=this;
this.setNotificationZone = function( id ) {
notificationZone = document.getElementById(id);
};
this.display = function (message, timeout) {
if (notificationZone === undefined) {
return;
}
notificationZone.innerHTML = message;
notificationZone.style.display = "block";
if (timeout !== undefined) {
setTimeout(function () { self.hide();}, timeout);
}
};
this.hide = function () {
if (notificationZone === undefined) {
return;
}
notificationZone.style.display = "none";
};
},
["setNotificationZone", "display", "hide"],
[]
);
return { Notificator: Notificator};
}
);
\ No newline at end of file
arcs_module(
function(ARCS, three) {
var Pong;
Pong = ARCS.Component.create(
function() {
var self=this;
var ground, ball, racket1, racket2, modelSize = 70.0;
var clock = new THREE.Clock();
var speed = 0.4;
var ballSpeed = new THREE.Vector3(-0.25, 0.25,0);
var score = [ 0,0 ];
this.createScene = function () {
var groundGeometry = new THREE.PlaneGeometry(2,1.5);
var groundMaterial = new THREE.MeshLambertMaterial( { color : 0x005060, transparent: true, opacity:0.7});
ground = new THREE.Object3D();
var groundRoot = new THREE.Mesh(groundGeometry, groundMaterial);
ground.add(groundRoot);
var filet = new THREE.Mesh(new THREE.CubeGeometry(0.05,1.5,0.2), new THREE.MeshLambertMaterial( {color: 0xffffff,transparent: true, opacity:0.7}));
filet.position.z = 0.1;
groundRoot.add(filet);
groundRoot.scale.x = modelSize;
groundRoot.scale.y = modelSize;
groundRoot.scale.z = modelSize;
var racketGeometry = new THREE.CubeGeometry(0.1, 0.4,0.2);
var racketMaterial1 = new THREE.MeshLambertMaterial( { color : 0xcccc00});
var racketMaterial2 = new THREE.MeshLambertMaterial( { color : 0xcc0000});
racket1 = new THREE.Object3D();
var subRacket1 = new THREE.Mesh(racketGeometry.clone(),racketMaterial1);
subRacket1.position.z = 0.1;
racket1.add(subRacket1);
racket2 = new THREE.Object3D();
var subRacket2 = new THREE.Mesh(racketGeometry.clone(),racketMaterial2);
subRacket2.position.z = 0.1;
racket2.add(subRacket2);
racket1.position.x = -1.05;
racket2.position.x = 1.05;
ball = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshLambertMaterial({color: 0xcc6600}));
ball.position.z = 0.1;
ball.position.x = 0.5;
groundRoot.add(ball);
groundRoot.add(racket1);
groundRoot.add(racket2);
//ground.position.z = -200;
this.emit("onSceneBuilt",ground);
this.emit("onMessage","Show ground marker in order to start game");
clock.start();
clock.getDelta();
resetBall();
};
var resetBall = function() {
clock.getDelta();
if ((score[0]+score[1])%2) {
ball.position.y = racket1.position.y;
ball.position.x = -1.0;
} else {
ball.position.y = racket2.position.y;
ball.position.x = 1.0;
}
// calculer ballSpeed en fonction de la position : direction : le centre
var vec2 = new THREE.Vector2(-ball.position.x, -ball.position.y );
vec2.normalize();
speed = 0.4;
ballSpeed.x = vec2.x*speed;
ballSpeed.y = vec2.y*speed;
};
var updateObject = function (object, rotation, translation){
/*****************************************************************************
Autre méthode préparant la matrice et l'appliquant
***************************************************************************/
object.position = new THREE.Vector3();
object.rotation = new THREE.Vector3();
object.updateMatrix();
var matrix = new THREE.Matrix4(
rotation[0][0], rotation[0][1], rotation[0][2], translation[0],
rotation[1][0], rotation[1][1], rotation[1][2], translation[1],
rotation[2][0], rotation[2][1], rotation[2][2], translation[2],
0 , 0, 0, 1
);
// stabilisation du quaternion
/*var quat = new THREE.Quaternion();
quat.setFromRotationMatrix(matrix.clone());
quaternions.push(quat.normalize().clone());
if (quaternions.length > MAX_NB_QUATERNIONS) {
quaternions.shift();
}
quat = quaternions[0].clone();
for (var i=1; i<quaternions.length; i++) {
quat.slerp(quaternions[i],1 - i/(i+1))
}
var tempmat = new THREE.Matrix4();
tempmat.setRotationFromQuaternion(quat);
tempmat.setPosition(new THREE.Vector3(translation[0],translation[1],translation[2]));*/
//object.applyMatrix(tempmat);
object.applyMatrix(matrix);
object.scale.x = 1.0;
object.scale.y = 1.0;
object.scale.z = 1.0;
};
this.updateScene = function (markers) {
var k;
if (markers.length > 0) {
for ( k = 0; k < markers.length; k++) {
if (markers[k].id == 17) {
updateObject(ground, markers[k].pose.rotation, markers[k].pose.position);
}
}
}
};
},
["createScene"],
["onSceneBuilt","onMessage"]
);
return { Pong: Pong};
},
[ 'deps/three.js/three.min.js' ]
);
\ No newline at end of file
arcs_module(function(ARCS) {
var LiveSource;
LiveSource = ARCS.Component.create(
function () {
var context, canvas, video, imageData;
var defaultWidth = 320;
var defaultHeight = 240;
var self = this;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
if (navigator.getUserMedia !== undefined){
navigator.getUserMedia({video:true},
function (stream) {
if (window.webkitURL) {
video.src = window.webkitURL.createObjectURL(stream);
} else if (video.mozSrcObject !== undefined) {
video.mozSrcObject = stream;
} else {
video.src = stream;
}
self.emit("onReady");
},
function(error){ console.error("Cannot initialize video component:", error.code); }
);
}
this.grabFrame = function () {
if ( context === undefined || canvas === undefined || video === undefined)
return;
if (video.readyState === video.HAVE_ENOUGH_DATA) {
context.drawImage(video, 0, 0, canvas.width, canvas.height);
imageData = context.getImageData(0, 0, canvas.width, canvas.height);
this.emit("onImage",imageData);
}
};
this.setSize = function(x,y) {
};
this.setWidgets = function (videoId, canvasId) {
video = document.getElementById(videoId);
canvas = document.getElementById(canvasId);
if (video === undefined || canvas === undefined) {
return;
}
context = canvas.getContext("2d");
var canvasStyle= window.getComputedStyle(canvas);
canvas.width=parseInt(canvasStyle.width);
canvas.height=parseInt(canvasStyle.height);
};
},
['grabFrame','setWidgets'],
['onReady','onImage']
);
return {LiveSource: LiveSource};
});
\ No newline at end of file
arcs_module(
function (ARCS) {
var WindowEvent;
WindowEvent = ARCS.Component.create(
function () {
var self= this;
window.onresize = function() {
self.emit("onResize",window.innerWidth, window.innerHeight);
};
},
[],
["onResize"]
);
return { WindowEvent: WindowEvent};
}
);
\ No newline at end of file
var POS = POS || {};
POS.SquareFiducial = function(modelSize, focalLength, width, height){
this.modelSize = modelSize;
this.focalLength = focalLength;
this.u0 = width/2.0;
this.v0 = height/2.0;
this.au = focalLength;
this.av = focalLength;
};
POS.SquareFiducial.prototype.pose = function(imagePoints){
var u0 = this.u0;
var v0 = this.v0;
var au = this.au;
var av = this.av;
var ua = imagePoints[0].x ;
var va = imagePoints[0].y ;
var ub = imagePoints[1].x ;
var vb = imagePoints[1].y ;
var uc = imagePoints[2].x ;
var vc = imagePoints[2].y ;
var ud = imagePoints[3].x ;
var vd = imagePoints[3].y ;
var detm = uc*vd - vc*ud + ud*vb - ub*vd + ub*vc - uc*vb;
var ZA = 1;
var ZB = (ua * (vc - vd) + va * (ud - uc) + (uc*vd - ud*vc))/detm ;
var ZC = (ua * (vb - vd) + va * (ud - ub) - (ud*vb - ub*vd))/detm ;
var ZD = (ua * (vb - vc) + va * (uc - ub) + (ub*vc - uc*vb))/detm ;
var r1 = ZC/ZA ;
var r2 = ZD/ZB ;
var tmp11 = (r1*(ua - u0)-(uc -u0))/au ;
var tmp12 = (r1*(va - v0)-(vc -v0))/av ;
var tmp21 = (r2*(ud - u0)-(ub -u0))/au ;
var tmp22 = (r2*(vd - v0)-(vb -v0))/av ;
var ZpA = -modelSize / Math.sqrt((r1-1)*(r1-1) + tmp11*tmp11 + tmp12*tmp12) ;
var ZpB = -modelSize / Math.sqrt((r2-1)*(r2-1) + tmp21*tmp21 + tmp22*tmp22) ;
var ZpC = r1 * ZpA;
var ZpD = r2 * ZpB;
var XA = ZpA/au *(ua-u0);
var XB = ZpB/au *(ub-u0);
var XC = ZpC/au *(uc-u0);
var XD = ZpD/au *(ud-u0);
var YA = ZpA/av *(va-v0);
var YB = ZpB/av *(vb-v0);
var YC = ZpC/av *(vc-v0);
var YD = ZpD/av *(vd-v0);
var position = [];
position[0] = -(XA + XB + XC + XD)/4.0;
position[1] = (YA + YB + YC + YD)/4.0;
position[2] = (ZpA + ZpB + ZpC + ZpD)/4.0;
var AC = [ - XC + XA, YC - YA, ZpC - ZpA ];
var DB = [ - XB + XD, YB - YD, ZpB - ZpD ];
var AB = [ XB - XA, YB - YA, ZpB - ZpA ];
var DA = [ XA - XD, YA - YD, ZpA - ZpD ];
var sV = this.sumVectors(AC,DB);
var dV = this.diffVectors(DB,AC);
var r1Star = this.scalVector(sV, 1.0/this.normVector(sV));
var r2Star = this.scalVector(dV, 1.0/this.normVector(dV));
var r3Star = this.crossProduct(r1Star,r2Star);
var rotation = [ [ r1Star[0], r2Star[0], r3Star[0] ],
[ r1Star[1], r2Star[1], r3Star[1] ],
[ r1Star[2], r2Star[2], r3Star[2] ]];
//console.log(rotation);
return new POS.SimplePose(position, rotation);
};
POS.SquareFiducial.prototype.sumVectors = function(a,b) {
return [ a[0]+b[0], a[1]+b[1], a[2]+b[2] ];
};
POS.SquareFiducial.prototype.diffVectors = function (a,b) {
return [ a[0]-b[0], a[1]-b[1], a[2]-b[2] ];
};
POS.SquareFiducial.prototype.scalVector = function(a,s) {
return [ a[0]*s, a[1]*s, a[2]*s ];
};
POS.SquareFiducial.prototype.normVector = function (a) {
return Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
};
POS.SquareFiducial.prototype.crossProduct = function(a,b) {
return [ a[1]*b[2] - a[2]*b[1],
a[2]*b[0] - a[0]*b[2],
a[0]*b[1] - a[1]*b[0]
];
};
POS.SimplePose = function(pos, rot) {
this.position = pos;
this.rotation = rot;
}
\ No newline at end of file
......@@ -13,7 +13,7 @@
"author": "Jean-Yves Didier",
"license": "GPL",
"devDependencies": {
"bower": "~1,3,9",
"bower": "~1.3.9",
"grunt": "~0.4.5",
"grunt-jslint": "~1.1.12",
"grunt-contrib-uglify": "~0.5.1",
......
......@@ -36,3 +36,4 @@ ARCS.isInNode = function () {
ARCS.isInRequire = function () {
return (typeof define === 'function' && define.amd);
};
......
/**
* Bootstrap for the ARCS engine in a browser environment.
* It relies on require.js to get the job done.
* @file
*/
console.log("Bootstrapping ARCS...");
var baseUrl, appDescription, requireMarkup, xhr;
requireMarkup = document.querySelector('[data-main]');
if (requireMarkup !== undefined) {
baseUrl = requireMarkup.dataset.baseUrl ;
appDescription = requireMarkup.dataset.arcsapp || "arcsapp.json";
}
// do not move these lines: xhr.open must be performed before require
// changes paths.
xhr = new XMLHttpRequest();
xhr.open('GET',appDescription,true);
xhr.overrideMimeType("application/json");
xhr.onerror = function (e) {
console.error("[ARCS] Failed to get app description (",appDescription,"):",e.target.status,e.message);
};
require(['arcs'], function (ARCS) {
//console.log(ARCS);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
try {
var applicationObject = JSON.parse(xhr.responseText);
if (baseUrl) {
require.config( { baseUrl: baseUrl });
}
var aap = new ARCS.Application();
aap.import(applicationObject);
aap.start();
} catch (e) {
console.error("[ARCS] Error while parsing JSON:",e);
}
}
};
xhr.send();
});
#!/usr/bin/env node
var ARCS = require('./arcs.js');
var application = require('./appli.json');
var aap = new ARCS.Application();
aap.import(application);
aap.start();
{
"context" : {
"libraries" : [ "components/loop","components/console"],
"components" : {
"loop": { "type": "Loop" },
"dint": { "type": "DisplayInt" },
"console": { "type":"Console", "value":"output"},
"statemachine" : {
"type": "StateMachine",
"value" : {
"initial": "start",
"final": "end",
"transitions" : {
"start" : { "end" : "start2"}
}
}
}
}
},
"controller" : "statemachine",
"sheets" : {
"start" : {
"preconnections" : [],
"postconnections" : [
{ "destination":"loop", "slot":"setIterations", "value":[4] }
],
"connections" : [
{ "source":"loop", "signal":"newIteration", "destination":"dint", "slot":"display" },
{ "source":"loop", "signal":"sendToken", "destination":"statemachine", "slot":"setToken" }
],
"cleanups" : []
},
"start2" : {
"preconnections" : [],
"postconnections" : [
{ "destination":"loop", "slot":"setIterations", "value":[8] }
],
"connections" : [
{ "source":"loop", "signal":"newIteration", "destination":"dint", "slot":"display" },
{ "source":"loop", "signal":"sendToken", "destination":"statemachine", "slot":"setToken" }
],
"cleanups" : []
}
}
}
\ No newline at end of file
<html>
<head>
<title>ARCS engine</title>
<script data-main="../../build/arcs_browser"
data-base-url="../.."
data-arcsapp="arcsapp.json"
src="../../deps/requirejs/require.js">
</script>
</head>
<body>
<h1>ARCS in Web Browser</h1>
<div style="height:100px; overflow: auto; border: solid 1px navy;">
<p id="output" style="margin: 5px; padding: 5px;"></p>
<div>
</body>
</html>
body {
font-family: sans-serif;
padding: 0px;
margin: 0px;
}
#canvas {
width: 320px;
height: 240px;
display: none;
}
#contents {
position: absolute;
z-index: 10;
left: 0px;
top: 0px;
margin: 0px;
height: 100%;
width: 100%;
overflow: auto;
}
#notification {
position: absolute;
left: 50%;
margin-left: -25%;
top: 50%;
margin-top: -2em;
text-align: center;
width: 50%;
bottom: 50%;
display: none;
font-size: 200%;
font-weight: bold;
color: white;
background: navy;
/*height: 2em;*/
opacity: 0.6;
display: none;
}
#output {
position: absolute;
bottom: 10px;
margin: 10px;
padding: 10px;
border: solid 1px black;
color: white;
background: navy;
height: 4em;
opacity: 0.6;
width: 50%;
overflow: auto;
font-weight: bold;
scroll-top: false;
}
.central {
position: absolute;
text-align: center;
margin: 10px;
left: auto;
right: auto;
top: auto;
bottom: 50%;
}
.marker {
display: inline-block;
width: 6em;
padding-right: 1em;
text-align: right;
}
#container {
left:0px;
top:0px;
width: 100%;
height: 100%;
}
{
"context" : {
"libraries" : [ "components/video", "components/animator",
"components/arucodetector", "components/arviewer",
"components/windowevent", "components/messagebox",
"components/pong",
"components/markerlocator",
"components/console", "components/notificator"],
"components" : {
"video": { "type": "LiveSource" },
"animator": { "type": "Animator" },
"detector": { "type": "ARUCODetector" },
"viewer": { "type": "ARViewer"},
"windowresize": { "type": "WindowEvent"},
"locator": { "type":"MarkerLocator"},
"messagebox": { "type": "MessageBox"},
"pong" : { "type": "Pong"},
"console" : { "type": "Console", "value":"output"},
"notificator" : { "type": "Notificator"},
"statemachine" : {
"type": "StateMachine",
"value" : {
"initial": "start",
"final": "end",
"transitions" : {
"start" : { "end" : "end"}
}
}
}
}
},
"controller" : "statemachine",
"sheets" : {
"start" : {
"preconnections" : [
{ "destination":"video", "slot":"setWidgets", "value":["video", "canvas"] },
{ "destination":"locator", "slot":"setImageSource", "value":["canvas"]},
{ "destination":"notificator", "slot":"setNotificationZone", "value":["notification"]},
{ "destination":"viewer", "slot":"keepAspectRatio", "value":[1]}
],
"postconnections" : [
{ "destination":"viewer", "slot":"setWidgets", "value":["container", "video"]},
{ "destination":"viewer", "slot":"setFocal", "value":[600]},
{ "destination":"pong", "slot":"createScene", "value":[] }
],
"connections" : [
{ "source": "video", "signal": "onImage", "destination": "detector", "slot": "detect"},
{ "source": "video", "signal": "onReady", "destination": "animator", "slot": "start"},
{ "source": "animator", "signal": "onAnimationFrame", "destination": "video", "slot": "grabFrame"},
{ "source": "windowresize", "signal": "onResize", "destination": "viewer", "slot":"setSize"},
{ "source": "video", "signal": "onImage", "destination": "viewer", "slot": "render"},
{ "source": "pong", "signal": "onSceneBuilt", "destination": "viewer", "slot": "addScene"},
{ "source": "detector", "signal": "onMarkers", "destination": "locator", "slot": "locateMarkers"},
{ "source": "locator", "signal": "onLocatedMarkers", "destination": "pong", "slot": "updateScene"},
{ "source": "pong", "signal": "onMessage", "destination": "notificator", "slot": "display"}
],
"cleanups" : []
},
"end" : {
"preconnections" : [],
"postconnections" : [],
"connections" : [],
"cleanups" : []
}
}
}
\ No newline at end of file
<html>
<head>
<title>ARCS: Pong experiment</title>
<link type="text/css" rel="stylesheet" href="arcs.css">
<script data-main="../../build/arcs_browser"
data-base-url="../.."
data-arcsapp="arcsapp.json"
src="../../deps/requirejs/require.js">
</script>
</head>
<body>
<video id="video" width=320 height=240 autoplay="true" style="display: none;"></video>
<canvas id="canvas"></canvas>
<div id="container" ></div>
<div id="contents">
<p id="output" >Console log:<br/></p>
<div id="notification"></div>
</div>
</body>
</html>