├── big_vis
├── wiki.html
└── words.html
├── img
├── Cho-TimePhrase-TSNE.png
├── MNIST-Graph-100.png
├── MNIST-Graph-Raw.png
├── MNIST-PCA-Conv1.png
├── MNIST-PCA-Conv2.png
├── MNIST-PCA-R5.png
├── MNIST-PCA-Sigmoid5.png
├── MNIST-PCA-raw.png
├── MNIST-tSNE-DigitsInImage.png
├── RepMap.png
├── Translation2-Backwards.png
├── Translation2-RepArrow.png
├── WordGender.png
├── fig.png
├── netvis-mnist-100S.png
├── netvis-mnist-5R-PCA.png
├── netvis-mnist-5S-PCA.png
├── netvis-simple-2S.png
├── netvis-simple-NoHid.png
├── simple2_0.png
├── simple2_1.png
├── simple2_data.png
├── simple2_linear.png
├── wiki-pic-major.png
├── wiki-pics-both.png
└── words-pic.png
├── index.md
└── js
├── BasicVis.js
├── CostLayout-worker-3D.js
├── CostLayout-worker.js
├── MnistVis.js
├── NetVis.js
├── data
├── ArxivEmbed-sub5.js
├── ArxivEmbed.js
├── MNIST-SNE-good.js
├── MNIST-reps.js
├── MNIST.js
├── TranslationEnglishEmbed-N1.js
├── WikiEmbed-sub2.js
├── WikiEmbed-sub5.js
├── WikiEmbed.js
├── WordEmbed-10000.js
├── WordEmbed-2000.js
├── WordEmbed-5000.js
├── WordEmbed-50000.js
├── WordEmbed-Meta.js
├── WordEmbed-Vecs.js
├── WordEmbed.js
├── mnist_pca.js
└── mnist_pca.js~
└── foreign
├── TrackballControls.js
├── TrackballControls.js~
├── d3.v3.min.js
├── jquery-1.7.0.min.js
├── jquery-ui.css
└── jquery-ui.min.js
/big_vis/wiki.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | ").appendTo(cont).css("margin-bottom", "10px");
237 | var sq = $("
").appendTo(inner);
238 | sq.css("width", "10%").css("height", "15px").css("display", "inline-block");
239 | sq.css("background-color", "hsl(" + 360*n/class_N + ",50%,50%)" );
240 | var div = $("").appendTo(inner);
241 | div.css("display", "inline-block");
242 | div.css("width", "80%");
243 | div.css("margin-left", "5%")
244 | div.css("font-size", "90%");
245 | //$("
").appendTo(cont);
246 | category_div(div);
247 | }
248 |
249 | var category_div = function(div){
250 |
251 | var n = this_.categories.length;
252 | this_.categories.push("");
253 |
254 | catChange = function(e, ui){
255 | if (ui && ui.item && ui.item.value) {
256 | var s = ui.item.value || this.value;
257 | } else {
258 | var s = this.value;
259 | }
260 | if (cats.indexOf(s) == -1 && s != "") return;
261 | this_.categories[n] = cats.indexOf(s);
262 | setTimeout(function() {scatter.recolor();}, 0);
263 | //if (this_.categories.length == n + 1 && s != "")
264 | // new_cat_div();
265 | }
266 |
267 | var getMatchList = function(req, resp) {
268 | var term = req.term;
269 | var max_matches = 14;
270 | if (term.length == 0) {
271 | var matches = cats.slice(0, max_matches);
272 | if (cats.length > max_matches){
273 | matches.push('...');
274 | }
275 | } else {
276 | var term_esc = term;
277 | var regex = new RegExp(term_esc, 'i'); //ignore case
278 | var matches = [];
279 | for (var i = 0; i < cats.length; i++) {
280 | if (!regex.test(cats[i]))
281 | continue;
282 | matches.push(cats[i]);
283 | if (matches.length >= max_matches) {
284 | matches.push('...');
285 | break;
286 | }
287 | }
288 | }
289 | resp(matches);
290 | }
291 |
292 | div.autocomplete({
293 | delay: 1,
294 | source: getMatchList,
295 | select: catChange,
296 | change: catChange
297 | });
298 | div.change(catChange);
299 |
300 | }
301 |
302 | for (var j = 0; j < class_N; j++) {
303 | new_cat_div();
304 | }
305 |
306 | setTimeout(function() {
307 | var H_main = parseInt(div.style("height"));
308 | var H_cont = parseInt(cont.style("height"));
309 | cont.style("top", (H_main-H_cont)/2 + "px")
310 | }, 1);
311 |
312 | }
313 |
314 |
315 | category_div_container(div.select(".legend"));
316 | $(".ui-autocomplete").css("font-size", "90%").css("text-align", "left");
317 |
318 | }
319 |
320 |
321 |
322 | //===============
323 |
324 | var friendly_reps = {};
325 |
326 | (function() {
327 |
328 | var rep_names = Object.keys(mnist_reps).sort();
329 | var human_name = function(name){
330 | var n = -1, np = -1, k = -1, i = -1, maxpool = false;
331 |
332 | if (name.indexOf("_N0") > -1) {i = 0;}
333 | if (name.indexOf("_N1") > -1) {i = 1;}
334 | if (name.indexOf("_N2") > -1) {i = 2;}
335 | if (name.indexOf("_N3") > -1) {i = 3;}
336 | if (name.indexOf("_N4") > -1) {i = 4;}
337 |
338 | if (name.indexOf("_net") > -1) {k = 0;}
339 | if (name.indexOf("_netR") > -1) {k = 1;}
340 | if (name.indexOf("_conv") > -1) {k = 2;}
341 | if (name.indexOf("_netR200-") > -1) {k = 3;}
342 | if (name.indexOf("_netR40-") > -1) {k = 3;}
343 | if (name.indexOf("_netR10-") > -1) {k = 3;}
344 |
345 | if (name.indexOf("200-100") > -1) {np = 200; n = 100;}
346 | if (name.indexOf("40-20") > -1) {np = 40; n = 20;}
347 | if (name.indexOf("10-5") > -1) {np = 10; n = 5;}
348 |
349 |
350 | if (name.indexOf("max2") > -1) {maxpool = true;}
351 |
352 | if (name.indexOf("net100") > -1) {n = 100;}
353 | else if (name.indexOf("net200") > -1) {n = 200;}
354 | else if (name.indexOf("net10") > -1) {n = 10; }
355 | else if (name.indexOf("net20") > -1) {n = 20; }
356 | else if (name.indexOf("net1") > -1) {n = 1; }
357 | else if (name.indexOf("net2") > -1) {n = 2; }
358 | else if (name.indexOf("net5") > -1) {n = 5; }
359 | else if (name.indexOf("net8") > -1) {n = 8; }
360 |
361 |
362 | if (name.indexOf("_netR1_") > -1) {n = 1; }
363 | if (name.indexOf("_netR2_") > -1) {n = 2; }
364 | if (name.indexOf("_netR5_") > -1) {n = 5; }
365 | if (name.indexOf("_netR10_") > -1) {n = 10; }
366 | if (name.indexOf("_netR20_") > -1) {n = 20; }
367 | if (name.indexOf("_netR100_") > -1) {n = 100;}
368 | if (name.indexOf("_netR200_") > -1) {n = 200;}
369 |
370 | if (i > 1)
371 | return null;
372 | if (n > -1 && k == 0)
373 | return "Sigmoid Layer (" + n + " units) - " +i;
374 | if (n > -1 && k == 1)
375 | return "ReLU Layer (" + n + " units) - " +i;
376 | if (n > -1 && k == 2 && maxpool)
377 | return "Conv Layer ("+ n +" features; 5x5 patch; max 2x2) - " +i;
378 | if (n > -1 && k == 2)
379 | return "Conv Layer ("+ n +" features; 5x5 patch) - " +i;
380 | if (n > -1 && k == 3)
381 | return "Two ReLU Layers (" + np + " units; " + n + " units) - " +i;
382 | if (name == "mnist_raw")
383 | return "Raw MNIST";
384 | if (name.indexOf("netR[40,20]") > -1)
385 | return "Two ReLU Layers (40 units; 20 units) - " +i;
386 | if (n == -1 || k > 1)
387 | return name;
388 | }
389 |
390 |
391 | for (var i in rep_names){
392 | var name = rep_names[i];
393 | var name2 = human_name(name);
394 | if (name2)
395 | friendly_reps[name2] = mnist_reps[name];
396 | }
397 |
398 | })();
399 |
400 |
--------------------------------------------------------------------------------
/js/data/MNIST-SNE-good.js:
--------------------------------------------------------------------------------
1 |
2 | "use strict";
3 |
4 | /* Array of bytes to base64 string decoding */
5 |
6 | function b64ToUint6 (nChr) {
7 |
8 | return nChr > 64 && nChr < 91 ?
9 | nChr - 65
10 | : nChr > 96 && nChr < 123 ?
11 | nChr - 71
12 | : nChr > 47 && nChr < 58 ?
13 | nChr + 4
14 | : nChr === 43 ?
15 | 62
16 | : nChr === 47 ?
17 | 63
18 | :
19 | 0;
20 | }
21 |
22 | function base64DecToArr (sBase64, nBlocksSize) {
23 |
24 | var
25 | sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
26 | nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);
27 |
28 | for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
29 | nMod4 = nInIdx & 3;
30 | nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
31 | if (nMod4 === 3 || nInLen - nInIdx === 1) {
32 | for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
33 | taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
34 | }
35 | nUint24 = 0;
36 |
37 | }
38 | }
39 |
40 | return taBytes;
41 | }
42 |
43 |
44 | var mnist_sne = new Float32Array( base64DecToArr("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").buffer );
--------------------------------------------------------------------------------
/js/data/mnist_pca.js:
--------------------------------------------------------------------------------
1 | mnist_pca = {
2 | W: new Float32Array( base64DecToArr("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" ).buffer ),
3 | mean: new Float32Array( base64DecToArr( "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAliYlN3UCGjjJjo03Yr48NQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsxac14C2QNoyENjgrweI4WvAiOWRdXDlPBsc5U1wVOkI+KDrIXi86jdE6OkmFMTpK0jU6SIoIOkc4rTktYII5I/hfOSF2pjho6B84s++KNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKzFpzYkCxg2AG8BOBHHujf+fUY5IQIOOlXBiDq/ff06dmxUO8PwoTvRefU7660lPFd4SzzkZmA8zF1jPBzwUTxdUC88mbv+O/XWmDtcWh07RdiQOt1e0jnSGC05/bwpOAAAAAAAAAAAAAAAAAAAAAC9Okc3ptWQN/28KThIM5Y5xLFuOr37Eztq+5c7WaMOPDp1aTyJDK88Zd/tPK62Gj2SkTo9inZNPb6kSz34wjg98SkXPUD22Dx5AYQ8otENPJT2hjt5zOA6I9s5Os7fBDlyM1w3AAAAAAAAAAC9Okc2CtcjN39qPDgCn585CW3ZOmWNiju2Zx48cRubPL7ZBz2GA1g9as2cPZug2D0c9gs+8W4lPt8mMz4zoS8+gigbPgLx+D3stLU9yZNrPXOiCD08pY08YOoDPNi2WDv5Zls6eJcLOWjoHzcAAAAAAAAAAF5jFzi1FXs5elPROt3SwjuN7mw8P+PqPJTBUT3Yqqo9Fmr9PUAeMT5a9Wo+YReTPiFqqT5BK7Q+W8uwPtFCnz6TzII+gmhFPkJJCD6tr6k90ctBPVHazTy/mjs8cThTO3fbBTpSSZ03AAAAAM2vZjV00vs4vmplOjCBkzujO1g8IxDzPGWqZj3OfMM9GSIWPkMWVT74640+DnWyPutT1D4ms+w+ueL3Pnzt8j66Wt8+916/PjyGlT63HVc+4JsMPksCpz0pljQ9RyCqPDEI7DvxS706eJcLOVVqdjZBmrE4tHbbOfwdGjvtthM82A2/PBZqSD3JSLU9jeISPhbYWD5d1pM+Siy8PhH+3j7O6vk+UAYFP2njBz+PqgU/UqT9PsT64j6n9Lo+wEeLPr4qPD7R6OI9Htx1PWRY5TxXlSk8GXMHO+xpBzn3WHo3TpxcOZtypToyWqc7xeZvPGXfBz2n+YY9inbuPR7nPD685Yg+Ytu0PmKV2D78cu4+okX3PkHF9z6C0/Y+NSH3PqOB9T644Og+OevIPmWHmj543FQ+SgcBPoIchj3jU+48EXAsPE2++ToEc/Q4yY4NN25ptTnghAI7EXDYO4LnjDwv3Rw9xF+cPZpxCj7R7ls+dsycPk4Xxj4Yidw+m2PdPjMe0j7mVsg+tx/JPgPS0j6KiN8+8szePiIjxj61T5o+9KZUPtc0AD5V+309ogvIPHHm/zs+lr46AG8BOT7LczcteNE5c6L9Oj81zjt4eoc8L4YdPZpCpD3vLBU+QfdvPlAzpz5JGsg+wu/NPgVDvD7Hrqc+m2OhPrFWqz4W+L0+YmHSPvmM1D4uTbw+NlyQPjRFQz6/Aug9PL1dPb7emTwJp507o5J6OhmtozghPNo3qreGOXOdxjrGUJ47t5xnPE1nGT0O56k9AaQgPrTWgD7GvK4+12DFPpxwvT44DaQ+zWyUPipGmj6UhKw+6ejDPtqv1z6PvNI+jEGyPjzagj4/zCs+uV/NPZSHTD2Q94I84C0gOwwHAjoukCA4DWyVNx7hNDnRXGc6jKFcOzs2Rjx2wxs9bsC3PaDmLz6oj4o+tIW0PirGwz7aVbY+idufPkcSoD4/97M+K0HMPvui4j4/eus+JdvWPlufqT5biGw+l9YaPlbIvz0Y7E09vryMPIz47jpybag5guJHOKzFJzYOT684J07uOQzIHjuXVj88IeorPTI4zT2Bcj8+QtKRPi6wtz7Ed8I+zCK3PivNrj4nRsM+kpzfPjmI+D5AEAI/mdL8PkOt2T5JAKM+G6RePqw/Fj7Ml8E9A3hcPan2pTw6Oxk7lbejObmlVTiCHBQ3nDMiOPXbVznaIPM6CD1HPFpkRz2HJ+Q96+5KPjfpkz5KW7U+g0C/PhDmuz4uMMU+vELoPrLrAj8gCww/Ck4JPz/R/z5+HdY+R6afPqfoYT4+1hw+6srNPTsZbD3Opbg8CHdXO/kszzllUy43za9mNiQLmDeHMz85is0HO/Q3ZTwGL2c9ZVP4PUwsTT5YKI8+iOWrPj+Stz7eeb0+9EnTPj6i9z5ETQg/dsALP6X5Az+b2PI+r7zKPsUVnT5gH2o+K7AlPqyc2T1kr3A9Bfq+PG4Xkjtauy06rMUnOBe3UTbG+Zs3jxmoOYY4Jjvy7488xr+DPUuCAj5xOEg+6OKEPnIKnD7dzac+YS+zPrK9yj5H1eg+HFD+PhsSAD/ygfI+5pHePqnkvj7K75o+Z8puPiT5KD7jttc9IuBmPTxOuTwiq6s714ZKOgr0CTgAAAAAODIPOG8SAzpeS4A7Jvy8PIpIkz2uUwY+XYRBPjU1cz43MYs+oSGWPlbcoT7fd7M+uhHNPk3w4j6z+Oc+hLDgPpNS0T6vPLk+tHyaPiw8bT414yM+MRnJPRrdTz1z16g8xHy5O+G0YDpOtCs4yY6NNlIP0TeGj0g6W+vLO+Rm8DxvjaI9q08MPnMjQj7iBms+0vuEPkFUkD5EiZk+vgenPrLuvz7zyNY+CB3hPrZ53j6xwdE+WSC7PiJAmT6PAmM+5coXPtjYtT3uCDc9uECUPCyCpztenSM6uYhvOFJJnTXGv084TUqhOtu/BjxETAo9GiitPUH3Ez5S50w+v1p6PlIyjz5kQJw+3gWmPgo8tT7PTsw+eanhPpIU6z474uY+sRnWPnVFuD7l/o8+dTxMPiOzAz5e15Y9t5cSPTJVaDwiiYY7Q8oPOsYWAjgAAAAA0xOWOBuBuDoLRhU8F7cHPfLNpT3+cRQ+LsVWPipRiT41JqI+Rym1Ps/GxD44gdY+ny7rPk5o+T5qDfo+3XvrPjl8zz5LS6g+qKl2PrzLJD4Xq8g9t5dZPQDjzzzWbic8URQ4O23/yjlvEoM2rMUnNjGxeThegJ06tJPxO0q11Tx/zYc9HHADPiNKTT5++Is+sMmtPoIZyj7gp+E+N9T1PlRQAj82eAM/N1H5Pusr3D5K7LM+uVOGPpfiNz7yNeY9TvqCPXo2CD3M0YE8NSnVO+Lp1TqKjmQ56nhMNn+HIjY7qpo2n8hTOl9GkTtmiIE8+gowPUF9vD3bIiI+En1yPpgmoT7AmMU+HPDhPgWg9D7gAfo+3NHwPr8L1z6OcrA+hASFPpBJNz6IBeg9xdWIPdIAFT2Pqpg8LgQNPPHXVDvMRTw6ptWQOGK+vDYAAAAAAAAAAAU0kTkAAOA68DPmO+zdpTyqmkQ96EHBPQ1mIT5B5Wo+uuuZPpENtz5HBsY+v/3EPmOItD4d+Jc+/+dnPtxAIj658M49nL93PQQhDD2GIJM8Ci4SPLkZfjtma5065E5pOeAQKjgAAAAAAAAAAAAAAABYVpo448IBOnkjEztEbtY7kj+MPNrmFT3jJYg9ekfZPaDaFz5ClTo+aZdLPiFZST6J+zQ+7aQTPjOK3T1q2Zk9UwVEPVDH6zzXL4I82/kGPNHLgDuM89c6KEnXObHc0jgkCxg3AAAAAAAAAAAAAAAAVWr2NjnRrjh1yA06+rP/On8wwDtrt1U8AoLLPOHRID2jO189at6DPSc9jT2OEos9u2F7PYhoUz2fjik9v5r5PHXlpzzMRVA8U67gO1aaZDtX7M86P8YcOvmDATk+P4w3nFAINwAAAAAAAAAAAAAAAAAAAAC9Okc2m1UfOUxULzpiFQ87K6ScO4/fFzx8m2I8HoqYPBfxtzzGosM8o3XAPBdlrjxihI48YvhkPOEoJTzAW9g78PmBOysTDjvGM4g6xLGuOS9pjDiCqHs0O6qaNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL06Rzdb64s4xtw1Odl3xTnVWwM6WvU5Oq/rlzreyLw61GD6Opz5BTsDfSI7J04OO0Ih4jrhRZ86661BOgKCuTmVDlY5GZC9OFaalDhSSR03AAAAAAAAAAAAAAAAAAAAAA=="
4 | ).buffer )
5 | }
6 |
--------------------------------------------------------------------------------
/js/data/mnist_pca.js~:
--------------------------------------------------------------------------------
1 | mnist_pca = {
2 | W: "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",
3 | mean: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAliYlN3UCGjjJjo03Yr48NQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsxac14C2QNoyENjgrweI4WvAiOWRdXDlPBsc5U1wVOkI+KDrIXi86jdE6OkmFMTpK0jU6SIoIOkc4rTktYII5I/hfOSF2pjho6B84s++KNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKzFpzYkCxg2AG8BOBHHujf+fUY5IQIOOlXBiDq/ff06dmxUO8PwoTvRefU7660lPFd4SzzkZmA8zF1jPBzwUTxdUC88mbv+O/XWmDtcWh07RdiQOt1e0jnSGC05/bwpOAAAAAAAAAAAAAAAAAAAAAC9Okc3ptWQN/28KThIM5Y5xLFuOr37Eztq+5c7WaMOPDp1aTyJDK88Zd/tPK62Gj2SkTo9inZNPb6kSz34wjg98SkXPUD22Dx5AYQ8otENPJT2hjt5zOA6I9s5Os7fBDlyM1w3AAAAAAAAAAC9Okc2CtcjN39qPDgCn585CW3ZOmWNiju2Zx48cRubPL7ZBz2GA1g9as2cPZug2D0c9gs+8W4lPt8mMz4zoS8+gigbPgLx+D3stLU9yZNrPXOiCD08pY08YOoDPNi2WDv5Zls6eJcLOWjoHzcAAAAAAAAAAF5jFzi1FXs5elPROt3SwjuN7mw8P+PqPJTBUT3Yqqo9Fmr9PUAeMT5a9Wo+YReTPiFqqT5BK7Q+W8uwPtFCnz6TzII+gmhFPkJJCD6tr6k90ctBPVHazTy/mjs8cThTO3fbBTpSSZ03AAAAAM2vZjV00vs4vmplOjCBkzujO1g8IxDzPGWqZj3OfMM9GSIWPkMWVT74640+DnWyPutT1D4ms+w+ueL3Pnzt8j66Wt8+916/PjyGlT63HVc+4JsMPksCpz0pljQ9RyCqPDEI7DvxS706eJcLOVVqdjZBmrE4tHbbOfwdGjvtthM82A2/PBZqSD3JSLU9jeISPhbYWD5d1pM+Siy8PhH+3j7O6vk+UAYFP2njBz+PqgU/UqT9PsT64j6n9Lo+wEeLPr4qPD7R6OI9Htx1PWRY5TxXlSk8GXMHO+xpBzn3WHo3TpxcOZtypToyWqc7xeZvPGXfBz2n+YY9inbuPR7nPD685Yg+Ytu0PmKV2D78cu4+okX3PkHF9z6C0/Y+NSH3PqOB9T644Og+OevIPmWHmj543FQ+SgcBPoIchj3jU+48EXAsPE2++ToEc/Q4yY4NN25ptTnghAI7EXDYO4LnjDwv3Rw9xF+cPZpxCj7R7ls+dsycPk4Xxj4Yidw+m2PdPjMe0j7mVsg+tx/JPgPS0j6KiN8+8szePiIjxj61T5o+9KZUPtc0AD5V+309ogvIPHHm/zs+lr46AG8BOT7LczcteNE5c6L9Oj81zjt4eoc8L4YdPZpCpD3vLBU+QfdvPlAzpz5JGsg+wu/NPgVDvD7Hrqc+m2OhPrFWqz4W+L0+YmHSPvmM1D4uTbw+NlyQPjRFQz6/Aug9PL1dPb7emTwJp507o5J6OhmtozghPNo3qreGOXOdxjrGUJ47t5xnPE1nGT0O56k9AaQgPrTWgD7GvK4+12DFPpxwvT44DaQ+zWyUPipGmj6UhKw+6ejDPtqv1z6PvNI+jEGyPjzagj4/zCs+uV/NPZSHTD2Q94I84C0gOwwHAjoukCA4DWyVNx7hNDnRXGc6jKFcOzs2Rjx2wxs9bsC3PaDmLz6oj4o+tIW0PirGwz7aVbY+idufPkcSoD4/97M+K0HMPvui4j4/eus+JdvWPlufqT5biGw+l9YaPlbIvz0Y7E09vryMPIz47jpybag5guJHOKzFJzYOT684J07uOQzIHjuXVj88IeorPTI4zT2Bcj8+QtKRPi6wtz7Ed8I+zCK3PivNrj4nRsM+kpzfPjmI+D5AEAI/mdL8PkOt2T5JAKM+G6RePqw/Fj7Ml8E9A3hcPan2pTw6Oxk7lbejObmlVTiCHBQ3nDMiOPXbVznaIPM6CD1HPFpkRz2HJ+Q96+5KPjfpkz5KW7U+g0C/PhDmuz4uMMU+vELoPrLrAj8gCww/Ck4JPz/R/z5+HdY+R6afPqfoYT4+1hw+6srNPTsZbD3Opbg8CHdXO/kszzllUy43za9mNiQLmDeHMz85is0HO/Q3ZTwGL2c9ZVP4PUwsTT5YKI8+iOWrPj+Stz7eeb0+9EnTPj6i9z5ETQg/dsALP6X5Az+b2PI+r7zKPsUVnT5gH2o+K7AlPqyc2T1kr3A9Bfq+PG4Xkjtauy06rMUnOBe3UTbG+Zs3jxmoOYY4Jjvy7488xr+DPUuCAj5xOEg+6OKEPnIKnD7dzac+YS+zPrK9yj5H1eg+HFD+PhsSAD/ygfI+5pHePqnkvj7K75o+Z8puPiT5KD7jttc9IuBmPTxOuTwiq6s714ZKOgr0CTgAAAAAODIPOG8SAzpeS4A7Jvy8PIpIkz2uUwY+XYRBPjU1cz43MYs+oSGWPlbcoT7fd7M+uhHNPk3w4j6z+Oc+hLDgPpNS0T6vPLk+tHyaPiw8bT414yM+MRnJPRrdTz1z16g8xHy5O+G0YDpOtCs4yY6NNlIP0TeGj0g6W+vLO+Rm8DxvjaI9q08MPnMjQj7iBms+0vuEPkFUkD5EiZk+vgenPrLuvz7zyNY+CB3hPrZ53j6xwdE+WSC7PiJAmT6PAmM+5coXPtjYtT3uCDc9uECUPCyCpztenSM6uYhvOFJJnTXGv084TUqhOtu/BjxETAo9GiitPUH3Ez5S50w+v1p6PlIyjz5kQJw+3gWmPgo8tT7PTsw+eanhPpIU6z474uY+sRnWPnVFuD7l/o8+dTxMPiOzAz5e15Y9t5cSPTJVaDwiiYY7Q8oPOsYWAjgAAAAA0xOWOBuBuDoLRhU8F7cHPfLNpT3+cRQ+LsVWPipRiT41JqI+Rym1Ps/GxD44gdY+ny7rPk5o+T5qDfo+3XvrPjl8zz5LS6g+qKl2PrzLJD4Xq8g9t5dZPQDjzzzWbic8URQ4O23/yjlvEoM2rMUnNjGxeThegJ06tJPxO0q11Tx/zYc9HHADPiNKTT5++Is+sMmtPoIZyj7gp+E+N9T1PlRQAj82eAM/N1H5Pusr3D5K7LM+uVOGPpfiNz7yNeY9TvqCPXo2CD3M0YE8NSnVO+Lp1TqKjmQ56nhMNn+HIjY7qpo2n8hTOl9GkTtmiIE8+gowPUF9vD3bIiI+En1yPpgmoT7AmMU+HPDhPgWg9D7gAfo+3NHwPr8L1z6OcrA+hASFPpBJNz6IBeg9xdWIPdIAFT2Pqpg8LgQNPPHXVDvMRTw6ptWQOGK+vDYAAAAAAAAAAAU0kTkAAOA68DPmO+zdpTyqmkQ96EHBPQ1mIT5B5Wo+uuuZPpENtz5HBsY+v/3EPmOItD4d+Jc+/+dnPtxAIj658M49nL93PQQhDD2GIJM8Ci4SPLkZfjtma5065E5pOeAQKjgAAAAAAAAAAAAAAABYVpo448IBOnkjEztEbtY7kj+MPNrmFT3jJYg9ekfZPaDaFz5ClTo+aZdLPiFZST6J+zQ+7aQTPjOK3T1q2Zk9UwVEPVDH6zzXL4I82/kGPNHLgDuM89c6KEnXObHc0jgkCxg3AAAAAAAAAAAAAAAAVWr2NjnRrjh1yA06+rP/On8wwDtrt1U8AoLLPOHRID2jO189at6DPSc9jT2OEos9u2F7PYhoUz2fjik9v5r5PHXlpzzMRVA8U67gO1aaZDtX7M86P8YcOvmDATk+P4w3nFAINwAAAAAAAAAAAAAAAAAAAAC9Okc2m1UfOUxULzpiFQ87K6ScO4/fFzx8m2I8HoqYPBfxtzzGosM8o3XAPBdlrjxihI48YvhkPOEoJTzAW9g78PmBOysTDjvGM4g6xLGuOS9pjDiCqHs0O6qaNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL06Rzdb64s4xtw1Odl3xTnVWwM6WvU5Oq/rlzreyLw61GD6Opz5BTsDfSI7J04OO0Ih4jrhRZ86661BOgKCuTmVDlY5GZC9OFaalDhSSR03AAAAAAAAAAAAAAAAAAAAAA=="}
4 |
--------------------------------------------------------------------------------
/js/foreign/TrackballControls.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Eberhard Graether / http://egraether.com/
3 | * @author Mark Lundin / http://mark-lundin.com
4 | */
5 |
6 | THREE.TrackballControls = function ( object, domElement ) {
7 |
8 | var _this = this;
9 | var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
10 |
11 | this.object = object;
12 | this.domElement = ( domElement !== undefined ) ? domElement : document;
13 |
14 | // API
15 |
16 | this.enabled = true;
17 |
18 | this.screen = { left: 0, top: 0, width: 0, height: 0 };
19 |
20 | this.rotateSpeed = 1.0;
21 | this.zoomSpeed = 1.2;
22 | this.panSpeed = 0.3;
23 |
24 | this.noRotate = false;
25 | this.noZoom = false;
26 | this.noPan = false;
27 | this.noRoll = false;
28 |
29 | this.staticMoving = false;
30 | this.dynamicDampingFactor = 0.2;
31 |
32 | this.minDistance = 0;
33 | this.maxDistance = Infinity;
34 |
35 | this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
36 |
37 | // internals
38 |
39 | this.target = new THREE.Vector3();
40 |
41 | var EPS = 0.000001;
42 |
43 | var lastPosition = new THREE.Vector3();
44 |
45 | var _state = STATE.NONE,
46 | _prevState = STATE.NONE,
47 |
48 | _eye = new THREE.Vector3(),
49 |
50 | _rotateStart = new THREE.Vector3(),
51 | _rotateEnd = new THREE.Vector3(),
52 |
53 | _zoomStart = new THREE.Vector2(),
54 | _zoomEnd = new THREE.Vector2(),
55 |
56 | _touchZoomDistanceStart = 0,
57 | _touchZoomDistanceEnd = 0,
58 |
59 | _panStart = new THREE.Vector2(),
60 | _panEnd = new THREE.Vector2();
61 |
62 | // for reset
63 |
64 | this.target0 = this.target.clone();
65 | this.position0 = this.object.position.clone();
66 | this.up0 = this.object.up.clone();
67 |
68 | // events
69 |
70 | var changeEvent = { type: 'change' };
71 | var startEvent = { type: 'start'};
72 | var endEvent = { type: 'end'};
73 |
74 |
75 | // methods
76 |
77 | this.handleResize = function () {
78 |
79 | if ( this.domElement === document ) {
80 |
81 | this.screen.left = 0;
82 | this.screen.top = 0;
83 | this.screen.width = window.innerWidth;
84 | this.screen.height = window.innerHeight;
85 |
86 | } else {
87 |
88 | var box = this.domElement.getBoundingClientRect();
89 | // adjustments come from similar code in the jquery offset() function
90 | var d = this.domElement.ownerDocument.documentElement;
91 | this.screen.left = box.left + window.pageXOffset - d.clientLeft;
92 | this.screen.top = box.top + window.pageYOffset - d.clientTop;
93 | this.screen.width = box.width;
94 | this.screen.height = box.height;
95 |
96 | }
97 |
98 | };
99 |
100 | this.handleEvent = function ( event ) {
101 |
102 | if ( typeof this[ event.type ] == 'function' ) {
103 |
104 | this[ event.type ]( event );
105 |
106 | }
107 |
108 | };
109 |
110 | var getMouseOnScreen = ( function () {
111 |
112 | var vector = new THREE.Vector2();
113 |
114 | return function ( pageX, pageY ) {
115 |
116 | vector.set(
117 | ( pageX - _this.screen.left ) / _this.screen.width,
118 | ( pageY - _this.screen.top ) / _this.screen.height
119 | );
120 |
121 | return vector;
122 |
123 | };
124 |
125 | }() );
126 |
127 | var getMouseOnScreenByEvent = ( function () {
128 |
129 | var vector = new THREE.Vector2();
130 |
131 | return function (e) {
132 | console.log("getMouseOnScreenByEvent called!");
133 | var X = e.offsetX || ( e.pageX - _this.screen.left );
134 | var Y = e.offsetY || ( e.pageY - _this.screen.top );
135 | console.log(e, X, Y);
136 | vector.set(
137 | X / _this.screen.width,
138 | Y / _this.screen.height
139 | );
140 |
141 | return vector;
142 |
143 | };
144 |
145 | }() );
146 |
147 | var getMouseProjectionOnBall = ( function () {
148 |
149 | var vector = new THREE.Vector3();
150 | var objectUp = new THREE.Vector3();
151 | var mouseOnBall = new THREE.Vector3();
152 |
153 | return function ( pageX, pageY ) {
154 |
155 | mouseOnBall.set(
156 | ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5),
157 | ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / (_this.screen.height*.5),
158 | 0.0
159 | );
160 |
161 | var length = mouseOnBall.length();
162 |
163 | if ( _this.noRoll ) {
164 |
165 | if ( length < Math.SQRT1_2 ) {
166 |
167 | mouseOnBall.z = Math.sqrt( 1.0 - length*length );
168 |
169 | } else {
170 |
171 | mouseOnBall.z = .5 / length;
172 |
173 | }
174 |
175 | } else if ( length > 1.0 ) {
176 |
177 | mouseOnBall.normalize();
178 |
179 | } else {
180 |
181 | mouseOnBall.z = Math.sqrt( 1.0 - length * length );
182 |
183 | }
184 |
185 | _eye.copy( _this.object.position ).sub( _this.target );
186 |
187 | vector.copy( _this.object.up ).setLength( mouseOnBall.y )
188 | vector.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
189 | vector.add( _eye.setLength( mouseOnBall.z ) );
190 |
191 | return vector;
192 |
193 | };
194 |
195 | }() );
196 |
197 | var getMouseProjectionOnBallByEvent = ( function () {
198 |
199 | var vector = new THREE.Vector3();
200 | var objectUp = new THREE.Vector3();
201 | var mouseOnBall = new THREE.Vector3();
202 |
203 | return function ( e ) {
204 |
205 | var X = e.offsetX || ( e.pageX - _this.screen.left );
206 | var Y = e.offsetY || ( e.pageY - _this.screen.top );
207 |
208 | mouseOnBall.set(
209 | ( X - _this.screen.width * 0.5 ) / (_this.screen.width*.5),
210 | ( _this.screen.height * 0.5 - Y ) / (_this.screen.height*.5),
211 | 0.0
212 | );
213 |
214 | var length = mouseOnBall.length();
215 |
216 | if ( _this.noRoll ) {
217 |
218 | if ( length < Math.SQRT1_2 ) {
219 |
220 | mouseOnBall.z = Math.sqrt( 1.0 - length*length );
221 |
222 | } else {
223 |
224 | mouseOnBall.z = .5 / length;
225 |
226 | }
227 |
228 | } else if ( length > 1.0 ) {
229 |
230 | mouseOnBall.normalize();
231 |
232 | } else {
233 |
234 | mouseOnBall.z = Math.sqrt( 1.0 - length * length );
235 |
236 | }
237 |
238 | _eye.copy( _this.object.position ).sub( _this.target );
239 |
240 | vector.copy( _this.object.up ).setLength( mouseOnBall.y )
241 | vector.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
242 | vector.add( _eye.setLength( mouseOnBall.z ) );
243 |
244 | return vector;
245 |
246 | };
247 |
248 | }() );
249 |
250 | this.rotateCamera = (function(){
251 |
252 | var axis = new THREE.Vector3(),
253 | quaternion = new THREE.Quaternion();
254 |
255 |
256 | return function () {
257 |
258 | var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
259 |
260 | if ( angle ) {
261 |
262 | axis.crossVectors( _rotateStart, _rotateEnd ).normalize();
263 |
264 | angle *= _this.rotateSpeed;
265 |
266 | quaternion.setFromAxisAngle( axis, -angle );
267 |
268 | _eye.applyQuaternion( quaternion );
269 | _this.object.up.applyQuaternion( quaternion );
270 |
271 | _rotateEnd.applyQuaternion( quaternion );
272 |
273 | if ( _this.staticMoving ) {
274 |
275 | _rotateStart.copy( _rotateEnd );
276 |
277 | } else {
278 |
279 | quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
280 | _rotateStart.applyQuaternion( quaternion );
281 |
282 | }
283 |
284 | }
285 | }
286 |
287 | }());
288 |
289 | this.zoomCamera = function () {
290 |
291 | if ( _state === STATE.TOUCH_ZOOM_PAN ) {
292 |
293 | var factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
294 | _touchZoomDistanceStart = _touchZoomDistanceEnd;
295 | _eye.multiplyScalar( factor );
296 |
297 | } else {
298 |
299 | var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
300 |
301 | if ( factor !== 1.0 && factor > 0.0 ) {
302 |
303 | _eye.multiplyScalar( factor );
304 |
305 | if ( _this.staticMoving ) {
306 |
307 | _zoomStart.copy( _zoomEnd );
308 |
309 | } else {
310 |
311 | _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
312 |
313 | }
314 |
315 | }
316 |
317 | }
318 |
319 | };
320 |
321 | this.panCamera = (function(){
322 |
323 | var mouseChange = new THREE.Vector2(),
324 | objectUp = new THREE.Vector3(),
325 | pan = new THREE.Vector3();
326 |
327 | return function () {
328 |
329 | mouseChange.copy( _panEnd ).sub( _panStart );
330 |
331 | if ( mouseChange.lengthSq() ) {
332 |
333 | mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
334 |
335 | pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
336 | pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) );
337 |
338 | _this.object.position.add( pan );
339 | _this.target.add( pan );
340 |
341 | if ( _this.staticMoving ) {
342 |
343 | _panStart.copy( _panEnd );
344 |
345 | } else {
346 |
347 | _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
348 |
349 | }
350 |
351 | }
352 | }
353 |
354 | }());
355 |
356 | this.checkDistances = function () {
357 |
358 | if ( !_this.noZoom || !_this.noPan ) {
359 |
360 | if ( _eye.lengthSq() > _this.maxDistance * _this.maxDistance ) {
361 |
362 | _this.object.position.addVectors( _this.target, _eye.setLength( _this.maxDistance ) );
363 |
364 | }
365 |
366 | if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {
367 |
368 | _this.object.position.addVectors( _this.target, _eye.setLength( _this.minDistance ) );
369 |
370 | }
371 |
372 | }
373 |
374 | };
375 |
376 | this.update = function () {
377 |
378 | _eye.subVectors( _this.object.position, _this.target );
379 |
380 | if ( !_this.noRotate ) {
381 |
382 | _this.rotateCamera();
383 |
384 | }
385 |
386 | if ( !_this.noZoom ) {
387 |
388 | _this.zoomCamera();
389 |
390 | }
391 |
392 | if ( !_this.noPan ) {
393 |
394 | _this.panCamera();
395 |
396 | }
397 |
398 | _this.object.position.addVectors( _this.target, _eye );
399 |
400 | _this.checkDistances();
401 |
402 | _this.object.lookAt( _this.target );
403 |
404 | if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) {
405 |
406 | _this.dispatchEvent( changeEvent );
407 |
408 | lastPosition.copy( _this.object.position );
409 |
410 | }
411 |
412 | };
413 |
414 | this.reset = function () {
415 |
416 | _state = STATE.NONE;
417 | _prevState = STATE.NONE;
418 |
419 | _this.target.copy( _this.target0 );
420 | _this.object.position.copy( _this.position0 );
421 | _this.object.up.copy( _this.up0 );
422 |
423 | _eye.subVectors( _this.object.position, _this.target );
424 |
425 | _this.object.lookAt( _this.target );
426 |
427 | _this.dispatchEvent( changeEvent );
428 |
429 | lastPosition.copy( _this.object.position );
430 |
431 | };
432 |
433 | // listeners
434 |
435 | function keydown( event ) {
436 |
437 | if ( _this.enabled === false ) return;
438 |
439 | window.removeEventListener( 'keydown', keydown );
440 |
441 | _prevState = _state;
442 |
443 | if ( _state !== STATE.NONE ) {
444 |
445 | return;
446 |
447 | } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && !_this.noRotate ) {
448 |
449 | _state = STATE.ROTATE;
450 |
451 | } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && !_this.noZoom ) {
452 |
453 | _state = STATE.ZOOM;
454 |
455 | } else if ( event.keyCode === _this.keys[ STATE.PAN ] && !_this.noPan ) {
456 |
457 | _state = STATE.PAN;
458 |
459 | }
460 |
461 | }
462 |
463 | function keyup( event ) {
464 |
465 | if ( _this.enabled === false ) return;
466 |
467 | _state = _prevState;
468 |
469 | window.addEventListener( 'keydown', keydown, false );
470 |
471 | }
472 |
473 | function mousedown( event ) {
474 |
475 | if ( _this.enabled === false ) return;
476 |
477 | event.preventDefault();
478 | event.stopPropagation();
479 |
480 | if ( _state === STATE.NONE ) {
481 |
482 | _state = event.button;
483 |
484 | }
485 |
486 | if ( _state === STATE.ROTATE && !_this.noRotate ) {
487 |
488 | _rotateStart.copy( getMouseProjectionOnBallByEvent( event ) );
489 | _rotateEnd.copy( _rotateStart );
490 |
491 | } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
492 |
493 | _zoomStart.copy( getMouseOnScreenByEvent( event ) );
494 | _zoomEnd.copy(_zoomStart);
495 |
496 | } else if ( _state === STATE.PAN && !_this.noPan ) {
497 |
498 | _panStart.copy( getMouseOnScreenByEvent( event ) );
499 | _panEnd.copy(_panStart)
500 |
501 | }
502 |
503 | document.addEventListener( 'mousemove', mousemove, false );
504 | document.addEventListener( 'mouseup', mouseup, false );
505 |
506 | _this.dispatchEvent( startEvent );
507 |
508 | }
509 |
510 | function mousemove( event ) {
511 |
512 | if ( _this.enabled === false ) return;
513 |
514 | event.preventDefault();
515 | event.stopPropagation();
516 |
517 | if ( _state === STATE.ROTATE && !_this.noRotate ) {
518 |
519 | _rotateEnd.copy( getMouseProjectionOnBallByEvent( event ) );
520 |
521 | } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
522 |
523 | _zoomEnd.copy( getMouseOnScreenByEvent( event ) );
524 |
525 | } else if ( _state === STATE.PAN && !_this.noPan ) {
526 |
527 | _panEnd.copy( getMouseOnScreenByEvent( event ) );
528 |
529 | }
530 |
531 | }
532 |
533 | function mouseup( event ) {
534 |
535 | if ( _this.enabled === false ) return;
536 |
537 | event.preventDefault();
538 | event.stopPropagation();
539 |
540 | _state = STATE.NONE;
541 |
542 | document.removeEventListener( 'mousemove', mousemove );
543 | document.removeEventListener( 'mouseup', mouseup );
544 | _this.dispatchEvent( endEvent );
545 |
546 | }
547 |
548 | function mousewheel( event ) {
549 |
550 | if ( _this.enabled === false ) return;
551 |
552 | event.preventDefault();
553 | event.stopPropagation();
554 |
555 | var delta = 0;
556 |
557 | if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
558 |
559 | delta = event.wheelDelta / 40;
560 |
561 | } else if ( event.detail ) { // Firefox
562 |
563 | delta = - event.detail / 3;
564 |
565 | }
566 |
567 | _zoomStart.y += delta * 0.01;
568 | _this.dispatchEvent( startEvent );
569 | _this.dispatchEvent( endEvent );
570 |
571 | }
572 |
573 | function touchstart( event ) {
574 |
575 | if ( _this.enabled === false ) return;
576 |
577 | switch ( event.touches.length ) {
578 |
579 | case 1:
580 | _state = STATE.TOUCH_ROTATE;
581 | _rotateStart.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
582 | _rotateEnd.copy( _rotateStart );
583 | break;
584 |
585 | case 2:
586 | _state = STATE.TOUCH_ZOOM_PAN;
587 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
588 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
589 | _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
590 |
591 | var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
592 | var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
593 | _panStart.copy( getMouseOnScreen( x, y ) );
594 | _panEnd.copy( _panStart );
595 | break;
596 |
597 | default:
598 | _state = STATE.NONE;
599 |
600 | }
601 | _this.dispatchEvent( startEvent );
602 |
603 |
604 | }
605 |
606 | function touchmove( event ) {
607 |
608 | if ( _this.enabled === false ) return;
609 |
610 | event.preventDefault();
611 | event.stopPropagation();
612 |
613 | switch ( event.touches.length ) {
614 |
615 | case 1:
616 | _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
617 | break;
618 |
619 | case 2:
620 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
621 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
622 | _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
623 |
624 | var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
625 | var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
626 | _panEnd.copy( getMouseOnScreen( x, y ) );
627 | break;
628 |
629 | default:
630 | _state = STATE.NONE;
631 |
632 | }
633 |
634 | }
635 |
636 | function touchend( event ) {
637 |
638 | if ( _this.enabled === false ) return;
639 |
640 | switch ( event.touches.length ) {
641 |
642 | case 1:
643 | _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
644 | _rotateStart.copy( _rotateEnd );
645 | break;
646 |
647 | case 2:
648 | _touchZoomDistanceStart = _touchZoomDistanceEnd = 0;
649 |
650 | var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
651 | var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
652 | _panEnd.copy( getMouseOnScreen( x, y ) );
653 | _panStart.copy( _panEnd );
654 | break;
655 |
656 | }
657 |
658 | _state = STATE.NONE;
659 | _this.dispatchEvent( endEvent );
660 |
661 | }
662 |
663 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
664 |
665 | this.domElement.addEventListener( 'mousedown', mousedown, false );
666 |
667 | this.domElement.addEventListener( 'mousewheel', mousewheel, false );
668 | this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox
669 |
670 | this.domElement.addEventListener( 'touchstart', touchstart, false );
671 | this.domElement.addEventListener( 'touchend', touchend, false );
672 | this.domElement.addEventListener( 'touchmove', touchmove, false );
673 |
674 | window.addEventListener( 'keydown', keydown, false );
675 | window.addEventListener( 'keyup', keyup, false );
676 |
677 | this.handleResize();
678 |
679 | // force an update at start
680 | this.update();
681 |
682 | };
683 |
684 | THREE.TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );
685 |
--------------------------------------------------------------------------------
/js/foreign/TrackballControls.js~:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Eberhard Graether / http://egraether.com/
3 | * @author Mark Lundin / http://mark-lundin.com
4 | */
5 |
6 | THREE.TrackballControls = function ( object, domElement ) {
7 |
8 | var _this = this;
9 | var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
10 |
11 | this.object = object;
12 | this.domElement = ( domElement !== undefined ) ? domElement : document;
13 |
14 | // API
15 |
16 | this.enabled = true;
17 |
18 | this.screen = { left: 0, top: 0, width: 0, height: 0 };
19 |
20 | this.rotateSpeed = 1.0;
21 | this.zoomSpeed = 1.2;
22 | this.panSpeed = 0.3;
23 |
24 | this.noRotate = false;
25 | this.noZoom = false;
26 | this.noPan = false;
27 | this.noRoll = false;
28 |
29 | this.staticMoving = false;
30 | this.dynamicDampingFactor = 0.2;
31 |
32 | this.minDistance = 0;
33 | this.maxDistance = Infinity;
34 |
35 | this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
36 |
37 | // internals
38 |
39 | this.target = new THREE.Vector3();
40 |
41 | var EPS = 0.000001;
42 |
43 | var lastPosition = new THREE.Vector3();
44 |
45 | var _state = STATE.NONE,
46 | _prevState = STATE.NONE,
47 |
48 | _eye = new THREE.Vector3(),
49 |
50 | _rotateStart = new THREE.Vector3(),
51 | _rotateEnd = new THREE.Vector3(),
52 |
53 | _zoomStart = new THREE.Vector2(),
54 | _zoomEnd = new THREE.Vector2(),
55 |
56 | _touchZoomDistanceStart = 0,
57 | _touchZoomDistanceEnd = 0,
58 |
59 | _panStart = new THREE.Vector2(),
60 | _panEnd = new THREE.Vector2();
61 |
62 | // for reset
63 |
64 | this.target0 = this.target.clone();
65 | this.position0 = this.object.position.clone();
66 | this.up0 = this.object.up.clone();
67 |
68 | // events
69 |
70 | var changeEvent = { type: 'change' };
71 | var startEvent = { type: 'start'};
72 | var endEvent = { type: 'end'};
73 |
74 |
75 | // methods
76 |
77 | this.handleResize = function () {
78 |
79 | if ( this.domElement === document ) {
80 |
81 | this.screen.left = 0;
82 | this.screen.top = 0;
83 | this.screen.width = window.innerWidth;
84 | this.screen.height = window.innerHeight;
85 |
86 | } else {
87 |
88 | var box = this.domElement.getBoundingClientRect();
89 | // adjustments come from similar code in the jquery offset() function
90 | var d = this.domElement.ownerDocument.documentElement;
91 | this.screen.left = box.left + window.pageXOffset - d.clientLeft;
92 | this.screen.top = box.top + window.pageYOffset - d.clientTop;
93 | this.screen.width = box.width;
94 | this.screen.height = box.height;
95 |
96 | }
97 |
98 | };
99 |
100 | this.handleEvent = function ( event ) {
101 |
102 | if ( typeof this[ event.type ] == 'function' ) {
103 |
104 | this[ event.type ]( event );
105 |
106 | }
107 |
108 | };
109 |
110 | var getMouseOnScreen = ( function () {
111 |
112 | var vector = new THREE.Vector2();
113 |
114 | return function ( pageX, pageY ) {
115 |
116 | vector.set(
117 | ( pageX - _this.screen.left ) / _this.screen.width,
118 | ( pageY - _this.screen.top ) / _this.screen.height
119 | );
120 |
121 | return vector;
122 |
123 | };
124 |
125 | }() );
126 |
127 | var getMouseOnScreenByEvent = ( function () {
128 |
129 | var vector = new THREE.Vector2();
130 |
131 | return function (e) {
132 | console.log("getMouseOnScreenByEvent called!");
133 | var X = e.offsetX || ( e.pageX - _this.screen.left );
134 | var Y = e.offsetY || ( e.pageY - _this.screen.top );
135 | console.log(e, X, Y);
136 | vector.set(
137 | X / _this.screen.width,
138 | Y / _this.screen.height
139 | );
140 |
141 | return vector;
142 |
143 | };
144 |
145 | }() );
146 |
147 | var getMouseProjectionOnBall = ( function () {
148 |
149 | var vector = new THREE.Vector3();
150 | var objectUp = new THREE.Vector3();
151 | var mouseOnBall = new THREE.Vector3();
152 |
153 | return function ( pageX, pageY ) {
154 |
155 | mouseOnBall.set(
156 | ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5),
157 | ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / (_this.screen.height*.5),
158 | 0.0
159 | );
160 |
161 | var length = mouseOnBall.length();
162 |
163 | if ( _this.noRoll ) {
164 |
165 | if ( length < Math.SQRT1_2 ) {
166 |
167 | mouseOnBall.z = Math.sqrt( 1.0 - length*length );
168 |
169 | } else {
170 |
171 | mouseOnBall.z = .5 / length;
172 |
173 | }
174 |
175 | } else if ( length > 1.0 ) {
176 |
177 | mouseOnBall.normalize();
178 |
179 | } else {
180 |
181 | mouseOnBall.z = Math.sqrt( 1.0 - length * length );
182 |
183 | }
184 |
185 | _eye.copy( _this.object.position ).sub( _this.target );
186 |
187 | vector.copy( _this.object.up ).setLength( mouseOnBall.y )
188 | vector.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
189 | vector.add( _eye.setLength( mouseOnBall.z ) );
190 |
191 | return vector;
192 |
193 | };
194 |
195 | }() );
196 |
197 | this.rotateCamera = (function(){
198 |
199 | var axis = new THREE.Vector3(),
200 | quaternion = new THREE.Quaternion();
201 |
202 |
203 | return function () {
204 |
205 | var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
206 |
207 | if ( angle ) {
208 |
209 | axis.crossVectors( _rotateStart, _rotateEnd ).normalize();
210 |
211 | angle *= _this.rotateSpeed;
212 |
213 | quaternion.setFromAxisAngle( axis, -angle );
214 |
215 | _eye.applyQuaternion( quaternion );
216 | _this.object.up.applyQuaternion( quaternion );
217 |
218 | _rotateEnd.applyQuaternion( quaternion );
219 |
220 | if ( _this.staticMoving ) {
221 |
222 | _rotateStart.copy( _rotateEnd );
223 |
224 | } else {
225 |
226 | quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
227 | _rotateStart.applyQuaternion( quaternion );
228 |
229 | }
230 |
231 | }
232 | }
233 |
234 | }());
235 |
236 | this.zoomCamera = function () {
237 |
238 | if ( _state === STATE.TOUCH_ZOOM_PAN ) {
239 |
240 | var factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
241 | _touchZoomDistanceStart = _touchZoomDistanceEnd;
242 | _eye.multiplyScalar( factor );
243 |
244 | } else {
245 |
246 | var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
247 |
248 | if ( factor !== 1.0 && factor > 0.0 ) {
249 |
250 | _eye.multiplyScalar( factor );
251 |
252 | if ( _this.staticMoving ) {
253 |
254 | _zoomStart.copy( _zoomEnd );
255 |
256 | } else {
257 |
258 | _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
259 |
260 | }
261 |
262 | }
263 |
264 | }
265 |
266 | };
267 |
268 | this.panCamera = (function(){
269 |
270 | var mouseChange = new THREE.Vector2(),
271 | objectUp = new THREE.Vector3(),
272 | pan = new THREE.Vector3();
273 |
274 | return function () {
275 |
276 | mouseChange.copy( _panEnd ).sub( _panStart );
277 |
278 | if ( mouseChange.lengthSq() ) {
279 |
280 | mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
281 |
282 | pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
283 | pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) );
284 |
285 | _this.object.position.add( pan );
286 | _this.target.add( pan );
287 |
288 | if ( _this.staticMoving ) {
289 |
290 | _panStart.copy( _panEnd );
291 |
292 | } else {
293 |
294 | _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
295 |
296 | }
297 |
298 | }
299 | }
300 |
301 | }());
302 |
303 | this.checkDistances = function () {
304 |
305 | if ( !_this.noZoom || !_this.noPan ) {
306 |
307 | if ( _eye.lengthSq() > _this.maxDistance * _this.maxDistance ) {
308 |
309 | _this.object.position.addVectors( _this.target, _eye.setLength( _this.maxDistance ) );
310 |
311 | }
312 |
313 | if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {
314 |
315 | _this.object.position.addVectors( _this.target, _eye.setLength( _this.minDistance ) );
316 |
317 | }
318 |
319 | }
320 |
321 | };
322 |
323 | this.update = function () {
324 |
325 | _eye.subVectors( _this.object.position, _this.target );
326 |
327 | if ( !_this.noRotate ) {
328 |
329 | _this.rotateCamera();
330 |
331 | }
332 |
333 | if ( !_this.noZoom ) {
334 |
335 | _this.zoomCamera();
336 |
337 | }
338 |
339 | if ( !_this.noPan ) {
340 |
341 | _this.panCamera();
342 |
343 | }
344 |
345 | _this.object.position.addVectors( _this.target, _eye );
346 |
347 | _this.checkDistances();
348 |
349 | _this.object.lookAt( _this.target );
350 |
351 | if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) {
352 |
353 | _this.dispatchEvent( changeEvent );
354 |
355 | lastPosition.copy( _this.object.position );
356 |
357 | }
358 |
359 | };
360 |
361 | this.reset = function () {
362 |
363 | _state = STATE.NONE;
364 | _prevState = STATE.NONE;
365 |
366 | _this.target.copy( _this.target0 );
367 | _this.object.position.copy( _this.position0 );
368 | _this.object.up.copy( _this.up0 );
369 |
370 | _eye.subVectors( _this.object.position, _this.target );
371 |
372 | _this.object.lookAt( _this.target );
373 |
374 | _this.dispatchEvent( changeEvent );
375 |
376 | lastPosition.copy( _this.object.position );
377 |
378 | };
379 |
380 | // listeners
381 |
382 | function keydown( event ) {
383 |
384 | if ( _this.enabled === false ) return;
385 |
386 | window.removeEventListener( 'keydown', keydown );
387 |
388 | _prevState = _state;
389 |
390 | if ( _state !== STATE.NONE ) {
391 |
392 | return;
393 |
394 | } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && !_this.noRotate ) {
395 |
396 | _state = STATE.ROTATE;
397 |
398 | } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && !_this.noZoom ) {
399 |
400 | _state = STATE.ZOOM;
401 |
402 | } else if ( event.keyCode === _this.keys[ STATE.PAN ] && !_this.noPan ) {
403 |
404 | _state = STATE.PAN;
405 |
406 | }
407 |
408 | }
409 |
410 | function keyup( event ) {
411 |
412 | if ( _this.enabled === false ) return;
413 |
414 | _state = _prevState;
415 |
416 | window.addEventListener( 'keydown', keydown, false );
417 |
418 | }
419 |
420 | function mousedown( event ) {
421 |
422 | if ( _this.enabled === false ) return;
423 |
424 | event.preventDefault();
425 | event.stopPropagation();
426 |
427 | if ( _state === STATE.NONE ) {
428 |
429 | _state = event.button;
430 |
431 | }
432 |
433 | if ( _state === STATE.ROTATE && !_this.noRotate ) {
434 |
435 | _rotateStart.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) );
436 | _rotateEnd.copy( _rotateStart );
437 |
438 | } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
439 |
440 | _zoomStart.copy( getMouseOnScreenByEvent( event ) );
441 | _zoomEnd.copy(_zoomStart);
442 |
443 | } else if ( _state === STATE.PAN && !_this.noPan ) {
444 |
445 | _panStart.copy( getMouseOnScreenByEvent( event ) );
446 | _panEnd.copy(_panStart)
447 |
448 | }
449 |
450 | document.addEventListener( 'mousemove', mousemove, false );
451 | document.addEventListener( 'mouseup', mouseup, false );
452 |
453 | _this.dispatchEvent( startEvent );
454 |
455 | }
456 |
457 | function mousemove( event ) {
458 |
459 | if ( _this.enabled === false ) return;
460 |
461 | event.preventDefault();
462 | event.stopPropagation();
463 |
464 | if ( _state === STATE.ROTATE && !_this.noRotate ) {
465 |
466 | _rotateEnd.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) );
467 |
468 | } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
469 |
470 | _zoomEnd.copy( getMouseOnScreenByEvent( event ) );
471 |
472 | } else if ( _state === STATE.PAN && !_this.noPan ) {
473 |
474 | _panEnd.copy( getMouseOnScreenByEvent( event ) );
475 |
476 | }
477 |
478 | }
479 |
480 | function mouseup( event ) {
481 |
482 | if ( _this.enabled === false ) return;
483 |
484 | event.preventDefault();
485 | event.stopPropagation();
486 |
487 | _state = STATE.NONE;
488 |
489 | document.removeEventListener( 'mousemove', mousemove );
490 | document.removeEventListener( 'mouseup', mouseup );
491 | _this.dispatchEvent( endEvent );
492 |
493 | }
494 |
495 | function mousewheel( event ) {
496 |
497 | if ( _this.enabled === false ) return;
498 |
499 | event.preventDefault();
500 | event.stopPropagation();
501 |
502 | var delta = 0;
503 |
504 | if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
505 |
506 | delta = event.wheelDelta / 40;
507 |
508 | } else if ( event.detail ) { // Firefox
509 |
510 | delta = - event.detail / 3;
511 |
512 | }
513 |
514 | _zoomStart.y += delta * 0.01;
515 | _this.dispatchEvent( startEvent );
516 | _this.dispatchEvent( endEvent );
517 |
518 | }
519 |
520 | function touchstart( event ) {
521 |
522 | if ( _this.enabled === false ) return;
523 |
524 | switch ( event.touches.length ) {
525 |
526 | case 1:
527 | _state = STATE.TOUCH_ROTATE;
528 | _rotateStart.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
529 | _rotateEnd.copy( _rotateStart );
530 | break;
531 |
532 | case 2:
533 | _state = STATE.TOUCH_ZOOM_PAN;
534 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
535 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
536 | _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
537 |
538 | var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
539 | var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
540 | _panStart.copy( getMouseOnScreen( x, y ) );
541 | _panEnd.copy( _panStart );
542 | break;
543 |
544 | default:
545 | _state = STATE.NONE;
546 |
547 | }
548 | _this.dispatchEvent( startEvent );
549 |
550 |
551 | }
552 |
553 | function touchmove( event ) {
554 |
555 | if ( _this.enabled === false ) return;
556 |
557 | event.preventDefault();
558 | event.stopPropagation();
559 |
560 | switch ( event.touches.length ) {
561 |
562 | case 1:
563 | _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
564 | break;
565 |
566 | case 2:
567 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
568 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
569 | _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
570 |
571 | var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
572 | var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
573 | _panEnd.copy( getMouseOnScreen( x, y ) );
574 | break;
575 |
576 | default:
577 | _state = STATE.NONE;
578 |
579 | }
580 |
581 | }
582 |
583 | function touchend( event ) {
584 |
585 | if ( _this.enabled === false ) return;
586 |
587 | switch ( event.touches.length ) {
588 |
589 | case 1:
590 | _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
591 | _rotateStart.copy( _rotateEnd );
592 | break;
593 |
594 | case 2:
595 | _touchZoomDistanceStart = _touchZoomDistanceEnd = 0;
596 |
597 | var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
598 | var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
599 | _panEnd.copy( getMouseOnScreen( x, y ) );
600 | _panStart.copy( _panEnd );
601 | break;
602 |
603 | }
604 |
605 | _state = STATE.NONE;
606 | _this.dispatchEvent( endEvent );
607 |
608 | }
609 |
610 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
611 |
612 | this.domElement.addEventListener( 'mousedown', mousedown, false );
613 |
614 | this.domElement.addEventListener( 'mousewheel', mousewheel, false );
615 | this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox
616 |
617 | this.domElement.addEventListener( 'touchstart', touchstart, false );
618 | this.domElement.addEventListener( 'touchend', touchend, false );
619 | this.domElement.addEventListener( 'touchmove', touchmove, false );
620 |
621 | window.addEventListener( 'keydown', keydown, false );
622 | window.addEventListener( 'keyup', keyup, false );
623 |
624 | this.handleResize();
625 |
626 | // force an update at start
627 | this.update();
628 |
629 | };
630 |
631 | THREE.TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );
632 |
--------------------------------------------------------------------------------