SEA3DAmmoLoader.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  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;
  91. if ( sea.target ) {
  92. transform = SEA3D.AMMO.getTransformFromMatrix( sea.target.tag.matrix );
  93. } else {
  94. THREE.SEA3D.MTXBUF.elements.set( sea.transform );
  95. transform = SEA3D.AMMO.getTransformFromMatrix( THREE.SEA3D.MTXBUF );
  96. }
  97. var motionState = new Ammo.btDefaultMotionState( transform );
  98. var localInertia = new Ammo.btVector3( 0, 0, 0 );
  99. shape.calculateLocalInertia( sea.mass, localInertia );
  100. var info = new Ammo.btRigidBodyConstructionInfo( sea.mass, motionState, shape, localInertia );
  101. info.set_m_friction( sea.friction );
  102. info.set_m_restitution( sea.restitution );
  103. info.set_m_linearDamping( sea.linearDamping );
  104. info.set_m_angularDamping( sea.angularDamping );
  105. var rb = new Ammo.btRigidBody( info );
  106. this.domain.rigidBodies = this.rigidBodies = this.rigidBodies || [];
  107. this.rigidBodies.push( this.objects[ "rb/" + sea.name ] = sea.tag = rb );
  108. return rb;
  109. };
  110. //
  111. // Rigid Body
  112. //
  113. THREE.SEA3D.prototype.readRigidBody = function ( sea ) {
  114. var rb = this.readRigidBodyBase( sea );
  115. SEA3D.AMMO.addRigidBody( rb, sea.target ? sea.target.tag : undefined, sea.offset ? new THREE.Matrix4().elements.set( sea.offset ) : undefined, this.config.enabledPhysics );
  116. };
  117. //
  118. // Car Controller
  119. //
  120. THREE.SEA3D.prototype.readCarController = function ( sea ) {
  121. var body = this.readRigidBodyBase( sea );
  122. body.setActivationState( SEA3D.AMMO.DISABLE_DEACTIVATION );
  123. // Car
  124. var vehicleRayCaster = new Ammo.btDefaultVehicleRaycaster( SEA3D.AMMO.world );
  125. var tuning = new Ammo.btVehicleTuning();
  126. tuning.set_m_suspensionStiffness( sea.suspensionStiffness );
  127. tuning.set_m_suspensionDamping( sea.suspensionDamping );
  128. tuning.set_m_suspensionCompression( sea.suspensionCompression );
  129. tuning.set_m_maxSuspensionTravelCm( sea.maxSuspensionTravelCm );
  130. tuning.set_m_maxSuspensionForce( sea.maxSuspensionForce );
  131. tuning.set_m_frictionSlip( sea.frictionSlip );
  132. var vehicle = new Ammo.btRaycastVehicle( tuning, body, vehicleRayCaster ),
  133. wheels = [];
  134. vehicle.setCoordinateSystem( 0, 1, 2 );
  135. for ( var i = 0; i < sea.wheel.length; i ++ ) {
  136. var wheel = sea.wheel[ i ];
  137. var wheelInfo = vehicle.addWheel(
  138. this.toAmmoVec3( wheel.pos ),
  139. this.toAmmoVec3( wheel.dir ),
  140. this.toAmmoVec3( wheel.axle ),
  141. wheel.suspensionRestLength,
  142. wheel.radius,
  143. tuning,
  144. wheel.isFront
  145. );
  146. var target = wheels[ i ] = wheel.target ? wheel.target.tag : undefined;
  147. if ( target ) {
  148. if ( target.parent ) {
  149. target.parent.remove( target );
  150. }
  151. if ( this.container ) {
  152. this.container.add( target );
  153. }
  154. }
  155. wheelInfo.set_m_suspensionStiffness( sea.suspensionStiffness );
  156. wheelInfo.set_m_wheelsDampingRelaxation( sea.dampingRelaxation );
  157. wheelInfo.set_m_wheelsDampingCompression( sea.dampingCompression );
  158. wheelInfo.set_m_frictionSlip( sea.frictionSlip );
  159. }
  160. SEA3D.AMMO.addVehicle( vehicle, wheels );
  161. SEA3D.AMMO.addRigidBody( body, sea.target ? sea.target.tag : undefined, sea.offset ? new THREE.Matrix4().elements.set( sea.offset ) : undefined, this.config.enabledPhysics );
  162. this.domain.vehicles = this.vehicles = this.vehicles || [];
  163. this.vehicles.push( this.objects[ "vhc/" + sea.name ] = sea.tag = vehicle );
  164. };
  165. //
  166. // P2P Constraint
  167. //
  168. THREE.SEA3D.prototype.readP2PConstraint = function ( sea ) {
  169. var ctrt;
  170. if ( sea.targetB ) {
  171. ctrt = new Ammo.btPoint2PointConstraint(
  172. sea.targetA.tag,
  173. sea.targetB.tag,
  174. this.toAmmoVec3( sea.pointA ),
  175. this.toAmmoVec3( sea.pointB )
  176. );
  177. } else {
  178. ctrt = new Ammo.btPoint2PointConstraint(
  179. sea.targetA.tag,
  180. this.toAmmoVec3( sea.pointA )
  181. );
  182. }
  183. SEA3D.AMMO.addConstraint( ctrt );
  184. this.domain.constraints = this.constraints = this.constraints || [];
  185. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  186. };
  187. //
  188. // Hinge Constraint
  189. //
  190. THREE.SEA3D.prototype.readHingeConstraint = function ( sea ) {
  191. var ctrt;
  192. if ( sea.targetB ) {
  193. ctrt = new Ammo.btHingeConstraint(
  194. sea.targetA.tag,
  195. sea.targetB.tag,
  196. this.toAmmoVec3( sea.pointA ),
  197. this.toAmmoVec3( sea.pointB ),
  198. this.toAmmoVec3( sea.axisA ),
  199. this.toAmmoVec3( sea.axisB ),
  200. false
  201. );
  202. } else {
  203. ctrt = new Ammo.btHingeConstraint(
  204. sea.targetA.tag,
  205. this.toAmmoVec3( sea.pointA ),
  206. this.toAmmoVec3( sea.axisA ),
  207. false
  208. );
  209. }
  210. if ( sea.limit ) {
  211. ctrt.setLimit( sea.limit.low, sea.limit.high, sea.limit.softness, sea.limit.biasFactor, sea.limit.relaxationFactor );
  212. }
  213. if ( sea.angularMotor ) {
  214. ctrt.enableAngularMotor( true, sea.angularMotor.velocity, sea.angularMotor.impulse );
  215. }
  216. SEA3D.AMMO.addConstraint( ctrt );
  217. this.domain.constraints = this.constraints = this.constraints || [];
  218. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  219. };
  220. //
  221. // Cone Twist Constraint
  222. //
  223. THREE.SEA3D.prototype.readConeTwistConstraint = function ( sea ) {
  224. var ctrt;
  225. if ( sea.targetB ) {
  226. ctrt = new Ammo.btConeTwistConstraint(
  227. sea.targetA.tag,
  228. sea.targetB.tag,
  229. this.toAmmoVec3( sea.pointA ),
  230. this.toAmmoVec3( sea.pointB ),
  231. false
  232. );
  233. } else {
  234. ctrt = new Ammo.btConeTwistConstraint(
  235. sea.targetA.tag,
  236. this.toAmmoVec3( sea.pointA ),
  237. false
  238. );
  239. }
  240. SEA3D.AMMO.addConstraint( ctrt );
  241. this.domain.constraints = this.constraints = this.constraints || [];
  242. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  243. };
  244. //
  245. // Domain
  246. //
  247. THREE.SEA3D.Domain.prototype.enabledPhysics = function ( enabled ) {
  248. var i = this.rigidBodies ? this.rigidBodies.length : 0;
  249. while ( i -- ) {
  250. SEA3D.AMMO.setEnabledRigidBody( this.rigidBodies[ i ], enabled );
  251. }
  252. };
  253. THREE.SEA3D.Domain.prototype.applyContainerTransform = function () {
  254. this.container.updateMatrix();
  255. var matrix = this.container.matrix.clone();
  256. this.container.position.set( 0, 0, 0 );
  257. this.container.rotation.set( 0, 0, 0 );
  258. this.container.scale.set( 1, 1, 1 );
  259. this.applyTransform( matrix );
  260. };
  261. THREE.SEA3D.Domain.prototype.applyTransform = function ( matrix ) {
  262. var mtx = THREE.SEA3D.MTXBUF, vec = THREE.SEA3D.VECBUF;
  263. var i = this.rigidBodies ? this.rigidBodies.length : 0,
  264. childs = this.container ? this.container.children : [],
  265. targets = [];
  266. while ( i -- ) {
  267. var rb = this.rigidBodies[ i ],
  268. target = SEA3D.AMMO.getTargetByRigidBody( rb ),
  269. transform = rb.getWorldTransform(),
  270. transformMatrix = SEA3D.AMMO.getMatrixFromTransform( transform );
  271. transformMatrix.multiplyMatrices( transformMatrix, matrix );
  272. transform = SEA3D.AMMO.getTransformFromMatrix( transformMatrix );
  273. rb.setWorldTransform( transform );
  274. if ( target ) targets.push( target );
  275. }
  276. for ( i = 0; i < childs.length; i ++ ) {
  277. var obj3d = childs[ i ];
  278. if ( targets.indexOf( obj3d ) > - 1 ) continue;
  279. obj3d.updateMatrix();
  280. mtx.copy( obj3d.matrix );
  281. mtx.multiplyMatrices( matrix, mtx );
  282. obj3d.position.setFromMatrixPosition( mtx );
  283. obj3d.scale.setFromMatrixScale( mtx );
  284. // ignore rotation scale
  285. mtx.scale( vec.set( 1 / obj3d.scale.x, 1 / obj3d.scale.y, 1 / obj3d.scale.z ) );
  286. obj3d.rotation.setFromRotationMatrix( mtx );
  287. }
  288. };
  289. //
  290. // Extension
  291. //
  292. THREE.SEA3D.Domain.prototype.getShape = THREE.SEA3D.prototype.getShape = function ( name ) {
  293. return this.objects[ "shpe/" + name ];
  294. };
  295. THREE.SEA3D.Domain.prototype.getRigidBody = THREE.SEA3D.prototype.getRigidBody = function ( name ) {
  296. return this.objects[ "rb/" + name ];
  297. };
  298. THREE.SEA3D.Domain.prototype.getConstraint = THREE.SEA3D.prototype.getConstraint = function ( name ) {
  299. return this.objects[ "ctnt/" + name ];
  300. };
  301. THREE.SEA3D.EXTENSIONS_LOADER.push( {
  302. parse: function () {
  303. delete this.shapes;
  304. delete this.rigidBodies;
  305. delete this.vehicles;
  306. delete this.constraints;
  307. },
  308. setTypeRead: function () {
  309. // CONFIG
  310. this.config.physics = this.config.physics !== undefined ? this.config.physics : true;
  311. this.config.convexHull = this.config.convexHull !== undefined ? this.config.convexHull : true;
  312. this.config.enabledPhysics = this.config.enabledPhysics !== undefined ? this.config.enabledPhysics : true;
  313. if ( this.config.physics ) {
  314. // SHAPES
  315. this.file.typeRead[ SEA3D.Sphere.prototype.type ] = this.readSphere;
  316. this.file.typeRead[ SEA3D.Box.prototype.type ] = this.readBox;
  317. this.file.typeRead[ SEA3D.Capsule.prototype.type ] = this.readCapsule;
  318. this.file.typeRead[ SEA3D.Cone.prototype.type ] = this.readCone;
  319. this.file.typeRead[ SEA3D.Cylinder.prototype.type ] = this.readCylinder;
  320. this.file.typeRead[ SEA3D.ConvexGeometry.prototype.type ] = this.readConvexGeometry;
  321. this.file.typeRead[ SEA3D.TriangleGeometry.prototype.type ] = this.readTriangleGeometry;
  322. this.file.typeRead[ SEA3D.Compound.prototype.type ] = this.readCompound;
  323. // CONSTRAINTS
  324. this.file.typeRead[ SEA3D.P2PConstraint.prototype.type ] = this.readP2PConstraint;
  325. this.file.typeRead[ SEA3D.HingeConstraint.prototype.type ] = this.readHingeConstraint;
  326. this.file.typeRead[ SEA3D.ConeTwistConstraint.prototype.type ] = this.readConeTwistConstraint;
  327. // PHYSICS
  328. this.file.typeRead[ SEA3D.RigidBody.prototype.type ] = this.readRigidBody;
  329. this.file.typeRead[ SEA3D.CarController.prototype.type ] = this.readCarController;
  330. }
  331. }
  332. } );
  333. THREE.SEA3D.EXTENSIONS_DOMAIN.push( {
  334. dispose: function () {
  335. var i;
  336. i = this.rigidBodies ? this.rigidBodies.length : 0;
  337. while ( i -- ) SEA3D.AMMO.removeRigidBody( this.rigidBodies[ i ], true );
  338. i = this.vehicles ? this.vehicles.length : 0;
  339. while ( i -- ) SEA3D.AMMO.removeVehicle( this.vehicles[ i ], true );
  340. i = this.constraints ? this.constraints.length : 0;
  341. while ( i -- ) SEA3D.AMMO.removeConstraint( this.constraints[ i ], true );
  342. i = this.shapes ? this.shapes.length : 0;
  343. while ( i -- ) Ammo.destroy( this.shapes[ i ] );
  344. }
  345. } );