SEA3DAmmoLoader.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. /**
  2. * SEA3D+AMMO for Three.JS
  3. * @author Sunag / http://www.sunag.com.br/
  4. */
  5. 'use strict';
  6. THREE.SEA3D.prototype.toAmmoVec3 = function ( v ) {
  7. return new Ammo.btVector3( v.x, v.y, v.z );
  8. };
  9. //
  10. // Sphere
  11. //
  12. THREE.SEA3D.prototype.readSphere = function ( sea ) {
  13. var shape = new Ammo.btSphereShape( sea.radius );
  14. this.domain.shapes = this.shapes = this.shapes || [];
  15. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  16. };
  17. //
  18. // Box
  19. //
  20. THREE.SEA3D.prototype.readBox = function ( sea ) {
  21. var shape = new Ammo.btBoxShape( new Ammo.btVector3( sea.width * .5, sea.height * .5, sea.depth * .5 ) );
  22. this.domain.shapes = this.shapes = this.shapes || [];
  23. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  24. };
  25. //
  26. // Cone
  27. //
  28. THREE.SEA3D.prototype.readCone = function ( sea ) {
  29. var shape = new Ammo.btConeShape( sea.radius, sea.height );
  30. this.domain.shapes = this.shapes = this.shapes || [];
  31. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  32. };
  33. //
  34. // Cylinder
  35. //
  36. THREE.SEA3D.prototype.readCylinder = function ( sea ) {
  37. var shape = new Ammo.btCylinderShape( new Ammo.btVector3( sea.height, sea.radius, sea.radius ) );
  38. this.domain.shapes = this.shapes = this.shapes || [];
  39. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  40. };
  41. //
  42. // Capsule
  43. //
  44. THREE.SEA3D.prototype.readCapsule = function ( sea ) {
  45. var shape = new Ammo.btCapsuleShape( sea.radius, sea.height );
  46. this.domain.shapes = this.shapes = this.shapes || [];
  47. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  48. };
  49. //
  50. // Convex Geometry
  51. //
  52. THREE.SEA3D.prototype.readConvexGeometry = function ( sea ) {
  53. if ( this.config.convexHull ) {
  54. var shape = SEA3D.AMMO.createConvexHull( sea.geometry.tag, sea.subGeometryIndex );
  55. } else {
  56. var triMesh = SEA3D.AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
  57. var shape = new Ammo.btConvexTriangleMeshShape( triMesh, true );
  58. }
  59. this.domain.shapes = this.shapes = this.shapes || [];
  60. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  61. };
  62. //
  63. // Triangle Geometry
  64. //
  65. THREE.SEA3D.prototype.readTriangleGeometry = function ( sea ) {
  66. var triMesh = SEA3D.AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
  67. var shape = new Ammo.btBvhTriangleMeshShape( triMesh, true, true );
  68. this.domain.shapes = this.shapes = this.shapes || [];
  69. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  70. };
  71. //
  72. // Compound
  73. //
  74. THREE.SEA3D.prototype.readCompound = function ( sea ) {
  75. var shape = new Ammo.btCompoundShape();
  76. for ( var i = 0; i < sea.compounds.length; i ++ ) {
  77. var compound = sea.compounds[ i ];
  78. THREE.SEA3D.MTXBUF.elements = compound.transform;
  79. var transform = SEA3D.AMMO.getTransformFromMatrix( THREE.SEA3D.MTXBUF );
  80. shape.addChildShape( transform, compound.shape.tag );
  81. }
  82. this.domain.shapes = this.shapes = this.shapes || [];
  83. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  84. };
  85. //
  86. // Rigid Body Base
  87. //
  88. THREE.SEA3D.prototype.readRigidBodyBase = function ( sea ) {
  89. var shape = sea.shape.tag,
  90. transform, target;
  91. if ( sea.target ) {
  92. target = sea.target.tag;
  93. target.physics = { enabled: true };
  94. target.updateMatrix();
  95. transform = SEA3D.AMMO.getTransformFromMatrix( sea.target.tag.matrix );
  96. } else {
  97. THREE.SEA3D.MTXBUF.elements.set( sea.transform );
  98. transform = SEA3D.AMMO.getTransformFromMatrix( THREE.SEA3D.MTXBUF );
  99. }
  100. var motionState = new Ammo.btDefaultMotionState( transform );
  101. var localInertia = new Ammo.btVector3( 0, 0, 0 );
  102. shape.calculateLocalInertia( sea.mass, localInertia );
  103. var info = new Ammo.btRigidBodyConstructionInfo( sea.mass, motionState, shape, localInertia );
  104. info.set_m_friction( sea.friction );
  105. info.set_m_restitution( sea.restitution );
  106. info.set_m_linearDamping( sea.linearDamping );
  107. info.set_m_angularDamping( sea.angularDamping );
  108. var rb = new Ammo.btRigidBody( info );
  109. if ( target ) {
  110. target.physics.rigidBody = rb;
  111. if ( sea.offset ) {
  112. var offset = new THREE.Matrix4();
  113. offset.elements.set( sea.offset );
  114. target.physics.offset = offset;
  115. }
  116. }
  117. Ammo.destroy( info );
  118. this.domain.rigidBodies = this.rigidBodies = this.rigidBodies || [];
  119. this.rigidBodies.push( this.objects[ "rb/" + sea.name ] = sea.tag = rb );
  120. return rb;
  121. };
  122. //
  123. // Rigid Body
  124. //
  125. THREE.SEA3D.prototype.readRigidBody = function ( sea ) {
  126. var rb = this.readRigidBodyBase( sea );
  127. SEA3D.AMMO.addRigidBody( rb, sea.target ? sea.target.tag : undefined, this.config.enabledPhysics );
  128. };
  129. //
  130. // Car Controller
  131. //
  132. THREE.SEA3D.prototype.readCarController = function ( sea ) {
  133. var body = this.readRigidBodyBase( sea );
  134. body.setActivationState( SEA3D.AMMO.DISABLE_DEACTIVATION );
  135. // Car
  136. var vehicleRayCaster = new Ammo.btDefaultVehicleRaycaster( SEA3D.AMMO.world );
  137. var tuning = new Ammo.btVehicleTuning();
  138. tuning.set_m_suspensionStiffness( sea.suspensionStiffness );
  139. tuning.set_m_suspensionDamping( sea.suspensionDamping );
  140. tuning.set_m_suspensionCompression( sea.suspensionCompression );
  141. tuning.set_m_maxSuspensionTravelCm( sea.maxSuspensionTravelCm );
  142. tuning.set_m_maxSuspensionForce( sea.maxSuspensionForce );
  143. tuning.set_m_frictionSlip( sea.frictionSlip );
  144. var vehicle = new Ammo.btRaycastVehicle( tuning, body, vehicleRayCaster ),
  145. wheels = [];
  146. vehicle.setCoordinateSystem( 0, 1, 2 );
  147. for ( var i = 0; i < sea.wheel.length; i ++ ) {
  148. var wheel = sea.wheel[ i ];
  149. var wheelInfo = vehicle.addWheel(
  150. this.toAmmoVec3( wheel.pos ),
  151. this.toAmmoVec3( wheel.dir ),
  152. this.toAmmoVec3( wheel.axle ),
  153. wheel.suspensionRestLength,
  154. wheel.radius,
  155. tuning,
  156. wheel.isFront
  157. );
  158. var target = wheels[ i ] = wheel.target ? wheel.target.tag : undefined;
  159. if ( target ) {
  160. target.physics = { enabled: true, rigidBody: wheelInfo };
  161. if ( wheel.offset ) {
  162. var offset = new THREE.Matrix4();
  163. offset.elements.set( wheel.offset );
  164. target.physics.offset = offset;
  165. }
  166. if ( target.parent ) {
  167. target.parent.remove( target );
  168. }
  169. if ( this.container ) {
  170. this.container.add( target );
  171. }
  172. }
  173. wheelInfo.set_m_suspensionStiffness( sea.suspensionStiffness );
  174. wheelInfo.set_m_wheelsDampingRelaxation( sea.dampingRelaxation );
  175. wheelInfo.set_m_wheelsDampingCompression( sea.dampingCompression );
  176. wheelInfo.set_m_frictionSlip( sea.frictionSlip );
  177. }
  178. SEA3D.AMMO.addVehicle( vehicle, wheels );
  179. SEA3D.AMMO.addRigidBody( body, sea.target ? sea.target.tag : undefined, this.config.enabledPhysics );
  180. this.domain.vehicles = this.vehicles = this.vehicles || [];
  181. this.vehicles.push( this.objects[ "vhc/" + sea.name ] = sea.tag = vehicle );
  182. };
  183. //
  184. // P2P Constraint
  185. //
  186. THREE.SEA3D.prototype.readP2PConstraint = function ( sea ) {
  187. var ctrt;
  188. if ( sea.targetB ) {
  189. ctrt = new Ammo.btPoint2PointConstraint(
  190. sea.targetA.tag,
  191. sea.targetB.tag,
  192. this.toAmmoVec3( sea.pointA ),
  193. this.toAmmoVec3( sea.pointB )
  194. );
  195. } else {
  196. ctrt = new Ammo.btPoint2PointConstraint(
  197. sea.targetA.tag,
  198. this.toAmmoVec3( sea.pointA )
  199. );
  200. }
  201. SEA3D.AMMO.addConstraint( ctrt );
  202. this.domain.constraints = this.constraints = this.constraints || [];
  203. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  204. };
  205. //
  206. // Hinge Constraint
  207. //
  208. THREE.SEA3D.prototype.readHingeConstraint = function ( sea ) {
  209. var ctrt;
  210. if ( sea.targetB ) {
  211. ctrt = new Ammo.btHingeConstraint(
  212. sea.targetA.tag,
  213. sea.targetB.tag,
  214. this.toAmmoVec3( sea.pointA ),
  215. this.toAmmoVec3( sea.pointB ),
  216. this.toAmmoVec3( sea.axisA ),
  217. this.toAmmoVec3( sea.axisB ),
  218. false
  219. );
  220. } else {
  221. ctrt = new Ammo.btHingeConstraint(
  222. sea.targetA.tag,
  223. this.toAmmoVec3( sea.pointA ),
  224. this.toAmmoVec3( sea.axisA ),
  225. false
  226. );
  227. }
  228. if ( sea.limit ) {
  229. ctrt.setLimit( sea.limit.low, sea.limit.high, sea.limit.softness, sea.limit.biasFactor, sea.limit.relaxationFactor );
  230. }
  231. if ( sea.angularMotor ) {
  232. ctrt.enableAngularMotor( true, sea.angularMotor.velocity, sea.angularMotor.impulse );
  233. }
  234. SEA3D.AMMO.addConstraint( ctrt );
  235. this.domain.constraints = this.constraints = this.constraints || [];
  236. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  237. };
  238. //
  239. // Cone Twist Constraint
  240. //
  241. THREE.SEA3D.prototype.readConeTwistConstraint = function ( sea ) {
  242. var ctrt;
  243. if ( sea.targetB ) {
  244. ctrt = new Ammo.btConeTwistConstraint(
  245. sea.targetA.tag,
  246. sea.targetB.tag,
  247. this.toAmmoVec3( sea.pointA ),
  248. this.toAmmoVec3( sea.pointB ),
  249. false
  250. );
  251. } else {
  252. ctrt = new Ammo.btConeTwistConstraint(
  253. sea.targetA.tag,
  254. this.toAmmoVec3( sea.pointA ),
  255. false
  256. );
  257. }
  258. SEA3D.AMMO.addConstraint( ctrt );
  259. this.domain.constraints = this.constraints = this.constraints || [];
  260. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  261. };
  262. //
  263. // Domain
  264. //
  265. THREE.SEA3D.Domain.prototype.enabledPhysics = function ( enabled ) {
  266. var i = this.rigidBodies ? this.rigidBodies.length : 0;
  267. while ( i -- ) {
  268. SEA3D.AMMO.setEnabledRigidBody( this.rigidBodies[ i ], enabled );
  269. }
  270. };
  271. THREE.SEA3D.Domain.prototype.applyContainerTransform = function () {
  272. this.container.updateMatrix();
  273. var matrix = this.container.matrix.clone();
  274. this.container.position.set( 0, 0, 0 );
  275. this.container.rotation.set( 0, 0, 0 );
  276. this.container.scale.set( 1, 1, 1 );
  277. this.applyTransform( matrix );
  278. };
  279. THREE.SEA3D.Domain.prototype.applyTransform = function ( matrix ) {
  280. var mtx = THREE.SEA3D.MTXBUF, vec = THREE.SEA3D.VECBUF;
  281. var i = this.rigidBodies ? this.rigidBodies.length : 0,
  282. childs = this.container ? this.container.children : [],
  283. targets = [];
  284. while ( i -- ) {
  285. var rb = this.rigidBodies[ i ],
  286. target = SEA3D.AMMO.getTargetByRigidBody( rb ),
  287. transform = rb.getWorldTransform(),
  288. transformMatrix = SEA3D.AMMO.getMatrixFromTransform( transform );
  289. transformMatrix.multiplyMatrices( transformMatrix, matrix );
  290. transform = SEA3D.AMMO.getTransformFromMatrix( transformMatrix );
  291. rb.setWorldTransform( transform );
  292. if ( target ) targets.push( target );
  293. }
  294. for ( i = 0; i < childs.length; i ++ ) {
  295. var obj3d = childs[ i ];
  296. if ( targets.indexOf( obj3d ) > - 1 ) continue;
  297. obj3d.updateMatrix();
  298. mtx.copy( obj3d.matrix );
  299. mtx.multiplyMatrices( matrix, mtx );
  300. obj3d.position.setFromMatrixPosition( mtx );
  301. obj3d.scale.setFromMatrixScale( mtx );
  302. // ignore rotation scale
  303. mtx.scale( vec.set( 1 / obj3d.scale.x, 1 / obj3d.scale.y, 1 / obj3d.scale.z ) );
  304. obj3d.rotation.setFromRotationMatrix( mtx );
  305. }
  306. };
  307. //
  308. // Extension
  309. //
  310. THREE.SEA3D.Domain.prototype.getShape = THREE.SEA3D.prototype.getShape = function ( name ) {
  311. return this.objects[ "shpe/" + name ];
  312. };
  313. THREE.SEA3D.Domain.prototype.getRigidBody = THREE.SEA3D.prototype.getRigidBody = function ( name ) {
  314. return this.objects[ "rb/" + name ];
  315. };
  316. THREE.SEA3D.Domain.prototype.getConstraint = THREE.SEA3D.prototype.getConstraint = function ( name ) {
  317. return this.objects[ "ctnt/" + name ];
  318. };
  319. THREE.SEA3D.EXTENSIONS_LOADER.push( {
  320. parse: function () {
  321. delete this.shapes;
  322. delete this.rigidBodies;
  323. delete this.vehicles;
  324. delete this.constraints;
  325. },
  326. setTypeRead: function () {
  327. // CONFIG
  328. this.config.physics = this.config.physics !== undefined ? this.config.physics : true;
  329. this.config.convexHull = this.config.convexHull !== undefined ? this.config.convexHull : true;
  330. this.config.enabledPhysics = this.config.enabledPhysics !== undefined ? this.config.enabledPhysics : true;
  331. if ( this.config.physics ) {
  332. // SHAPES
  333. this.file.typeRead[ SEA3D.Sphere.prototype.type ] = this.readSphere;
  334. this.file.typeRead[ SEA3D.Box.prototype.type ] = this.readBox;
  335. this.file.typeRead[ SEA3D.Capsule.prototype.type ] = this.readCapsule;
  336. this.file.typeRead[ SEA3D.Cone.prototype.type ] = this.readCone;
  337. this.file.typeRead[ SEA3D.Cylinder.prototype.type ] = this.readCylinder;
  338. this.file.typeRead[ SEA3D.ConvexGeometry.prototype.type ] = this.readConvexGeometry;
  339. this.file.typeRead[ SEA3D.TriangleGeometry.prototype.type ] = this.readTriangleGeometry;
  340. this.file.typeRead[ SEA3D.Compound.prototype.type ] = this.readCompound;
  341. // CONSTRAINTS
  342. this.file.typeRead[ SEA3D.P2PConstraint.prototype.type ] = this.readP2PConstraint;
  343. this.file.typeRead[ SEA3D.HingeConstraint.prototype.type ] = this.readHingeConstraint;
  344. this.file.typeRead[ SEA3D.ConeTwistConstraint.prototype.type ] = this.readConeTwistConstraint;
  345. // PHYSICS
  346. this.file.typeRead[ SEA3D.RigidBody.prototype.type ] = this.readRigidBody;
  347. this.file.typeRead[ SEA3D.CarController.prototype.type ] = this.readCarController;
  348. }
  349. }
  350. } );
  351. THREE.SEA3D.EXTENSIONS_DOMAIN.push( {
  352. dispose: function () {
  353. var i;
  354. i = this.rigidBodies ? this.rigidBodies.length : 0;
  355. while ( i -- ) SEA3D.AMMO.removeRigidBody( this.rigidBodies[ i ], true );
  356. i = this.vehicles ? this.vehicles.length : 0;
  357. while ( i -- ) SEA3D.AMMO.removeVehicle( this.vehicles[ i ], true );
  358. i = this.constraints ? this.constraints.length : 0;
  359. while ( i -- ) SEA3D.AMMO.removeConstraint( this.constraints[ i ], true );
  360. i = this.shapes ? this.shapes.length : 0;
  361. while ( i -- ) Ammo.destroy( this.shapes[ i ] );
  362. }
  363. } );