aframe-extras.controls.js 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871
  1. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. 'use strict';
  3. require('./src/controls');
  4. },{"./src/controls":7}],2:[function(require,module,exports){
  5. "use strict";
  6. module.exports = Object.assign(function GamepadButton() {}, {
  7. FACE_1: 0,
  8. FACE_2: 1,
  9. FACE_3: 2,
  10. FACE_4: 3,
  11. L_SHOULDER_1: 4,
  12. R_SHOULDER_1: 5,
  13. L_SHOULDER_2: 6,
  14. R_SHOULDER_2: 7,
  15. SELECT: 8,
  16. START: 9,
  17. DPAD_UP: 12,
  18. DPAD_DOWN: 13,
  19. DPAD_LEFT: 14,
  20. DPAD_RIGHT: 15,
  21. VENDOR: 16
  22. });
  23. },{}],3:[function(require,module,exports){
  24. "use strict";
  25. function GamepadButtonEvent(type, index, details) {
  26. this.type = type;
  27. this.index = index;
  28. this.pressed = details.pressed;
  29. this.value = details.value;
  30. }
  31. module.exports = GamepadButtonEvent;
  32. },{}],4:[function(require,module,exports){
  33. 'use strict';
  34. /**
  35. * Polyfill for the additional KeyboardEvent properties defined in the D3E and
  36. * D4E draft specifications, by @inexorabletash.
  37. *
  38. * See: https://github.com/inexorabletash/polyfill
  39. */
  40. (function (global) {
  41. var nativeKeyboardEvent = 'KeyboardEvent' in global;
  42. if (!nativeKeyboardEvent) global.KeyboardEvent = function KeyboardEvent() {
  43. throw TypeError('Illegal constructor');
  44. };
  45. if (!('DOM_KEY_LOCATION_STANDARD' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_STANDARD = 0x00; // Default or unknown location
  46. if (!('DOM_KEY_LOCATION_LEFT' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_LEFT = 0x01; // e.g. Left Alt key
  47. if (!('DOM_KEY_LOCATION_RIGHT' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_RIGHT = 0x02; // e.g. Right Alt key
  48. if (!('DOM_KEY_LOCATION_NUMPAD' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD = 0x03; // e.g. Numpad 0 or +
  49. var STANDARD = window.KeyboardEvent.DOM_KEY_LOCATION_STANDARD,
  50. LEFT = window.KeyboardEvent.DOM_KEY_LOCATION_LEFT,
  51. RIGHT = window.KeyboardEvent.DOM_KEY_LOCATION_RIGHT,
  52. NUMPAD = window.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD;
  53. //--------------------------------------------------------------------
  54. //
  55. // Utilities
  56. //
  57. //--------------------------------------------------------------------
  58. function contains(s, ss) {
  59. return String(s).indexOf(ss) !== -1;
  60. }
  61. var os = function () {
  62. if (contains(navigator.platform, 'Win')) {
  63. return 'win';
  64. }
  65. if (contains(navigator.platform, 'Mac')) {
  66. return 'mac';
  67. }
  68. if (contains(navigator.platform, 'CrOS')) {
  69. return 'cros';
  70. }
  71. if (contains(navigator.platform, 'Linux')) {
  72. return 'linux';
  73. }
  74. if (contains(navigator.userAgent, 'iPad') || contains(navigator.platform, 'iPod') || contains(navigator.platform, 'iPhone')) {
  75. return 'ios';
  76. }
  77. return '';
  78. }();
  79. var browser = function () {
  80. if (contains(navigator.userAgent, 'Chrome/')) {
  81. return 'chrome';
  82. }
  83. if (contains(navigator.vendor, 'Apple')) {
  84. return 'safari';
  85. }
  86. if (contains(navigator.userAgent, 'MSIE')) {
  87. return 'ie';
  88. }
  89. if (contains(navigator.userAgent, 'Gecko/')) {
  90. return 'moz';
  91. }
  92. if (contains(navigator.userAgent, 'Opera/')) {
  93. return 'opera';
  94. }
  95. return '';
  96. }();
  97. var browser_os = browser + '-' + os;
  98. function mergeIf(baseTable, select, table) {
  99. if (browser_os === select || browser === select || os === select) {
  100. Object.keys(table).forEach(function (keyCode) {
  101. baseTable[keyCode] = table[keyCode];
  102. });
  103. }
  104. }
  105. function remap(o, key) {
  106. var r = {};
  107. Object.keys(o).forEach(function (k) {
  108. var item = o[k];
  109. if (key in item) {
  110. r[item[key]] = item;
  111. }
  112. });
  113. return r;
  114. }
  115. function invert(o) {
  116. var r = {};
  117. Object.keys(o).forEach(function (k) {
  118. r[o[k]] = k;
  119. });
  120. return r;
  121. }
  122. //--------------------------------------------------------------------
  123. //
  124. // Generic Mappings
  125. //
  126. //--------------------------------------------------------------------
  127. // "keyInfo" is a dictionary:
  128. // code: string - name from DOM Level 3 KeyboardEvent code Values
  129. // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-code.html
  130. // location (optional): number - one of the DOM_KEY_LOCATION values
  131. // keyCap (optional): string - keyboard label in en-US locale
  132. // USB code Usage ID from page 0x07 unless otherwise noted (Informative)
  133. // Map of keyCode to keyInfo
  134. var keyCodeToInfoTable = {
  135. // 0x01 - VK_LBUTTON
  136. // 0x02 - VK_RBUTTON
  137. 0x03: { code: 'Cancel' }, // [USB: 0x9b] char \x0018 ??? (Not in D3E)
  138. // 0x04 - VK_MBUTTON
  139. // 0x05 - VK_XBUTTON1
  140. // 0x06 - VK_XBUTTON2
  141. 0x06: { code: 'Help' }, // [USB: 0x75] ???
  142. // 0x07 - undefined
  143. 0x08: { code: 'Backspace' }, // [USB: 0x2a] Labelled Delete on Macintosh keyboards.
  144. 0x09: { code: 'Tab' }, // [USB: 0x2b]
  145. // 0x0A-0x0B - reserved
  146. 0X0C: { code: 'Clear' }, // [USB: 0x9c] NumPad Center (Not in D3E)
  147. 0X0D: { code: 'Enter' }, // [USB: 0x28]
  148. // 0x0E-0x0F - undefined
  149. 0x10: { code: 'Shift' },
  150. 0x11: { code: 'Control' },
  151. 0x12: { code: 'Alt' },
  152. 0x13: { code: 'Pause' }, // [USB: 0x48]
  153. 0x14: { code: 'CapsLock' }, // [USB: 0x39]
  154. 0x15: { code: 'KanaMode' }, // [USB: 0x88] - "HangulMode" for Korean layout
  155. 0x16: { code: 'HangulMode' }, // [USB: 0x90] 0x15 as well in MSDN VK table ???
  156. 0x17: { code: 'JunjaMode' }, // (Not in D3E)
  157. 0x18: { code: 'FinalMode' }, // (Not in D3E)
  158. 0x19: { code: 'KanjiMode' }, // [USB: 0x91] - "HanjaMode" for Korean layout
  159. // 0x1A - undefined
  160. 0x1B: { code: 'Escape' }, // [USB: 0x29]
  161. 0x1C: { code: 'Convert' }, // [USB: 0x8a]
  162. 0x1D: { code: 'NonConvert' }, // [USB: 0x8b]
  163. 0x1E: { code: 'Accept' }, // (Not in D3E)
  164. 0x1F: { code: 'ModeChange' }, // (Not in D3E)
  165. 0x20: { code: 'Space' }, // [USB: 0x2c]
  166. 0x21: { code: 'PageUp' }, // [USB: 0x4b]
  167. 0x22: { code: 'PageDown' }, // [USB: 0x4e]
  168. 0x23: { code: 'End' }, // [USB: 0x4d]
  169. 0x24: { code: 'Home' }, // [USB: 0x4a]
  170. 0x25: { code: 'ArrowLeft' }, // [USB: 0x50]
  171. 0x26: { code: 'ArrowUp' }, // [USB: 0x52]
  172. 0x27: { code: 'ArrowRight' }, // [USB: 0x4f]
  173. 0x28: { code: 'ArrowDown' }, // [USB: 0x51]
  174. 0x29: { code: 'Select' }, // (Not in D3E)
  175. 0x2A: { code: 'Print' }, // (Not in D3E)
  176. 0x2B: { code: 'Execute' }, // [USB: 0x74] (Not in D3E)
  177. 0x2C: { code: 'PrintScreen' }, // [USB: 0x46]
  178. 0x2D: { code: 'Insert' }, // [USB: 0x49]
  179. 0x2E: { code: 'Delete' }, // [USB: 0x4c]
  180. 0x2F: { code: 'Help' }, // [USB: 0x75] ???
  181. 0x30: { code: 'Digit0', keyCap: '0' }, // [USB: 0x27] 0)
  182. 0x31: { code: 'Digit1', keyCap: '1' }, // [USB: 0x1e] 1!
  183. 0x32: { code: 'Digit2', keyCap: '2' }, // [USB: 0x1f] 2@
  184. 0x33: { code: 'Digit3', keyCap: '3' }, // [USB: 0x20] 3#
  185. 0x34: { code: 'Digit4', keyCap: '4' }, // [USB: 0x21] 4$
  186. 0x35: { code: 'Digit5', keyCap: '5' }, // [USB: 0x22] 5%
  187. 0x36: { code: 'Digit6', keyCap: '6' }, // [USB: 0x23] 6^
  188. 0x37: { code: 'Digit7', keyCap: '7' }, // [USB: 0x24] 7&
  189. 0x38: { code: 'Digit8', keyCap: '8' }, // [USB: 0x25] 8*
  190. 0x39: { code: 'Digit9', keyCap: '9' }, // [USB: 0x26] 9(
  191. // 0x3A-0x40 - undefined
  192. 0x41: { code: 'KeyA', keyCap: 'a' }, // [USB: 0x04]
  193. 0x42: { code: 'KeyB', keyCap: 'b' }, // [USB: 0x05]
  194. 0x43: { code: 'KeyC', keyCap: 'c' }, // [USB: 0x06]
  195. 0x44: { code: 'KeyD', keyCap: 'd' }, // [USB: 0x07]
  196. 0x45: { code: 'KeyE', keyCap: 'e' }, // [USB: 0x08]
  197. 0x46: { code: 'KeyF', keyCap: 'f' }, // [USB: 0x09]
  198. 0x47: { code: 'KeyG', keyCap: 'g' }, // [USB: 0x0a]
  199. 0x48: { code: 'KeyH', keyCap: 'h' }, // [USB: 0x0b]
  200. 0x49: { code: 'KeyI', keyCap: 'i' }, // [USB: 0x0c]
  201. 0x4A: { code: 'KeyJ', keyCap: 'j' }, // [USB: 0x0d]
  202. 0x4B: { code: 'KeyK', keyCap: 'k' }, // [USB: 0x0e]
  203. 0x4C: { code: 'KeyL', keyCap: 'l' }, // [USB: 0x0f]
  204. 0x4D: { code: 'KeyM', keyCap: 'm' }, // [USB: 0x10]
  205. 0x4E: { code: 'KeyN', keyCap: 'n' }, // [USB: 0x11]
  206. 0x4F: { code: 'KeyO', keyCap: 'o' }, // [USB: 0x12]
  207. 0x50: { code: 'KeyP', keyCap: 'p' }, // [USB: 0x13]
  208. 0x51: { code: 'KeyQ', keyCap: 'q' }, // [USB: 0x14]
  209. 0x52: { code: 'KeyR', keyCap: 'r' }, // [USB: 0x15]
  210. 0x53: { code: 'KeyS', keyCap: 's' }, // [USB: 0x16]
  211. 0x54: { code: 'KeyT', keyCap: 't' }, // [USB: 0x17]
  212. 0x55: { code: 'KeyU', keyCap: 'u' }, // [USB: 0x18]
  213. 0x56: { code: 'KeyV', keyCap: 'v' }, // [USB: 0x19]
  214. 0x57: { code: 'KeyW', keyCap: 'w' }, // [USB: 0x1a]
  215. 0x58: { code: 'KeyX', keyCap: 'x' }, // [USB: 0x1b]
  216. 0x59: { code: 'KeyY', keyCap: 'y' }, // [USB: 0x1c]
  217. 0x5A: { code: 'KeyZ', keyCap: 'z' }, // [USB: 0x1d]
  218. 0x5B: { code: 'OSLeft', location: LEFT }, // [USB: 0xe3]
  219. 0x5C: { code: 'OSRight', location: RIGHT }, // [USB: 0xe7]
  220. 0x5D: { code: 'ContextMenu' }, // [USB: 0x65] Context Menu
  221. // 0x5E - reserved
  222. 0x5F: { code: 'Standby' }, // [USB: 0x82] Sleep
  223. 0x60: { code: 'Numpad0', keyCap: '0', location: NUMPAD }, // [USB: 0x62]
  224. 0x61: { code: 'Numpad1', keyCap: '1', location: NUMPAD }, // [USB: 0x59]
  225. 0x62: { code: 'Numpad2', keyCap: '2', location: NUMPAD }, // [USB: 0x5a]
  226. 0x63: { code: 'Numpad3', keyCap: '3', location: NUMPAD }, // [USB: 0x5b]
  227. 0x64: { code: 'Numpad4', keyCap: '4', location: NUMPAD }, // [USB: 0x5c]
  228. 0x65: { code: 'Numpad5', keyCap: '5', location: NUMPAD }, // [USB: 0x5d]
  229. 0x66: { code: 'Numpad6', keyCap: '6', location: NUMPAD }, // [USB: 0x5e]
  230. 0x67: { code: 'Numpad7', keyCap: '7', location: NUMPAD }, // [USB: 0x5f]
  231. 0x68: { code: 'Numpad8', keyCap: '8', location: NUMPAD }, // [USB: 0x60]
  232. 0x69: { code: 'Numpad9', keyCap: '9', location: NUMPAD }, // [USB: 0x61]
  233. 0x6A: { code: 'NumpadMultiply', keyCap: '*', location: NUMPAD }, // [USB: 0x55]
  234. 0x6B: { code: 'NumpadAdd', keyCap: '+', location: NUMPAD }, // [USB: 0x57]
  235. 0x6C: { code: 'NumpadComma', keyCap: ',', location: NUMPAD }, // [USB: 0x85]
  236. 0x6D: { code: 'NumpadSubtract', keyCap: '-', location: NUMPAD }, // [USB: 0x56]
  237. 0x6E: { code: 'NumpadDecimal', keyCap: '.', location: NUMPAD }, // [USB: 0x63]
  238. 0x6F: { code: 'NumpadDivide', keyCap: '/', location: NUMPAD }, // [USB: 0x54]
  239. 0x70: { code: 'F1' }, // [USB: 0x3a]
  240. 0x71: { code: 'F2' }, // [USB: 0x3b]
  241. 0x72: { code: 'F3' }, // [USB: 0x3c]
  242. 0x73: { code: 'F4' }, // [USB: 0x3d]
  243. 0x74: { code: 'F5' }, // [USB: 0x3e]
  244. 0x75: { code: 'F6' }, // [USB: 0x3f]
  245. 0x76: { code: 'F7' }, // [USB: 0x40]
  246. 0x77: { code: 'F8' }, // [USB: 0x41]
  247. 0x78: { code: 'F9' }, // [USB: 0x42]
  248. 0x79: { code: 'F10' }, // [USB: 0x43]
  249. 0x7A: { code: 'F11' }, // [USB: 0x44]
  250. 0x7B: { code: 'F12' }, // [USB: 0x45]
  251. 0x7C: { code: 'F13' }, // [USB: 0x68]
  252. 0x7D: { code: 'F14' }, // [USB: 0x69]
  253. 0x7E: { code: 'F15' }, // [USB: 0x6a]
  254. 0x7F: { code: 'F16' }, // [USB: 0x6b]
  255. 0x80: { code: 'F17' }, // [USB: 0x6c]
  256. 0x81: { code: 'F18' }, // [USB: 0x6d]
  257. 0x82: { code: 'F19' }, // [USB: 0x6e]
  258. 0x83: { code: 'F20' }, // [USB: 0x6f]
  259. 0x84: { code: 'F21' }, // [USB: 0x70]
  260. 0x85: { code: 'F22' }, // [USB: 0x71]
  261. 0x86: { code: 'F23' }, // [USB: 0x72]
  262. 0x87: { code: 'F24' }, // [USB: 0x73]
  263. // 0x88-0x8F - unassigned
  264. 0x90: { code: 'NumLock', location: NUMPAD }, // [USB: 0x53]
  265. 0x91: { code: 'ScrollLock' }, // [USB: 0x47]
  266. // 0x92-0x96 - OEM specific
  267. // 0x97-0x9F - unassigned
  268. // NOTE: 0xA0-0xA5 usually mapped to 0x10-0x12 in browsers
  269. 0xA0: { code: 'ShiftLeft', location: LEFT }, // [USB: 0xe1]
  270. 0xA1: { code: 'ShiftRight', location: RIGHT }, // [USB: 0xe5]
  271. 0xA2: { code: 'ControlLeft', location: LEFT }, // [USB: 0xe0]
  272. 0xA3: { code: 'ControlRight', location: RIGHT }, // [USB: 0xe4]
  273. 0xA4: { code: 'AltLeft', location: LEFT }, // [USB: 0xe2]
  274. 0xA5: { code: 'AltRight', location: RIGHT }, // [USB: 0xe6]
  275. 0xA6: { code: 'BrowserBack' }, // [USB: 0x0c/0x0224]
  276. 0xA7: { code: 'BrowserForward' }, // [USB: 0x0c/0x0225]
  277. 0xA8: { code: 'BrowserRefresh' }, // [USB: 0x0c/0x0227]
  278. 0xA9: { code: 'BrowserStop' }, // [USB: 0x0c/0x0226]
  279. 0xAA: { code: 'BrowserSearch' }, // [USB: 0x0c/0x0221]
  280. 0xAB: { code: 'BrowserFavorites' }, // [USB: 0x0c/0x0228]
  281. 0xAC: { code: 'BrowserHome' }, // [USB: 0x0c/0x0222]
  282. 0xAD: { code: 'VolumeMute' }, // [USB: 0x7f]
  283. 0xAE: { code: 'VolumeDown' }, // [USB: 0x81]
  284. 0xAF: { code: 'VolumeUp' }, // [USB: 0x80]
  285. 0xB0: { code: 'MediaTrackNext' }, // [USB: 0x0c/0x00b5]
  286. 0xB1: { code: 'MediaTrackPrevious' }, // [USB: 0x0c/0x00b6]
  287. 0xB2: { code: 'MediaStop' }, // [USB: 0x0c/0x00b7]
  288. 0xB3: { code: 'MediaPlayPause' }, // [USB: 0x0c/0x00cd]
  289. 0xB4: { code: 'LaunchMail' }, // [USB: 0x0c/0x018a]
  290. 0xB5: { code: 'MediaSelect' },
  291. 0xB6: { code: 'LaunchApp1' },
  292. 0xB7: { code: 'LaunchApp2' },
  293. // 0xB8-0xB9 - reserved
  294. 0xBA: { code: 'Semicolon', keyCap: ';' }, // [USB: 0x33] ;: (US Standard 101)
  295. 0xBB: { code: 'Equal', keyCap: '=' }, // [USB: 0x2e] =+
  296. 0xBC: { code: 'Comma', keyCap: ',' }, // [USB: 0x36] ,<
  297. 0xBD: { code: 'Minus', keyCap: '-' }, // [USB: 0x2d] -_
  298. 0xBE: { code: 'Period', keyCap: '.' }, // [USB: 0x37] .>
  299. 0xBF: { code: 'Slash', keyCap: '/' }, // [USB: 0x38] /? (US Standard 101)
  300. 0xC0: { code: 'Backquote', keyCap: '`' }, // [USB: 0x35] `~ (US Standard 101)
  301. // 0xC1-0xCF - reserved
  302. // 0xD0-0xD7 - reserved
  303. // 0xD8-0xDA - unassigned
  304. 0xDB: { code: 'BracketLeft', keyCap: '[' }, // [USB: 0x2f] [{ (US Standard 101)
  305. 0xDC: { code: 'Backslash', keyCap: '\\' }, // [USB: 0x31] \| (US Standard 101)
  306. 0xDD: { code: 'BracketRight', keyCap: ']' }, // [USB: 0x30] ]} (US Standard 101)
  307. 0xDE: { code: 'Quote', keyCap: '\'' }, // [USB: 0x34] '" (US Standard 101)
  308. // 0xDF - miscellaneous/varies
  309. // 0xE0 - reserved
  310. // 0xE1 - OEM specific
  311. 0xE2: { code: 'IntlBackslash', keyCap: '\\' }, // [USB: 0x64] \| (UK Standard 102)
  312. // 0xE3-0xE4 - OEM specific
  313. 0xE5: { code: 'Process' }, // (Not in D3E)
  314. // 0xE6 - OEM specific
  315. // 0xE7 - VK_PACKET
  316. // 0xE8 - unassigned
  317. // 0xE9-0xEF - OEM specific
  318. // 0xF0-0xF5 - OEM specific
  319. 0xF6: { code: 'Attn' }, // [USB: 0x9a] (Not in D3E)
  320. 0xF7: { code: 'CrSel' }, // [USB: 0xa3] (Not in D3E)
  321. 0xF8: { code: 'ExSel' }, // [USB: 0xa4] (Not in D3E)
  322. 0xF9: { code: 'EraseEof' }, // (Not in D3E)
  323. 0xFA: { code: 'Play' }, // (Not in D3E)
  324. 0xFB: { code: 'ZoomToggle' }, // (Not in D3E)
  325. // 0xFC - VK_NONAME - reserved
  326. // 0xFD - VK_PA1
  327. 0xFE: { code: 'Clear' // [USB: 0x9c] (Not in D3E)
  328. } };
  329. // No legacy keyCode, but listed in D3E:
  330. // code: usb
  331. // 'IntlHash': 0x070032,
  332. // 'IntlRo': 0x070087,
  333. // 'IntlYen': 0x070089,
  334. // 'NumpadBackspace': 0x0700bb,
  335. // 'NumpadClear': 0x0700d8,
  336. // 'NumpadClearEntry': 0x0700d9,
  337. // 'NumpadMemoryAdd': 0x0700d3,
  338. // 'NumpadMemoryClear': 0x0700d2,
  339. // 'NumpadMemoryRecall': 0x0700d1,
  340. // 'NumpadMemoryStore': 0x0700d0,
  341. // 'NumpadMemorySubtract': 0x0700d4,
  342. // 'NumpadParenLeft': 0x0700b6,
  343. // 'NumpadParenRight': 0x0700b7,
  344. //--------------------------------------------------------------------
  345. //
  346. // Browser/OS Specific Mappings
  347. //
  348. //--------------------------------------------------------------------
  349. mergeIf(keyCodeToInfoTable, 'moz', {
  350. 0x3B: { code: 'Semicolon', keyCap: ';' }, // [USB: 0x33] ;: (US Standard 101)
  351. 0x3D: { code: 'Equal', keyCap: '=' }, // [USB: 0x2e] =+
  352. 0x6B: { code: 'Equal', keyCap: '=' }, // [USB: 0x2e] =+
  353. 0x6D: { code: 'Minus', keyCap: '-' }, // [USB: 0x2d] -_
  354. 0xBB: { code: 'NumpadAdd', keyCap: '+', location: NUMPAD }, // [USB: 0x57]
  355. 0xBD: { code: 'NumpadSubtract', keyCap: '-', location: NUMPAD // [USB: 0x56]
  356. } });
  357. mergeIf(keyCodeToInfoTable, 'moz-mac', {
  358. 0x0C: { code: 'NumLock', location: NUMPAD }, // [USB: 0x53]
  359. 0xAD: { code: 'Minus', keyCap: '-' // [USB: 0x2d] -_
  360. } });
  361. mergeIf(keyCodeToInfoTable, 'moz-win', {
  362. 0xAD: { code: 'Minus', keyCap: '-' // [USB: 0x2d] -_
  363. } });
  364. mergeIf(keyCodeToInfoTable, 'chrome-mac', {
  365. 0x5D: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
  366. } });
  367. // Windows via Bootcamp (!)
  368. if (0) {
  369. mergeIf(keyCodeToInfoTable, 'chrome-win', {
  370. 0xC0: { code: 'Quote', keyCap: '\'' }, // [USB: 0x34] '" (US Standard 101)
  371. 0xDE: { code: 'Backslash', keyCap: '\\' }, // [USB: 0x31] \| (US Standard 101)
  372. 0xDF: { code: 'Backquote', keyCap: '`' // [USB: 0x35] `~ (US Standard 101)
  373. } });
  374. mergeIf(keyCodeToInfoTable, 'ie', {
  375. 0xC0: { code: 'Quote', keyCap: '\'' }, // [USB: 0x34] '" (US Standard 101)
  376. 0xDE: { code: 'Backslash', keyCap: '\\' }, // [USB: 0x31] \| (US Standard 101)
  377. 0xDF: { code: 'Backquote', keyCap: '`' // [USB: 0x35] `~ (US Standard 101)
  378. } });
  379. }
  380. mergeIf(keyCodeToInfoTable, 'safari', {
  381. 0x03: { code: 'Enter' }, // [USB: 0x28] old Safari
  382. 0x19: { code: 'Tab' // [USB: 0x2b] old Safari for Shift+Tab
  383. } });
  384. mergeIf(keyCodeToInfoTable, 'ios', {
  385. 0x0A: { code: 'Enter', location: STANDARD // [USB: 0x28]
  386. } });
  387. mergeIf(keyCodeToInfoTable, 'safari-mac', {
  388. 0x5B: { code: 'OSLeft', location: LEFT }, // [USB: 0xe3]
  389. 0x5D: { code: 'OSRight', location: RIGHT }, // [USB: 0xe7]
  390. 0xE5: { code: 'KeyQ', keyCap: 'Q' // [USB: 0x14] On alternate presses, Ctrl+Q sends this
  391. } });
  392. //--------------------------------------------------------------------
  393. //
  394. // Identifier Mappings
  395. //
  396. //--------------------------------------------------------------------
  397. // Cases where newer-ish browsers send keyIdentifier which can be
  398. // used to disambiguate keys.
  399. // keyIdentifierTable[keyIdentifier] -> keyInfo
  400. var keyIdentifierTable = {};
  401. if ('cros' === os) {
  402. keyIdentifierTable['U+00A0'] = { code: 'ShiftLeft', location: LEFT };
  403. keyIdentifierTable['U+00A1'] = { code: 'ShiftRight', location: RIGHT };
  404. keyIdentifierTable['U+00A2'] = { code: 'ControlLeft', location: LEFT };
  405. keyIdentifierTable['U+00A3'] = { code: 'ControlRight', location: RIGHT };
  406. keyIdentifierTable['U+00A4'] = { code: 'AltLeft', location: LEFT };
  407. keyIdentifierTable['U+00A5'] = { code: 'AltRight', location: RIGHT };
  408. }
  409. if ('chrome-mac' === browser_os) {
  410. keyIdentifierTable['U+0010'] = { code: 'ContextMenu' };
  411. }
  412. if ('safari-mac' === browser_os) {
  413. keyIdentifierTable['U+0010'] = { code: 'ContextMenu' };
  414. }
  415. if ('ios' === os) {
  416. // These only generate keyup events
  417. keyIdentifierTable['U+0010'] = { code: 'Function' };
  418. keyIdentifierTable['U+001C'] = { code: 'ArrowLeft' };
  419. keyIdentifierTable['U+001D'] = { code: 'ArrowRight' };
  420. keyIdentifierTable['U+001E'] = { code: 'ArrowUp' };
  421. keyIdentifierTable['U+001F'] = { code: 'ArrowDown' };
  422. keyIdentifierTable['U+0001'] = { code: 'Home' }; // [USB: 0x4a] Fn + ArrowLeft
  423. keyIdentifierTable['U+0004'] = { code: 'End' }; // [USB: 0x4d] Fn + ArrowRight
  424. keyIdentifierTable['U+000B'] = { code: 'PageUp' }; // [USB: 0x4b] Fn + ArrowUp
  425. keyIdentifierTable['U+000C'] = { code: 'PageDown' }; // [USB: 0x4e] Fn + ArrowDown
  426. }
  427. //--------------------------------------------------------------------
  428. //
  429. // Location Mappings
  430. //
  431. //--------------------------------------------------------------------
  432. // Cases where newer-ish browsers send location/keyLocation which
  433. // can be used to disambiguate keys.
  434. // locationTable[location][keyCode] -> keyInfo
  435. var locationTable = [];
  436. locationTable[LEFT] = {
  437. 0x10: { code: 'ShiftLeft', location: LEFT }, // [USB: 0xe1]
  438. 0x11: { code: 'ControlLeft', location: LEFT }, // [USB: 0xe0]
  439. 0x12: { code: 'AltLeft', location: LEFT // [USB: 0xe2]
  440. } };
  441. locationTable[RIGHT] = {
  442. 0x10: { code: 'ShiftRight', location: RIGHT }, // [USB: 0xe5]
  443. 0x11: { code: 'ControlRight', location: RIGHT }, // [USB: 0xe4]
  444. 0x12: { code: 'AltRight', location: RIGHT // [USB: 0xe6]
  445. } };
  446. locationTable[NUMPAD] = {
  447. 0x0D: { code: 'NumpadEnter', location: NUMPAD // [USB: 0x58]
  448. } };
  449. mergeIf(locationTable[NUMPAD], 'moz', {
  450. 0x6D: { code: 'NumpadSubtract', location: NUMPAD }, // [USB: 0x56]
  451. 0x6B: { code: 'NumpadAdd', location: NUMPAD // [USB: 0x57]
  452. } });
  453. mergeIf(locationTable[LEFT], 'moz-mac', {
  454. 0xE0: { code: 'OSLeft', location: LEFT // [USB: 0xe3]
  455. } });
  456. mergeIf(locationTable[RIGHT], 'moz-mac', {
  457. 0xE0: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
  458. } });
  459. mergeIf(locationTable[RIGHT], 'moz-win', {
  460. 0x5B: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
  461. } });
  462. mergeIf(locationTable[RIGHT], 'mac', {
  463. 0x5D: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
  464. } });
  465. mergeIf(locationTable[NUMPAD], 'chrome-mac', {
  466. 0x0C: { code: 'NumLock', location: NUMPAD // [USB: 0x53]
  467. } });
  468. mergeIf(locationTable[NUMPAD], 'safari-mac', {
  469. 0x0C: { code: 'NumLock', location: NUMPAD }, // [USB: 0x53]
  470. 0xBB: { code: 'NumpadAdd', location: NUMPAD }, // [USB: 0x57]
  471. 0xBD: { code: 'NumpadSubtract', location: NUMPAD }, // [USB: 0x56]
  472. 0xBE: { code: 'NumpadDecimal', location: NUMPAD }, // [USB: 0x63]
  473. 0xBF: { code: 'NumpadDivide', location: NUMPAD // [USB: 0x54]
  474. } });
  475. //--------------------------------------------------------------------
  476. //
  477. // Key Values
  478. //
  479. //--------------------------------------------------------------------
  480. // Mapping from `code` values to `key` values. Values defined at:
  481. // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-key.html
  482. // Entries are only provided when `key` differs from `code`. If
  483. // printable, `shiftKey` has the shifted printable character. This
  484. // assumes US Standard 101 layout
  485. var codeToKeyTable = {
  486. // Modifier Keys
  487. ShiftLeft: { key: 'Shift' },
  488. ShiftRight: { key: 'Shift' },
  489. ControlLeft: { key: 'Control' },
  490. ControlRight: { key: 'Control' },
  491. AltLeft: { key: 'Alt' },
  492. AltRight: { key: 'Alt' },
  493. OSLeft: { key: 'OS' },
  494. OSRight: { key: 'OS' },
  495. // Whitespace Keys
  496. NumpadEnter: { key: 'Enter' },
  497. Space: { key: ' ' },
  498. // Printable Keys
  499. Digit0: { key: '0', shiftKey: ')' },
  500. Digit1: { key: '1', shiftKey: '!' },
  501. Digit2: { key: '2', shiftKey: '@' },
  502. Digit3: { key: '3', shiftKey: '#' },
  503. Digit4: { key: '4', shiftKey: '$' },
  504. Digit5: { key: '5', shiftKey: '%' },
  505. Digit6: { key: '6', shiftKey: '^' },
  506. Digit7: { key: '7', shiftKey: '&' },
  507. Digit8: { key: '8', shiftKey: '*' },
  508. Digit9: { key: '9', shiftKey: '(' },
  509. KeyA: { key: 'a', shiftKey: 'A' },
  510. KeyB: { key: 'b', shiftKey: 'B' },
  511. KeyC: { key: 'c', shiftKey: 'C' },
  512. KeyD: { key: 'd', shiftKey: 'D' },
  513. KeyE: { key: 'e', shiftKey: 'E' },
  514. KeyF: { key: 'f', shiftKey: 'F' },
  515. KeyG: { key: 'g', shiftKey: 'G' },
  516. KeyH: { key: 'h', shiftKey: 'H' },
  517. KeyI: { key: 'i', shiftKey: 'I' },
  518. KeyJ: { key: 'j', shiftKey: 'J' },
  519. KeyK: { key: 'k', shiftKey: 'K' },
  520. KeyL: { key: 'l', shiftKey: 'L' },
  521. KeyM: { key: 'm', shiftKey: 'M' },
  522. KeyN: { key: 'n', shiftKey: 'N' },
  523. KeyO: { key: 'o', shiftKey: 'O' },
  524. KeyP: { key: 'p', shiftKey: 'P' },
  525. KeyQ: { key: 'q', shiftKey: 'Q' },
  526. KeyR: { key: 'r', shiftKey: 'R' },
  527. KeyS: { key: 's', shiftKey: 'S' },
  528. KeyT: { key: 't', shiftKey: 'T' },
  529. KeyU: { key: 'u', shiftKey: 'U' },
  530. KeyV: { key: 'v', shiftKey: 'V' },
  531. KeyW: { key: 'w', shiftKey: 'W' },
  532. KeyX: { key: 'x', shiftKey: 'X' },
  533. KeyY: { key: 'y', shiftKey: 'Y' },
  534. KeyZ: { key: 'z', shiftKey: 'Z' },
  535. Numpad0: { key: '0' },
  536. Numpad1: { key: '1' },
  537. Numpad2: { key: '2' },
  538. Numpad3: { key: '3' },
  539. Numpad4: { key: '4' },
  540. Numpad5: { key: '5' },
  541. Numpad6: { key: '6' },
  542. Numpad7: { key: '7' },
  543. Numpad8: { key: '8' },
  544. Numpad9: { key: '9' },
  545. NumpadMultiply: { key: '*' },
  546. NumpadAdd: { key: '+' },
  547. NumpadComma: { key: ',' },
  548. NumpadSubtract: { key: '-' },
  549. NumpadDecimal: { key: '.' },
  550. NumpadDivide: { key: '/' },
  551. Semicolon: { key: ';', shiftKey: ':' },
  552. Equal: { key: '=', shiftKey: '+' },
  553. Comma: { key: ',', shiftKey: '<' },
  554. Minus: { key: '-', shiftKey: '_' },
  555. Period: { key: '.', shiftKey: '>' },
  556. Slash: { key: '/', shiftKey: '?' },
  557. Backquote: { key: '`', shiftKey: '~' },
  558. BracketLeft: { key: '[', shiftKey: '{' },
  559. Backslash: { key: '\\', shiftKey: '|' },
  560. BracketRight: { key: ']', shiftKey: '}' },
  561. Quote: { key: '\'', shiftKey: '"' },
  562. IntlBackslash: { key: '\\', shiftKey: '|' }
  563. };
  564. mergeIf(codeToKeyTable, 'mac', {
  565. OSLeft: { key: 'Meta' },
  566. OSRight: { key: 'Meta' }
  567. });
  568. // Corrections for 'key' names in older browsers (e.g. FF36-)
  569. // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.key#Key_values
  570. var keyFixTable = {
  571. Esc: 'Escape',
  572. Nonconvert: 'NonConvert',
  573. Left: 'ArrowLeft',
  574. Up: 'ArrowUp',
  575. Right: 'ArrowRight',
  576. Down: 'ArrowDown',
  577. Del: 'Delete',
  578. Menu: 'ContextMenu',
  579. MediaNextTrack: 'MediaTrackNext',
  580. MediaPreviousTrack: 'MediaTrackPrevious',
  581. SelectMedia: 'MediaSelect',
  582. HalfWidth: 'Hankaku',
  583. FullWidth: 'Zenkaku',
  584. RomanCharacters: 'Romaji',
  585. Crsel: 'CrSel',
  586. Exsel: 'ExSel',
  587. Zoom: 'ZoomToggle'
  588. };
  589. //--------------------------------------------------------------------
  590. //
  591. // Exported Functions
  592. //
  593. //--------------------------------------------------------------------
  594. var codeTable = remap(keyCodeToInfoTable, 'code');
  595. try {
  596. var nativeLocation = nativeKeyboardEvent && 'location' in new KeyboardEvent('');
  597. } catch (_) {}
  598. function keyInfoForEvent(event) {
  599. var keyCode = 'keyCode' in event ? event.keyCode : 'which' in event ? event.which : 0;
  600. var keyInfo = function () {
  601. if (nativeLocation || 'keyLocation' in event) {
  602. var location = nativeLocation ? event.location : event.keyLocation;
  603. if (location && keyCode in locationTable[location]) {
  604. return locationTable[location][keyCode];
  605. }
  606. }
  607. if ('keyIdentifier' in event && event.keyIdentifier in keyIdentifierTable) {
  608. return keyIdentifierTable[event.keyIdentifier];
  609. }
  610. if (keyCode in keyCodeToInfoTable) {
  611. return keyCodeToInfoTable[keyCode];
  612. }
  613. return null;
  614. }();
  615. // TODO: Track these down and move to general tables
  616. if (0) {
  617. // TODO: Map these for newerish browsers?
  618. // TODO: iOS only?
  619. // TODO: Override with more common keyIdentifier name?
  620. switch (event.keyIdentifier) {
  621. case 'U+0010':
  622. keyInfo = { code: 'Function' };break;
  623. case 'U+001C':
  624. keyInfo = { code: 'ArrowLeft' };break;
  625. case 'U+001D':
  626. keyInfo = { code: 'ArrowRight' };break;
  627. case 'U+001E':
  628. keyInfo = { code: 'ArrowUp' };break;
  629. case 'U+001F':
  630. keyInfo = { code: 'ArrowDown' };break;
  631. }
  632. }
  633. if (!keyInfo) return null;
  634. var key = function () {
  635. var entry = codeToKeyTable[keyInfo.code];
  636. if (!entry) return keyInfo.code;
  637. return event.shiftKey && 'shiftKey' in entry ? entry.shiftKey : entry.key;
  638. }();
  639. return {
  640. code: keyInfo.code,
  641. key: key,
  642. location: keyInfo.location,
  643. keyCap: keyInfo.keyCap
  644. };
  645. }
  646. function queryKeyCap(code, locale) {
  647. code = String(code);
  648. if (!codeTable.hasOwnProperty(code)) return 'Undefined';
  649. if (locale && String(locale).toLowerCase() !== 'en-us') throw Error('Unsupported locale');
  650. var keyInfo = codeTable[code];
  651. return keyInfo.keyCap || keyInfo.code || 'Undefined';
  652. }
  653. if ('KeyboardEvent' in global && 'defineProperty' in Object) {
  654. (function () {
  655. function define(o, p, v) {
  656. if (p in o) return;
  657. Object.defineProperty(o, p, v);
  658. }
  659. define(KeyboardEvent.prototype, 'code', { get: function get() {
  660. var keyInfo = keyInfoForEvent(this);
  661. return keyInfo ? keyInfo.code : '';
  662. } });
  663. // Fix for nonstandard `key` values (FF36-)
  664. if ('key' in KeyboardEvent.prototype) {
  665. var desc = Object.getOwnPropertyDescriptor(KeyboardEvent.prototype, 'key');
  666. Object.defineProperty(KeyboardEvent.prototype, 'key', { get: function get() {
  667. var key = desc.get.call(this);
  668. return keyFixTable.hasOwnProperty(key) ? keyFixTable[key] : key;
  669. } });
  670. }
  671. define(KeyboardEvent.prototype, 'key', { get: function get() {
  672. var keyInfo = keyInfoForEvent(this);
  673. return keyInfo && 'key' in keyInfo ? keyInfo.key : 'Unidentified';
  674. } });
  675. define(KeyboardEvent.prototype, 'location', { get: function get() {
  676. var keyInfo = keyInfoForEvent(this);
  677. return keyInfo && 'location' in keyInfo ? keyInfo.location : STANDARD;
  678. } });
  679. define(KeyboardEvent.prototype, 'locale', { get: function get() {
  680. return '';
  681. } });
  682. })();
  683. }
  684. if (!('queryKeyCap' in global.KeyboardEvent)) global.KeyboardEvent.queryKeyCap = queryKeyCap;
  685. // Helper for IE8-
  686. global.identifyKey = function (event) {
  687. if ('code' in event) return;
  688. var keyInfo = keyInfoForEvent(event);
  689. event.code = keyInfo ? keyInfo.code : '';
  690. event.key = keyInfo && 'key' in keyInfo ? keyInfo.key : 'Unidentified';
  691. event.location = 'location' in event ? event.location : 'keyLocation' in event ? event.keyLocation : keyInfo && 'location' in keyInfo ? keyInfo.location : STANDARD;
  692. event.locale = '';
  693. };
  694. })(window);
  695. },{}],5:[function(require,module,exports){
  696. 'use strict';
  697. var EPS = 0.1;
  698. module.exports = AFRAME.registerComponent('checkpoint-controls', {
  699. schema: {
  700. enabled: { default: true },
  701. mode: { default: 'teleport', oneOf: ['teleport', 'animate'] },
  702. animateSpeed: { default: 3.0 }
  703. },
  704. init: function init() {
  705. this.active = true;
  706. this.checkpoint = null;
  707. this.isNavMeshConstrained = false;
  708. this.offset = new THREE.Vector3();
  709. this.position = new THREE.Vector3();
  710. this.targetPosition = new THREE.Vector3();
  711. },
  712. play: function play() {
  713. this.active = true;
  714. },
  715. pause: function pause() {
  716. this.active = false;
  717. },
  718. setCheckpoint: function setCheckpoint(checkpoint) {
  719. var el = this.el;
  720. if (!this.active) return;
  721. if (this.checkpoint === checkpoint) return;
  722. if (this.checkpoint) {
  723. el.emit('navigation-end', { checkpoint: this.checkpoint });
  724. }
  725. this.checkpoint = checkpoint;
  726. this.sync();
  727. // Ignore new checkpoint if we're already there.
  728. if (this.position.distanceTo(this.targetPosition) < EPS) {
  729. this.checkpoint = null;
  730. return;
  731. }
  732. el.emit('navigation-start', { checkpoint: checkpoint });
  733. if (this.data.mode === 'teleport') {
  734. this.el.setAttribute('position', this.targetPosition);
  735. this.checkpoint = null;
  736. el.emit('navigation-end', { checkpoint: checkpoint });
  737. el.components['movement-controls'].updateNavLocation();
  738. }
  739. },
  740. isVelocityActive: function isVelocityActive() {
  741. return !!(this.active && this.checkpoint);
  742. },
  743. getVelocity: function getVelocity() {
  744. if (!this.active) return;
  745. var data = this.data;
  746. var offset = this.offset;
  747. var position = this.position;
  748. var targetPosition = this.targetPosition;
  749. var checkpoint = this.checkpoint;
  750. this.sync();
  751. if (position.distanceTo(targetPosition) < EPS) {
  752. this.checkpoint = null;
  753. this.el.emit('navigation-end', { checkpoint: checkpoint });
  754. return offset.set(0, 0, 0);
  755. }
  756. offset.setLength(data.animateSpeed);
  757. return offset;
  758. },
  759. sync: function sync() {
  760. var offset = this.offset;
  761. var position = this.position;
  762. var targetPosition = this.targetPosition;
  763. position.copy(this.el.getAttribute('position'));
  764. this.checkpoint.object3D.getWorldPosition(targetPosition);
  765. targetPosition.add(this.checkpoint.components.checkpoint.getOffset());
  766. offset.copy(targetPosition).sub(position);
  767. }
  768. });
  769. },{}],6:[function(require,module,exports){
  770. 'use strict';
  771. /**
  772. * Gamepad controls for A-Frame.
  773. *
  774. * Stripped-down version of: https://github.com/donmccurdy/aframe-gamepad-controls
  775. *
  776. * For more information about the Gamepad API, see:
  777. * https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API
  778. */
  779. var GamepadButton = require('../../lib/GamepadButton'),
  780. GamepadButtonEvent = require('../../lib/GamepadButtonEvent');
  781. var JOYSTICK_EPS = 0.2;
  782. var Joystick = {
  783. MOVEMENT: 1,
  784. ROTATION: 2
  785. };
  786. module.exports = AFRAME.registerComponent('gamepad-controls', {
  787. /*******************************************************************
  788. * Statics
  789. */
  790. GamepadButton: GamepadButton,
  791. /*******************************************************************
  792. * Schema
  793. */
  794. schema: {
  795. // Controller 0-3
  796. controller: { default: 0, oneOf: [0, 1, 2, 3] },
  797. // Enable/disable features
  798. enabled: { default: true },
  799. // Debugging
  800. debug: { default: false },
  801. // Heading element for rotation
  802. camera: { default: '[camera]', type: 'selector' },
  803. // Rotation sensitivity
  804. rotationSensitivity: { default: 2.0 }
  805. },
  806. /*******************************************************************
  807. * Core
  808. */
  809. /**
  810. * Called once when component is attached. Generally for initial setup.
  811. */
  812. init: function init() {
  813. var sceneEl = this.el.sceneEl;
  814. this.system = sceneEl.systems['tracked-controls-webxr'] || { controllers: [] };
  815. this.prevTime = window.performance.now();
  816. // Button state
  817. this.buttons = {};
  818. // Rotation
  819. var rotation = this.el.object3D.rotation;
  820. this.pitch = new THREE.Object3D();
  821. this.pitch.rotation.x = THREE.Math.degToRad(rotation.x);
  822. this.yaw = new THREE.Object3D();
  823. this.yaw.position.y = 10;
  824. this.yaw.rotation.y = THREE.Math.degToRad(rotation.y);
  825. this.yaw.add(this.pitch);
  826. this._lookVector = new THREE.Vector2();
  827. this._moveVector = new THREE.Vector2();
  828. this._dpadVector = new THREE.Vector2();
  829. sceneEl.addBehavior(this);
  830. },
  831. /**
  832. * Called when component is attached and when component data changes.
  833. * Generally modifies the entity based on the data.
  834. */
  835. update: function update() {
  836. this.tick();
  837. },
  838. /**
  839. * Called on each iteration of main render loop.
  840. */
  841. tick: function tick(t, dt) {
  842. this.updateButtonState();
  843. this.updateRotation(dt);
  844. },
  845. /**
  846. * Called when a component is removed (e.g., via removeAttribute).
  847. * Generally undoes all modifications to the entity.
  848. */
  849. remove: function remove() {},
  850. /*******************************************************************
  851. * Movement
  852. */
  853. isVelocityActive: function isVelocityActive() {
  854. if (!this.data.enabled || !this.isConnected()) return false;
  855. var dpad = this._dpadVector;
  856. var joystick = this._moveVector;
  857. this.getDpad(dpad);
  858. this.getJoystick(Joystick.MOVEMENT, joystick);
  859. var inputX = dpad.x || joystick.x;
  860. var inputY = dpad.y || joystick.y;
  861. return Math.abs(inputX) > JOYSTICK_EPS || Math.abs(inputY) > JOYSTICK_EPS;
  862. },
  863. getVelocityDelta: function getVelocityDelta() {
  864. var dpad = this._dpadVector;
  865. var joystick = this._moveVector;
  866. this.getDpad(dpad);
  867. this.getJoystick(Joystick.MOVEMENT, joystick);
  868. var inputX = dpad.x || joystick.x;
  869. var inputY = dpad.y || joystick.y;
  870. var dVelocity = new THREE.Vector3();
  871. if (Math.abs(inputX) > JOYSTICK_EPS) {
  872. dVelocity.x += inputX;
  873. }
  874. if (Math.abs(inputY) > JOYSTICK_EPS) {
  875. dVelocity.z += inputY;
  876. }
  877. return dVelocity;
  878. },
  879. /*******************************************************************
  880. * Rotation
  881. */
  882. isRotationActive: function isRotationActive() {
  883. if (!this.data.enabled || !this.isConnected()) return false;
  884. var joystick = this._lookVector;
  885. this.getJoystick(Joystick.ROTATION, joystick);
  886. return Math.abs(joystick.x) > JOYSTICK_EPS || Math.abs(joystick.y) > JOYSTICK_EPS;
  887. },
  888. updateRotation: function updateRotation(dt) {
  889. if (!this.isRotationActive()) return;
  890. var data = this.data;
  891. var yaw = this.yaw;
  892. var pitch = this.pitch;
  893. var lookControls = data.camera.components['look-controls'];
  894. var hasLookControls = lookControls && lookControls.pitchObject && lookControls.yawObject;
  895. // Sync with look-controls pitch/yaw if available.
  896. if (hasLookControls) {
  897. pitch.rotation.copy(lookControls.pitchObject.rotation);
  898. yaw.rotation.copy(lookControls.yawObject.rotation);
  899. }
  900. var lookVector = this._lookVector;
  901. this.getJoystick(Joystick.ROTATION, lookVector);
  902. if (Math.abs(lookVector.x) <= JOYSTICK_EPS) lookVector.x = 0;
  903. if (Math.abs(lookVector.y) <= JOYSTICK_EPS) lookVector.y = 0;
  904. lookVector.multiplyScalar(data.rotationSensitivity * dt / 1000);
  905. yaw.rotation.y -= lookVector.x;
  906. pitch.rotation.x -= lookVector.y;
  907. pitch.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, pitch.rotation.x));
  908. data.camera.object3D.rotation.set(pitch.rotation.x, yaw.rotation.y, 0);
  909. // Sync with look-controls pitch/yaw if available.
  910. if (hasLookControls) {
  911. lookControls.pitchObject.rotation.copy(pitch.rotation);
  912. lookControls.yawObject.rotation.copy(yaw.rotation);
  913. }
  914. },
  915. /*******************************************************************
  916. * Button events
  917. */
  918. updateButtonState: function updateButtonState() {
  919. var gamepad = this.getGamepad();
  920. if (this.data.enabled && gamepad) {
  921. // Fire DOM events for button state changes.
  922. for (var i = 0; i < gamepad.buttons.length; i++) {
  923. if (gamepad.buttons[i].pressed && !this.buttons[i]) {
  924. this.emit(new GamepadButtonEvent('gamepadbuttondown', i, gamepad.buttons[i]));
  925. } else if (!gamepad.buttons[i].pressed && this.buttons[i]) {
  926. this.emit(new GamepadButtonEvent('gamepadbuttonup', i, gamepad.buttons[i]));
  927. }
  928. this.buttons[i] = gamepad.buttons[i].pressed;
  929. }
  930. } else if (Object.keys(this.buttons)) {
  931. // Reset state if controls are disabled or controller is lost.
  932. this.buttons = {};
  933. }
  934. },
  935. emit: function emit(event) {
  936. // Emit original event.
  937. this.el.emit(event.type, event);
  938. // Emit convenience event, identifying button index.
  939. this.el.emit(event.type + ':' + event.index, new GamepadButtonEvent(event.type, event.index, event));
  940. },
  941. /*******************************************************************
  942. * Gamepad state
  943. */
  944. /**
  945. * Returns the Gamepad instance attached to the component. If connected,
  946. * a proxy-controls component may provide access to Gamepad input from a
  947. * remote device.
  948. *
  949. * @return {Gamepad}
  950. */
  951. getGamepad: function getGamepad() {
  952. var stdGamepad = navigator.getGamepads && navigator.getGamepads()[this.data.controller],
  953. xrController = this.system.controllers[this.data.controller],
  954. xrGamepad = xrController && xrController.gamepad,
  955. proxyControls = this.el.sceneEl.components['proxy-controls'],
  956. proxyGamepad = proxyControls && proxyControls.isConnected() && proxyControls.getGamepad(this.data.controller);
  957. return proxyGamepad || xrGamepad || stdGamepad;
  958. },
  959. /**
  960. * Returns the state of the given button.
  961. * @param {number} index The button (0-N) for which to find state.
  962. * @return {GamepadButton}
  963. */
  964. getButton: function getButton(index) {
  965. return this.getGamepad().buttons[index];
  966. },
  967. /**
  968. * Returns state of the given axis. Axes are labelled 0-N, where 0-1 will
  969. * represent X/Y on the first joystick, and 2-3 X/Y on the second.
  970. * @param {number} index The axis (0-N) for which to find state.
  971. * @return {number} On the interval [-1,1].
  972. */
  973. getAxis: function getAxis(index) {
  974. return this.getGamepad().axes[index];
  975. },
  976. /**
  977. * Returns the state of the specified joystick as a THREE.Vector2.
  978. * @param {Joystick} role
  979. * @param {THREE.Vector2} target
  980. * @return {THREE.Vector2}
  981. */
  982. getJoystick: function getJoystick(index, target) {
  983. var gamepad = this.getGamepad();
  984. if (gamepad.mapping === 'xr-standard') {
  985. // See: https://github.com/donmccurdy/aframe-extras/issues/307
  986. switch (index) {
  987. case Joystick.MOVEMENT:
  988. return target.set(gamepad.axes[2], gamepad.axes[3]);
  989. case Joystick.ROTATION:
  990. return target.set(gamepad.axes[0], gamepad.axes[1]);
  991. }
  992. } else {
  993. switch (index) {
  994. case Joystick.MOVEMENT:
  995. return target.set(gamepad.axes[0], gamepad.axes[1]);
  996. case Joystick.ROTATION:
  997. return target.set(gamepad.axes[2], gamepad.axes[3]);
  998. }
  999. }
  1000. throw new Error('Unexpected joystick index "%d".', index);
  1001. },
  1002. /**
  1003. * Returns the state of the dpad as a THREE.Vector2.
  1004. * @param {THREE.Vector2} target
  1005. * @return {THREE.Vector2}
  1006. */
  1007. getDpad: function getDpad(target) {
  1008. var gamepad = this.getGamepad();
  1009. if (!gamepad.buttons[GamepadButton.DPAD_RIGHT]) {
  1010. return target.set(0, 0);
  1011. }
  1012. return target.set((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));
  1013. },
  1014. /**
  1015. * Returns true if the gamepad is currently connected to the system.
  1016. * @return {boolean}
  1017. */
  1018. isConnected: function isConnected() {
  1019. var gamepad = this.getGamepad();
  1020. return !!(gamepad && gamepad.connected);
  1021. },
  1022. /**
  1023. * Returns a string containing some information about the controller. Result
  1024. * may vary across browsers, for a given controller.
  1025. * @return {string}
  1026. */
  1027. getID: function getID() {
  1028. return this.getGamepad().id;
  1029. }
  1030. });
  1031. },{"../../lib/GamepadButton":2,"../../lib/GamepadButtonEvent":3}],7:[function(require,module,exports){
  1032. 'use strict';
  1033. require('./checkpoint-controls');
  1034. require('./gamepad-controls');
  1035. require('./keyboard-controls');
  1036. require('./touch-controls');
  1037. require('./movement-controls');
  1038. require('./trackpad-controls');
  1039. },{"./checkpoint-controls":5,"./gamepad-controls":6,"./keyboard-controls":8,"./movement-controls":9,"./touch-controls":10,"./trackpad-controls":11}],8:[function(require,module,exports){
  1040. 'use strict';
  1041. require('../../lib/keyboard.polyfill');
  1042. var MAX_DELTA = 0.2,
  1043. PROXY_FLAG = '__keyboard-controls-proxy';
  1044. var KeyboardEvent = window.KeyboardEvent;
  1045. /**
  1046. * Keyboard Controls component.
  1047. *
  1048. * Stripped-down version of: https://github.com/donmccurdy/aframe-keyboard-controls
  1049. *
  1050. * Bind keyboard events to components, or control your entities with the WASD keys.
  1051. *
  1052. * Why use KeyboardEvent.code? "This is set to a string representing the key that was pressed to
  1053. * generate the KeyboardEvent, without taking the current keyboard layout (e.g., QWERTY vs.
  1054. * Dvorak), locale (e.g., English vs. French), or any modifier keys into account. This is useful
  1055. * when you care about which physical key was pressed, rather thanwhich character it corresponds
  1056. * to. For example, if you’re a writing a game, you might want a certain set of keys to move the
  1057. * player in different directions, and that mapping should ideally be independent of keyboard
  1058. * layout. See: https://developers.google.com/web/updates/2016/04/keyboardevent-keys-codes
  1059. *
  1060. * @namespace wasd-controls
  1061. * keys the entity moves and if you release it will stop. Easing simulates friction.
  1062. * to the entity when pressing the keys.
  1063. * @param {bool} [enabled=true] - To completely enable or disable the controls
  1064. */
  1065. module.exports = AFRAME.registerComponent('keyboard-controls', {
  1066. schema: {
  1067. enabled: { default: true },
  1068. debug: { default: false }
  1069. },
  1070. init: function init() {
  1071. this.dVelocity = new THREE.Vector3();
  1072. this.localKeys = {};
  1073. this.listeners = {
  1074. keydown: this.onKeyDown.bind(this),
  1075. keyup: this.onKeyUp.bind(this),
  1076. blur: this.onBlur.bind(this)
  1077. };
  1078. this.attachEventListeners();
  1079. },
  1080. /*******************************************************************
  1081. * Movement
  1082. */
  1083. isVelocityActive: function isVelocityActive() {
  1084. return this.data.enabled && !!Object.keys(this.getKeys()).length;
  1085. },
  1086. getVelocityDelta: function getVelocityDelta() {
  1087. var data = this.data,
  1088. keys = this.getKeys();
  1089. this.dVelocity.set(0, 0, 0);
  1090. if (data.enabled) {
  1091. if (keys.KeyW || keys.ArrowUp) {
  1092. this.dVelocity.z -= 1;
  1093. }
  1094. if (keys.KeyA || keys.ArrowLeft) {
  1095. this.dVelocity.x -= 1;
  1096. }
  1097. if (keys.KeyS || keys.ArrowDown) {
  1098. this.dVelocity.z += 1;
  1099. }
  1100. if (keys.KeyD || keys.ArrowRight) {
  1101. this.dVelocity.x += 1;
  1102. }
  1103. }
  1104. return this.dVelocity.clone();
  1105. },
  1106. /*******************************************************************
  1107. * Events
  1108. */
  1109. play: function play() {
  1110. this.attachEventListeners();
  1111. },
  1112. pause: function pause() {
  1113. this.removeEventListeners();
  1114. },
  1115. remove: function remove() {
  1116. this.pause();
  1117. },
  1118. attachEventListeners: function attachEventListeners() {
  1119. window.addEventListener('keydown', this.listeners.keydown, false);
  1120. window.addEventListener('keyup', this.listeners.keyup, false);
  1121. window.addEventListener('blur', this.listeners.blur, false);
  1122. },
  1123. removeEventListeners: function removeEventListeners() {
  1124. window.removeEventListener('keydown', this.listeners.keydown);
  1125. window.removeEventListener('keyup', this.listeners.keyup);
  1126. window.removeEventListener('blur', this.listeners.blur);
  1127. },
  1128. onKeyDown: function onKeyDown(event) {
  1129. if (AFRAME.utils.shouldCaptureKeyEvent(event)) {
  1130. this.localKeys[event.code] = true;
  1131. this.emit(event);
  1132. }
  1133. },
  1134. onKeyUp: function onKeyUp(event) {
  1135. if (AFRAME.utils.shouldCaptureKeyEvent(event)) {
  1136. delete this.localKeys[event.code];
  1137. this.emit(event);
  1138. }
  1139. },
  1140. onBlur: function onBlur() {
  1141. for (var code in this.localKeys) {
  1142. if (this.localKeys.hasOwnProperty(code)) {
  1143. delete this.localKeys[code];
  1144. }
  1145. }
  1146. },
  1147. emit: function emit(event) {
  1148. // TODO - keydown only initially?
  1149. // TODO - where the f is the spacebar
  1150. // Emit original event.
  1151. if (PROXY_FLAG in event) {
  1152. // TODO - Method never triggered.
  1153. this.el.emit(event.type, event);
  1154. }
  1155. // Emit convenience event, identifying key.
  1156. this.el.emit(event.type + ':' + event.code, new KeyboardEvent(event.type, event));
  1157. if (this.data.debug) console.log(event.type + ':' + event.code);
  1158. },
  1159. /*******************************************************************
  1160. * Accessors
  1161. */
  1162. isPressed: function isPressed(code) {
  1163. return code in this.getKeys();
  1164. },
  1165. getKeys: function getKeys() {
  1166. if (this.isProxied()) {
  1167. return this.el.sceneEl.components['proxy-controls'].getKeyboard();
  1168. }
  1169. return this.localKeys;
  1170. },
  1171. isProxied: function isProxied() {
  1172. var proxyControls = this.el.sceneEl.components['proxy-controls'];
  1173. return proxyControls && proxyControls.isConnected();
  1174. }
  1175. });
  1176. },{"../../lib/keyboard.polyfill":4}],9:[function(require,module,exports){
  1177. 'use strict';
  1178. /**
  1179. * Movement Controls
  1180. *
  1181. * @author Don McCurdy <dm@donmccurdy.com>
  1182. */
  1183. var COMPONENT_SUFFIX = '-controls',
  1184. MAX_DELTA = 0.2,
  1185. // ms
  1186. EPS = 10e-6;
  1187. module.exports = AFRAME.registerComponent('movement-controls', {
  1188. /*******************************************************************
  1189. * Schema
  1190. */
  1191. dependencies: ['rotation'],
  1192. schema: {
  1193. enabled: { default: true },
  1194. controls: { default: ['gamepad', 'trackpad', 'keyboard', 'touch'] },
  1195. speed: { default: 0.3, min: 0 },
  1196. fly: { default: false },
  1197. constrainToNavMesh: { default: false },
  1198. camera: { default: '[movement-controls] [camera]', type: 'selector' }
  1199. },
  1200. /*******************************************************************
  1201. * Lifecycle
  1202. */
  1203. init: function init() {
  1204. var el = this.el;
  1205. this.velocityCtrl = null;
  1206. this.velocity = new THREE.Vector3();
  1207. this.heading = new THREE.Quaternion();
  1208. // Navigation
  1209. this.navGroup = null;
  1210. this.navNode = null;
  1211. if (el.sceneEl.hasLoaded) {
  1212. this.injectControls();
  1213. } else {
  1214. el.sceneEl.addEventListener('loaded', this.injectControls.bind(this));
  1215. }
  1216. },
  1217. update: function update(prevData) {
  1218. var el = this.el;
  1219. var data = this.data;
  1220. var nav = el.sceneEl.systems.nav;
  1221. if (el.sceneEl.hasLoaded) {
  1222. this.injectControls();
  1223. }
  1224. if (nav && data.constrainToNavMesh !== prevData.constrainToNavMesh) {
  1225. data.constrainToNavMesh ? nav.addAgent(this) : nav.removeAgent(this);
  1226. }
  1227. },
  1228. injectControls: function injectControls() {
  1229. var data = this.data;
  1230. var name;
  1231. for (var i = 0; i < data.controls.length; i++) {
  1232. name = data.controls[i] + COMPONENT_SUFFIX;
  1233. if (!this.el.components[name]) {
  1234. this.el.setAttribute(name, '');
  1235. }
  1236. }
  1237. },
  1238. updateNavLocation: function updateNavLocation() {
  1239. this.navGroup = null;
  1240. this.navNode = null;
  1241. },
  1242. /*******************************************************************
  1243. * Tick
  1244. */
  1245. tick: function () {
  1246. var start = new THREE.Vector3();
  1247. var end = new THREE.Vector3();
  1248. var clampedEnd = new THREE.Vector3();
  1249. return function (t, dt) {
  1250. if (!dt) return;
  1251. var el = this.el;
  1252. var data = this.data;
  1253. if (!data.enabled) return;
  1254. this.updateVelocityCtrl();
  1255. var velocityCtrl = this.velocityCtrl;
  1256. var velocity = this.velocity;
  1257. if (!velocityCtrl) return;
  1258. // Update velocity. If FPS is too low, reset.
  1259. if (dt / 1000 > MAX_DELTA) {
  1260. velocity.set(0, 0, 0);
  1261. } else {
  1262. this.updateVelocity(dt);
  1263. }
  1264. if (data.constrainToNavMesh && velocityCtrl.isNavMeshConstrained !== false) {
  1265. if (velocity.lengthSq() < EPS) return;
  1266. start.copy(el.object3D.position);
  1267. end.copy(velocity).multiplyScalar(dt / 1000).add(start);
  1268. var nav = el.sceneEl.systems.nav;
  1269. this.navGroup = this.navGroup === null ? nav.getGroup(start) : this.navGroup;
  1270. this.navNode = this.navNode || nav.getNode(start, this.navGroup);
  1271. this.navNode = nav.clampStep(start, end, this.navGroup, this.navNode, clampedEnd);
  1272. el.object3D.position.copy(clampedEnd);
  1273. } else if (el.hasAttribute('velocity')) {
  1274. el.setAttribute('velocity', velocity);
  1275. } else {
  1276. el.object3D.position.x += velocity.x * dt / 1000;
  1277. el.object3D.position.y += velocity.y * dt / 1000;
  1278. el.object3D.position.z += velocity.z * dt / 1000;
  1279. }
  1280. };
  1281. }(),
  1282. /*******************************************************************
  1283. * Movement
  1284. */
  1285. updateVelocityCtrl: function updateVelocityCtrl() {
  1286. var data = this.data;
  1287. if (data.enabled) {
  1288. for (var i = 0, l = data.controls.length; i < l; i++) {
  1289. var control = this.el.components[data.controls[i] + COMPONENT_SUFFIX];
  1290. if (control && control.isVelocityActive()) {
  1291. this.velocityCtrl = control;
  1292. return;
  1293. }
  1294. }
  1295. this.velocityCtrl = null;
  1296. }
  1297. },
  1298. updateVelocity: function () {
  1299. var vector2 = new THREE.Vector2();
  1300. var quaternion = new THREE.Quaternion();
  1301. return function (dt) {
  1302. var dVelocity = void 0;
  1303. var el = this.el;
  1304. var control = this.velocityCtrl;
  1305. var velocity = this.velocity;
  1306. var data = this.data;
  1307. if (control) {
  1308. if (control.getVelocityDelta) {
  1309. dVelocity = control.getVelocityDelta(dt);
  1310. } else if (control.getVelocity) {
  1311. velocity.copy(control.getVelocity());
  1312. return;
  1313. } else if (control.getPositionDelta) {
  1314. velocity.copy(control.getPositionDelta(dt).multiplyScalar(1000 / dt));
  1315. return;
  1316. } else {
  1317. throw new Error('Incompatible movement controls: ', control);
  1318. }
  1319. }
  1320. if (el.hasAttribute('velocity') && !data.constrainToNavMesh) {
  1321. velocity.copy(this.el.getAttribute('velocity'));
  1322. }
  1323. if (dVelocity && data.enabled) {
  1324. var cameraEl = data.camera;
  1325. // Rotate to heading
  1326. quaternion.copy(cameraEl.object3D.quaternion);
  1327. quaternion.premultiply(el.object3D.quaternion);
  1328. dVelocity.applyQuaternion(quaternion);
  1329. var factor = dVelocity.length();
  1330. if (data.fly) {
  1331. velocity.copy(dVelocity);
  1332. velocity.multiplyScalar(this.data.speed * 16.66667);
  1333. } else {
  1334. vector2.set(dVelocity.x, dVelocity.z);
  1335. vector2.setLength(factor * this.data.speed * 16.66667);
  1336. velocity.x = vector2.x;
  1337. velocity.z = vector2.y;
  1338. }
  1339. }
  1340. };
  1341. }()
  1342. });
  1343. },{}],10:[function(require,module,exports){
  1344. 'use strict';
  1345. /**
  1346. * Touch-to-move-forward controls for mobile.
  1347. */
  1348. module.exports = AFRAME.registerComponent('touch-controls', {
  1349. schema: {
  1350. enabled: { default: true },
  1351. reverseEnabled: { default: true }
  1352. },
  1353. init: function init() {
  1354. this.dVelocity = new THREE.Vector3();
  1355. this.bindMethods();
  1356. this.direction = 0;
  1357. },
  1358. play: function play() {
  1359. this.addEventListeners();
  1360. },
  1361. pause: function pause() {
  1362. this.removeEventListeners();
  1363. this.dVelocity.set(0, 0, 0);
  1364. },
  1365. remove: function remove() {
  1366. this.pause();
  1367. },
  1368. addEventListeners: function addEventListeners() {
  1369. var sceneEl = this.el.sceneEl;
  1370. var canvasEl = sceneEl.canvas;
  1371. if (!canvasEl) {
  1372. sceneEl.addEventListener('render-target-loaded', this.addEventListeners.bind(this));
  1373. return;
  1374. }
  1375. canvasEl.addEventListener('touchstart', this.onTouchStart);
  1376. canvasEl.addEventListener('touchend', this.onTouchEnd);
  1377. },
  1378. removeEventListeners: function removeEventListeners() {
  1379. var canvasEl = this.el.sceneEl && this.el.sceneEl.canvas;
  1380. if (!canvasEl) {
  1381. return;
  1382. }
  1383. canvasEl.removeEventListener('touchstart', this.onTouchStart);
  1384. canvasEl.removeEventListener('touchend', this.onTouchEnd);
  1385. },
  1386. isVelocityActive: function isVelocityActive() {
  1387. return this.data.enabled && !!this.direction;
  1388. },
  1389. getVelocityDelta: function getVelocityDelta() {
  1390. this.dVelocity.z = this.direction;
  1391. return this.dVelocity.clone();
  1392. },
  1393. bindMethods: function bindMethods() {
  1394. this.onTouchStart = this.onTouchStart.bind(this);
  1395. this.onTouchEnd = this.onTouchEnd.bind(this);
  1396. },
  1397. onTouchStart: function onTouchStart(e) {
  1398. this.direction = -1;
  1399. if (this.data.reverseEnabled && e.touches.length === 2) {
  1400. this.direction = 1;
  1401. }
  1402. e.preventDefault();
  1403. },
  1404. onTouchEnd: function onTouchEnd(e) {
  1405. this.direction = 0;
  1406. e.preventDefault();
  1407. }
  1408. });
  1409. },{}],11:[function(require,module,exports){
  1410. 'use strict';
  1411. /**
  1412. * 3dof (Gear VR, Daydream) controls for mobile.
  1413. */
  1414. module.exports = AFRAME.registerComponent('trackpad-controls', {
  1415. schema: {
  1416. enabled: { default: true },
  1417. enableNegX: { default: true },
  1418. enablePosX: { default: true },
  1419. enableNegZ: { default: true },
  1420. enablePosZ: { default: true },
  1421. mode: { default: 'touch', oneOf: ['swipe', 'touch', 'press'] }
  1422. },
  1423. init: function init() {
  1424. this.dVelocity = new THREE.Vector3();
  1425. this.zVel = 0;
  1426. this.xVel = 0;
  1427. this.bindMethods();
  1428. },
  1429. play: function play() {
  1430. this.addEventListeners();
  1431. },
  1432. pause: function pause() {
  1433. this.removeEventListeners();
  1434. this.dVelocity.set(0, 0, 0);
  1435. },
  1436. remove: function remove() {
  1437. this.pause();
  1438. },
  1439. addEventListeners: function addEventListeners() {
  1440. var data = this.data;
  1441. var sceneEl = this.el.sceneEl;
  1442. sceneEl.addEventListener('axismove', this.onAxisMove);
  1443. switch (data.mode) {
  1444. case 'swipe':
  1445. case 'touch':
  1446. sceneEl.addEventListener('trackpadtouchstart', this.onTouchStart);
  1447. sceneEl.addEventListener('trackpadtouchend', this.onTouchEnd);
  1448. break;
  1449. case 'press':
  1450. sceneEl.addEventListener('trackpaddown', this.onTouchStart);
  1451. sceneEl.addEventListener('trackpadup', this.onTouchEnd);
  1452. break;
  1453. }
  1454. },
  1455. removeEventListeners: function removeEventListeners() {
  1456. var sceneEl = this.el.sceneEl;
  1457. sceneEl.removeEventListener('axismove', this.onAxisMove);
  1458. sceneEl.removeEventListener('trackpadtouchstart', this.onTouchStart);
  1459. sceneEl.removeEventListener('trackpadtouchend', this.onTouchEnd);
  1460. sceneEl.removeEventListener('trackpaddown', this.onTouchStart);
  1461. sceneEl.removeEventListener('trackpadup', this.onTouchEnd);
  1462. },
  1463. isVelocityActive: function isVelocityActive() {
  1464. return this.data.enabled && this.isMoving;
  1465. },
  1466. getVelocityDelta: function getVelocityDelta() {
  1467. this.dVelocity.z = this.isMoving ? -this.zVel : 1;
  1468. this.dVelocity.x = this.isMoving ? this.xVel : 1;
  1469. return this.dVelocity.clone();
  1470. },
  1471. bindMethods: function bindMethods() {
  1472. this.onTouchStart = this.onTouchStart.bind(this);
  1473. this.onTouchEnd = this.onTouchEnd.bind(this);
  1474. this.onAxisMove = this.onAxisMove.bind(this);
  1475. },
  1476. onTouchStart: function onTouchStart(e) {
  1477. switch (this.data.mode) {
  1478. case 'swipe':
  1479. this.canRecordAxis = true;
  1480. this.startingAxisData = [];
  1481. break;
  1482. case 'touch':
  1483. this.isMoving = true;
  1484. break;
  1485. case 'press':
  1486. this.isMoving = true;
  1487. break;
  1488. }
  1489. e.preventDefault();
  1490. },
  1491. onTouchEnd: function onTouchEnd(e) {
  1492. if (this.data.mode == 'swipe') {
  1493. this.startingAxisData = [];
  1494. }
  1495. this.isMoving = false;
  1496. e.preventDefault();
  1497. },
  1498. onAxisMove: function onAxisMove(e) {
  1499. switch (this.data.mode) {
  1500. case 'swipe':
  1501. return this.handleSwipeAxis(e);
  1502. case 'touch':
  1503. case 'press':
  1504. return this.handleTouchAxis(e);
  1505. }
  1506. },
  1507. handleSwipeAxis: function handleSwipeAxis(e) {
  1508. var data = this.data;
  1509. var axisData = e.detail.axis;
  1510. if (this.startingAxisData.length === 0 && this.canRecordAxis) {
  1511. this.canRecordAxis = false;
  1512. this.startingAxisData[0] = axisData[0];
  1513. this.startingAxisData[1] = axisData[1];
  1514. }
  1515. if (this.startingAxisData.length > 0) {
  1516. var velX = 0;
  1517. var velZ = 0;
  1518. if (data.enableNegX && axisData[0] < this.startingAxisData[0]) {
  1519. velX = -1;
  1520. }
  1521. if (data.enablePosX && axisData[0] > this.startingAxisData[0]) {
  1522. velX = 1;
  1523. }
  1524. if (data.enablePosZ && axisData[1] > this.startingAxisData[1]) {
  1525. velZ = -1;
  1526. }
  1527. if (data.enableNegZ && axisData[1] < this.startingAxisData[1]) {
  1528. velZ = 1;
  1529. }
  1530. var absChangeZ = Math.abs(this.startingAxisData[1] - axisData[1]);
  1531. var absChangeX = Math.abs(this.startingAxisData[0] - axisData[0]);
  1532. if (absChangeX > absChangeZ) {
  1533. this.zVel = 0;
  1534. this.xVel = velX;
  1535. this.isMoving = true;
  1536. } else {
  1537. this.xVel = 0;
  1538. this.zVel = velZ;
  1539. this.isMoving = true;
  1540. }
  1541. }
  1542. },
  1543. handleTouchAxis: function handleTouchAxis(e) {
  1544. var data = this.data;
  1545. var axisData = e.detail.axis;
  1546. var velX = 0;
  1547. var velZ = 0;
  1548. if (data.enableNegX && axisData[0] < 0) {
  1549. velX = -1;
  1550. }
  1551. if (data.enablePosX && axisData[0] > 0) {
  1552. velX = 1;
  1553. }
  1554. if (data.enablePosZ && axisData[1] > 0) {
  1555. velZ = -1;
  1556. }
  1557. if (data.enableNegZ && axisData[1] < 0) {
  1558. velZ = 1;
  1559. }
  1560. if (Math.abs(axisData[0]) > Math.abs(axisData[1])) {
  1561. this.zVel = 0;
  1562. this.xVel = velX;
  1563. } else {
  1564. this.xVel = 0;
  1565. this.zVel = velZ;
  1566. }
  1567. }
  1568. });
  1569. },{}]},{},[1]);