1 /* Copyright 2018 Paul Hänsch
3 This file is part of Serve0
5 Serve0 is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Affero General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 Serve0 is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with Serve0 If not, see <http://www.gnu.org/licenses/>.
19 var render, video, controlTimeout = 0;
20 var pitch = 0, roll = 0, yaw = 0;
21 var w, h, hdeg, vdeg, scale, fov = 90;
22 var lv = document.createElement("canvas");
23 var rv = document.createElement("canvas");
24 var debug = document.createElement("p");
30 dh = h / 2 * scale |0;
32 if ( layout == "180" ) {
33 sx = (w / 2 - fov * hdeg) / 2 + yaw * hdeg |0;
34 sy = ( h - fov * vdeg) / 2 + pitch * vdeg |0;
35 if (sx + sw > w / 2) { sx = w / 2 - sw; } else if (sx < 0) { sx = 0; }
36 lc.drawImage(video, sx, sy, sw, sh, 0, 0, lv.width, dh);
37 rc.drawImage(video, w / 2 + sx, sy, sw, sh, 0, 0, rv.width, dh);
39 sx = (w - fov * hdeg) / 2 + yaw * hdeg |0;
40 sy = (h - fov * vdeg) / 4 + pitch * vdeg |0;
41 lc.drawImage(video, sx, sy, sw, sh, 0, 0, lv.width, dh);
42 rc.drawImage(video, sx, h/2 + sy, sw, sh, 0, 0, rv.width, dh);
44 lc.drawImage(video, sx + w, sy, sw, sh, 0, 0, lv.width, dh);
45 rc.drawImage(video, sx + w, h/2 + sy, sw, sh, 0, 0, rv.width, dh);
46 } else if ( sx + fov * hdeg > w) {
47 lc.drawImage(video, sx - w, sy, sw, sh, 0, 0, lv.width, dh);
48 rc.drawImage(video, sx - w, h/2 + sy, sw, sh, 0, 0, rv.width, dh);
52 lv.style.transform = "rotate(" + roll + "deg)";
53 rv.style.transform = "rotate(" + roll + "deg)";
55 requestAnimationFrame(draw);
57 gp = navigator.getGamepads()[0];
58 if ( gp && Date.now() > controlTimeout ) {
59 if ( gp.axes[0] > .3) { video.currentTime += 10; controlTimeout = Date.now() + 500; }
60 if ( gp.axes[0] < -.3) { video.currentTime -= 10; controlTimeout = Date.now() + 500; }
61 if ( gp.axes[1] < -.3) { video.currentTime += 60; controlTimeout = Date.now() + 500; }
62 if ( gp.axes[1] > .3) { video.currentTime -= 60; controlTimeout = Date.now() + 500; }
63 if ( gp.buttons[0].pressed ) { video.currentTime += 1/30; video.pause(); }
64 if ( gp.buttons[1].pressed ) { video.play(); }
65 if ( gp.buttons[2].pressed ) { fov -= 10; controlTimeout = Date.now() + 500; }
66 if ( gp.buttons[3].pressed ) { fov += 10; controlTimeout = Date.now() + 500; }
69 // debug.textContent = "" + video.currentTime + " " + controlTimeout + " " + tx + " " + ty + " " + tz;
72 function stereoview(layout, video) {
73 this.layout = layout; this.video = video;
74 document.body.appendChild( lv );
75 document.body.appendChild( rv );
76 document.body.appendChild( debug );
78 lv.setAttribute( "style", "position: fixed; top: 0; left: 0 ; width: 50%; height: 100%; z-index: 100;");
79 rv.setAttribute( "style", "position: fixed; top: 0; left: 50%; width: 50%; height: 100%; z-index: 100;");
80 debug.setAttribute( "style", "position: fixed; top: 0; left: 0; z-index: 101; background: #000;");
82 lv.setAttribute( "width", "" + lv.offsetWidth);
83 rv.setAttribute( "width", "" + rv.offsetWidth);
84 lv.setAttribute("height", "" + lv.offsetHeight);
85 rv.setAttribute("height", "" + rv.offsetHeight);
87 lc = lv.getContext("2d");
88 rc = rv.getContext("2d");
90 mpuevent = new EventSource("http://localhost:314");
91 var x = [], y = [], z = [], cnt = -1, inertia = 6;
93 mpuevent.addEventListener("bearing", function(e) {
94 bearing = e.data.split(" ");
95 yaw = -parseFloat(bearing[0]);
97 mpuevent.addEventListener("motion", function(e) {
98 motion = e.data.split(" ");
100 cnt = (cnt + 1) % inertia;
101 x[cnt] = parseFloat(motion[0]);
102 y[cnt] = parseFloat(motion[1]);
103 z[cnt] = parseFloat(motion[2]);
105 // tx = 0; x.forEach( function(n, i){ tx += n; } ); tx /= inertia;
106 ty = 0; y.forEach( function(n, i){ ty += n; } ); ty /= inertia;
107 tz = 0; z.forEach( function(n, i){ tz += n; } ); tz /= inertia;
109 pitch = Math.asin((tz / 9.81 > 1)?1:(tz/9.81)) / Math.PI * 180 + 22.5;
110 roll = - Math.asin((ty / 9.81 > 1)?1:(ty/9.81)) / Math.PI * 180;
111 // yaw = (yaw + ty) % 360;
114 window.addEventListener("devicemotion", (function() {
115 var x = [], y = [], z = [], cnt = -1, inertia = 6;
116 return function(event) {
117 cnt = (cnt + 1) % inertia;
119 x[cnt] = event.accelerationIncludingGravity.x;
120 y[cnt] = event.accelerationIncludingGravity.y;
121 z[cnt] = event.accelerationIncludingGravity.z;
123 tx = 0; x.forEach( function(n, i){ tx += n; } ); tx /= inertia;
124 ty = 0; y.forEach( function(n, i){ ty += n; } ); ty /= inertia;
125 tz = 0; z.forEach( function(n, i){ tz += n; } ); tz /= inertia;
127 pitch = Math.asin((tz / 9.81 > 1)?1:(tz/9.81)) / Math.PI * 180 + 22.5;
128 roll = - Math.asin((ty / 9.81 > 1)?1:(ty/9.81)) / Math.PI * 180;
129 yaw = (yaw + ty) % 360;
133 window.addEventListener("click", function(event) {
134 (lv.parentElement)?lv.parentElement.removeChild(lv):{};
135 (rv.parentElement)?rv.parentElement.removeChild(rv):{};
136 video.style.display = "block";
140 w = video.videoWidth; h = video.videoHeight;
141 hdeg = w / 360; vdeg = h / 180;
142 scale = lv.width / (fov * hdeg |0);
143 // scale = lv.width / (w / 4);
145 video.style.display = "none";