123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
- /******/ (function(modules) { // webpackBootstrap
- /******/ // The module cache
- /******/ var installedModules = {};
- /******/ // The require function
- /******/ function __webpack_require__(moduleId) {
- /******/ // Check if module is in cache
- /******/ if(installedModules[moduleId])
- /******/ return installedModules[moduleId].exports;
- /******/ // Create a new module (and put it into the cache)
- /******/ var module = installedModules[moduleId] = {
- /******/ exports: {},
- /******/ id: moduleId,
- /******/ loaded: false
- /******/ };
- /******/ // Execute the module function
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
- /******/ // Flag the module as loaded
- /******/ module.loaded = true;
- /******/ // Return the exports of the module
- /******/ return module.exports;
- /******/ }
- /******/ // expose the modules object (__webpack_modules__)
- /******/ __webpack_require__.m = modules;
- /******/ // expose the module cache
- /******/ __webpack_require__.c = installedModules;
- /******/ // __webpack_public_path__
- /******/ __webpack_require__.p = "";
- /******/ // Load entry module and return exports
- /******/ return __webpack_require__(0);
- /******/ })
- /************************************************************************/
- /******/ ([
- /* 0 */
- /***/ function(module, exports, __webpack_require__) {
-
- // Browser distrubution of the A-Frame component.
- (function (AFRAME) {
- if (!AFRAME) {
- console.error('Component attempted to register before AFRAME was available.');
- return;
- }
- (AFRAME.aframeCore || AFRAME).registerComponent('gamepad-controls', __webpack_require__(1));
- }(window.AFRAME));
- /***/ },
- /* 1 */
- /***/ function(module, exports, __webpack_require__) {
- /**
- * Gamepad controls for A-Frame.
- *
- * For more information about the Gamepad API, see:
- * https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API
- */
- var GamepadButton = __webpack_require__(2),
- GamepadButtonEvent = __webpack_require__(3);
- var MAX_DELTA = 200, // ms
- PI_2 = Math.PI / 2;
- var JOYSTICK_EPS = 0.2;
- module.exports = {
- /*******************************************************************
- * Statics
- */
- GamepadButton: GamepadButton,
- /*******************************************************************
- * Schema
- */
- schema: {
- // Controller 0-3
- controller: { default: 0, oneOf: [0, 1, 2, 3] },
- // Enable/disable features
- enabled: { default: true },
- movementEnabled: { default: true },
- lookEnabled: { default: true },
- flyEnabled: { default: false },
- invertAxisY: { default: false },
- // Constants
- easing: { default: 20 },
- acceleration: { default: 65 },
- sensitivity: { default: 0.04 },
- // Control axes
- pitchAxis: { default: 'x', oneOf: [ 'x', 'y', 'z' ] },
- yawAxis: { default: 'y', oneOf: [ 'x', 'y', 'z' ] },
- rollAxis: { default: 'z', oneOf: [ 'x', 'y', 'z' ] },
- // Debugging
- debug: { default: false }
- },
- /*******************************************************************
- * Core
- */
- /**
- * Called once when component is attached. Generally for initial setup.
- */
- init: function () {
- // Movement
- this.velocity = new THREE.Vector3(0, 0, 0);
- this.direction = new THREE.Vector3(0, 0, 0);
- // Rotation
- this.pitch = new THREE.Object3D();
- this.yaw = new THREE.Object3D();
- this.yaw.position.y = 10;
- this.yaw.add(this.pitch);
- // Button state
- this.buttons = {};
- if (!this.getGamepad()) {
- console.warn(
- 'Gamepad #%d not found. Connect controller and press any button to continue.',
- this.data.controller
- );
- }
- },
- /**
- * Called on each iteration of main render loop.
- */
- tick: function (t, dt) {
- this.updateRotation(dt);
- this.updatePosition(dt);
- this.updateButtonState();
- },
- /*******************************************************************
- * Movement
- */
- updatePosition: function (dt) {
- var data = this.data;
- var acceleration = data.acceleration;
- var easing = data.easing;
- var velocity = this.velocity;
- var rollAxis = data.rollAxis;
- var pitchAxis = data.pitchAxis;
- var el = this.el;
- var gamepad = this.getGamepad();
- // If data has changed or FPS is too low
- // we reset the velocity
- if (dt > MAX_DELTA) {
- velocity[rollAxis] = 0;
- velocity[pitchAxis] = 0;
- return;
- }
- velocity[rollAxis] -= velocity[rollAxis] * easing * dt / 1000;
- velocity[pitchAxis] -= velocity[pitchAxis] * easing * dt / 1000;
- var position = el.getAttribute('position');
- if (data.enabled && data.movementEnabled && gamepad) {
- var dpad = this.getDpad(),
- inputX = dpad.x || this.getJoystick(0).x,
- inputY = dpad.y || this.getJoystick(0).y;
- if (Math.abs(inputX) > JOYSTICK_EPS) {
- velocity[pitchAxis] += inputX * acceleration * dt / 1000;
- }
- if (Math.abs(inputY) > JOYSTICK_EPS) {
- velocity[rollAxis] += inputY * acceleration * dt / 1000;
- }
- }
- var movementVector = this.getMovementVector(dt);
- el.object3D.translateX(movementVector.x);
- el.object3D.translateY(movementVector.y);
- el.object3D.translateZ(movementVector.z);
- el.setAttribute('position', {
- x: position.x + movementVector.x,
- y: position.y + movementVector.y,
- z: position.z + movementVector.z
- });
- },
- getMovementVector: function (dt) {
- if (this._getMovementVector) {
- return this._getMovementVector(dt);
- }
- var euler = new THREE.Euler(0, 0, 0, 'YXZ'),
- rotation = new THREE.Vector3();
- this._getMovementVector = function (dt) {
- rotation.copy(this.el.getAttribute('rotation'));
- this.direction.copy(this.velocity);
- this.direction.multiplyScalar(dt / 1000);
- if (!rotation) { return this.direction; }
- if (!this.data.flyEnabled) { rotation.x = 0; }
- euler.set(
- THREE.Math.degToRad(rotation.x),
- THREE.Math.degToRad(rotation.y),
- 0
- );
- this.direction.applyEuler(euler);
- return this.direction;
- };
- return this._getMovementVector(dt);
- },
- /*******************************************************************
- * Rotation
- */
- updateRotation: function () {
- if (this._updateRotation) {
- return this._updateRotation();
- }
- var initialRotation = new THREE.Vector3(),
- prevInitialRotation = new THREE.Vector3(),
- prevFinalRotation = new THREE.Vector3();
- var tCurrent,
- tLastLocalActivity = 0,
- tLastExternalActivity = 0;
- var ROTATION_EPS = 0.0001,
- DEBOUNCE = 500;
- this._updateRotation = function () {
- if (!this.data.lookEnabled || !this.getGamepad()) {
- return;
- }
- tCurrent = Date.now();
- initialRotation.copy(this.el.getAttribute('rotation') || initialRotation);
- // If initial rotation for this frame is different from last frame, and
- // doesn't match last gamepad state, assume an external component is
- // active on this element.
- if (initialRotation.distanceToSquared(prevInitialRotation) > ROTATION_EPS
- && initialRotation.distanceToSquared(prevFinalRotation) > ROTATION_EPS) {
- prevInitialRotation.copy(initialRotation);
- tLastExternalActivity = tCurrent;
- return;
- }
- prevInitialRotation.copy(initialRotation);
- // If external controls have been active in last 500ms, wait.
- if (tCurrent - tLastExternalActivity < DEBOUNCE) {
- return;
- }
- var lookVector = this.getJoystick(1);
- if (Math.abs(lookVector.x) <= JOYSTICK_EPS) lookVector.x = 0;
- if (Math.abs(lookVector.y) <= JOYSTICK_EPS) lookVector.y = 0;
- if (this.data.invertAxisY) lookVector.y = -lookVector.y;
- // If external controls have been active more recently than gamepad,
- // and gamepad hasn't moved, don't overwrite the existing rotation.
- if (tLastExternalActivity > tLastLocalActivity && !lookVector.lengthSq()) {
- return;
- }
- lookVector.multiplyScalar(this.data.sensitivity);
- this.yaw.rotation.y -= lookVector.x;
- this.pitch.rotation.x -= lookVector.y;
- this.pitch.rotation.x = Math.max(-PI_2, Math.min(PI_2, this.pitch.rotation.x));
- this.el.setAttribute('rotation', {
- x: THREE.Math.radToDeg(this.pitch.rotation.x),
- y: THREE.Math.radToDeg(this.yaw.rotation.y),
- z: 0
- });
- prevFinalRotation.copy(this.el.getAttribute('rotation'));
- tLastLocalActivity = tCurrent;
- };
- return this._updateRotation();
- },
- /*******************************************************************
- * Button events
- */
- updateButtonState: function () {
- var gamepad = this.getGamepad();
- if (this.data.enabled && gamepad) {
- // Fire DOM events for button state changes.
- for (var i = 0; i < gamepad.buttons.length; i++) {
- if (gamepad.buttons[i].pressed && !this.buttons[i]) {
- this.emit(new GamepadButtonEvent('gamepadbuttondown', i, gamepad.buttons[i]));
- } else if (!gamepad.buttons[i].pressed && this.buttons[i]) {
- this.emit(new GamepadButtonEvent('gamepadbuttonup', i, gamepad.buttons[i]));
- }
- this.buttons[i] = gamepad.buttons[i].pressed;
- }
- } else if (Object.keys(this.buttons)) {
- // Reset state if controls are disabled or controller is lost.
- this.buttons = {};
- }
- },
- emit: function (event) {
- // Emit original event.
- this.el.emit(event.type, event);
- // Emit convenience event, identifying button index.
- this.el.emit(
- event.type + ':' + event.index,
- new GamepadButtonEvent(event.type, event.index, event)
- );
- },
- /*******************************************************************
- * Gamepad state
- */
- /**
- * Returns the Gamepad instance attached to the component. If connected,
- * a proxy-controls component may provide access to Gamepad input from a
- * remote device.
- *
- * @return {Gamepad}
- */
- getGamepad: function () {
- var localGamepad = navigator.getGamepads
- && navigator.getGamepads()[this.data.controller],
- proxyControls = this.el.sceneEl.components['proxy-controls'],
- proxyGamepad = proxyControls && proxyControls.isConnected()
- && proxyControls.getGamepad(this.data.controller);
- return proxyGamepad || localGamepad;
- },
- /**
- * Returns the state of the given button.
- * @param {number} index The button (0-N) for which to find state.
- * @return {GamepadButton}
- */
- getButton: function (index) {
- return this.getGamepad().buttons[index];
- },
- /**
- * Returns state of the given axis. Axes are labelled 0-N, where 0-1 will
- * represent X/Y on the first joystick, and 2-3 X/Y on the second.
- * @param {number} index The axis (0-N) for which to find state.
- * @return {number} On the interval [-1,1].
- */
- getAxis: function (index) {
- return this.getGamepad().axes[index];
- },
- /**
- * Returns the state of the given joystick (0 or 1) as a THREE.Vector2.
- * @param {number} id The joystick (0, 1) for which to find state.
- * @return {THREE.Vector2}
- */
- getJoystick: function (index) {
- var gamepad = this.getGamepad();
- switch (index) {
- case 0: return new THREE.Vector2(gamepad.axes[0], gamepad.axes[1]);
- case 1: return new THREE.Vector2(gamepad.axes[2], gamepad.axes[3]);
- default: throw new Error('Unexpected joystick index "%d".', index);
- }
- },
- /**
- * Returns the state of the dpad as a THREE.Vector2.
- * @return {THREE.Vector2}
- */
- getDpad: function () {
- var gamepad = this.getGamepad();
- if (!gamepad.buttons[GamepadButton.DPAD_RIGHT]) {
- return new THREE.Vector2();
- }
- return new THREE.Vector2(
- (gamepad.buttons[GamepadButton.DPAD_RIGHT].pressed ? 1 : 0)
- + (gamepad.buttons[GamepadButton.DPAD_LEFT].pressed ? -1 : 0),
- (gamepad.buttons[GamepadButton.DPAD_UP].pressed ? -1 : 0)
- + (gamepad.buttons[GamepadButton.DPAD_DOWN].pressed ? 1 : 0)
- );
- },
- /**
- * Returns true if the gamepad is currently connected to the system.
- * @return {boolean}
- */
- isConnected: function () {
- var gamepad = this.getGamepad();
- return !!(gamepad && gamepad.connected);
- },
- /**
- * Returns a string containing some information about the controller. Result
- * may vary across browsers, for a given controller.
- * @return {string}
- */
- getID: function () {
- return this.getGamepad().id;
- }
- };
- /***/ },
- /* 2 */
- /***/ function(module, exports) {
- module.exports = Object.assign(function GamepadButton () {}, {
- FACE_1: 0,
- FACE_2: 1,
- FACE_3: 2,
- FACE_4: 3,
- L_SHOULDER_1: 4,
- R_SHOULDER_1: 5,
- L_SHOULDER_2: 6,
- R_SHOULDER_2: 7,
- SELECT: 8,
- START: 9,
- DPAD_UP: 12,
- DPAD_DOWN: 13,
- DPAD_LEFT: 14,
- DPAD_RIGHT: 15,
- VENDOR: 16,
- });
- /***/ },
- /* 3 */
- /***/ function(module, exports) {
- function GamepadButtonEvent (type, index, details) {
- this.type = type;
- this.index = index;
- this.pressed = details.pressed;
- this.value = details.value;
- }
- module.exports = GamepadButtonEvent;
- /***/ }
- /******/ ]);
|