diff --git a/analysis/dbrequests.js b/analysis/dbrequests.js index 0f41b1c..8fe3570 100644 --- a/analysis/dbrequests.js +++ b/analysis/dbrequests.js @@ -55,8 +55,8 @@ if (!Array.prototype.reduce) { } var pg = require('pg'); -var pgc = require('../../private.js'); -var Log = require('../../lib/NodeLog.js'); +var pgc = require('../private.js'); +var Log = require('../lib/NodeLog.js'); var async = require('async'); /** diff --git a/analysis/initScene.js b/analysis/initScene.js new file mode 100644 index 0000000..ef09cb3 --- /dev/null +++ b/analysis/initScene.js @@ -0,0 +1,206 @@ +function Vector3(x, y, z) { + this.x = x; + this.y = y; + this.z = z; +} + +function createRecommendation(position, target) { + return { + position: position, + target: target + } +} + +module.exports.createPeachRecommendations = function(width, height, rec) { + var recos = []; + + recos.push( + createRecommendation( + new Vector3(-4.318087280217455,2.8007613084859253,1.5193437897009336), + new Vector3(19.04561491034525,-11.893857635144567,-27.432436709124897) + ), + createRecommendation( + new Vector3(-6.257935852456958,2.093463399444844,-7.017904350052701), + new Vector3(25.88235261144178,-14.928107421416371,-23.669270187358173) + ), + createRecommendation( + new Vector3(9.807915641060413,1.599662719763407,1.3278972044453563), + new Vector3(-16.404678696813406,-19.467671402046243,-20.330065097629618) + ), + createRecommendation( + new Vector3(8.593027849546461,2.341563400341173,-10.381814971692629), + new Vector3(-23.363783342561,-18.42997444113019,1.755130036517576) + ), + createRecommendation( + new Vector3(6.422879729593868,3.06821771913114,-4.664407524854438), + new Vector3(-15.171947266786782,-24.05662912371069,-24.6119921091785) + ), + createRecommendation( + new Vector3(10.155340138717236,6.631665534350463,-5.574670324070963), + new Vector3(-20.721131232754608,-9.966488352174423,-24.839789145555535) + ), + createRecommendation( + new Vector3(-6.548087435820877,6.193523907010158,-3.627483164733988), + new Vector3(16.752484674681824,-11.466024392567634,-30.926268727065203) + ) + ); + + return recos; +}; + +module.exports.createBobombRecommendations = function(width, height) { + var recos = []; + + recos.push( + createRecommendation( + new Vector3(22.81974561274774,23.728166674516967,-23.50757340835654), + new Vector3(27.45807332015761,4.665400463440239,11.350666083340474) + ), + createRecommendation( + new Vector3(4.512241856806823,19.542184465749266,-21.6277607809511), + new Vector3(-16.322542559288507,6.552211144388629,9.95027512132075) + ), + createRecommendation( + new Vector3(3.7236872166568786,11.547542009941035,7.743737673292326), + new Vector3(11.778234958188895,3.590700880634021,46.107951987185814) + ), + createRecommendation( + new Vector3(17.51280189401515,22.651733665113007,32.1344270612909), + new Vector3(-17.09689080040822,6.202382514300329,20.663244981189692) + ), + createRecommendation( + new Vector3(-12.00887621348721,25.979463024729398,37.05007506157123), + new Vector3(-6.018501236275041,9.054329353511584,1.3057712098552159) + ), + createRecommendation( + new Vector3(-9.467050533255307,30.088761873923442,28.727671886170505), + new Vector3(-39.96888839418932,10.735797300746938,11.549178083317258) + ), + createRecommendation( + new Vector3(-30.2051081707108,44.36298906887656,35.77746943907231), + new Vector3(-16.54652438711394,19.924260316887796,7.208401795672) + ), + createRecommendation( + new Vector3(-52.44058113318328,27.688845222097196,28.78379753054363), + new Vector3(-21.760754138048632,11.37128676599093,8.972550684871294) + ), + createRecommendation( + new Vector3(-32.51800140864256,30.21720398723899,-2.2695677339908484), + new Vector3(-4.161205509090522,12.002869652965245,-23.813247806588592) + ), + createRecommendation( + new Vector3(-24.869080810307878,24.29489455015078,-48.36061039882109), + new Vector3(-16.792809571743753,4.99108388972596,-14.270483721620096) + ), + createRecommendation( + new Vector3(24.213548666073923,19.67561630411922,-34.50857509027397), + new Vector3(35.82557966946029,-3.7247748037464845,-4.21695195820471) + ) + ); + + return recos; + +}; + +module.exports.createWhompRecommendations = function(width, height) { + var recos = []; + + recos.push( + createRecommendation( + new Vector3(-9.183036772081453,3.0766349039394916,-10.631680881366988), + new Vector3(23.306020365359252,-17.647069934844886,0.09162197153512075) + ), + createRecommendation( + new Vector3(-11.38099373489364,4.5301496570861906,-8.680448599715064), + new Vector3(14.218919789700848,-9.33335658285769,18.75033014002037) + ), + createRecommendation( + new Vector3(-2.989815984700766,4.808626217924975,-10.034026966216151), + new Vector3(10.476586340125928,-16.676909597940817,20.90183828968142) + ), + createRecommendation( + new Vector3(8.739544533019469,4.57426117700506,-10.246457362075027), + new Vector3(-7.420839007222124,-3.599225856368915,25.419157921381895) + ), + createRecommendation( + new Vector3(11.215995865644405,5.100092599462174,5.157320142222007), + new Vector3(-17.739835597264776,-0.18398638725505378,-21.92843872759245) + ), + createRecommendation( + new Vector3(-7.511384733151988,6.569117611729606,13.141669794236272), + new Vector3(11.160164249947218,-9.709441800002363,-18.26504544391685) + ), + createRecommendation( + new Vector3(0.6846182375474082,13.717750177060871,-3.878598405225172), + new Vector3(14.749877291524962,-2.4709024675402205,29.886709431324352) + ), + createRecommendation( + new Vector3(-5.628153398727744,10.292624364958618,-0.15423059405658932), + new Vector3(21.830921092510273,-1.2953399806023977,26.523818630177338) + ), + createRecommendation( + new Vector3(-3.2817952119549387,8.014848779391615,-6.822708271111021), + new Vector3(13.01307852868053,-12.339101451861252,23.511988031315184) + ), + createRecommendation( + new Vector3(7.805400745480024,9.185305503970957,11.919240783005307), + new Vector3(-9.777424733344784,-5.603738432878275,-20.8241314870455) + ) + ); + + return recos; +}; + +module.exports.createMountainRecommendations = function(width, height) { + var recos = []; + + recos.push( + createRecommendation( + new Vector3(-32.55470573684094,29.55322138048939,-17.59574199842915), + new Vector3(-2.6530082773148784,13.825746134447998,3.8176886333992925) + ), + createRecommendation( + new Vector3(12.100158831224025,26.077021046580555,-23.46706423961512), + new Vector3(-13.67308964482135,11.574392013301521,3.4664356093669397) + ), + createRecommendation( + new Vector3(16.801072439731502,20.09189357317027,14.011145351254608), + new Vector3(-13.195470192683612,-4.443428210365667,4.1002717732066145) + ), + createRecommendation( + new Vector3(-16.879597154353956,28.027328987174787,23.2120994633039), + new Vector3(-6.922498345966725,7.02598138495819,-9.342463691665415) + ), + createRecommendation( + new Vector3(24.007103291390404,-10.579535956547192,-30.14734612569218), + new Vector3(5.7117612503958135,-23.76440846717267,2.8895967789043198) + ), + createRecommendation( + new Vector3(-12.257327932010769,-12.526038797341444,-36.05191812094985), + new Vector3(0.19983861525745894,-20.375474197075437,1.1395508675026633) + ), + createRecommendation( + new Vector3(16.426221516558684,4.064315972012067,-19.84262328062327), + new Vector3(-16.71831968665397,-6.887503610208118,-0.3106741646994493) + ), + createRecommendation( + new Vector3(44.96685545730114,-6.205815468014633,-0.5730193999373548), + new Vector3(7.154826082461277,-13.661034435943513,10.135395267812534) + ), + createRecommendation( + new Vector3(-33.00196818869413,20.41721604790279,38.566026084656386), + new Vector3(-11.64931778228043,-1.846673249080439,13.102649364489118) + ), + createRecommendation( + new Vector3(-53.183958472088925,-8.39869666868559,28.102017801758063), + new Vector3(-15.679778341058253,-11.462793205152831,14.53559656716515) + ), + createRecommendation( + new Vector3(27.528666741865862,-9.63536430265764,46.43021804402408), + new Vector3(1.1519844626168592,-18.896564555304533,17.820765028981576) + ) + ); + + return recos; +}; + diff --git a/analysis/length.js b/analysis/length.js new file mode 100755 index 0000000..a583fd9 --- /dev/null +++ b/analysis/length.js @@ -0,0 +1,105 @@ +#!/usr/bin/node +var lib = require('./lib.js'); +var r = require('./initScene.js'); + +var reco = [ + r.createPeachRecommendations(), + r.createBobombRecommendations(), + r.createMountainRecommendations(), + r.createWhompRecommendations() +]; + +function distanceBetweenPoints(pt1, pt2) { + return ( + Math.sqrt( + (pt2.x - pt1.x) * (pt2.x - pt1.x) + + (pt2.y - pt1.y) * (pt2.y - pt1.y) + + (pt2.z - pt1.z) * (pt2.z - pt1.z) + ) + ); +} + +function main(path) { + + var db = lib.loadFromFile(path); + var groups = lib.makeGroups(db); + + // Erase groups that are not usable + var invalid = 0; + groups = groups.filter(function(elt) { + + // An elt is valid if it contains at least 2 exp, BaseRecommendation included + if (elt.length > 1 && elt.find(function(e) { return e.recommendation_style[4] === 'B'; }) !== undefined) { + return true + } else { + invalid++; + return false; + } + + }); + + var percentSum = 0; + var eltNum = 0; + + for (var i = 0; i < db.experiments.length; i++) { + + var exp = db.experiments[i]; + + if (exp.coinCombination.scene_id === 1 || exp.recommendation_style[4] === 'B' || !exp.finished || lib.coinsGot(exp) < 6) { + continue; + } + + eltNum++; + + var distance = 0; + var distanceWithReco = 0; + + + var j = 0; + + while (exp.elements.events[j].position === undefined) { j++; }; + + var startPosition = exp.elements.events[j].position; + j++; + + while (j < exp.elements.events.length) { + + var nextPosition, evt = exp.elements.events[j]; + + if (evt.position === undefined && evt.type !== 'arrow') { j++; continue; } + + if (evt.type === 'arrow') { + nextPosition = reco[exp.coinCombination.scene_id - 1][evt.id].position; + } else { + nextPosition = evt.position; + } + + var tmp = distanceBetweenPoints(startPosition, nextPosition); + + if (evt.type === 'arrow') { + distanceWithReco += tmp; + } + + distance += tmp; + + startPosition = nextPosition; + + j++; + + } + + percentSum += 100 * distanceWithReco / distance; + console.log(exp.id + ' -> ' + Math.floor(100 * distanceWithReco / distance) + '%'); + + } + + console.log('Mean : ' + percentSum / eltNum); + +} + +if (process.argv.length !== 3) { + process.stderr.write('Error : please give me a JSON file to work on\n'); + process.exit(-1); +} + +main(process.argv[2]) diff --git a/analysis/lib.js b/analysis/lib.js index b425aa9..ba537ff 100644 --- a/analysis/lib.js +++ b/analysis/lib.js @@ -46,7 +46,17 @@ Lib.experimentDuration = function(exp) { } } - return Lib.timeDifference(exp.elements.events[0].time, lastCoin.time); + if (lastCoin === null) { + console.log(exp.id); + } + + if (Lib.coinsGot(exp) === 8) + return Lib.timeDifference(exp.elements.events[0].time, lastCoin.time); + else + return Lib.timeDifference( + exp.elements.events[0].time, + exp.elements.events[exp.elements.events.length-1].time + ); }; @@ -88,6 +98,21 @@ Lib.timeToString = function(_time) { }; +Lib.coinsGot = function(exp) { + var counter = 0; + + for (var i = 0; i < exp.elements.events.length; i++) { + + if (exp.elements.events[i].type === 'coin') { + + counter ++; + + } + } + + return counter; +} + Lib.makeGroups = function(db) { var elements = []; @@ -96,7 +121,17 @@ Lib.makeGroups = function(db) { if (db.experiments[i].coinCombination.scene_id !== 1 && db.experiments[i].elements.events.length !== 0) { - elements.push(db.experiments[i]); + if (db.experiments[i].finished === true && Lib.coinsGot(db.experiments[i]) > 5) { + + if (db.experiments[i].user === undefined) { + db.experiments[i].user = {}; + } + + elements.push(db.experiments[i]); + + // } + + } } @@ -126,6 +161,19 @@ Lib.toMatlabArray = function(name, array) { }; +Lib.toLaTeXCoordinate = function(name, array) { + var str = '\\addplot coordinates {'; + + for (var i = 0; i < array.length; i++) { + + str += '(' + i + ',' + array[i] + ') '; + + } + + return str + '};\n'; + +} + // http://stackoverflow.com/questions/3895478/ Lib.range = function(start, stop, step, computation) { @@ -150,7 +198,10 @@ Lib.range = function(start, stop, step, computation) { var a = []; while (start < stop) { - a.push(computation(start)); + var e = computation(start); + if (e === undefined) + e = NaN; + a.push(e); start += step; } return a; @@ -198,3 +249,18 @@ Lib.durationBetweenCoins = function(exp) { return ret; }; + +Lib.toLaTeXMatrix = function(mat) { + var str = 'x,y,r\n'; + + for (var i = 0; i < mat.length; i++) { + + for (var j = 0; j < mat[i].length; j++) { + str += i + ',' + j + ',' + mat[i][j] + '\n'; + } + + // str += i === mat.length - 1 ? '' : '\n'; + } + + return str; +} diff --git a/analysis/matlab/interactionAnalyse.m b/analysis/matlab/interactionAnalyse.m index 13402d9..5167a48 100644 --- a/analysis/matlab/interactionAnalyse.m +++ b/analysis/matlab/interactionAnalyse.m @@ -5,3 +5,5 @@ plot(X, Y2, 'red'); hold on; plot(X, Y3, 'green'); legend('Without recommendation', 'Worst with recommendation', 'Best with recommendation'); +xlabel('Group id'); +ylabel('Number of interaction received by the server'); diff --git a/analysis/matlab/timeAnalyse.m b/analysis/matlab/timeAnalyse.m index 323831c..4ebee6d 100644 --- a/analysis/matlab/timeAnalyse.m +++ b/analysis/matlab/timeAnalyse.m @@ -1,16 +1,9 @@ -timecoins; +time; plot(X,Y1); hold on; -names = who('Y*'); - -N = size(names, 1); - -for i = 1:N, - name = names(i) - name = name{1}; - plot(X, eval(name)); - pause - clf -end - -close all; +plot(X, Y2, 'red'); +hold on; +plot(X, Y3, 'green'); +legend('Without recommendation', 'Worst with recommendation', 'Best with recommendation'); +xlabel('Group id'); +ylabel('Time to get the last coin'); diff --git a/analysis/matlab/timeCoinsAnalyse.m b/analysis/matlab/timeCoinsAnalyse.m new file mode 100644 index 0000000..323831c --- /dev/null +++ b/analysis/matlab/timeCoinsAnalyse.m @@ -0,0 +1,16 @@ +timecoins; +plot(X,Y1); +hold on; +names = who('Y*'); + +N = size(names, 1); + +for i = 1:N, + name = names(i) + name = name{1}; + plot(X, eval(name)); + pause + clf +end + +close all; diff --git a/analysis/numberOfInteractionCurve.js b/analysis/numberOfInteractionCurve.js index 096815b..6e80f85 100755 --- a/analysis/numberOfInteractionCurve.js +++ b/analysis/numberOfInteractionCurve.js @@ -19,22 +19,76 @@ function main(path) { groups.forEach(function(elt) { elt.sort(lib.compareRecommendationStyle); + + if (elt.length === 2 && elt[1].recommendation_style[4] === 'V') { + elt[2] = elt[1]; + elt[1] = undefined; + } }); - console.log(lib.toMatlabArray('X', lib.range(0, groups.length))); + groups.sort(function(elt1, elt2) { - console.log(lib.toMatlabArray('Y1', lib.range(0, groups.length, function(i) { + el1 = []; + el2 = []; + + if (elt1[0] === undefined) el1[0] = {user:{}}; else el1[0] = elt1[0]; + if (elt1[1] === undefined) el1[1] = {user:{}}; else el1[1] = elt1[1]; + if (elt1[2] === undefined) el1[2] = {user:{}}; else el1[2] = elt1[2]; + + if (elt2[0] === undefined) el2[0] = {user:{}}; else el2[0] = elt2[0]; + if (elt2[1] === undefined) el2[1] = {user:{}}; else el2[1] = elt2[1]; + if (elt2[2] === undefined) el2[2] = {user:{}}; else el2[2] = elt2[2]; + + + var r1 = el1[0].user.rating || el1[1].user.rating; + var r2 = el2[0].user.rating || el2[1].user.rating; + + return r1 - r2;; + }); + + // console.log(lib.toMatlabArray('X', lib.range(0, groups.length))); + + var header = + '\\begin{axis}[\n' + + ' ybar,\n' + + ' enlargelimits=0.05,\n' + + ' legend style={at={(0.5,-0.15)},\n' + + ' anchor=north,legend columns=-1},\n' + + ' ylabel={Number of interactions},\n' + + ' xlabel={Groups sharing the same coin combination},\n' + + ' symbolic x coords={ '; + + for (var i = 0; i < groups.length; i++) { + header += i + (i === groups.length -1 ? '' : ','); + } + 1,2,3,4,5,6,7,8,9,10 + + header += '},\n' + + ' xtick=data,\n' + + ' nodes near coords,\n' + + ' width=32cm,\n' + + ' height=10cm,\n' + + ' % nodes near coords align5={vertical},\n' + + ']\n'; + + console.log(header); + + + console.log(lib.toLaTeXCoordinate('Y1', lib.range(0, groups.length, function(i) { return lib.numberOfInteraction(groups[i][0]); }))); - console.log(lib.toMatlabArray('Y2', lib.range(0, groups.length, function(i) { - return lib.max(lib.numberOfInteraction(groups[i][1]), lib.numberOfInteraction(groups[i][2])); + console.log(lib.toLaTeXCoordinate('Y2', lib.range(0, groups.length, function(i) { + return lib.max(lib.numberOfInteraction(groups[i][1]), 0); }))); - console.log(lib.toMatlabArray('Y3', lib.range(0, groups.length, function(i) { - return lib.min(lib.numberOfInteraction(groups[i][1]), lib.numberOfInteraction(groups[i][2])); + console.log(lib.toLaTeXCoordinate('Y3', lib.range(0, groups.length, function(i) { + return lib.max(0, lib.numberOfInteraction(groups[i][2])); }))); + console.log('\\legend{Without reco, With viewports, With arrows}'); + console.log('\\end{axis}'); + } if (process.argv.length !== 3) { diff --git a/analysis/recommendationChain.js b/analysis/recommendationChain.js new file mode 100755 index 0000000..c52ea56 --- /dev/null +++ b/analysis/recommendationChain.js @@ -0,0 +1,127 @@ +#!/usr/bin/node + +"use strict"; + +var fs = require('fs'); + +var lib = require('./lib.js'); + +function zeros(lines, columns) { + + if (columns === undefined) + columns = lines; + + var ret = []; + + for(var i=0; i max) + max = mat[i][j]; + } + } + + return mat.map(function(line) { return line.map(function(num) { return num / (2 * max) })}); + + +} + +function main(path) { + + // Generated with ./test.pgsql | tail -n+3 | head -n-2 | cut -d '|' -f 2 | sort -g | tr '\n' ' ' | tr -s ' ' | tr ' ' ',' + var recoExps = [10,27,28,57,68,83,127,129,145,192,205,206,209,210,212,214,236,240]; + + var db = lib.loadFromFile(path); + var mat1 = zeros(12); // Bombomb + var mat2 = zeros(12); // Mountain + var mat3 = zeros(11); // Whomp + + var matt1 = zeros(12); // Bombomb + var matt2 = zeros(12); // Mountain + var matt3 = zeros(11); // Whomp + + for (var expIndex = 0; expIndex < db.experiments.length; expIndex++) { + + var exp = db.experiments[expIndex]; + var coinCombination = db.coinCombinations[exp.coin_combination_id - 1]; + let mat, matt; + + switch (coinCombination.scene_id) { + + case 1: continue; // Continue the loop + case 2: mat = mat1; matt = matt1; break; + case 3: mat = mat2; matt = matt2; break; + case 4: mat = mat3; matt = matt3; break; + default: continue; + + } + + var prev = 0; // 0 is the reset camera + var next = null; + + for (var evtIndex = 0; evtIndex < exp.elements.events.length; evtIndex++) { + + var evt = exp.elements.events[evtIndex]; + + if (evt.type === 'reset') { + prev = 0; + continue; + } + + if (evt.type === 'arrow') { + next = evt.id + 1; + if (prev !== next) { + mat[prev][next]++; + if (recoExps.indexOf(exp.id) !== -1) { + matt[prev][next]++; + } + } + + + // Update prev + prev = next; + next = null; + } + + + + } + + } + + mat1 = normalize(mat1); + mat2 = normalize(mat2); + mat3 = normalize(mat3); + + fs.writeFile('mat1.dat', lib.toLaTeXMatrix(mat1), function(e) {}); + fs.writeFile('mat2.dat', lib.toLaTeXMatrix(mat2), function(e) {}); + fs.writeFile('mat3.dat', lib.toLaTeXMatrix(mat3), function(e) {}); + + matt1 = normalize(matt1); + matt2 = normalize(matt2); + matt3 = normalize(matt3); + + fs.writeFile('matt1.dat', lib.toLaTeXMatrix(matt1), function(e) {}); + fs.writeFile('matt2.dat', lib.toLaTeXMatrix(matt2), function(e) {}); + fs.writeFile('matt3.dat', lib.toLaTeXMatrix(matt3), function(e) {}); +} + +if (process.argv.length !== 3) { + process.stderr.write('Error : please give me a JSON file to work on\n'); + process.exit(-1); +} + +main(process.argv[2]) diff --git a/geo/MeshContainer.js b/geo/MeshContainer.js index d0aa363..18ea50f 100644 --- a/geo/MeshContainer.js +++ b/geo/MeshContainer.js @@ -1,12 +1,72 @@ var Log = require('../lib/NodeLog.js'); +function clone(vec) { + return {x : vec.x, y : vec.y, z : vec.z}; +} + +function rotation(vec1, x, y, z) { + + var cos = Math.cos(z); + var sin = Math.sin(z); + + var newVec = {x:0, y:0, z:0}; + oldVec = clone(vec1); + + newVec.x = cos * oldVec.x - sin * oldVec.y; + newVec.y = sin * oldVec.x + cos * oldVec.y; + newVec.z = oldVec.z; + + oldVec = clone(newVec); + + cos = Math.cos(y); + sin = Math.sin(y); + + newVec.x = cos * oldVec.x + sin * oldVec.z; + newVec.y = oldVec.y; + newVec.z = - sin * oldVec.x + cos * oldVec.z; + + cos = Math.cos(x); + sin = Math.sin(x); + + oldVec = clone(newVec); + + newVec.x = oldVec.x; + newVec.y = oldVec.y * cos - oldVec.z * sin; + newVec.z = oldVec.y * sin + oldVec.z * cos; + + return clone(newVec); +} + +function applyTransformation(vector, transfo) { + + var ret = rotation(vector, transfo.rotation.x, transfo.rotation.y, transfo.rotation.z); + var scale = transfo.scale || 1; + + return { + x: (ret.x + transfo.translation.x) * scale, + y: (ret.y + transfo.translation.y) * scale, + z: (ret.z + transfo.translation.z) * scale + }; +} + + + /** * Represents a mesh. All meshes are loaded once in geo.availableMesh to avoid * loading at each mesh request * @constructor * @memberOf geo */ -geo.MeshContainer = function(path, callback) { +geo.MeshContainer = function(path, transfo, callback) { + + if (callback === undefined && typeof transfo === 'function') { + callback = transfo; + transfo = {translation: {x:0,y:0,z:0}, rotation: {x:0,y:0,z:0}}; + } + + if (transfo === undefined) { + transfo = {translation: {x:0,y:0,z:0}, rotation: {x:0,y:0,z:0}}; + } /** * array of each part of the mesh @@ -44,6 +104,8 @@ geo.MeshContainer = function(path, callback) { */ this.numberOfFaces = 0; + this.transfo = transfo; + this.callback = callback; if (path !== undefined) { @@ -92,6 +154,12 @@ geo.MeshContainer.prototype.loadFromFile = function(path) { // Just a simple vertex var vertex = new geo.Vertex(line); + var vertexTransformed = applyTransformation(vertex, self.transfo); + + vertex.x = vertexTransformed.x; + vertex.y = vertexTransformed.y; + vertex.z = vertexTransformed.z; + vertex.index = self.vertices.length; self.vertices.push(vertex); @@ -152,7 +220,7 @@ geo.MeshContainer.prototype.loadFromFile = function(path) { function trySetLoaded() { for (var name in availableMeshNames) { - if (availableMeshNames[name] === false) { + if (availableMeshNames[name].done === false) { return; @@ -160,15 +228,54 @@ function trySetLoaded() { } - Log.ready("All meshes are ready"); + Log.ready("Meshes loaded in " + (Date.now() - start) + 'ms'); } var availableMeshNames = { - '/static/data/castle/princess peaches castle (outside).obj':false, - '/static/data/mountain/coocoolmountain.obj':false, - '/static/data/whomp/Whomps Fortress.obj':false, - '/static/data/bobomb/bobomb battlefeild.obj':false, - '/static/data/sponza/sponza.obj':false + '/static/data/castle/princess peaches castle (outside).obj': { + done: false + }, + '/static/data/mountain/coocoolmountain.obj': { + done: false + }, + + '/static/data/whomp/Whomps Fortress.obj': { + done: false, + transfo: { + rotation: { + x: -Math.PI / 2, + y: 0, + z: Math.PI / 2 + }, + translation: { + x: 0, + y: 0, + z: 0 + }, + scale: 0.1 + } + }, + + '/static/data/bobomb/bobomb battlefeild.obj': { + done: false, + transfo: { + rotation: { + x: 0, + y: Math.PI - 0.27, + z: 0 + }, + translation: { + x: 0, + y: 0, + z: 0 + } + } + }, + + '/static/data/sponza/sponza.obj': { + done: false + } + }; for (var i = 1; i < 26; i++) { @@ -179,12 +286,18 @@ for (var i = 1; i < 26; i++) { geo.availableMeshes = {}; +var start = Date.now(); + function pushMesh(name) { - geo.availableMeshes[name] = new geo.MeshContainer(name.substring(1, name.length), function() { - availableMeshNames[name] = true; - trySetLoaded(); - }); + geo.availableMeshes[name] = new geo.MeshContainer( + name.substring(1, name.length), + availableMeshNames[name].transfo, + function() { + availableMeshNames[name].done = true; + trySetLoaded(); + } + ); } diff --git a/js/l3d/src/scenes/initScene.js b/js/l3d/src/scenes/initScene.js index f83de0d..4e605e7 100644 --- a/js/l3d/src/scenes/initScene.js +++ b/js/l3d/src/scenes/initScene.js @@ -180,8 +180,8 @@ L3D.initBobombScene = function(scene, collidableObjects, recommendation, clickab ); loader.load(); - var theta = 0.27; - loader.obj.rotation.y = Math.PI - theta; + // var theta = 0.27; + // loader.obj.rotation.y = Math.PI - theta; loader.obj.up = new THREE.Vector3(0,0,1); collidableObjects.push(loader.obj); @@ -377,9 +377,9 @@ L3D.initWhompScene = function(scene, collidableObjects, recommendation, clickabl loader.load(); - loader.obj.rotation.x = -Math.PI/2; - loader.obj.rotation.z = Math.PI/2; - loader.obj.scale.set(0.1,0.1,0.1); + // loader.obj.rotation.x = -Math.PI/2; + // loader.obj.rotation.z = Math.PI/2; + // loader.obj.scale.set(0.1,0.1,0.1); // loader.getRecommendation = function() { // var ret = loader.recommendation.toList(); diff --git a/server.js b/server.js index cfa0e16..05d0821 100644 --- a/server.js +++ b/server.js @@ -104,7 +104,8 @@ app.use(function(req, res) { var serverPort, serverIpAddress; if ( isDev ) { serverPort = 4000; - serverIpAddress = require('ip').address(); + // serverIpAddress = require('ip').address(); + serverIpAddress = '0.0.0.0'; } else { // Openhift conf serverPort = process.env.OPENSHIFT_NODEJS_PORT || 8080; diff --git a/sql/backup.pgsql b/sql/backup.pgsql old mode 100644 new mode 100755 index 17508a1..9456241 --- a/sql/backup.pgsql +++ b/sql/backup.pgsql @@ -1,3 +1,7 @@ +#!/bin/sh + +psql interface 3dinterface << E_O_SQL + -- Clear database from previous tables (just in case...) DROP TABLE IF EXISTS Users CASCADE; DROP TABLE IF EXISTS Arrowclicked CASCADE; @@ -154,3 +158,5 @@ CREATE TABLE SwitchedLockOption( time TIMESTAMP DEFAULT NOW(), locked BOOLEAN ); + +E_O_SQL diff --git a/sql/check.pgsql b/sql/check.pgsql old mode 100644 new mode 100755 index 34e5706..a78505e --- a/sql/check.pgsql +++ b/sql/check.pgsql @@ -1,3 +1,7 @@ +#!/bin/bash + +psql interface 3dinterface << E_O_SQL + -- Checks that each user has never twice either the same scene or the same recommendation style SELECT count(*) = 0 FROM @@ -32,3 +36,5 @@ FROM ( GROUP BY Experiment.coin_combination_id HAVING count(CoinCombination.id) != 1 ) AS T; + +E_O_SQL diff --git a/sql/scenes.pgsql b/sql/scenes.pgsql new file mode 100755 index 0000000..11d3258 --- /dev/null +++ b/sql/scenes.pgsql @@ -0,0 +1,11 @@ +#!/bin/bash + +psql interface 3dinterface << E_O_SQL + +ALTER TABLE Scene ADD recommendation_number INTEGER; + +UPDATE SCENE SET recommendation_number = 11 WHERE id = 2; +UPDATE SCENE SET recommendation_number = 11 WHERE id = 3; +UPDATE SCENE SET recommendation_number = 10 WHERE id = 4; + +E_O_SQL diff --git a/sql/test.pgsql b/sql/test.pgsql new file mode 100755 index 0000000..8be6ead --- /dev/null +++ b/sql/test.pgsql @@ -0,0 +1,33 @@ +#! /bin/sh + +psql interface 3dinterface << E_O_SQL + +SELECT * FROM ( + SELECT Users.id AS user_id, + Experiment.id AS exp_id, + Scene.name AS scene_name, + Scene.recommendation_number AS reco_total, + count(DISTINCT ArrowClicked.arrow_id) AS reco_clicked, + -- Scene.recommendation_number - 2 <= count(DISTINCT ArrowClicked.arrow_id) AS reco_clicker + 100 * count(DISTINCT ArrowClicked.arrow_id) / Scene.recommendation_number AS reco_percent + + FROM Users, Experiment, CoinCombination, ArrowClicked, Scene + -- JOIN conditions + WHERE Experiment.user_id = Users.id AND + CoinCombination.id = Experiment.coin_combination_id AND + ArrowClicked.exp_id = Experiment.id AND + Scene.id = CoinCombination.scene_id AND + + -- other conditions + Experiment.finished AND + CoinCombination.scene_id != 1 AND + Users.valid + + GROUP BY Users.id, Experiment.id, Scene.name, Scene.recommendation_number +) T +WHERE reco_percent > 75 +ORDER BY reco_percent + +; + +E_O_SQL