SEA3DAmmo.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /** _ _ _ _____ __ _______ ______
  2. * | |___| |_| |__ /__ | | | | _ | * *
  3. * | / _ \ _| | __\ | | \ | _ | U _
  4. * |_\___/\__|_||_| _ |____/____ |__ \_|_ |_|_____|
  5. *
  6. * @author LoTh / http://3dflashlo.wordpress.com/
  7. * @author SUNAG / http://www.sunag.com.br/
  8. * @author Ammo.lab / https://github.com/lo-th/Ammo.lab/
  9. */
  10. 'use strict';
  11. SEA3D.AMMO = {
  12. world: null,
  13. rigidBodies: [],
  14. rigidBodiesTarget: [],
  15. rigidBodiesOffset: [],
  16. rigidBodiesEnabled: [],
  17. constraints: [],
  18. vehicles: [],
  19. vehiclesWheels: [],
  20. ACTIVE: 1,
  21. ISLAND_SLEEPING: 2,
  22. WANTS_DEACTIVATION: 3,
  23. DISABLE_DEACTIVATION: 4,
  24. DISABLE_SIMULATION: 5,
  25. VERSION: 0.8,
  26. init: function ( gravity, worldScale, broadphase ) {
  27. gravity = gravity !== undefined ? gravity : - 90.8;
  28. this.worldScale = worldScale == undefined ? 1 : worldScale;
  29. this.broadphase = broadphase == undefined ? 'bvt' : broadphase;
  30. this.solver = new Ammo.btSequentialImpulseConstraintSolver();
  31. this.collisionConfig = new Ammo.btDefaultCollisionConfiguration();
  32. this.dispatcher = new Ammo.btCollisionDispatcher( this.collisionConfig );
  33. switch ( this.broadphase ) {
  34. case 'bvt':
  35. this.broadphase = new Ammo.btDbvtBroadphase();
  36. break;
  37. case 'sap':
  38. this.broadphase = new Ammo.btAxisSweep3(
  39. new Ammo.btVector3( - this.worldScale, - this.worldScale, - this.worldScale ),
  40. new Ammo.btVector3( this.worldScale, this.worldScale, this.worldScale ),
  41. 4096
  42. );
  43. break;
  44. case 'simple':
  45. this.broadphase = new Ammo.btSimpleBroadphase();
  46. break;
  47. }
  48. this.world = new Ammo.btDiscreteDynamicsWorld( this.dispatcher, this.broadphase, this.solver, this.collisionConfig );
  49. this.setGravity( gravity );
  50. console.log( "THREE.AMMO " + this.VERSION );
  51. },
  52. setGravity: function ( gravity ) {
  53. this.gravity = gravity;
  54. this.world.setGravity( new Ammo.btVector3( 0, gravity, 0 ) );
  55. return this;
  56. },
  57. getGravity: function () {
  58. return this.gravity;
  59. },
  60. setEnabledRigidBody: function ( rb, enabled ) {
  61. if ( this.getEnabledRigidBody( rb ) == enabled ) return;
  62. if ( enabled ) this.world.addRigidBody( rb );
  63. else this.world.removeRigidBody( rb );
  64. return this;
  65. },
  66. getEnabledRigidBody: function ( rb ) {
  67. return this.rigidBodiesEnabled[ this.rigidBodies.indexOf( rb ) ] === true;
  68. },
  69. addRigidBody: function ( rb, target, offset, enabled ) {
  70. enabled = enabled !== undefined ? enabled : true;
  71. this.rigidBodies.push( rb );
  72. this.rigidBodiesTarget.push( target );
  73. this.rigidBodiesOffset.push( offset );
  74. this.rigidBodiesEnabled.push( false );
  75. this.setEnabledRigidBody( rb, enabled );
  76. return this;
  77. },
  78. removeRigidBody: function ( rb, destroy ) {
  79. var index = this.rigidBodies.indexOf( rb );
  80. this.setEnabledRigidBody( rb, false );
  81. this.rigidBodies.splice( index, 1 );
  82. this.rigidBodiesTarget.splice( index, 1 );
  83. this.rigidBodiesOffset.splice( index, 1 );
  84. this.rigidBodiesEnabled.splice( index, 1 );
  85. if ( destroy ) Ammo.destroy( rb );
  86. return this;
  87. },
  88. containsRigidBody: function ( rb ) {
  89. return this.rigidBodies.indexOf( rb ) > - 1;
  90. },
  91. addConstraint: function ( ctrt, disableCollisionsBetweenBodies ) {
  92. disableCollisionsBetweenBodies = disableCollisionsBetweenBodies == undefined ? true : disableCollisionsBetweenBodies;
  93. this.constraints.push( ctrt );
  94. this.world.addConstraint( ctrt, disableCollisionsBetweenBodies );
  95. return this;
  96. },
  97. removeConstraint: function ( ctrt, destroy ) {
  98. this.constraints.splice( this.constraints.indexOf( ctrt ), 1 );
  99. this.world.removeConstraint( ctrt );
  100. if ( destroy ) Ammo.destroy( ctrt );
  101. return this;
  102. },
  103. containsConstraint: function ( ctrt ) {
  104. return this.constraints.indexOf( rb ) > - 1;
  105. },
  106. addVehicle: function ( vehicle, wheels ) {
  107. this.vehicles.push( vehicle );
  108. this.vehiclesWheels.push( wheels != undefined ? wheels : [] );
  109. this.world.addAction( vehicle );
  110. return this;
  111. },
  112. removeVehicle: function ( vehicle, destroy ) {
  113. var index = this.vehicles.indexOf( vehicle );
  114. this.vehicles.splice( index, 1 );
  115. this.vehiclesWheels.splice( index, 1 );
  116. this.world.removeAction( vehicle );
  117. if ( destroy ) Ammo.destroy( vehicle );
  118. return this;
  119. },
  120. containsVehicle: function ( vehicle ) {
  121. return this.vehicles.indexOf( vehicle ) > - 1;
  122. },
  123. createTriangleMesh: function ( geometry, index, removeDuplicateVertices ) {
  124. index = index == undefined ? - 1 : index;
  125. removeDuplicateVertices = removeDuplicateVertices == undefined ? false : removeDuplicateVertices;
  126. var mTriMesh = new Ammo.btTriangleMesh();
  127. var v0 = new Ammo.btVector3( 0, 0, 0 );
  128. var v1 = new Ammo.btVector3( 0, 0, 0 );
  129. var v2 = new Ammo.btVector3( 0, 0, 0 );
  130. var vertex = geometry.getAttribute( 'position' ).array;
  131. var indexes = geometry.getIndex().array;
  132. var group = index >= 0 ? geometry.groups[ index ] : undefined,
  133. start = group ? group.start : 0,
  134. count = group ? group.count : indexes.length;
  135. var scale = 1 / this.worldScale;
  136. for ( var idx = start; idx < count; idx += 3 ) {
  137. var vx1 = indexes[ idx ] * 3,
  138. vx2 = indexes[ idx + 1 ] * 3,
  139. vx3 = indexes[ idx + 2 ] * 3;
  140. v0.setValue( vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale );
  141. v1.setValue( vertex[ vx2 ] * scale, vertex[ vx2 + 1 ] * scale, vertex[ vx2 + 2 ] * scale );
  142. v2.setValue( vertex[ vx3 ] * scale, vertex[ vx3 + 1 ] * scale, vertex[ vx3 + 2 ] * scale );
  143. mTriMesh.addTriangle( v0, v1, v2, removeDuplicateVertices );
  144. }
  145. return mTriMesh;
  146. },
  147. createConvexHull: function ( geometry, index ) {
  148. index = index == undefined ? - 1 : index;
  149. var mConvexHull = new Ammo.btConvexHullShape();
  150. var v0 = new Ammo.btVector3( 0, 0, 0 );
  151. var vertex = geometry.getAttribute( 'position' ).array;
  152. var indexes = geometry.getIndex().array;
  153. var group = index >= 0 ? geometry.groups[ index ] : undefined,
  154. start = group ? group.start : 0,
  155. count = group ? group.count : indexes.length;
  156. var scale = 1 / this.worldScale;
  157. for ( var idx = start; idx < count; idx += 3 ) {
  158. var vx1 = indexes[ idx ] * 3;
  159. var point = new Ammo.btVector3(
  160. vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale
  161. );
  162. mConvexHull.addPoint( point );
  163. }
  164. return mConvexHull;
  165. },
  166. getTargetByRigidBody: function ( rb ) {
  167. return this.rigidBodiesTarget[ this.rigidBodies.indexOf( rb ) ];
  168. },
  169. getRigidBodyByTarget: function ( target ) {
  170. return this.rigidBodies[ this.rigidBodiesTarget.indexOf( target ) ];
  171. },
  172. getTransformFromMatrix: function ( mtx ) {
  173. var transform = new Ammo.btTransform();
  174. var pos = THREE.SEA3D.VECBUF.setFromMatrixPosition( mtx );
  175. transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
  176. var scl = THREE.SEA3D.VECBUF.setFromMatrixScale( mtx );
  177. mtx.scale( scl.set( 1 / scl.x, 1 / scl.y, 1 / scl.z ) );
  178. var quat = new THREE.Quaternion().setFromRotationMatrix( mtx );
  179. var q = new Ammo.btQuaternion();
  180. q.setValue( quat.x, quat.y, quat.z, quat.w );
  181. transform.setRotation( q );
  182. Ammo.destroy( q );
  183. return transform;
  184. },
  185. getMatrixFromTransform: function ( transform ) {
  186. var position = new THREE.Vector3();
  187. var quaternion = new THREE.Quaternion();
  188. var scale = new THREE.Vector3( 1, 1, 1 );
  189. return function ( transform, matrix ) {
  190. matrix = matrix || new THREE.Matrix4();
  191. var pos = transform.getOrigin(),
  192. quat = transform.getRotation();
  193. position.set( pos.x(), pos.y(), pos.z() );
  194. quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
  195. matrix.compose( position, quaternion, scale );
  196. return matrix;
  197. };
  198. }(),
  199. updateTargetTransform: function () {
  200. var matrix = new THREE.Matrix4();
  201. var position = new THREE.Vector3();
  202. var quaternion = new THREE.Quaternion();
  203. var scale = new THREE.Vector3( 1, 1, 1 );
  204. return function ( obj3d, transform, offset ) {
  205. var pos = transform.getOrigin(),
  206. quat = transform.getRotation();
  207. if ( offset == undefined ) {
  208. obj3d.position.set( pos.x(), pos.y(), pos.z() );
  209. obj3d.quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
  210. } else {
  211. position.set( pos.x(), pos.y(), pos.z() );
  212. quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
  213. matrix.compose( position, quaternion, scale );
  214. matrix.multiplyMatrices( matrix, offset );
  215. obj3d.position.setFromMatrixPosition( matrix );
  216. obj3d.quaternion.setFromRotationMatrix( matrix );
  217. }
  218. return this;
  219. };
  220. }(),
  221. update: function ( delta, iteration, fixedDelta ) {
  222. this.world.stepSimulation( delta, iteration || 0, fixedDelta || ( 60 / 1000 ) );
  223. var i, j;
  224. for ( i = 0; i < this.vehicles.length; i ++ ) {
  225. var vehicle = this.vehicles[ i ],
  226. numWheels = vehicle.getNumWheels(),
  227. wheels = this.vehiclesWheels[ i ];
  228. for ( j = 0; j < numWheels; j ++ ) {
  229. vehicle.updateWheelTransform( j, true );
  230. var wheelsTransform = vehicle.getWheelTransformWS( j ),
  231. wheelTarget = wheels[ j ];
  232. if ( wheelTarget ) {
  233. this.updateTargetTransform( wheelTarget, wheelsTransform );
  234. }
  235. }
  236. }
  237. for ( i = 0; i < this.rigidBodies.length; i ++ ) {
  238. var rb = this.rigidBodies[ i ],
  239. target = this.rigidBodiesTarget[ i ],
  240. offset = this.rigidBodiesOffset[ i ];
  241. if ( target && rb.isActive() ) {
  242. this.updateTargetTransform( target, rb.getWorldTransform(), offset );
  243. }
  244. }
  245. return this;
  246. }
  247. };