glge.js 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314
  1. "use strict";
  2. // Copyright 2012 United States Government, as represented by the Secretary of Defense, Under
  3. // Secretary of Defense (Personnel & Readiness).
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed under the License
  11. // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  12. // or implied. See the License for the specific language governing permissions and limitations under
  13. // the License.
  14. /// @module vwf/view/glge
  15. /// @requires vwf/view
  16. /// @requires vwf/utility
  17. define( [ "module", "vwf/view", "vwf/utility" ], function( module, view, utility ) {
  18. return view.load( module, {
  19. initialize: function( options ) {
  20. if (!vwf) return;
  21. checkCompatibility.call(this);
  22. this.pickInterval = 10;
  23. this.enableInputs = true;
  24. // Store parameter options for persistence functionality
  25. this.parameters = options;
  26. if(typeof options == "object") {
  27. this.rootSelector = options["application-root"];
  28. if("pick-interval" in options) {
  29. this.pickInterval = options["pick-interval"];
  30. }
  31. if("enable-inputs" in options) {
  32. this.enableInputs = options["enable-inputs"];
  33. }
  34. }
  35. else {
  36. this.rootSelector = options;
  37. }
  38. this.canvasQuery = undefined;
  39. this.lastPick = undefined;
  40. this.lastEventData = undefined;
  41. this.mouseOverCanvas = false;
  42. this.keyStates = { keysDown: {}, mods: {}, keysUp: {} };
  43. this.height = 600;
  44. this.width = 800;
  45. if ( window && window.innerHeight ) this.height = window.innerHeight - 20;
  46. if ( window && window.innerWidth ) this.width = window.innerWidth - 20;
  47. this.canvasQuery = jQuery( this.rootSelector );
  48. // Connect GLGE to the VWF timeline.
  49. GLGE.now = function() {
  50. return vwf.time() * 1000;
  51. }
  52. },
  53. createdNode: function( nodeID, childID, childExtendsID, childImplementsIDs,
  54. childSource, childType, childIndex, childName, callback /* ( ready ) */) {
  55. if (childExtendsID === undefined /* || childName === undefined */)
  56. return;
  57. if (this.state.scenes[childID]) {
  58. // this is the scene definition so go ahead and create the canvas and setup the view
  59. var glgeView = this;
  60. var domWin = window;
  61. this.canvasQuery = jQuery(this.rootSelector).append(
  62. "<canvas id='" + this.state.sceneRootID + "' class='vwf-scene' width='" + this.width + "' height='" + this.height + "'/>"
  63. ).children(":last");
  64. var canvas = this.canvasQuery.get(0);
  65. if( this.enableInputs ) {
  66. window.onkeydown = function (event) {
  67. var key = undefined;
  68. var validKey = false;
  69. var keyAlreadyDown = false;
  70. switch (event.keyCode) {
  71. case 17:
  72. case 16:
  73. case 18:
  74. case 19:
  75. case 20:
  76. break;
  77. default:
  78. key = getKeyValue.call( glgeView, event.keyCode);
  79. keyAlreadyDown = !!glgeView.keyStates.keysDown[key.key];
  80. glgeView.keyStates.keysDown[key.key] = key;
  81. validKey = true;
  82. break;
  83. }
  84. if (!glgeView.keyStates.mods) glgeView.keyStates.mods = {};
  85. glgeView.keyStates.mods.alt = event.altKey;
  86. glgeView.keyStates.mods.shift = event.shiftKey;
  87. glgeView.keyStates.mods.ctrl = event.ctrlKey;
  88. glgeView.keyStates.mods.meta = event.metaKey;
  89. var sceneNode = glgeView.state.scenes[glgeView.state.sceneRootID];
  90. if (validKey && sceneNode && !keyAlreadyDown /*&& Object.keys( glgeView.keyStates.keysDown ).length > 0*/) {
  91. //var params = JSON.stringify( glgeView.keyStates );
  92. glgeView.kernel.dispatchEvent(sceneNode.ID, "keyDown", [glgeView.keyStates]);
  93. }
  94. };
  95. window.onkeyup = function (event) {
  96. var key = undefined;
  97. var validKey = false;
  98. switch (event.keyCode) {
  99. case 16:
  100. case 17:
  101. case 18:
  102. case 19:
  103. case 20:
  104. break;
  105. default:
  106. key = getKeyValue.call( glgeView, event.keyCode);
  107. delete glgeView.keyStates.keysDown[key.key];
  108. glgeView.keyStates.keysUp[key.key] = key;
  109. validKey = true;
  110. break;
  111. }
  112. glgeView.keyStates.mods.alt = event.altKey;
  113. glgeView.keyStates.mods.shift = event.shiftKey;
  114. glgeView.keyStates.mods.ctrl = event.ctrlKey;
  115. glgeView.keyStates.mods.meta = event.metaKey;
  116. var sceneNode = glgeView.state.scenes[glgeView.state.sceneRootID];
  117. if (validKey && sceneNode) {
  118. //var params = JSON.stringify( glgeView.keyStates );
  119. glgeView.kernel.dispatchEvent(sceneNode.ID, "keyUp", [glgeView.keyStates]);
  120. delete glgeView.keyStates.keysUp[key.key];
  121. }
  122. };
  123. }
  124. window.onresize = function () {
  125. var origWidth = glgeView.width;
  126. var origHeight = glgeView.height;
  127. if (domWin && domWin.innerHeight) glgeView.height = domWin.innerHeight - 20;
  128. if (domWin && domWin.innerWidth) glgeView.width = domWin.innerWidth - 20;
  129. if ((origWidth != glgeView.width) || (origHeight != glgeView.height)) {
  130. canvas.height = glgeView.height;
  131. canvas.width = glgeView.width;
  132. var cam = glgeView.state.cameraInUse;
  133. if ( cam ) {
  134. cam.setAspect( ( canvas.width / canvas.height ) );
  135. }
  136. $('#topdown_a').height(canvas.height);
  137. $('#topdown_b').height(canvas.height);
  138. $('#client_list').height(canvas.height);
  139. $('#time_control').height(canvas.height);
  140. $('#about_tab').height(canvas.height);
  141. $('#model_a').height(canvas.height);
  142. $('#model_b').height(canvas.height);
  143. }
  144. }
  145. var sceneNode = this.state.scenes[childID];
  146. if (sceneNode) {
  147. initScene.call(this, sceneNode);
  148. }
  149. }
  150. },
  151. // -- deletedNode ------------------------------------------------------------------------------
  152. //deletedNode: function( nodeID ) { },
  153. // -- addedChild -------------------------------------------------------------------------------
  154. //addedChild: function( nodeID, childID, childName ) { },
  155. // -- removedChild -----------------------------------------------------------------------------
  156. //removedChild: function( nodeID, childID ) { },
  157. // -- createdProperty --------------------------------------------------------------------------
  158. //createdProperty: function (nodeID, propertyName, propertyValue) { },
  159. // -- initializedProperty ----------------------------------------------------------------------
  160. //initializedProperty: function (nodeID, propertyName, propertyValue) { },
  161. // TODO: deletedProperty
  162. // -- satProperty ------------------------------------------------------------------------------
  163. //satProperty: function (nodeID, propertyName, propertyValue) { },
  164. // -- gotProperty ------------------------------------------------------------------------------
  165. //gotProperty: function ( nodeID, propertyName, propertyValue ) { },
  166. } );
  167. // GLGE private functions
  168. // -- checkCompatibility -------------------------------------------------------------
  169. function checkCompatibility() {
  170. this.compatibilityStatus = { compatible:true, errors:{} }
  171. var contextNames = ["webgl","experimental-webgl","moz-webgl","webkit-3d"];
  172. for(var i = 0; i < contextNames.length; i++){
  173. try{
  174. var canvas = document.createElement('canvas');
  175. var gl = canvas.getContext(contextNames[i]);
  176. if(gl){
  177. return true;
  178. }
  179. }
  180. catch(e){}
  181. }
  182. this.compatibilityStatus.compatible = false;
  183. this.compatibilityStatus.errors["WGL"] = "This browser is not compatible. The vwf/view/threejs driver requires WebGL.";
  184. return false;
  185. }
  186. // -- initScene ------------------------------------------------------------------------
  187. function initScene( sceneNode ) {
  188. var self = this;
  189. var lastPickTime = 0;
  190. function renderScene(time) {
  191. time = time || 0;
  192. window.requestAnimationFrame( renderScene );
  193. sceneNode.frameCount++;
  194. if((time - lastPickTime) > self.pickInterval && self.enableInputs) {
  195. var newPick = mousePick.call( this, mouse, sceneNode );
  196. self.lastPick = newPick;
  197. if((mouse.getMousePosition().x != oldMouseX || mouse.getMousePosition().y != oldMouseY)) {
  198. oldMouseX = mouse.getMousePosition().x;
  199. oldMouseY = mouse.getMousePosition().y;
  200. hovering = false;
  201. }
  202. else if(self.lastEventData && self.mouseOverCanvas && !hovering) {
  203. var pickId = getPickObjectID.call( view, self.lastPick, false );
  204. if(!pickId) {
  205. pickId = view.state.sceneRootID;
  206. }
  207. view.kernel.dispatchEvent( pickId, "pointerHover", self.lastEventData.eventData, self.lastEventData.eventNodeData );
  208. hovering = true;
  209. }
  210. lastPickTime = time;
  211. }
  212. renderer.render();
  213. };
  214. var canvas = this.canvasQuery.get( 0 );
  215. if ( canvas ) {
  216. var mouse = new GLGE.MouseInput( canvas );
  217. var oldMouseX = mouse.getMousePosition().x;
  218. var oldMouseY = mouse.getMousePosition().y;
  219. var hovering = false;
  220. sceneNode.glgeRenderer = new GLGE.Renderer( canvas );
  221. sceneNode.glgeRenderer.setScene( sceneNode.glgeScene );
  222. this.state.cameraInUse = sceneNode.glgeScene.camera;
  223. this.state.cameraInUse.setAspect( ( canvas.width / canvas.height) );
  224. // set up all of the mouse event handlers
  225. if( self.enableInputs ) {
  226. initMouseEvents.call( this, canvas );
  227. }
  228. // Schedule the renderer.
  229. var view = this;
  230. var scene = sceneNode.glgeScene;
  231. var renderer = sceneNode.glgeRenderer;
  232. sceneNode.frameCount = 0; // needed for estimating when we're pick-safe
  233. renderScene();
  234. }
  235. }
  236. // -- initCamera ------------------------------------------------------------------------
  237. function initCamera( glgeCamera ) {
  238. if ( glgeCamera ) {
  239. glgeCamera.setLoc( 0, 0, 0 );
  240. glgeCamera.setRot( 0, 0, 0 );
  241. glgeCamera.setType( GLGE.C_PERSPECTIVE );
  242. glgeCamera.setRotOrder( GLGE.ROT_XZY );
  243. }
  244. }
  245. // -- initMouseEvents ------------------------------------------------------------------------
  246. function initMouseEvents( canvas ) {
  247. var sceneNode = this.state.scenes[this.state.sceneRootID], child;
  248. var sceneID = this.state.sceneRootID;
  249. var sceneView = this;
  250. var pointerDownID = undefined;
  251. var pointerOverID = undefined;
  252. var pointerPickID = undefined;
  253. var glgeActualObj = undefined;
  254. var lastXPos = -1;
  255. var lastYPos = -1;
  256. var mouseRightDown = false;
  257. var mouseLeftDown = false;
  258. var mouseMiddleDown = false;
  259. var win = window;
  260. var container = document.getElementById("container");
  261. var sceneCanvas = canvas;
  262. var mouse = new GLGE.MouseInput( sceneCanvas );
  263. var self = this;
  264. var getEventData = function( e, debug ) {
  265. var returnData = { eventData: undefined, eventNodeData: undefined };
  266. var pickInfo = self.lastPick;
  267. pointerPickID = undefined;
  268. glgeActualObj = pickInfo ? pickInfo.object : undefined;
  269. pointerPickID = pickInfo ? getPickObjectID.call( sceneView, pickInfo, debug ) : undefined;
  270. var mouseButton = "left";
  271. switch( e.button ) {
  272. case 2:
  273. mouseButton = "right";
  274. break;
  275. case 1:
  276. mouseButton = "middle";
  277. break;
  278. default:
  279. mouseButton = "left";
  280. break;
  281. };
  282. var mousePos = utility.coordinates.contentFromWindow( e.target, { x: e.clientX, y: e.clientY } ); // canvas coordinates from window coordinates
  283. returnData.eventData = [ {
  284. /*client: "123456789ABCDEFG", */
  285. button: mouseButton,
  286. clicks: 1,
  287. buttons: {
  288. left: mouseLeftDown,
  289. middle: mouseMiddleDown,
  290. right: mouseRightDown,
  291. },
  292. modifiers: {
  293. alt: e.altKey,
  294. ctrl: e.ctrlKey,
  295. shift: e.shiftKey,
  296. meta: e.metaKey,
  297. },
  298. position: [ mousePos.x / sceneView.width, mousePos.y / sceneView.height ],
  299. screenPosition: [ mousePos.x, mousePos.y ]
  300. } ];
  301. var camera = sceneView.state.cameraInUse;
  302. var worldCamPos, worldCamTrans, camInverse;
  303. if ( camera ) {
  304. worldCamTrans = camera.getModelMatrix();
  305. worldCamPos = [ worldCamTrans[3], worldCamTrans[7], worldCamTrans[11] ];
  306. //worldCamPos = [ camera.getLocX(), camera.getLocY(), camera.getLocZ() ];
  307. // worldCamTrans = goog.vec.Mat4.createFromArray( camera.getLocalMatrix() );
  308. // goog.vec.Mat4.transpose( worldCamTrans, worldCamTrans );
  309. // camInverse = goog.vec.Mat4.create();
  310. // goog.vec.Mat4.invert( worldCamTrans, camInverse );
  311. }
  312. returnData.eventNodeData = { "": [ {
  313. distance: pickInfo ? pickInfo.distance : undefined,
  314. origin: pickInfo ? pickInfo.pickOrigin : undefined,
  315. globalPosition: pickInfo ? pickInfo.coord : undefined,
  316. globalNormal: pickInfo ? pickInfo.normal : undefined,
  317. globalSource: worldCamPos,
  318. } ] };
  319. if ( pickInfo && pickInfo.normal ) {
  320. var pin = pickInfo.normal;
  321. var nml = goog.vec.Vec3.createFloat32FromValues( pin[0], pin[1], pin[2] );
  322. nml = goog.vec.Vec3.normalize( nml, goog.vec.Vec3.create() );
  323. returnData.eventNodeData[""][0].globalNormal = [ nml[0], nml[1], nml[2] ];
  324. }
  325. if ( sceneView && sceneView.state.nodes[ pointerPickID ] ) {
  326. var camera = sceneView.state.cameraInUse;
  327. var childID = pointerPickID;
  328. var child = sceneView.state.nodes[ childID ];
  329. var parentID = child.parentID;
  330. var parent = sceneView.state.nodes[ child.parentID ];
  331. var trans, parentTrans, localTrans, localNormal, parentInverse, relativeCamPos;
  332. while ( child ) {
  333. trans = goog.vec.Mat4.createFromArray( child.glgeObject.getLocalMatrix() );
  334. goog.vec.Mat4.transpose( trans, trans );
  335. if ( parent ) {
  336. parentTrans = goog.vec.Mat4.createFromArray( parent.glgeObject.getLocalMatrix() );
  337. goog.vec.Mat4.transpose( parentTrans, parentTrans );
  338. } else {
  339. parentTrans = undefined;
  340. }
  341. if ( trans && parentTrans ) {
  342. // get the parent inverse, and multiply by the world
  343. // transform to get the local transform
  344. parentInverse = goog.vec.Mat4.create();
  345. if ( goog.vec.Mat4.invert( parentTrans, parentInverse ) ) {
  346. localTrans = goog.vec.Mat4.multMat( parentInverse, trans,
  347. goog.vec.Mat4.create()
  348. );
  349. }
  350. }
  351. // transform the global normal into local
  352. if ( pickInfo && pickInfo.normal ) {
  353. localNormal = goog.vec.Mat4.multVec3Projective( trans, pickInfo.normal,
  354. goog.vec.Vec3.create() );
  355. } else {
  356. localNormal = undefined;
  357. }
  358. if ( worldCamPos ) {
  359. relativeCamPos = goog.vec.Mat4.multVec3Projective( trans, worldCamPos,
  360. goog.vec.Vec3.create() );
  361. } else {
  362. relativeCamPos = undefined;
  363. }
  364. returnData.eventNodeData[ childID ] = [ {
  365. position: localTrans,
  366. normal: localNormal,
  367. source: relativeCamPos,
  368. distance: pickInfo ? pickInfo.distance : undefined,
  369. globalPosition: pickInfo ? pickInfo.coord : undefined,
  370. globalNormal: pickInfo ? pickInfo.normal : undefined,
  371. globalSource: worldCamPos,
  372. } ];
  373. childID = parentID;
  374. child = sceneView.state.nodes[ childID ];
  375. parentID = child ? child.parentID : undefined;
  376. parent = parentID ? sceneView.state.nodes[ child.parentID ] : undefined;
  377. }
  378. }
  379. self.lastEventData = returnData;
  380. return returnData;
  381. }
  382. canvas.onmousedown = function( e ) {
  383. switch( e.button ) {
  384. case 2:
  385. mouseRightDown = true;
  386. break;
  387. case 1:
  388. mouseMiddleDown = true;
  389. break;
  390. case 0:
  391. mouseLeftDown = true;
  392. break;
  393. };
  394. var event = getEventData( e, false );
  395. if ( event ) {
  396. pointerDownID = pointerPickID ? pointerPickID : sceneID;
  397. sceneView.kernel.dispatchEvent( pointerDownID, "pointerDown", event.eventData, event.eventNodeData );
  398. }
  399. e.preventDefault();
  400. }
  401. canvas.onmouseup = function( e ) {
  402. var ctrlDown = e.ctrlKey;
  403. var altDown = e.altKey;
  404. var ctrlAndAltDown = ctrlDown && altDown;
  405. switch( e.button ) {
  406. case 2:
  407. mouseRightDown = false;
  408. break;
  409. case 1:
  410. mouseMiddleDown = false;
  411. break;
  412. case 0:
  413. mouseLeftDown = false;
  414. break;
  415. };
  416. var eData = getEventData( e, ctrlAndAltDown );
  417. if ( eData ) {
  418. var mouseUpObjectID = pointerPickID;
  419. if ( mouseUpObjectID && pointerDownID && mouseUpObjectID == pointerDownID ) {
  420. sceneView.kernel.dispatchEvent( mouseUpObjectID, "pointerClick", eData.eventData, eData.eventNodeData );
  421. var glgeObj = sceneView.state.nodes[mouseUpObjectID].glgeObject;
  422. if ( glgeObj ) {
  423. if ( ctrlDown || altDown ) {
  424. var colladaObj;
  425. var currentObj = glgeObj;
  426. while ( !colladaObj && currentObj ) {
  427. if ( currentObj.constructor == GLGE.Collada )
  428. colladaObj = currentObj;
  429. else
  430. currentObj = currentObj.parent;
  431. }
  432. if( ctrlDown && !altDown ) {
  433. if ( sceneView.state.nodes[mouseUpObjectID] ) {
  434. if ( colladaObj ) {
  435. recurseGroup.call( sceneView, colladaObj, 0 );
  436. }
  437. }
  438. } else if ( altDown && !ctrlDown ) {
  439. recurseGroup.call( sceneView, glgeObj, 0 );
  440. consoleScene.call( sceneView, sceneNode.glgeScene, 0 );
  441. }
  442. }
  443. }
  444. }
  445. sceneView.kernel.dispatchEvent( pointerDownID, "pointerUp", eData.eventData, eData.eventNodeData );
  446. }
  447. pointerDownID = undefined;
  448. e.preventDefault();
  449. }
  450. canvas.onmouseover = function( e ) {
  451. self.mouseOverCanvas = true;
  452. var eData = getEventData( e, false );
  453. if ( eData ) {
  454. pointerOverID = pointerPickID ? pointerPickID : sceneID;
  455. sceneView.kernel.dispatchEvent( pointerOverID, "pointerOver", eData.eventData, eData.eventNodeData );
  456. }
  457. e.preventDefault();
  458. }
  459. canvas.onmousemove = function( e ) {
  460. var eData = getEventData( e, false );
  461. if ( eData ) {
  462. if ( mouseLeftDown || mouseRightDown || mouseMiddleDown ) {
  463. sceneView.kernel.dispatchEvent( pointerDownID, "pointerMove", eData.eventData, eData.eventNodeData );
  464. } else {
  465. if ( pointerPickID ) {
  466. if ( pointerOverID ) {
  467. if ( pointerPickID != pointerOverID ) {
  468. sceneView.kernel.dispatchEvent( pointerOverID, "pointerOut", eData.eventData, eData.eventNodeData );
  469. pointerOverID = pointerPickID;
  470. sceneView.kernel.dispatchEvent( pointerOverID, "pointerOver", eData.eventData, eData.eventNodeData );
  471. }
  472. } else {
  473. pointerOverID = pointerPickID;
  474. sceneView.kernel.dispatchEvent( pointerOverID, "pointerOver", eData.eventData, eData.eventNodeData );
  475. }
  476. } else {
  477. if ( pointerOverID ) {
  478. sceneView.kernel.dispatchEvent( pointerOverID, "pointerOut", eData.eventData, eData.eventNodeData );
  479. pointerOverID = undefined;
  480. }
  481. }
  482. }
  483. }
  484. e.preventDefault();
  485. }
  486. canvas.onmouseout = function( e ) {
  487. if ( pointerOverID ) {
  488. sceneView.kernel.dispatchEvent( pointerOverID, "pointerOut" );
  489. pointerOverID = undefined;
  490. }
  491. self.mouseOverCanvas = false;
  492. e.preventDefault();
  493. }
  494. canvas.setAttribute("onmousewheel", '');
  495. if(typeof canvas.onmousewheel == "function") {
  496. canvas.removeAttribute("onmousewheel");
  497. canvas.onmousewheel = function( e ) {
  498. var eData = getEventData( e, false );
  499. if ( eData ) {
  500. eData.eventNodeData[""][0].wheel = {
  501. delta: e.wheelDelta / -40,
  502. deltaX: e.wheelDeltaX / -40,
  503. deltaY: e.wheelDeltaY / -40,
  504. };
  505. var id = sceneID;
  506. if ( pointerDownID && mouseRightDown || mouseLeftDown || mouseMiddleDown )
  507. id = pointerDownID;
  508. else if ( pointerOverID )
  509. id = pointerOverID;
  510. sceneView.kernel.dispatchEvent( id, "pointerWheel", eData.eventData, eData.eventNodeData );
  511. }
  512. };
  513. }
  514. else {
  515. canvas.removeAttribute("onmousewheel");
  516. canvas.addEventListener('DOMMouseScroll', function( e ) {
  517. var eData = getEventData( e, false );
  518. if ( eData ) {
  519. eData.eventNodeData[""][0].wheel = {
  520. delta: e.detail,
  521. deltaX: e.detail,
  522. deltaY: e.detail,
  523. };
  524. var id = sceneID;
  525. if ( pointerDownID && mouseRightDown || mouseLeftDown || mouseMiddleDown )
  526. id = pointerDownID;
  527. else if ( pointerOverID )
  528. id = pointerOverID;
  529. sceneView.kernel.dispatchEvent( id, "pointerWheel", eData.eventData, eData.eventNodeData );
  530. }
  531. });
  532. }
  533. // == Draggable Content ========================================================================
  534. // canvas.addEventListener( "dragenter", function( e ) {
  535. // e.stopPropagation();
  536. // e.preventDefault();
  537. // }, false );
  538. // canvas.addEventListener( "dragexit", function( e ) {
  539. // e.stopPropagation();
  540. // e.preventDefault();
  541. // }, false );
  542. // -- dragOver ---------------------------------------------------------------------------------
  543. canvas.ondragover = function( e ) {
  544. sceneCanvas.mouseX=e.clientX;
  545. sceneCanvas.mouseY=e.clientY;
  546. var eData = getEventData( e, false );
  547. if ( eData ) {
  548. e.dataTransfer.dropEffect = "copy";
  549. }
  550. e.preventDefault();
  551. };
  552. // -- drop ---------------------------------------------------------------------------------
  553. canvas.ondrop = function( e ) {
  554. e.preventDefault();
  555. var eData = getEventData( e, false );
  556. if ( eData ) {
  557. var fileData, fileName, fileUrl, rotation, scale, translation, match, object;
  558. try {
  559. fileData = JSON.parse( e.dataTransfer.getData('text/plain') );
  560. fileName = decodeURIComponent(fileData.fileName);
  561. fileUrl = decodeURIComponent(fileData.fileUrl);
  562. rotation = decodeURIComponent(fileData.rotation);
  563. rotation = rotation ? JSON.parse(rotation) : undefined;
  564. scale = decodeURIComponent(fileData.scale);
  565. scale = scale ? JSON.parse(scale) : [1, 1, 1];
  566. translation = decodeURIComponent(fileData.translation);
  567. translation = translation ? JSON.parse(translation) : [0, 0, 0];
  568. if($.isArray(translation) && translation.length == 3) {
  569. translation[0] += eData.eventNodeData[""][0].globalPosition[0];
  570. translation[1] += eData.eventNodeData[""][0].globalPosition[1];
  571. translation[2] += eData.eventNodeData[""][0].globalPosition[2];
  572. }
  573. else {
  574. translation = eData.eventNodeData[""][0].globalPosition;
  575. }
  576. if ( match = /* assignment! */ fileUrl.match( /(.*\.vwf)\.(json|yaml)$/i ) ) {
  577. object = {
  578. extends: match[1],
  579. properties: {
  580. translation: translation,
  581. rotation : rotation,
  582. scale: scale,
  583. },
  584. };
  585. fileName = fileName.replace( /\.(json|yaml)$/i, "" );
  586. } else if ( match = /* assignment! */ fileUrl.match( /\.dae$/i ) ) {
  587. object = {
  588. extends: "http://vwf.example.com/node3.vwf",
  589. source: fileUrl,
  590. type: "model/vnd.collada+xml",
  591. properties: {
  592. translation: translation,
  593. rotation : rotation,
  594. scale: scale,
  595. },
  596. };
  597. }
  598. if ( object ) {
  599. sceneView.kernel.createChild( sceneView.kernel.application(), fileName, object );
  600. }
  601. } catch ( e ) {
  602. // TODO: invalid JSON
  603. }
  604. }
  605. };
  606. };
  607. function nameGlge(obj) {
  608. return obj.colladaName || obj.colladaId || obj.name || obj.id || obj.uid || "";
  609. }
  610. function name(obj) {
  611. return obj.colladaName || obj.colladaId || obj.name || obj.id || "";
  612. }
  613. function path(obj) {
  614. var sOut = "";
  615. var sName = "";
  616. while (obj && obj.parent) {
  617. if (sOut == "")
  618. sOut = name.call(this,obj);
  619. else
  620. sOut = name.call(this,obj) + "." + sOut;
  621. obj = obj.parent;
  622. }
  623. return sOut;
  624. }
  625. function getPickObjectID( pickInfo, debug ) {
  626. if ( pickInfo && pickInfo.object ) {
  627. return getObjectID.call( this, pickInfo.object, true, debug );
  628. }
  629. return undefined;
  630. }
  631. function getObjectID( objectToLookFor, bubbleUp, debug ) {
  632. var objectIDFound = -1;
  633. var self = this;
  634. while (objectIDFound == -1 && objectToLookFor) {
  635. if ( debug ) {
  636. this.logger.info("====>>> vwf.view-glge.mousePick: searching for: " + path.call(this,objectToLookFor) );
  637. }
  638. jQuery.each( this.state.nodes, function (nodeID, node) {
  639. if ( node.glgeObject == objectToLookFor && !node.glgeMaterial ) {
  640. if ( debug ) { self.logger.info("pick object name: " + name(objectToLookFor) + " with id = " + nodeID ); }
  641. objectIDFound = nodeID;
  642. }
  643. });
  644. if ( bubbleUp ) {
  645. objectToLookFor = objectToLookFor.parent;
  646. } else {
  647. objectToLookFor = undefined;
  648. }
  649. }
  650. if (objectIDFound != -1)
  651. return objectIDFound;
  652. return undefined;
  653. }
  654. function mousePick( mouse, sceneNode ) {
  655. if (sceneNode && sceneNode.glgeScene) {
  656. // GLGE won't calculate picks if we pick too soon after launch. The exact cause is
  657. // unclear, but it appears to work if there isn't a pick before the first few frames
  658. // or while deferred loads are occurring.
  659. if ( sceneNode.frameCount > 10 && sceneNode.pendingLoads == 0 ) {
  660. var objectIDFound = -1;
  661. var mousepos=mouse.getMousePosition(); // window coordinates
  662. mousepos = utility.coordinates.contentFromWindow( mouse.element, mousepos ); // canvas coordinates
  663. var returnValue = sceneNode.glgeScene.pick( mousepos.x, mousepos.y );
  664. if (!returnValue) {
  665. returnValue = { };
  666. }
  667. var originRay = sceneNode.glgeScene.makeRay(mousepos.x, mousepos.y)
  668. returnValue.pickOrigin = originRay ? originRay.origin : undefined;
  669. return returnValue;
  670. }
  671. }
  672. return undefined;
  673. }
  674. function getObjectType( obj ) {
  675. // var type = "Group";
  676. // if ( object3 instanceof GLGE.Camera ) {
  677. // type = "camera"
  678. // } else if ( object3 instanceof GLGE.Light ) {
  679. // type = "light"
  680. // } else if ( object3 instanceof GLGE.Mesh ) {
  681. // type = "mesh"
  682. // } else if ( object3 instanceof GLGE.Object ) {
  683. // type = "object"
  684. // } else if ( object3 instanceof GLGE.Scene ) {
  685. // type = "scene";
  686. // }
  687. return obj.className;
  688. }
  689. function consoleOut( msg ) {
  690. console.info( msg );
  691. }
  692. function consoleObject( object3, depth ) {
  693. consoleOut.call( this, indent2.call( this, depth ) + name.call( this, object3 )+ " -> " + " type = " + getObjectType.call( this, object3 ) );
  694. }
  695. function consoleScene( parent, depth ) {
  696. consoleObject.call( this, parent, depth );
  697. if ( parent.children !== undefined ) {
  698. for ( var i = 0; i < parent.children.length; i++ ) {
  699. consoleScene.call( this, parent.children[i], depth+1 );
  700. }
  701. }
  702. }
  703. function recurseGroup( grp, depth ) {
  704. if ( grp && grp.getChildren ) {
  705. var grpChildren = grp.getChildren();
  706. var sOut = indent.call( this,depth);
  707. var name = "";
  708. for (var i = 0; i < grpChildren.length; i++) {
  709. if (grpChildren[i].constructor == GLGE.Collada) {
  710. depth++;
  711. outputCollada.call( this, grpChildren[i], depth, true);
  712. recurseGroup.call( this, grpChildren[i], depth + 1);
  713. outputCollada.call( this, grpChildren[i], depth, false);
  714. depth--;
  715. } else if (grpChildren[i].constructor == GLGE.Group) {
  716. depth++;
  717. outputGroup.call( this, grpChildren[i], depth, true);
  718. recurseGroup.call( this, grpChildren[i], depth + 1);
  719. outputGroup.call( this, grpChildren[i], depth, false);
  720. depth--;
  721. } else if ( grpChildren[i].constructor == GLGE.Object ) {
  722. outputObject.call( this, grpChildren[i], depth);
  723. }
  724. }
  725. } else if ( grp.constructor == GLGE.Object ) {
  726. outputObject.call( this, grp, depth );
  727. }
  728. }
  729. function getChildCount(grp) {
  730. var iCount = 0;
  731. if (grp) {
  732. var grpChildren = grp.getChildren();
  733. if (grpChildren) {
  734. for (var i = 0; i < grpChildren.length; i++) {
  735. if (grpChildren[i].constructor != GLGE.Object) {
  736. iCount++;
  737. }
  738. }
  739. }
  740. }
  741. return iCount;
  742. };
  743. function indentStr() {
  744. return " ";
  745. }
  746. function indent(iIndent) {
  747. var sOut = "";
  748. for (var j = 0; j < iIndent; j++) { sOut = sOut + indentStr.call( this ); }
  749. return sOut;
  750. }
  751. function indent2(iIndent) {
  752. var sOut = "";
  753. var idt = indentStr.call( this )
  754. for ( var j = 0; j < iIndent; j++ ) {
  755. sOut = sOut + idt + idt;
  756. }
  757. return sOut;
  758. }
  759. function outputCollada(collada, iIndent, open) {
  760. var sOut = indent.call(this,iIndent);
  761. if (open) {
  762. this.logger.info(sOut + "children:")
  763. }
  764. }
  765. function outputGroup( group, iIndent, open ) {
  766. var sOut = indent.call( this, iIndent + 1);
  767. if (open) {
  768. var lastGroupName = name(group);
  769. this.logger.info(indent.call( this,iIndent) + lastGroupName + ":");
  770. this.logger.info(indent.call( this,iIndent + 1) + "extends: http://vwf.example.com/node3.vwf");
  771. if (getChildCount.call( this, group) > 0) {
  772. this.logger.info(sOut + "children:");
  773. }
  774. }
  775. }
  776. function outputObject(obj, iIndent) {
  777. var indentAdd = 0;
  778. var objName = name( obj );
  779. if ( objName != "" ) {
  780. this.logger.info( indent.call( this,iIndent) + "children:" );
  781. this.logger.info( indent.call( this,iIndent+1) + objName + ":");
  782. this.logger.info( indent.call( this,iIndent+2) + "extends: http://vwf.example.com/node3.vwf");
  783. indentAdd = 2;
  784. }
  785. }
  786. function outputMaterial( obj, iIndent, objName, index ) {
  787. var sOut = indent.call( this, iIndent + 1 );
  788. this.logger.info( indent.call( this, iIndent) + "material" + index + ":" );
  789. this.logger.info( sOut + "extends: http://vwf.example.com/material.vwf");
  790. }
  791. function getKeyValue( keyCode ) {
  792. var key = { key: undefined, code: keyCode, char: undefined };
  793. switch ( keyCode ) {
  794. case 8:
  795. key.key = "backspace";
  796. break;
  797. case 9:
  798. key.key = "tab";
  799. break;
  800. case 13:
  801. key.key = "enter";
  802. break;
  803. case 16:
  804. key.key = "shift";
  805. break;
  806. case 17:
  807. key.key = "ctrl";
  808. break;
  809. case 18:
  810. key = "alt";
  811. break;
  812. case 19:
  813. key.key = "pausebreak";
  814. break;
  815. case 20:
  816. key.key = "capslock";
  817. break;
  818. case 27:
  819. key.key = "escape";
  820. break;
  821. case 33:
  822. key.key = "pageup";
  823. break;
  824. case 34:
  825. key.key = "pagedown";
  826. break;
  827. case 35:
  828. key.key = "end";
  829. break;
  830. case 36:
  831. key.key = "home";
  832. break;
  833. case 37:
  834. key.key = "leftarrow";
  835. break;
  836. case 38:
  837. key.key = "uparrow";
  838. break;
  839. case 39:
  840. key.key = "rightarrow";
  841. break;
  842. case 40:
  843. key.key = "downarrow";
  844. break;
  845. case 45:
  846. key.key = "insert";
  847. break;
  848. case 46:
  849. key.key = "delete";
  850. break;
  851. case 48:
  852. key.key = "0";
  853. key.char = "0";
  854. break;
  855. case 49:
  856. key.key = "1";
  857. key.char = "1";
  858. break;
  859. case 50:
  860. key.key = "2";
  861. key.char = "2";
  862. break;
  863. case 51:
  864. key.key = "3";
  865. key.char = "3";
  866. break;
  867. case 52:
  868. key.key = "4";
  869. key.char = "4";
  870. break;
  871. case 53:
  872. key.key = "5";
  873. key.char = "5";
  874. break;
  875. case 54:
  876. key.key = "6";
  877. key.char = "6";
  878. break;
  879. case 55:
  880. key.key = "7";
  881. key.char = "7";
  882. break;
  883. case 56:
  884. key.key = "8";
  885. key.char = "8";
  886. break;
  887. case 57:
  888. key.key = "9";
  889. key.char = "9";
  890. break;
  891. case 65:
  892. key.key = "A";
  893. key.char = "A";
  894. break;
  895. case 66:
  896. key.key = "B";
  897. key.char = "B";
  898. break;
  899. case 67:
  900. key.key = "C";
  901. key.char = "C";
  902. break;
  903. case 68:
  904. key.key = "D";
  905. key.char = "D";
  906. break;
  907. case 69:
  908. key.key = "E";
  909. key.char = "E";
  910. break;
  911. case 70:
  912. key.key = "F";
  913. key.char = "F";
  914. break;
  915. case 71:
  916. key.key = "G";
  917. key.char = "G";
  918. break;
  919. case 72:
  920. key.key = "H";
  921. key.char = "H";
  922. break;
  923. case 73:
  924. key.key = "I";
  925. key.char = "I";
  926. break;
  927. case 74:
  928. key.key = "J";
  929. key.char = "J";
  930. break;
  931. case 75:
  932. key.key = "K";
  933. key.char = "K";
  934. break;
  935. case 76:
  936. key.key = "L";
  937. key.char = "L";
  938. break;
  939. case 77:
  940. key.key = "M";
  941. key.char = "M";
  942. break;
  943. case 78:
  944. key.key = "N";
  945. key.char = "N";
  946. break;
  947. case 79:
  948. key.key = "O";
  949. key.char = "O";
  950. break;
  951. case 80:
  952. key.key = "P";
  953. key.char = "P";
  954. break;
  955. case 81:
  956. key.key = "Q";
  957. key.char = "Q";
  958. break;
  959. case 82:
  960. key.key = "R";
  961. key.char = "R";
  962. break;
  963. case 83:
  964. key.key = "S";
  965. key.char = "S";
  966. break;
  967. case 84:
  968. key.key = "T";
  969. key.char = "T";
  970. break;
  971. case 85:
  972. key.key = "U";
  973. key.char = "U";
  974. break;
  975. case 86:
  976. key.key = "V";
  977. key.char = "V";
  978. break;
  979. case 87:
  980. key.key = "W";
  981. key.char = "W";
  982. break;
  983. case 88:
  984. key.key = "X";
  985. key.char = "X";
  986. break;
  987. case 89:
  988. key.key = "Y";
  989. key.char = "Y";
  990. break;
  991. case 90:
  992. key.key = "Z";
  993. key.char = "Z";
  994. break;
  995. case 91:
  996. key.key = "leftwindow";
  997. break;
  998. case 92:
  999. key.key = "rightwindow";
  1000. break;
  1001. case 93:
  1002. key.key = "select";
  1003. break;
  1004. case 96:
  1005. key.key = "numpad0";
  1006. key.char = "0";
  1007. break;
  1008. case 97:
  1009. key.key = "numpad1";
  1010. key.char = "1";
  1011. break;
  1012. case 98:
  1013. key.key = "numpad2";
  1014. key.char = "2";
  1015. break;
  1016. case 99:
  1017. key.key = "numpad3";
  1018. key.char = "3";
  1019. break;
  1020. case 100:
  1021. key.key = "numpad4";
  1022. key.char = "4";
  1023. break;
  1024. case 101:
  1025. key.key = "numpad5";
  1026. key.char = "5";
  1027. break;
  1028. case 102:
  1029. key.key = "numpad6";
  1030. key.char = "6";
  1031. break;
  1032. case 103:
  1033. key.key = "numpad7";
  1034. key.char = "7";
  1035. break;
  1036. case 104:
  1037. key.key = "numpad8";
  1038. key.char = "8";
  1039. break;
  1040. case 105:
  1041. key.key = "numpad9";
  1042. key.char = "9";
  1043. break;
  1044. case 106:
  1045. key.key = "multiply";
  1046. key.char = "*";
  1047. break;
  1048. case 107:
  1049. key.key = "add";
  1050. key.char = "+";
  1051. break;
  1052. case 109:
  1053. key.key = "subtract";
  1054. key.char = "-";
  1055. break;
  1056. case 110:
  1057. key.key = "decimalpoint";
  1058. key.char = ".";
  1059. break;
  1060. case 111:
  1061. key.key = "divide";
  1062. key.char = "/";
  1063. break;
  1064. case 112:
  1065. key.key = "f1";
  1066. break;
  1067. case 113:
  1068. key.key = "f2";
  1069. break;
  1070. case 114:
  1071. key.key = "f3";
  1072. break;
  1073. case 115:
  1074. key.key = "f4";
  1075. break;
  1076. case 116:
  1077. key.key = "f5";
  1078. break;
  1079. case 117:
  1080. key.key = "f6";
  1081. break;
  1082. case 118:
  1083. key.key = "f7";
  1084. break;
  1085. case 119:
  1086. key.key = "f8";
  1087. break;
  1088. case 120:
  1089. key.key = "f9";
  1090. break;
  1091. case 121:
  1092. key.key = "f10";
  1093. break;
  1094. case 122:
  1095. key.key = "f11";
  1096. break;
  1097. case 123:
  1098. key.key = "f12";
  1099. break;
  1100. case 144:
  1101. key.key = "numlock";
  1102. break;
  1103. case 145:
  1104. key.key = "scrolllock";
  1105. break;
  1106. case 186:
  1107. key.key = "semicolon";
  1108. key.char = ";";
  1109. break;
  1110. case 187:
  1111. key.key = "equal";
  1112. key.char = "=";
  1113. break;
  1114. case 188:
  1115. key.key = "comma";
  1116. key.char = ",";
  1117. break;
  1118. case 189:
  1119. key.key = "dash";
  1120. key.char = "-";
  1121. break;
  1122. case 190:
  1123. key.key = "period";
  1124. key.char = ".";
  1125. break;
  1126. case 191:
  1127. key.key = "forwardslash";
  1128. key.char = "/";
  1129. break;
  1130. case 192:
  1131. key.key = "graveaccent";
  1132. break;
  1133. case 219:
  1134. key.key = "openbraket";
  1135. key.char = "{";
  1136. break;
  1137. case 220:
  1138. key.key = "backslash";
  1139. key.char = "\\";
  1140. break;
  1141. case 221:
  1142. key.key = "closebraket";
  1143. key.char = "}";
  1144. break;
  1145. case 222:
  1146. key.key = "singlequote";
  1147. key.char = "'";
  1148. break;
  1149. case 32:
  1150. key.key = "space";
  1151. key.char = " ";
  1152. break;
  1153. }
  1154. return key;
  1155. }
  1156. } );