SEA3DAmmoLoader.js 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  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. import {
  11. Vector3,
  12. Quaternion,
  13. Matrix4
  14. } from "../../../../../build/three.module.js";
  15. import { SEA3DSDK } from '../SEA3DSDK.js';
  16. import { SEA3D } from '../SEA3DLoader.js';
  17. var AMMO = {
  18. world: null,
  19. rigidBodies: [],
  20. rigidBodiesTarget: [],
  21. rigidBodiesEnabled: [],
  22. constraints: [],
  23. vehicles: [],
  24. vehiclesWheels: [],
  25. ACTIVE: 1,
  26. ISLAND_SLEEPING: 2,
  27. WANTS_DEACTIVATION: 3,
  28. DISABLE_DEACTIVATION: 4,
  29. DISABLE_SIMULATION: 5,
  30. VERSION: 0.8,
  31. init: function ( gravity, worldScale, broadphase ) {
  32. gravity = gravity !== undefined ? gravity : - 90.8;
  33. this.worldScale = worldScale == undefined ? 1 : worldScale;
  34. this.broadphase = broadphase == undefined ? 'bvt' : broadphase;
  35. this.solver = new Ammo.btSequentialImpulseConstraintSolver();
  36. this.collisionConfig = new Ammo.btDefaultCollisionConfiguration();
  37. this.dispatcher = new Ammo.btCollisionDispatcher( this.collisionConfig );
  38. switch ( this.broadphase ) {
  39. case 'bvt':
  40. this.broadphase = new Ammo.btDbvtBroadphase();
  41. break;
  42. case 'sap':
  43. this.broadphase = new Ammo.btAxisSweep3(
  44. new Ammo.btVector3( - this.worldScale, - this.worldScale, - this.worldScale ),
  45. new Ammo.btVector3( this.worldScale, this.worldScale, this.worldScale ),
  46. 4096
  47. );
  48. break;
  49. case 'simple':
  50. this.broadphase = new Ammo.btSimpleBroadphase();
  51. break;
  52. }
  53. this.world = new Ammo.btDiscreteDynamicsWorld( this.dispatcher, this.broadphase, this.solver, this.collisionConfig );
  54. this.setGravity( gravity );
  55. console.log( "SEA3D.AMMO " + this.VERSION );
  56. },
  57. setGravity: function ( gravity ) {
  58. this.gravity = gravity;
  59. this.world.setGravity( new Ammo.btVector3( 0, gravity, 0 ) );
  60. return this;
  61. },
  62. getGravity: function () {
  63. return this.gravity;
  64. },
  65. setEnabledRigidBody: function ( rb, enabled ) {
  66. var index = this.rigidBodies.indexOf( rb );
  67. if ( this.rigidBodiesEnabled[ index ] == enabled ) return;
  68. if ( enabled ) this.world.addRigidBody( rb );
  69. else this.world.removeRigidBody( rb );
  70. this.rigidBodiesEnabled[ index ] = true;
  71. return this;
  72. },
  73. getEnabledRigidBody: function ( rb ) {
  74. return this.rigidBodiesEnabled[ this.rigidBodies.indexOf( rb ) ];
  75. },
  76. addRigidBody: function ( rb, target, enabled ) {
  77. enabled = enabled !== undefined ? enabled : true;
  78. this.rigidBodies.push( rb );
  79. this.rigidBodiesTarget.push( target );
  80. this.rigidBodiesEnabled.push( false );
  81. this.setEnabledRigidBody( rb, enabled );
  82. return this;
  83. },
  84. removeRigidBody: function ( rb, destroy ) {
  85. var index = this.rigidBodies.indexOf( rb );
  86. this.setEnabledRigidBody( rb, false );
  87. this.rigidBodies.splice( index, 1 );
  88. this.rigidBodiesTarget.splice( index, 1 );
  89. this.rigidBodiesEnabled.splice( index, 1 );
  90. if ( destroy ) Ammo.destroy( rb );
  91. return this;
  92. },
  93. containsRigidBody: function ( rb ) {
  94. return this.rigidBodies.indexOf( rb ) > - 1;
  95. },
  96. addConstraint: function ( ctrt, disableCollisionsBetweenBodies ) {
  97. disableCollisionsBetweenBodies = disableCollisionsBetweenBodies == undefined ? true : disableCollisionsBetweenBodies;
  98. this.constraints.push( ctrt );
  99. this.world.addConstraint( ctrt, disableCollisionsBetweenBodies );
  100. return this;
  101. },
  102. removeConstraint: function ( ctrt, destroy ) {
  103. this.constraints.splice( this.constraints.indexOf( ctrt ), 1 );
  104. this.world.removeConstraint( ctrt );
  105. if ( destroy ) Ammo.destroy( ctrt );
  106. return this;
  107. },
  108. containsConstraint: function ( ctrt ) {
  109. return this.constraints.indexOf( rb ) > - 1;
  110. },
  111. addVehicle: function ( vehicle, wheels ) {
  112. this.vehicles.push( vehicle );
  113. this.vehiclesWheels.push( wheels != undefined ? wheels : [] );
  114. this.world.addAction( vehicle );
  115. return this;
  116. },
  117. removeVehicle: function ( vehicle, destroy ) {
  118. var index = this.vehicles.indexOf( vehicle );
  119. this.vehicles.splice( index, 1 );
  120. this.vehiclesWheels.splice( index, 1 );
  121. this.world.removeAction( vehicle );
  122. if ( destroy ) Ammo.destroy( vehicle );
  123. return this;
  124. },
  125. containsVehicle: function ( vehicle ) {
  126. return this.vehicles.indexOf( vehicle ) > - 1;
  127. },
  128. createTriangleMesh: function ( geometry, index, removeDuplicateVertices ) {
  129. index = index == undefined ? - 1 : index;
  130. removeDuplicateVertices = removeDuplicateVertices == undefined ? false : removeDuplicateVertices;
  131. var mTriMesh = new Ammo.btTriangleMesh();
  132. var v0 = new Ammo.btVector3( 0, 0, 0 );
  133. var v1 = new Ammo.btVector3( 0, 0, 0 );
  134. var v2 = new Ammo.btVector3( 0, 0, 0 );
  135. var vertex = geometry.getAttribute( 'position' ).array;
  136. var indexes = geometry.getIndex().array;
  137. var group = index >= 0 ? geometry.groups[ index ] : undefined,
  138. start = group ? group.start : 0,
  139. count = group ? group.count : indexes.length;
  140. var scale = 1 / this.worldScale;
  141. for ( var idx = start; idx < count; idx += 3 ) {
  142. var vx1 = indexes[ idx ] * 3,
  143. vx2 = indexes[ idx + 1 ] * 3,
  144. vx3 = indexes[ idx + 2 ] * 3;
  145. v0.setValue( vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale );
  146. v1.setValue( vertex[ vx2 ] * scale, vertex[ vx2 + 1 ] * scale, vertex[ vx2 + 2 ] * scale );
  147. v2.setValue( vertex[ vx3 ] * scale, vertex[ vx3 + 1 ] * scale, vertex[ vx3 + 2 ] * scale );
  148. mTriMesh.addTriangle( v0, v1, v2, removeDuplicateVertices );
  149. }
  150. return mTriMesh;
  151. },
  152. createConvexHull: function ( geometry, index ) {
  153. index = index == undefined ? - 1 : index;
  154. var mConvexHull = new Ammo.btConvexHullShape();
  155. var v0 = new Ammo.btVector3( 0, 0, 0 );
  156. var vertex = geometry.getAttribute( 'position' ).array;
  157. var indexes = geometry.getIndex().array;
  158. var group = index >= 0 ? geometry.groups[ index ] : undefined,
  159. start = group ? group.start : 0,
  160. count = group ? group.count : indexes.length;
  161. var scale = 1 / this.worldScale;
  162. for ( var idx = start; idx < count; idx += 3 ) {
  163. var vx1 = indexes[ idx ] * 3;
  164. var point = new Ammo.btVector3(
  165. vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale
  166. );
  167. mConvexHull.addPoint( point );
  168. }
  169. return mConvexHull;
  170. },
  171. getTargetByRigidBody: function ( rb ) {
  172. return this.rigidBodiesTarget[ this.rigidBodies.indexOf( rb ) ];
  173. },
  174. getRigidBodyByTarget: function ( target ) {
  175. return this.rigidBodies[ this.rigidBodiesTarget.indexOf( target ) ];
  176. },
  177. getTransformFromMatrix: function ( mtx ) {
  178. var transform = new Ammo.btTransform();
  179. var pos = SEA3D.VECBUF.setFromMatrixPosition( mtx );
  180. transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
  181. var scl = SEA3D.VECBUF.setFromMatrixScale( mtx );
  182. mtx.scale( scl.set( 1 / scl.x, 1 / scl.y, 1 / scl.z ) );
  183. var quat = new Quaternion().setFromRotationMatrix( mtx );
  184. var q = new Ammo.btQuaternion();
  185. q.setValue( quat.x, quat.y, quat.z, quat.w );
  186. transform.setRotation( q );
  187. Ammo.destroy( q );
  188. return transform;
  189. },
  190. getMatrixFromTransform: function ( transform ) {
  191. var position = new Vector3();
  192. var quaternion = new Quaternion();
  193. var scale = new Vector3( 1, 1, 1 );
  194. return function ( transform, matrix ) {
  195. matrix = matrix || new Matrix4();
  196. var pos = transform.getOrigin(),
  197. quat = transform.getRotation();
  198. position.set( pos.x(), pos.y(), pos.z() );
  199. quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
  200. matrix.compose( position, quaternion, scale );
  201. return matrix;
  202. };
  203. }(),
  204. updateTargetTransform: function () {
  205. var matrix = new Matrix4();
  206. var position = new Vector3();
  207. var quaternion = new Quaternion();
  208. var scale = new Vector3( 1, 1, 1 );
  209. return function ( obj3d, transform, offset ) {
  210. var pos = transform.getOrigin(),
  211. quat = transform.getRotation();
  212. if ( offset ) {
  213. position.set( pos.x(), pos.y(), pos.z() );
  214. quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
  215. matrix.compose( position, quaternion, scale );
  216. matrix.multiplyMatrices( matrix, offset );
  217. obj3d.position.setFromMatrixPosition( matrix );
  218. obj3d.quaternion.setFromRotationMatrix( matrix );
  219. } else {
  220. obj3d.position.set( pos.x(), pos.y(), pos.z() );
  221. obj3d.quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
  222. }
  223. return this;
  224. };
  225. }(),
  226. update: function ( delta, iteration, fixedDelta ) {
  227. this.world.stepSimulation( delta, iteration || 0, fixedDelta || ( 60 / 1000 ) );
  228. var i, j;
  229. for ( i = 0; i < this.vehicles.length; i ++ ) {
  230. var vehicle = this.vehicles[ i ],
  231. numWheels = vehicle.getNumWheels(),
  232. wheels = this.vehiclesWheels[ i ];
  233. for ( j = 0; j < numWheels; j ++ ) {
  234. vehicle.updateWheelTransform( j, true );
  235. var wheelsTransform = vehicle.getWheelTransformWS( j ),
  236. wheelTarget = wheels[ j ];
  237. if ( wheelTarget ) {
  238. this.updateTargetTransform( wheelTarget, wheelsTransform, wheelTarget.physics ? wheelTarget.physics.offset : null );
  239. }
  240. }
  241. }
  242. for ( i = 0; i < this.rigidBodies.length; i ++ ) {
  243. var rb = this.rigidBodies[ i ],
  244. target = this.rigidBodiesTarget[ i ];
  245. if ( target && rb.isActive() ) {
  246. this.updateTargetTransform( target, rb.getWorldTransform(), target.physics ? target.physics.offset : null );
  247. }
  248. }
  249. return this;
  250. }
  251. };
  252. //
  253. // Utils
  254. //
  255. SEA3D.prototype.toAmmoVec3 = function ( v ) {
  256. return new Ammo.btVector3( v.x, v.y, v.z );
  257. };
  258. //
  259. // Sphere
  260. //
  261. SEA3D.prototype.readSphere = function ( sea ) {
  262. var shape = new Ammo.btSphereShape( sea.radius );
  263. this.domain.shapes = this.shapes = this.shapes || [];
  264. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  265. };
  266. //
  267. // Box
  268. //
  269. SEA3D.prototype.readBox = function ( sea ) {
  270. var shape = new Ammo.btBoxShape( new Ammo.btVector3( sea.width * .5, sea.height * .5, sea.depth * .5 ) );
  271. this.domain.shapes = this.shapes = this.shapes || [];
  272. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  273. };
  274. //
  275. // Cone
  276. //
  277. SEA3D.prototype.readCone = function ( sea ) {
  278. var shape = new Ammo.btConeShape( sea.radius, sea.height );
  279. this.domain.shapes = this.shapes = this.shapes || [];
  280. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  281. };
  282. //
  283. // Cylinder
  284. //
  285. SEA3D.prototype.readCylinder = function ( sea ) {
  286. var shape = new Ammo.btCylinderShape( new Ammo.btVector3( sea.height, sea.radius, sea.radius ) );
  287. this.domain.shapes = this.shapes = this.shapes || [];
  288. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  289. };
  290. //
  291. // Capsule
  292. //
  293. SEA3D.prototype.readCapsule = function ( sea ) {
  294. var shape = new Ammo.btCapsuleShape( sea.radius, sea.height );
  295. this.domain.shapes = this.shapes = this.shapes || [];
  296. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  297. };
  298. //
  299. // Convex Geometry
  300. //
  301. SEA3D.prototype.readConvexGeometry = function ( sea ) {
  302. if ( this.config.convexHull ) {
  303. var shape = AMMO.createConvexHull( sea.geometry.tag, sea.subGeometryIndex );
  304. } else {
  305. var triMesh = AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
  306. var shape = new Ammo.btConvexTriangleMeshShape( triMesh, true );
  307. }
  308. this.domain.shapes = this.shapes = this.shapes || [];
  309. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  310. };
  311. //
  312. // Triangle Geometry
  313. //
  314. SEA3D.prototype.readTriangleGeometry = function ( sea ) {
  315. var triMesh = AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
  316. var shape = new Ammo.btBvhTriangleMeshShape( triMesh, true, true );
  317. this.domain.shapes = this.shapes = this.shapes || [];
  318. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  319. };
  320. //
  321. // Compound
  322. //
  323. SEA3D.prototype.readCompound = function ( sea ) {
  324. var shape = new Ammo.btCompoundShape();
  325. for ( var i = 0; i < sea.compounds.length; i ++ ) {
  326. var compound = sea.compounds[ i ];
  327. SEA3D.MTXBUF.elements = compound.transform;
  328. var transform = AMMO.getTransformFromMatrix( SEA3D.MTXBUF );
  329. shape.addChildShape( transform, compound.shape.tag );
  330. }
  331. this.domain.shapes = this.shapes = this.shapes || [];
  332. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  333. };
  334. //
  335. // Rigid Body Base
  336. //
  337. SEA3D.prototype.readRigidBodyBase = function ( sea ) {
  338. var shape = sea.shape.tag,
  339. transform, target;
  340. if ( sea.target ) {
  341. target = sea.target.tag;
  342. target.physics = { enabled: true };
  343. target.updateMatrix();
  344. transform = AMMO.getTransformFromMatrix( sea.target.tag.matrix );
  345. } else {
  346. SEA3D.MTXBUF.fromArray( sea.transform );
  347. transform = AMMO.getTransformFromMatrix( SEA3D.MTXBUF );
  348. }
  349. var motionState = new Ammo.btDefaultMotionState( transform );
  350. var localInertia = new Ammo.btVector3( 0, 0, 0 );
  351. shape.calculateLocalInertia( sea.mass, localInertia );
  352. var info = new Ammo.btRigidBodyConstructionInfo( sea.mass, motionState, shape, localInertia );
  353. info.set_m_friction( sea.friction );
  354. info.set_m_restitution( sea.restitution );
  355. info.set_m_linearDamping( sea.linearDamping );
  356. info.set_m_angularDamping( sea.angularDamping );
  357. var rb = new Ammo.btRigidBody( info );
  358. if ( target ) {
  359. target.physics.rigidBody = rb;
  360. if ( sea.offset ) {
  361. var offset = new Matrix4();
  362. offset.fromArray( sea.offset );
  363. target.physics.offset = offset;
  364. }
  365. }
  366. Ammo.destroy( info );
  367. this.domain.rigidBodies = this.rigidBodies = this.rigidBodies || [];
  368. this.rigidBodies.push( this.objects[ "rb/" + sea.name ] = sea.tag = rb );
  369. return rb;
  370. };
  371. //
  372. // Rigid Body
  373. //
  374. SEA3D.prototype.readRigidBody = function ( sea ) {
  375. var rb = this.readRigidBodyBase( sea );
  376. AMMO.addRigidBody( rb, sea.target ? sea.target.tag : undefined, this.config.enabledPhysics );
  377. };
  378. //
  379. // Car Controller
  380. //
  381. SEA3D.prototype.readCarController = function ( sea ) {
  382. var body = this.readRigidBodyBase( sea );
  383. body.setActivationState( AMMO.DISABLE_DEACTIVATION );
  384. // Car
  385. var vehicleRayCaster = new Ammo.btDefaultVehicleRaycaster( AMMO.world );
  386. var tuning = new Ammo.btVehicleTuning();
  387. tuning.set_m_suspensionStiffness( sea.suspensionStiffness );
  388. tuning.set_m_suspensionDamping( sea.suspensionDamping );
  389. tuning.set_m_suspensionCompression( sea.suspensionCompression );
  390. tuning.set_m_maxSuspensionTravelCm( sea.maxSuspensionTravelCm );
  391. tuning.set_m_maxSuspensionForce( sea.maxSuspensionForce );
  392. tuning.set_m_frictionSlip( sea.frictionSlip );
  393. var vehicle = new Ammo.btRaycastVehicle( tuning, body, vehicleRayCaster ),
  394. wheels = [];
  395. vehicle.setCoordinateSystem( 0, 1, 2 );
  396. for ( var i = 0; i < sea.wheel.length; i ++ ) {
  397. var wheel = sea.wheel[ i ];
  398. var wheelInfo = vehicle.addWheel(
  399. this.toAmmoVec3( wheel.pos ),
  400. this.toAmmoVec3( wheel.dir ),
  401. this.toAmmoVec3( wheel.axle ),
  402. wheel.suspensionRestLength,
  403. wheel.radius,
  404. tuning,
  405. wheel.isFront
  406. );
  407. var target = wheels[ i ] = wheel.target ? wheel.target.tag : undefined;
  408. if ( target ) {
  409. target.physics = { enabled: true, rigidBody: wheelInfo };
  410. if ( wheel.offset ) {
  411. var offset = new Matrix4();
  412. offset.fromArray( wheel.offset );
  413. target.physics.offset = offset;
  414. }
  415. if ( target.parent ) {
  416. target.parent.remove( target );
  417. }
  418. if ( this.container ) {
  419. this.container.add( target );
  420. }
  421. }
  422. wheelInfo.set_m_suspensionStiffness( sea.suspensionStiffness );
  423. wheelInfo.set_m_wheelsDampingRelaxation( sea.dampingRelaxation );
  424. wheelInfo.set_m_wheelsDampingCompression( sea.dampingCompression );
  425. wheelInfo.set_m_frictionSlip( sea.frictionSlip );
  426. }
  427. AMMO.addVehicle( vehicle, wheels );
  428. AMMO.addRigidBody( body, sea.target ? sea.target.tag : undefined, this.config.enabledPhysics );
  429. this.domain.vehicles = this.vehicles = this.vehicles || [];
  430. this.vehicles.push( this.objects[ "vhc/" + sea.name ] = sea.tag = vehicle );
  431. };
  432. //
  433. // P2P Constraint
  434. //
  435. SEA3D.prototype.readP2PConstraint = function ( sea ) {
  436. var ctrt;
  437. if ( sea.targetB ) {
  438. ctrt = new Ammo.btPoint2PointConstraint(
  439. sea.targetA.tag,
  440. sea.targetB.tag,
  441. this.toAmmoVec3( sea.pointA ),
  442. this.toAmmoVec3( sea.pointB )
  443. );
  444. } else {
  445. ctrt = new Ammo.btPoint2PointConstraint(
  446. sea.targetA.tag,
  447. this.toAmmoVec3( sea.pointA )
  448. );
  449. }
  450. AMMO.addConstraint( ctrt );
  451. this.domain.constraints = this.constraints = this.constraints || [];
  452. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  453. };
  454. //
  455. // Hinge Constraint
  456. //
  457. SEA3D.prototype.readHingeConstraint = function ( sea ) {
  458. var ctrt;
  459. if ( sea.targetB ) {
  460. ctrt = new Ammo.btHingeConstraint(
  461. sea.targetA.tag,
  462. sea.targetB.tag,
  463. this.toAmmoVec3( sea.pointA ),
  464. this.toAmmoVec3( sea.pointB ),
  465. this.toAmmoVec3( sea.axisA ),
  466. this.toAmmoVec3( sea.axisB ),
  467. false
  468. );
  469. } else {
  470. ctrt = new Ammo.btHingeConstraint(
  471. sea.targetA.tag,
  472. this.toAmmoVec3( sea.pointA ),
  473. this.toAmmoVec3( sea.axisA ),
  474. false
  475. );
  476. }
  477. if ( sea.limit ) {
  478. ctrt.setLimit( sea.limit.low, sea.limit.high, sea.limit.softness, sea.limit.biasFactor, sea.limit.relaxationFactor );
  479. }
  480. if ( sea.angularMotor ) {
  481. ctrt.enableAngularMotor( true, sea.angularMotor.velocity, sea.angularMotor.impulse );
  482. }
  483. AMMO.addConstraint( ctrt );
  484. this.domain.constraints = this.constraints = this.constraints || [];
  485. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  486. };
  487. //
  488. // Cone Twist Constraint
  489. //
  490. SEA3D.prototype.readConeTwistConstraint = function ( sea ) {
  491. var ctrt;
  492. if ( sea.targetB ) {
  493. ctrt = new Ammo.btConeTwistConstraint(
  494. sea.targetA.tag,
  495. sea.targetB.tag,
  496. this.toAmmoVec3( sea.pointA ),
  497. this.toAmmoVec3( sea.pointB ),
  498. false
  499. );
  500. } else {
  501. ctrt = new Ammo.btConeTwistConstraint(
  502. sea.targetA.tag,
  503. this.toAmmoVec3( sea.pointA ),
  504. false
  505. );
  506. }
  507. AMMO.addConstraint( ctrt );
  508. this.domain.constraints = this.constraints = this.constraints || [];
  509. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  510. };
  511. //
  512. // Domain
  513. //
  514. SEA3D.Domain.prototype.enabledPhysics = function ( enabled ) {
  515. var i = this.rigidBodies ? this.rigidBodies.length : 0;
  516. while ( i -- ) {
  517. AMMO.setEnabledRigidBody( this.rigidBodies[ i ], enabled );
  518. }
  519. };
  520. SEA3D.Domain.prototype.applyContainerTransform = function () {
  521. this.container.updateMatrix();
  522. var matrix = this.container.matrix.clone();
  523. this.container.position.set( 0, 0, 0 );
  524. this.container.quaternion.set( 0, 0, 0, 1 );
  525. this.container.scale.set( 1, 1, 1 );
  526. this.applyTransform( matrix );
  527. };
  528. SEA3D.Domain.prototype.applyTransform = function ( matrix ) {
  529. var mtx = SEA3D.MTXBUF, vec = SEA3D.VECBUF;
  530. var i = this.rigidBodies ? this.rigidBodies.length : 0,
  531. childs = this.container ? this.container.children : [],
  532. targets = [];
  533. while ( i -- ) {
  534. var rb = this.rigidBodies[ i ],
  535. target = AMMO.getTargetByRigidBody( rb ),
  536. transform = rb.getWorldTransform(),
  537. transformMatrix = AMMO.getMatrixFromTransform( transform );
  538. transformMatrix.multiplyMatrices( transformMatrix, matrix );
  539. transform = AMMO.getTransformFromMatrix( transformMatrix );
  540. rb.setWorldTransform( transform );
  541. if ( target ) targets.push( target );
  542. }
  543. for ( i = 0; i < childs.length; i ++ ) {
  544. var obj3d = childs[ i ];
  545. if ( targets.indexOf( obj3d ) > - 1 ) continue;
  546. obj3d.updateMatrix();
  547. mtx.copy( obj3d.matrix );
  548. mtx.multiplyMatrices( matrix, mtx );
  549. obj3d.position.setFromMatrixPosition( mtx );
  550. obj3d.scale.setFromMatrixScale( mtx );
  551. // ignore rotation scale
  552. mtx.scale( vec.set( 1 / obj3d.scale.x, 1 / obj3d.scale.y, 1 / obj3d.scale.z ) );
  553. obj3d.quaternion.setFromRotationMatrix( mtx );
  554. }
  555. };
  556. //
  557. // Extension
  558. //
  559. SEA3D.Domain.prototype.getShape = SEA3D.prototype.getShape = function ( name ) {
  560. return this.objects[ "shpe/" + name ];
  561. };
  562. SEA3D.Domain.prototype.getRigidBody = SEA3D.prototype.getRigidBody = function ( name ) {
  563. return this.objects[ "rb/" + name ];
  564. };
  565. SEA3D.Domain.prototype.getConstraint = SEA3D.prototype.getConstraint = function ( name ) {
  566. return this.objects[ "ctnt/" + name ];
  567. };
  568. SEA3D.EXTENSIONS_LOADER.push( {
  569. parse: function () {
  570. delete this.shapes;
  571. delete this.rigidBodies;
  572. delete this.vehicles;
  573. delete this.constraints;
  574. },
  575. setTypeRead: function () {
  576. // CONFIG
  577. this.config.physics = this.config.physics !== undefined ? this.config.physics : true;
  578. this.config.convexHull = this.config.convexHull !== undefined ? this.config.convexHull : true;
  579. this.config.enabledPhysics = this.config.enabledPhysics !== undefined ? this.config.enabledPhysics : true;
  580. if ( this.config.physics ) {
  581. // SHAPES
  582. this.file.typeRead[ SEA3DSDK.Sphere.prototype.type ] = this.readSphere;
  583. this.file.typeRead[ SEA3DSDK.Box.prototype.type ] = this.readBox;
  584. this.file.typeRead[ SEA3DSDK.Capsule.prototype.type ] = this.readCapsule;
  585. this.file.typeRead[ SEA3DSDK.Cone.prototype.type ] = this.readCone;
  586. this.file.typeRead[ SEA3DSDK.Cylinder.prototype.type ] = this.readCylinder;
  587. this.file.typeRead[ SEA3DSDK.ConvexGeometry.prototype.type ] = this.readConvexGeometry;
  588. this.file.typeRead[ SEA3DSDK.TriangleGeometry.prototype.type ] = this.readTriangleGeometry;
  589. this.file.typeRead[ SEA3DSDK.Compound.prototype.type ] = this.readCompound;
  590. // CONSTRAINTS
  591. this.file.typeRead[ SEA3DSDK.P2PConstraint.prototype.type ] = this.readP2PConstraint;
  592. this.file.typeRead[ SEA3DSDK.HingeConstraint.prototype.type ] = this.readHingeConstraint;
  593. this.file.typeRead[ SEA3DSDK.ConeTwistConstraint.prototype.type ] = this.readConeTwistConstraint;
  594. // PHYSICS
  595. this.file.typeRead[ SEA3DSDK.RigidBody.prototype.type ] = this.readRigidBody;
  596. this.file.typeRead[ SEA3DSDK.CarController.prototype.type ] = this.readCarController;
  597. }
  598. }
  599. } );
  600. SEA3D.EXTENSIONS_DOMAIN.push( {
  601. dispose: function () {
  602. var i;
  603. i = this.rigidBodies ? this.rigidBodies.length : 0;
  604. while ( i -- ) AMMO.removeRigidBody( this.rigidBodies[ i ], true );
  605. i = this.vehicles ? this.vehicles.length : 0;
  606. while ( i -- ) AMMO.removeVehicle( this.vehicles[ i ], true );
  607. i = this.constraints ? this.constraints.length : 0;
  608. while ( i -- ) AMMO.removeConstraint( this.constraints[ i ], true );
  609. i = this.shapes ? this.shapes.length : 0;
  610. while ( i -- ) Ammo.destroy( this.shapes[ i ] );
  611. }
  612. } );
  613. export { AMMO };