jiglib.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  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/model/jiglib
  15. /// @requires vwf/model
  16. define( [ "module", "vwf/model" ], function( module, model ) {
  17. return model.load( module, {
  18. // == Module Definition ====================================================================
  19. // -- initialize ---------------------------------------------------------------------------
  20. initialize: function() {
  21. this.nodes = {}; // maps id => { property: value, ... }
  22. this.scenes = {};
  23. this.active = {};
  24. this.enabled = false;
  25. this.lastTime = 0;
  26. this.delayedProperties = {};
  27. this.updating = false;
  28. },
  29. // == Model API ============================================================================
  30. // -- creatingNode -------------------------------------------------------------------------
  31. creatingNode: function( nodeID, childID, childExtendsID, childImplementsIDs,
  32. childSource, childType, childIndex, childName, callback /* ( ready ) */) {
  33. var kernel = this.kernel;
  34. //this.logger.enable = true;
  35. //this.logger.infox( "creatingNode", nodeID, childID, childExtendsID, childImplementsIDs,
  36. // childSource, childType, childIndex, childName );
  37. //this.logger.enabled = false;
  38. if ( childExtendsID && this.kernel.test( childExtendsID,
  39. "self::element(*,'http://vwf.example.com/scene.vwf')", childExtendsID ) ) {
  40. this.scenes[ childID ] = {};
  41. this.scenes[ childID ].ID = childID;
  42. this.scenes[ childID ].extendsID = childExtendsID;
  43. this.scenes[ childID ].implementsIDs = childImplementsIDs;
  44. this.scenes[ childID ].source = childSource;
  45. this.scenes[ childID ].type = childType;
  46. this.scenes[ childID ].system = jigLib.PhysicsSystem.getInstance();
  47. this.scenes[ childID ].initialized = false;
  48. this.scenes[ childID ].propertyMap = {};
  49. } else {
  50. switch ( childExtendsID && this.kernel.uri( childExtendsID ) ) {
  51. case "http://vwf.example.com/physics3.vwf":
  52. case "http://vwf.example.com/node3.vwf":
  53. case "http://vwf.example.com/mesh.vwf":
  54. this.nodes[ childID ] = {};
  55. this.nodes[ childID ].sceneID = this.kernel.application();
  56. this.nodes[ childID ].name = childName;
  57. this.nodes[ childID ].ID = childID;
  58. this.nodes[ childID ].parentID = nodeID;
  59. this.nodes[ childID ].extendsID = childExtendsID;
  60. this.nodes[ childID ].implementsIDs = childImplementsIDs;
  61. this.nodes[ childID ].source = childSource;
  62. this.nodes[ childID ].type = childType;
  63. break;
  64. }
  65. }
  66. },
  67. // -- initializingNode ---------------------------------------------------------------------
  68. // Invoke an initialize() function if one exists.
  69. initializingNode: function( nodeID, childID ) {
  70. var scene = this.scenes[ childID ];
  71. var node = this.nodes[ childID ];
  72. if ( scene && scene.system ) {
  73. if ( !scene.initialized ) {
  74. initializeScene.call( this, scene );
  75. }
  76. this.enabled = true;
  77. } else if ( node ) {
  78. if ( node.jigLibObj && node.jigLibInternals ) {
  79. node.jigLibObj._currState.position = node.jigLibInternals._currState.position.slice(0);
  80. node.jigLibObj._currState.set_orientation( new jigLib.Matrix3D( node.jigLibInternals._currState._orientation.glmatrix ) );
  81. node.jigLibObj._currState.linVelocity = node.jigLibInternals._currState.linVelocity.slice(0);
  82. node.jigLibObj._currState.rotVelocity = node.jigLibInternals._currState.rotVelocity.slice(0);
  83. node.jigLibObj._oldState.position = node.jigLibInternals._oldState.position.slice(0);
  84. node.jigLibObj._oldState.set_orientation( new jigLib.Matrix3D( node.jigLibInternals._oldState._orientation.glmatrix ) );
  85. node.jigLibObj._oldState.linVelocity = node.jigLibInternals._oldState.linVelocity.slice(0);
  86. node.jigLibObj._oldState.rotVelocity = node.jigLibInternals._oldState.rotVelocity.slice(0);
  87. node.jigLibObj._velChanged = node.jigLibInternals._velChanged;
  88. node.jigLibObj._storedPositionForActivation = node.jigLibInternals._storedPositionForActivation.slice(0);
  89. node.jigLibObj._lastPositionForDeactivation = node.jigLibInternals._lastPositionForDeactivation.slice(0);
  90. delete node.jigLibInternals;
  91. }
  92. }
  93. return undefined;
  94. },
  95. // -- deletingNode -------------------------------------------------------------------------
  96. deletingNode: function( nodeID ) {
  97. if ( this.active[ nodeID ] ) {
  98. delete this.active[ nodeID ];
  99. }
  100. if ( this.nodes[ nodeID ] ) {
  101. var node = this.nodes[ nodeID ];
  102. var scene = this.scenes[ node.sceneID ];
  103. if ( node.jigLibObj ) {
  104. if ( node.jigLibObj ) {
  105. if ( scene ) scene.system.removeBody( node.jigLibObj );
  106. node.jigLibObj = undefined;
  107. }
  108. }
  109. if ( node.jigLibMeshes ) {
  110. for ( var j = 0; j < node.jigLibMeshes.length; j++ ) {
  111. if ( scene ) scene.system.removeBody( node.jigLibMeshes[ j ] );
  112. }
  113. node.jigLibMeshes = undefined;
  114. }
  115. delete this.nodes[ nodeID ];
  116. }
  117. },
  118. // -- addingChild --------------------------------------------------------------------------
  119. //addingChild: function( nodeID, childID, childName ) {
  120. //},
  121. // -- movingChild --------------------------------------------------------------------------
  122. //movingChild: function( nodeID, childID, childName ) {
  123. //},
  124. // -- removingChild ------------------------------------------------------------------------
  125. //removingChild: function( nodeID, childID, childName ) {
  126. //},
  127. // -- creatingProperty ---------------------------------------------------------------------
  128. creatingProperty: function( nodeID, propertyName, propertyValue ) {
  129. return this.initializingProperty( nodeID, propertyName, propertyValue );
  130. },
  131. // -- initializingProperty -----------------------------------------------------------------
  132. initializingProperty: function( nodeID, propertyName, propertyValue ) {
  133. var value = undefined;
  134. //this.logger.enabled = true;
  135. //this.logger.infox( "creatingProperty", nodeID, propertyName, propertyValue );
  136. //this.logger.enabled = false;
  137. if ( !( propertyValue === undefined ) ) {
  138. var node = this.nodes[ nodeID ];
  139. if ( node ) {
  140. var scene = this.scenes[ node.sceneID ];
  141. if ( scene && !scene.initialized ) {
  142. var pm;
  143. if ( !scene.propertyMap[ nodeID ] ) {
  144. scene.propertyMap[ nodeID ] = {};
  145. scene.propertyMap[ nodeID ].hasPhysics = false;
  146. }
  147. pm = scene.propertyMap[ nodeID ];
  148. pm[ propertyName ] = propertyValue;
  149. if ( !pm.hasPhysics ) {
  150. pm.hasPhysics = isPhysicsProp.call( this, propertyName );
  151. }
  152. } else {
  153. if ( node.jigLibObj ) {
  154. this.settingProperty( nodeID, propertyName, propertyValue );
  155. } else {
  156. if ( propertyName == "physics" ) {
  157. this.settingProperty( nodeID, propertyName, propertyValue );
  158. if ( this.delayedProperties[ nodeID ] ) {
  159. var propValue;
  160. for ( propName in this.delayedProperties[ nodeID ] ) {
  161. propValue = this.delayedProperties[ nodeID ][ propName ];
  162. this.settingProperty( nodeID, propName, propValue );
  163. }
  164. delete this.delayedProperties[ nodeID ];
  165. }
  166. } else {
  167. if ( !this.delayedProperties[ nodeID ] ) {
  168. this.delayedProperties[ nodeID ] = {};
  169. }
  170. this.delayedProperties[ nodeID ][ propertyName ] = propertyValue;
  171. }
  172. }
  173. }
  174. } else {
  175. var scene = this.scenes[ nodeID ];
  176. if ( scene ) {
  177. this.settingProperty( nodeID, propertyName, propertyValue );
  178. }
  179. }
  180. }
  181. return value;
  182. },
  183. // TODO: deletingProperty
  184. // -- settingProperty ----------------------------------------------------------------------
  185. settingProperty: function( nodeID, propertyName, propertyValue ) {
  186. var value = undefined;
  187. if ( propertyValue === undefined )
  188. return value;
  189. if ( this.updating ) {
  190. switch ( propertyName ) {
  191. case "transform":
  192. return;
  193. break;
  194. }
  195. }
  196. var activeNode = this.active[ nodeID ];
  197. var node = this.nodes[ nodeID ];
  198. var scene = this.scenes[ nodeID ];
  199. if ( node && node.jigLibObj ) {
  200. scene = this.scenes[ node.sceneID ];
  201. switch ( propertyName ) {
  202. case "transform":
  203. if ( activeNode && activeNode.jlObj ) {
  204. //console.info( "ACTIVEOBJ " + nodeID + ".transform = " + Array.prototype.slice.apply( propertyValue ) );
  205. activeNode.jlObj.set_Transform( propertyValue );
  206. } else {
  207. //console.info( "MODELOBJ " + nodeID + ".transform = " + Array.prototype.slice.apply( propertyValue ) );
  208. node.jigLibObj.set_Transform( propertyValue );
  209. }
  210. break;
  211. // case "scale":
  212. // var physics = this.gettingProperty( nodeID, "physics", [] );
  213. // physicsType = ( physics.constructor == Array ) ? physics[0] : physics;
  214. // switch( physicsType ) {
  215. // case "box":
  216. // createJBox.call( this, nodeID, propertyValue, undefined );
  217. // break;
  218. // case "sphere":
  219. // createJSphere.call( this, nodeID, propertyValue, undefined );
  220. // break;
  221. // case "mesh":
  222. // createJMesh.call( this, nodeID, propertyValue );
  223. // break;
  224. // }
  225. // break;
  226. case "mass":
  227. node.jigLibObj.set_mass( propertyValue );
  228. break;
  229. case "restitution":
  230. node.jigLibObj.set_restitution( propertyValue );
  231. break;
  232. case "friction":
  233. node.jigLibObj.set_friction( propertyValue );
  234. break;
  235. case "rotVelocityDamping":
  236. node.jigLibObj.set_rotVelocityDamping( propertyValue );
  237. break;
  238. case "linVelocityDamping":
  239. node.jigLibObj.set_linVelocityDamping( propertyValue );
  240. break;
  241. case "velocity":
  242. //console.info( nodeID + ".velocity = " + propertyValue );
  243. node.jigLibObj.setVelocity( propertyValue ); // should be [ x, y, z ]
  244. break;
  245. case "private":
  246. node.jigLibInternals = propertyValue;
  247. break;
  248. }
  249. } else if ( node && !scene ) {
  250. scene = this.scenes[ node.sceneID ];
  251. if ( propertyName == "physics" ) {
  252. if ( scene && scene.system && propertyValue ) {
  253. var type = ( propertyValue.constructor == Array ) ? propertyValue[0] : propertyValue;
  254. switch ( type ) {
  255. case "mesh":
  256. createJMesh.call( this, nodeID, undefined );
  257. break;
  258. case "box":
  259. createJBox.call( this, nodeID, undefined, propertyValue );
  260. break;
  261. case "sphere":
  262. createJSphere.call( this, nodeID, undefined, propertyValue );
  263. break;
  264. case "plane":
  265. createJPlane.call( this, nodeID, propertyValue );
  266. break;
  267. default:
  268. //node.jigLibObj = undefined;
  269. break;
  270. }
  271. }
  272. if ( this.delayedProperties[nodeID] ) {
  273. var props = this.delayedProperties[nodeID];
  274. for ( var propName in props ) {
  275. this.settingProperty( nodeID, propName, props[propName] );
  276. }
  277. delete this.delayedProperties[nodeID];
  278. }
  279. } else {
  280. if ( node ) {
  281. var propArray;
  282. if ( !this.delayedProperties[nodeID] ) {
  283. this.delayedProperties[nodeID] = {};
  284. }
  285. propArray = this.delayedProperties[nodeID];
  286. propArray[ propertyName ] = propertyValue;
  287. }
  288. }
  289. } else {
  290. if ( scene && scene.system ) {
  291. switch ( propertyName ) {
  292. case "gravity":
  293. scene.system.setGravity( propertyValue );
  294. break;
  295. case "collisionSystem": {
  296. var pv = propertyValue;
  297. if ( pv.constructor == Array ) {
  298. switch ( pv.length ) {
  299. case 10:
  300. scene.system.setCollisionSystem( pv[0], pv[1], pv[2], pv[3], pv[4], pv[5], pv[6], pv[7], pv[8], pv[9] );
  301. break;
  302. case 1:
  303. scene.system.setCollisionSystem( pv[0] );
  304. break;
  305. }
  306. }
  307. break;
  308. }
  309. }
  310. }
  311. }
  312. return value;
  313. },
  314. // -- gettingProperty ----------------------------------------------------------------------
  315. gettingProperty: function( nodeID, propertyName, propertyValue ) {
  316. propertyValue = undefined;
  317. if ( this.nodes[ nodeID ] ) {
  318. var node = this.nodes[ nodeID ];
  319. if ( node && node.jigLibObj ) {
  320. switch ( propertyName ) {
  321. case "physics":
  322. if ( node.jigLibObj.constructor == jigLib.JBox ) {
  323. propertyValue = [];
  324. propertyValue.push( "box" );
  325. propertyValue.push( node.jigLibObj._sideLengths[0] );
  326. propertyValue.push( node.jigLibObj._sideLengths[1] );
  327. propertyValue.push( node.jigLibObj._sideLengths[2] );
  328. } else if ( node.jigLibObj.constructor == jigLib.JSphere ) {
  329. propertyValue = [];
  330. propertyValue.push( "sphere" );
  331. propertyValue.push( node.jigLibObj.get_radius() );
  332. } else if ( node.jigLibObj.constructor == jigLib.JPlane ) {
  333. propertyValue = [];
  334. propertyValue.push( "plane" );
  335. propertyValue.push( node.jigLibObj.get_normal() );
  336. } else {
  337. propertyValue = [];
  338. propertyValue.push( "mesh" );
  339. }
  340. break;
  341. case "mass":
  342. propertyValue = node.jigLibObj.get_mass();
  343. break;
  344. case "restitution":
  345. propertyValue = node.jigLibObj.get_restitution();
  346. break;
  347. case "friction":
  348. propertyValue = node.jigLibObj.get_friction();
  349. break;
  350. case "rotVelocityDamping":
  351. propertyValue = node.jigLibObj.get_rotVelocityDamping();
  352. break;
  353. case "linVelocityDamping":
  354. propertyValue = node.jigLibObj.get_linVelocityDamping();
  355. break;
  356. case "velocity":
  357. propertyValue = node.jigLibObj.getVelocity( node.jigLibObj.get_position() );
  358. break;
  359. case "private":
  360. propertyValue = {
  361. _currState: node.jigLibObj._currState,
  362. _oldState: node.jigLibObj._oldState,
  363. _velChanged: node.jigLibObj._velChanged,
  364. _storedPositionForActivation: node.jigLibObj._storedPositionForActivation,
  365. _lastPositionForDeactivation: node.jigLibObj._lastPositionForDeactivation,
  366. }
  367. break;
  368. }
  369. }
  370. } else if ( this.scenes[ nodeID ] ) {
  371. var sceneNode = this.scenes[ nodeID ];
  372. if ( sceneNode && sceneNode.system ) {
  373. switch ( propertyName ) {
  374. case "gravity":
  375. propertyValue = sceneNode.system.get_gravity();
  376. break;
  377. case "collisionSystem":
  378. propertyValue = undefined;
  379. break;
  380. }
  381. }
  382. }
  383. return propertyValue;
  384. },
  385. // -- creatingMethod ------------------------------------------------------------------------
  386. //creatingMethod: function( nodeID, methodName, methodParameters, methodBody ) {
  387. //},
  388. // -- callingMethod ------------------------------------------------------------------------
  389. //callingMethod: function( nodeID, methodName, methodParameters ) {
  390. //},
  391. // -- creatingEvent ------------------------------------------------------------------------
  392. //creatingEvent: function( nodeID, eventName, eventParameters ) {
  393. //},
  394. // TODO: deletingEvent
  395. // -- firingEvent --------------------------------------------------------------------------
  396. // firingEvent: function( nodeID, eventName, eventParameters ) {
  397. //},
  398. // -- executing ----------------------------------------------------------------------------
  399. // executing: function (nodeID, scriptText, scriptType) {
  400. // return undefined;
  401. //},
  402. // == ticking =============================================================================
  403. ticking: function( vwfTime ) {
  404. var elaspedTime = vwfTime - this.lastTime;
  405. this.lastTime = vwfTime;
  406. if ( this.enabled ) {
  407. if ( elaspedTime > 0 ) {
  408. if (elaspedTime > 0.05) elaspedTime = 0.05;
  409. var activeObj, posRotProp, pos, rot, posRot;
  410. var sceneNode = this.scenes[this.kernel.application()];
  411. if ( sceneNode && sceneNode.system ) {
  412. sceneNode.system.integrate( elaspedTime );
  413. this.updating = true;
  414. for ( var nodeID in this.active ) {
  415. activeObj = this.active[nodeID];
  416. if ( activeObj && activeObj.jlObj ) {
  417. var trans = activeObj.jlObj.get_Transform();
  418. this.kernel.setProperty( nodeID, "transform", trans );
  419. }
  420. }
  421. this.updating = false;
  422. }
  423. }
  424. }
  425. },
  426. } );
  427. // == Private functions ==================================================================
  428. // == calcRadius =========================================================================
  429. function calcRadius( offset, verts ) {
  430. var radius = 0;
  431. var temp = 0;
  432. var iIndex = -1;
  433. for ( var i = 0; i < verts.length; i++ ) {
  434. temp = ( verts[i][0] - offset[0] ) ^ 2 + ( verts[i][1] - offset[1] ) ^ 2 + + ( verts[i][2] - offset[2] ) ^ 2;
  435. if ( temp > radius ) {
  436. radius = temp;
  437. iIndex = i;
  438. }
  439. }
  440. raduis = Math.sqrt( radius );
  441. return radius;
  442. }
  443. // == createJBox =====================================================================
  444. function createJBox( nodeID, scale, def ) {
  445. var node = this.nodes[ nodeID ];
  446. if ( node ) {
  447. var scene = this.scenes[ node.sceneID ];
  448. if ( scene ) {
  449. var v1, v2;
  450. var width = 1;
  451. var depth = 1;
  452. var height = 1;
  453. var pos = this.kernel.getProperty( nodeID, "translation" ) || [ 0, 0, 0 ];
  454. var useBoundingBox = scale || !def;
  455. if ( useBoundingBox ) {
  456. var bBox = this.kernel.getProperty( nodeID, "boundingbox" );
  457. var offset = this.kernel.getProperty( nodeID, "centerOffset" ) || [ 0, 0, 0 ] ;
  458. if ( bBox.max[0] - bBox.min[0] != 0 ) width = ( bBox.max[0] - bBox.min[0] );
  459. if ( bBox.max[1] - bBox.min[1] != 0 ) depth = ( bBox.max[1] - bBox.min[1] );
  460. if ( bBox.max[2] - bBox.min[2] != 0 ) height = ( bBox.max[2] - bBox.min[2] );
  461. } else if ( def.constructor == Array && def.length == 4 ) {
  462. width = def[ 1 ];
  463. depth = def[ 2 ]
  464. height = def[ 3 ];
  465. }
  466. if ( node.jigLibObj ) {
  467. scene.system.removeBody( node.jigLibObj );
  468. node.jigLibObj = null;
  469. }
  470. node.jigLibObj = new jigLib.JBox( null, width, depth, height );
  471. if ( node.jigLibObj ) {
  472. scene.system.addBody( node.jigLibObj );
  473. if ( pos ) node.jigLibObj.moveTo( [ pos[0], pos[1], pos[2] ] );
  474. this.active[ nodeID ] = {};
  475. this.active[ nodeID ].jlObj = node.jigLibObj;
  476. this.active[ nodeID ].offset = offset;
  477. }
  478. }
  479. }
  480. }
  481. // == createJSphere =====================================================================
  482. function createJSphere( nodeID, scale, def ) {
  483. var node = this.nodes[ nodeID ];
  484. if ( node ) {
  485. var scene = this.scenes[ node.sceneID ];
  486. if ( scene ) {
  487. var v1, v2;
  488. var verts = this.kernel.getProperty( nodeID, "vertices" );
  489. var offset = this.kernel.getProperty( nodeID, "centerOffset" ) || [ 0, 0, 0 ];
  490. var pos = this.kernel.getProperty( nodeID, "translation" )|| [ 0, 0, 0 ];
  491. var raduis = 10;
  492. var useBoundingBox = scale || !def;
  493. if ( useBoundingBox ) {
  494. var cRadius = 0;
  495. if ( !scale ) scale = this.kernel.getProperty( nodeID, "scale" ) || [ 1, 1, 1 ];
  496. for ( var j = 0; j < verts.length; j++ ) {
  497. vt = verts[j];
  498. if ( scale ) {
  499. vt[0] = vt[0] * scale[0];
  500. vt[1] = vt[1] * scale[1];
  501. vt[2] = vt[2] * scale[2];
  502. }
  503. verts[j] = vt;
  504. }
  505. cRadius = calcRadius.call( this, offset, verts );
  506. if ( cRadius > 0 ) raduis = cRadius;
  507. } else if ( def.constructor == Array && def.length == 2 ) {
  508. raduis = def[1];
  509. }
  510. if ( node.jigLibObj ) {
  511. scene.system.removeBody( node.jigLibObj );
  512. node.jigLibObj = null;
  513. }
  514. node.jigLibObj = new jigLib.JSphere( null, raduis );
  515. if ( node.jigLibObj ) {
  516. scene.system.addBody( node.jigLibObj );
  517. if ( pos ) node.jigLibObj.moveTo( [ pos[0], pos[1], pos[2] ] );
  518. this.active[ nodeID ] = {};
  519. this.active[ nodeID ].jlObj = node.jigLibObj;
  520. this.active[ nodeID ].offset = this.kernel.getProperty( nodeID, "centerOffset" ) || [ 0, 0, 0 ];
  521. }
  522. }
  523. }
  524. }
  525. // == createJMesh =====================================================================
  526. function createJMesh( nodeID, scale ) {
  527. var node = this.nodes[ nodeID ];
  528. if ( node ) {
  529. var scene = this.scenes[ node.sceneID ];
  530. if ( scene ) {
  531. if ( node.jigLibMeshes ) {
  532. for ( var j = 0; j < node.jigLibMeshes.length; j++ ) {
  533. scene.system.removeBody( node.jigLibMeshes[ j ] );
  534. }
  535. }
  536. node.jigLibMeshes = [];
  537. var pos = this.kernel.getProperty( nodeID, "translation" ) || [ 0, 0, 0 ];
  538. var meshDataList = this.kernel.getProperty( nodeID, "meshData" );
  539. if ( meshDataList ) {
  540. var verts, vertIndices, scale, vt, jMesh;
  541. for ( var i = 0; i < meshDataList.length; i++ ) {
  542. verts = meshDataList[i].vertices;
  543. vertIndices = meshDataList[i].vertexIndices;
  544. scale = meshDataList[i].scale || [ 1, 1, 1 ];
  545. for ( var j = 0; j < verts.length; j++ ) {
  546. vt = verts[j];
  547. if ( scale ) {
  548. vt[0] = vt[0] * scale[0];
  549. vt[1] = vt[1] * scale[1];
  550. vt[2] = vt[2] * scale[2];
  551. }
  552. verts[j] = vt;
  553. }
  554. jMesh = new jigLib.JTriangleMesh();
  555. node.jigLibMeshes.push( jMesh );
  556. jMesh.createMesh( verts, vertIndices );
  557. scene.system.addBody( jMesh );
  558. if ( pos ) jMesh.moveTo( [ pos[0], pos[1], pos[2] ] );
  559. }
  560. }
  561. }
  562. }
  563. }
  564. // == createJPlane =====================================================================
  565. function createJPlane( nodeID, physicsDef ) {
  566. var node = this.nodes[ nodeID ];
  567. if ( node ) {
  568. var scene = this.scenes[ node.sceneID ];
  569. if ( scene ) {
  570. var normal = [0, 0, 1, 0];
  571. var pos = this.kernel.getProperty( nodeID, "translation" )|| [ 0, 0, 0 ];
  572. if ( physicsDef.constructor == Array ) {
  573. switch ( physicsDef.length ) {
  574. case 2:
  575. if ( physicsDef[1].constructor == Array ) {
  576. if ( physicsDef[1].length == 4 ) {
  577. normal = physicsDef[1];
  578. }
  579. }
  580. break;
  581. case 5:
  582. for ( var i = 0; i < 4; i++ ) {
  583. normal[i] = physicsDef[i+1];
  584. }
  585. break;
  586. }
  587. }
  588. if ( node.jigLibObj ) {
  589. scene.system.removeBody( node.jigLibObj );
  590. node.jigLibObj = null;
  591. }
  592. node.jigLibObj = new jigLib.JPlane( null, normal );
  593. scene.system.addBody( node.jigLibObj );
  594. if ( pos ) node.jigLibObj.moveTo( [ pos[0], pos[1], pos[2] ] );
  595. }
  596. }
  597. }
  598. // == isPhysicsProp =====================================================================
  599. function isPhysicsProp( pn ) {
  600. var physicsProp = false;
  601. switch ( pn ) {
  602. case "physics":
  603. case "mass":
  604. case "velocity":
  605. case "restitution":
  606. case "friction":
  607. case "rotVelocityDamping":
  608. case "linVelocityDamping":
  609. physicsProp = true;
  610. break;
  611. default:
  612. physicsProp = false;
  613. break;
  614. }
  615. return physicsProp;
  616. }
  617. // == initializeScene ===================================================================
  618. function initializeScene( scene ) {
  619. var pm;
  620. for ( var nodeID in scene.propertyMap ) {
  621. pm = scene.propertyMap[ nodeID ];
  622. if ( pm.hasPhysics ) {
  623. initializeObject.call( this, nodeID, pm );
  624. }
  625. }
  626. scene.propertyMap = {};
  627. scene.initialized = true;
  628. }
  629. // == initializeObject ===================================================================
  630. function initializeObject( nodeID, props ) {
  631. var physicsDef, physicsType, scale;
  632. if ( props.physics ) {
  633. physicsDef = props.physics;
  634. physicsType = ( physicsDef.constructor == Array ) ? physicsDef[0] : physicsDef;
  635. scale = props.scale
  636. // set up the physics object for each
  637. switch( physicsType ) {
  638. case "box":
  639. if ( scale ) {
  640. createJBox.call( this, nodeID, scale, undefined );
  641. } else {
  642. createJBox.call( this, nodeID, undefined, physicsDef );
  643. }
  644. break;
  645. case "sphere":
  646. if ( scale ) {
  647. createJSphere.call( this, nodeID, scale, undefined );
  648. } else {
  649. createJSphere.call( this, nodeID, undefined, physicsDef );
  650. }
  651. break;
  652. case "mesh":
  653. createJMesh.call( this, nodeID, scale );
  654. break;
  655. case "plane":
  656. createJPlane.call( this, nodeID, physicsDef );
  657. break;
  658. }
  659. // set the rest of the non physics props
  660. for ( var propertyName in props ) {
  661. switch( propertyName ) {
  662. case "physics":
  663. case "scale":
  664. break;
  665. default:
  666. if ( !isPhysicsProp.call( this, propertyName ) ) {
  667. this.settingProperty( nodeID, propertyName, props[ propertyName ] );
  668. }
  669. break;
  670. }
  671. }
  672. // set the physics props
  673. for ( propertyName in props ) {
  674. switch( propertyName ) {
  675. case "physics":
  676. case "scale":
  677. break;
  678. default:
  679. if ( isPhysicsProp.call( this, propertyName ) ) {
  680. this.settingProperty( nodeID, propertyName, props[ propertyName ] );
  681. }
  682. break;
  683. }
  684. }
  685. }
  686. }
  687. } );