mirror of
https://github.com/damouse/Drop64.git
synced 2024-05-16 02:50:40 -04:00
refactor
This commit is contained in:
parent
a9691fc88a
commit
36599e89f6
|
@ -19,4 +19,4 @@ Note that the controller portion of this app comes in a smartphone flavor too. S
|
|||
|
||||
- Multiplayer
|
||||
- Canvas Streaming
|
||||
|
||||
- Lobbies
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
MIN_TIMESTEP = 0.001;
|
||||
MAX_TIMESTEP = 1;
|
||||
|
||||
function ComplementaryOrientation() {
|
||||
this.accelerometer = new THREE.Vector3();
|
||||
this.gyroscope = new THREE.Vector3();
|
||||
|
||||
window.addEventListener('devicemotion', this.onDeviceMotionChange_.bind(this));
|
||||
window.addEventListener('orientationchange', this.onScreenOrientationChange_.bind(this));
|
||||
|
||||
this.filter = new ComplementaryFilter(0.98);
|
||||
this.posePredictor = new PosePredictor(0.050);
|
||||
|
||||
this.filterToWorldQ = new THREE.Quaternion();
|
||||
|
||||
// Set the filter to world transform, but only for Android.
|
||||
if (Util.isIOS()) {
|
||||
this.filterToWorldQ.setFromAxisAngle(new THREE.Vector3(1, 0, 0), Math.PI/2);
|
||||
} else {
|
||||
this.filterToWorldQ.setFromAxisAngle(new THREE.Vector3(1, 0, 0), -Math.PI/2);
|
||||
}
|
||||
|
||||
this.worldToScreenQ = new THREE.Quaternion();
|
||||
this.setScreenTransform_();
|
||||
}
|
||||
|
||||
ComplementaryOrientation.prototype.onDeviceMotionChange_ = function(deviceMotion) {
|
||||
var accGravity = deviceMotion.accelerationIncludingGravity;
|
||||
var rotRate = deviceMotion.rotationRate;
|
||||
var timestampS = deviceMotion.timeStamp / 1000;
|
||||
|
||||
var deltaS = timestampS - this.previousTimestampS;
|
||||
if (deltaS <= MIN_TIMESTEP || deltaS > MAX_TIMESTEP) {
|
||||
console.warn('Invalid timestamps detected. Time step between successive ' +
|
||||
'gyroscope sensor samples is very small or not monotonic');
|
||||
this.previousTimestampS = timestampS;
|
||||
return;
|
||||
}
|
||||
this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);
|
||||
this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);
|
||||
|
||||
// In iOS, rotationRate is reported in degrees, so we first convert to
|
||||
// radians.
|
||||
if (Util.isIOS()) {
|
||||
this.gyroscope.multiplyScalar(Math.PI / 180);
|
||||
}
|
||||
|
||||
this.filter.addAccelMeasurement(this.accelerometer, timestampS);
|
||||
this.filter.addGyroMeasurement(this.gyroscope, timestampS);
|
||||
|
||||
this.previousTimestampS = timestampS;
|
||||
};
|
||||
|
||||
ComplementaryOrientation.prototype.onScreenOrientationChange_ =
|
||||
function(screenOrientation) {
|
||||
this.setScreenTransform_();
|
||||
};
|
||||
|
||||
ComplementaryOrientation.prototype.setScreenTransform_ = function() {
|
||||
this.worldToScreenQ.set(0, 0, 0, 1);
|
||||
switch (window.orientation) {
|
||||
case 0:
|
||||
break;
|
||||
case 90:
|
||||
this.worldToScreenQ.setFromAxisAngle(new THREE.Vector3(0, 0, 1), -Math.PI/2);
|
||||
break;
|
||||
case -90:
|
||||
this.worldToScreenQ.setFromAxisAngle(new THREE.Vector3(0, 0, 1), Math.PI/2);
|
||||
break;
|
||||
case 180:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
ComplementaryOrientation.prototype.getOrientation = function() {
|
||||
// Convert from filter space to the the same system used by the
|
||||
// deviceorientation event.
|
||||
var orientation = this.filter.getOrientation();
|
||||
|
||||
// Predict orientation.
|
||||
this.predictedQ = this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);
|
||||
|
||||
// Convert to THREE coordinate system: -Z forward, Y up, X right.
|
||||
var out = new THREE.Quaternion();
|
||||
out.copy(this.filterToWorldQ);
|
||||
out.multiply(this.predictedQ);
|
||||
out.multiply(this.worldToScreenQ);
|
||||
return out;
|
||||
};
|
|
@ -1,72 +0,0 @@
|
|||
// Create a three.js scene in which the camera is controlled by the orientation
|
||||
// from the complementary filter.
|
||||
|
||||
var co = new ComplementaryOrientation();
|
||||
|
||||
var scene = new THREE.Scene();
|
||||
|
||||
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
|
||||
camera.position.z = -1;
|
||||
|
||||
var renderer = new THREE.WebGLRenderer();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
var geometry = new THREE.SphereGeometry( 1, 16, 16 );
|
||||
var material = new THREE.MeshBasicMaterial( {color: 'red', wireframe: true} );
|
||||
var sphereX = new THREE.Mesh( geometry, material );
|
||||
sphereX.position.set(5, 0, 0);
|
||||
scene.add( sphereX );
|
||||
|
||||
var geometry = new THREE.SphereGeometry( 1, 16, 16 );
|
||||
var material = new THREE.MeshBasicMaterial( {color: 'green', wireframe: true} );
|
||||
var sphereY = new THREE.Mesh( geometry, material );
|
||||
sphereY.position.set(0, 5, 0);
|
||||
scene.add( sphereY );
|
||||
|
||||
var geometry = new THREE.SphereGeometry( 1, 16, 16 );
|
||||
var material = new THREE.MeshBasicMaterial( {color: 'blue', wireframe: true} );
|
||||
var sphereZ = new THREE.Mesh( geometry, material );
|
||||
sphereZ.position.set(0, 0, 5);
|
||||
scene.add( sphereZ );
|
||||
|
||||
var geometry = new THREE.SphereGeometry( 1, 16, 16 );
|
||||
var material = new THREE.MeshBasicMaterial( {color: 'cyan', wireframe: true} );
|
||||
var sphereBottom = new THREE.Mesh( geometry, material );
|
||||
sphereBottom.position.set(0, -5, 0);
|
||||
scene.add( sphereBottom );
|
||||
|
||||
// Add a repeating grid as a skybox.
|
||||
var boxWidth = 10;
|
||||
var texture = THREE.ImageUtils.loadTexture(
|
||||
'img/box.png'
|
||||
);
|
||||
texture.wrapS = THREE.RepeatWrapping;
|
||||
texture.wrapT = THREE.RepeatWrapping;
|
||||
texture.repeat.set(boxWidth, boxWidth);
|
||||
|
||||
var geometry = new THREE.BoxGeometry(boxWidth, boxWidth, boxWidth);
|
||||
var material = new THREE.MeshBasicMaterial({
|
||||
map: texture,
|
||||
color: 0xffffff,
|
||||
side: THREE.BackSide
|
||||
});
|
||||
|
||||
var skybox = new THREE.Mesh(geometry, material);
|
||||
scene.add(skybox);
|
||||
|
||||
function render() {
|
||||
camera.quaternion.copy(co.getOrientation());
|
||||
|
||||
requestAnimationFrame( render );
|
||||
renderer.render( scene, camera );
|
||||
}
|
||||
render();
|
||||
|
||||
|
||||
window.addEventListener('resize', function() {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
|
||||
renderer.setSize( window.innerWidth, window.innerHeight );
|
||||
});
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Copyright 2015 Google Inc. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var DEBUG = false;
|
||||
|
||||
/**
|
||||
* Given an orientation and the gyroscope data, predicts the future orientation
|
||||
* of the head. This makes rendering appear faster.
|
||||
*
|
||||
* Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf
|
||||
*
|
||||
* @param {Number} predictionTimeS time from head movement to the appearance of
|
||||
* the corresponding image.
|
||||
*/
|
||||
function PosePredictor(predictionTimeS) {
|
||||
this.predictionTimeS = predictionTimeS;
|
||||
|
||||
// The quaternion corresponding to the previous state.
|
||||
this.previousQ = new THREE.Quaternion();
|
||||
// Previous time a prediction occurred.
|
||||
this.previousTimestampS = null;
|
||||
|
||||
// The delta quaternion that adjusts the current pose.
|
||||
this.deltaQ = new THREE.Quaternion();
|
||||
// The output quaternion.
|
||||
this.outQ = new THREE.Quaternion();
|
||||
}
|
||||
|
||||
PosePredictor.prototype.getPrediction = function(currentQ, gyro, timestampS) {
|
||||
if (!this.previousTimestampS) {
|
||||
this.previousQ.copy(currentQ);
|
||||
this.previousTimestampS = timestampS;
|
||||
return currentQ;
|
||||
}
|
||||
|
||||
// Calculate axis and angle based on gyroscope rotation rate data.
|
||||
var axis = new THREE.Vector3();
|
||||
axis.copy(gyro);
|
||||
axis.normalize();
|
||||
|
||||
var angularSpeed = gyro.length();
|
||||
|
||||
// If we're rotating slowly, don't do prediction.
|
||||
if (angularSpeed < THREE.Math.degToRad(20)) {
|
||||
if (DEBUG) {
|
||||
console.log('Moving slowly, at %s deg/s: no prediction',
|
||||
THREE.Math.radToDeg(angularSpeed).toFixed(1));
|
||||
}
|
||||
this.outQ.copy(currentQ);
|
||||
this.previousQ.copy(currentQ);
|
||||
return this.outQ;
|
||||
}
|
||||
|
||||
// Get the predicted angle based on the time delta and latency.
|
||||
var deltaT = timestampS - this.previousTimestampS;
|
||||
var predictAngle = angularSpeed * this.predictionTimeS;
|
||||
|
||||
this.deltaQ.setFromAxisAngle(axis, predictAngle);
|
||||
this.outQ.copy(this.previousQ);
|
||||
this.outQ.multiply(this.deltaQ);
|
||||
|
||||
this.previousQ.copy(currentQ);
|
||||
|
||||
return this.outQ;
|
||||
};
|
|
@ -1,12 +0,0 @@
|
|||
function SensorSample(sample, timestampS) {
|
||||
this.set(sample, timestampS);
|
||||
};
|
||||
|
||||
SensorSample.prototype.set = function(sample, timestampS) {
|
||||
this.sample = sample;
|
||||
this.timestampS = timestampS;
|
||||
};
|
||||
|
||||
SensorSample.prototype.copy = function(sensorSample) {
|
||||
this.set(sensorSample.sample, sensorSample.timestampS);
|
||||
};
|
|
@ -16,11 +16,7 @@
|
|||
"license": "MIT",
|
||||
"homepage": "https://github.com/christianalfoni/webpack-express-boilerplate",
|
||||
"scripts": {
|
||||
"test": "",
|
||||
"start": "node server",
|
||||
"build": "rimraf dist && cross-env NODE_ENV=production webpack --config ./webpack.production.config.js --progress --profile --colors",
|
||||
"eslint": "eslint .",
|
||||
"jscs": "jscs ."
|
||||
"start": "node src/server"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-cli": "^6.4.0",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version: 1
|
||||
type: light
|
||||
use: node
|
||||
command: node server
|
||||
command: npm start
|
|
@ -26,7 +26,7 @@ function loop() {
|
|||
lastGyro.applyQuaternion(invGyroOnly);
|
||||
lastGyro.normalize();
|
||||
gyroHistory.push(lastGyro);
|
||||
console.log('G: ', lastGyro);
|
||||
// console.log('G: ', lastGyro);
|
||||
} else {
|
||||
gyroHistory.data = [];
|
||||
}
|
|
@ -3,9 +3,12 @@ const app = express();
|
|||
var http = require('http').Server(app);
|
||||
var io = require('socket.io')(http);
|
||||
|
||||
app.use('/assets', express.static('./app'));
|
||||
app.get('/', (req, res) => { res.sendFile('index.html', { root: './app' }) })
|
||||
app.get('/controller', (req, res) => { res.sendFile('controller.html', { root: './app' }) })
|
||||
app.get('/', (req, res) => { res.sendFile('display.html', { root: 'views' }) })
|
||||
app.get('/controller', (req, res) => { res.sendFile('controller.html', { root: 'views' }) })
|
||||
|
||||
for (var d of["stylesheets", "vendor", "sensors", "src"]) {
|
||||
app.use('/assets', express.static(d));
|
||||
}
|
||||
|
||||
io.on('connection', (socket) => {
|
||||
socket.on("controller", (m) => io.emit('input', m))
|
|
@ -5,17 +5,17 @@
|
|||
<meta charset='utf-8' />
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="/assets/stylesheets/controller.css">
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="/assets/controller.css">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
|
||||
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
|
||||
<script src="assets/vendor/three.min.js"></script>
|
||||
<script src="assets/vendor/mathbox/build/mathbox-bundle.js"></script>
|
||||
<script src="assets/vendor/cbuffer/cbuffer.js"></script>
|
||||
<script src="assets/vendor/dat.gui/dat.gui.js"></script>
|
||||
<script src="assets/three.min.js"></script>
|
||||
<script src="assets/mathbox/build/mathbox-bundle.js"></script>
|
||||
<script src="assets/cbuffer/cbuffer.js"></script>
|
||||
<script src="assets/dat.gui/dat.gui.js"></script>
|
||||
|
||||
<script type='text/javascript' src='assets/controller.js'></script>
|
||||
|
||||
|
@ -24,9 +24,9 @@
|
|||
|
||||
<body ng-app="controller" ng-controller='RootController'>
|
||||
|
||||
<script src="assets/sensors/util.js"></script>
|
||||
<script src="assets/sensors/complementary-filter.js"></script>
|
||||
<script src="assets/sensors/plot-sensors.js"></script>
|
||||
<script src="assets/util.js"></script>
|
||||
<script src="assets/complementary-filter.js"></script>
|
||||
<script src="assets/plot-sensors.js"></script>
|
||||
|
||||
<div class='container'>
|
||||
<div class='row main-row'></div>
|
|
@ -4,7 +4,7 @@
|
|||
<head>
|
||||
<meta charset='utf-8' />
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="/assets/stylesheets/stylesheet.css">
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="assets/stylesheet.css">
|
||||
|
||||
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
|
@ -20,8 +20,6 @@
|
|||
<div id='filechooser' style="visibility:hidden;">
|
||||
<input type="file" id="files" name="files[]" multiple />
|
||||
<output id="list"></output>
|
||||
<script>
|
||||
</script>
|
||||
</div>
|
||||
<div class="emscripten">
|
||||
<progress value="0" max="100" id="progress" hidden=1></progress>
|
||||
|
@ -29,7 +27,7 @@
|
|||
<div class="emscripten_border">
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
</div>
|
||||
<script type='text/javascript' src='assets/main.js'></script>
|
||||
<script type='text/javascript' src='assets/display.js'></script>
|
||||
<script async type="text/javascript" src="assets/mupen64plus-ui-console.js"></script>
|
||||
</p>
|
||||
</section>
|
Loading…
Reference in a new issue