SEA3DAmmoLoader.js 22 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  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( ctrt ) > - 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 vertex = geometry.getAttribute( 'position' ).array;
  156. var indexes = geometry.getIndex().array;
  157. var group = index >= 0 ? geometry.groups[ index ] : undefined,
  158. start = group ? group.start : 0,
  159. count = group ? group.count : indexes.length;
  160. var scale = 1 / this.worldScale;
  161. for ( var idx = start; idx < count; idx += 3 ) {
  162. var vx1 = indexes[ idx ] * 3;
  163. var point = new Ammo.btVector3(
  164. vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale
  165. );
  166. mConvexHull.addPoint( point );
  167. }
  168. return mConvexHull;
  169. },
  170. getTargetByRigidBody: function ( rb ) {
  171. return this.rigidBodiesTarget[ this.rigidBodies.indexOf( rb ) ];
  172. },
  173. getRigidBodyByTarget: function ( target ) {
  174. return this.rigidBodies[ this.rigidBodiesTarget.indexOf( target ) ];
  175. },
  176. getTransformFromMatrix: function ( mtx ) {
  177. var transform = new Ammo.btTransform();
  178. var pos = SEA3D.VECBUF.setFromMatrixPosition( mtx );
  179. transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
  180. var scl = SEA3D.VECBUF.setFromMatrixScale( mtx );
  181. mtx.scale( scl.set( 1 / scl.x, 1 / scl.y, 1 / scl.z ) );
  182. var quat = new Quaternion().setFromRotationMatrix( mtx );
  183. var q = new Ammo.btQuaternion();
  184. q.setValue( quat.x, quat.y, quat.z, quat.w );
  185. transform.setRotation( q );
  186. Ammo.destroy( q );
  187. return transform;
  188. },
  189. getMatrixFromTransform: function ( transform ) {
  190. var position = new Vector3();
  191. var quaternion = new Quaternion();
  192. var scale = new Vector3( 1, 1, 1 );
  193. return function ( transform, matrix ) {
  194. matrix = matrix || new Matrix4();
  195. var pos = transform.getOrigin(),
  196. quat = transform.getRotation();
  197. position.set( pos.x(), pos.y(), pos.z() );
  198. quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
  199. matrix.compose( position, quaternion, scale );
  200. return matrix;
  201. };
  202. }(),
  203. updateTargetTransform: function () {
  204. var matrix = new Matrix4();
  205. var position = new Vector3();
  206. var quaternion = new Quaternion();
  207. var scale = new Vector3( 1, 1, 1 );
  208. return function ( obj3d, transform, offset ) {
  209. var pos = transform.getOrigin(),
  210. quat = transform.getRotation();
  211. if ( offset ) {
  212. position.set( pos.x(), pos.y(), pos.z() );
  213. quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
  214. matrix.compose( position, quaternion, scale );
  215. matrix.multiplyMatrices( matrix, offset );
  216. obj3d.position.setFromMatrixPosition( matrix );
  217. obj3d.quaternion.setFromRotationMatrix( matrix );
  218. } else {
  219. obj3d.position.set( pos.x(), pos.y(), pos.z() );
  220. obj3d.quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
  221. }
  222. return this;
  223. };
  224. }(),
  225. update: function ( delta, iteration, fixedDelta ) {
  226. this.world.stepSimulation( delta, iteration || 0, fixedDelta || ( 60 / 1000 ) );
  227. var i, j;
  228. for ( i = 0; i < this.vehicles.length; i ++ ) {
  229. var vehicle = this.vehicles[ i ],
  230. numWheels = vehicle.getNumWheels(),
  231. wheels = this.vehiclesWheels[ i ];
  232. for ( j = 0; j < numWheels; j ++ ) {
  233. vehicle.updateWheelTransform( j, true );
  234. var wheelsTransform = vehicle.getWheelTransformWS( j ),
  235. wheelTarget = wheels[ j ];
  236. if ( wheelTarget ) {
  237. this.updateTargetTransform( wheelTarget, wheelsTransform, wheelTarget.physics ? wheelTarget.physics.offset : null );
  238. }
  239. }
  240. }
  241. for ( i = 0; i < this.rigidBodies.length; i ++ ) {
  242. var rb = this.rigidBodies[ i ],
  243. target = this.rigidBodiesTarget[ i ];
  244. if ( target && rb.isActive() ) {
  245. this.updateTargetTransform( target, rb.getWorldTransform(), target.physics ? target.physics.offset : null );
  246. }
  247. }
  248. return this;
  249. }
  250. };
  251. //
  252. // Utils
  253. //
  254. SEA3D.prototype.toAmmoVec3 = function ( v ) {
  255. return new Ammo.btVector3( v.x, v.y, v.z );
  256. };
  257. //
  258. // Sphere
  259. //
  260. SEA3D.prototype.readSphere = function ( sea ) {
  261. var shape = new Ammo.btSphereShape( sea.radius );
  262. this.domain.shapes = this.shapes = this.shapes || [];
  263. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  264. };
  265. //
  266. // Box
  267. //
  268. SEA3D.prototype.readBox = function ( sea ) {
  269. var shape = new Ammo.btBoxShape( new Ammo.btVector3( sea.width * .5, sea.height * .5, sea.depth * .5 ) );
  270. this.domain.shapes = this.shapes = this.shapes || [];
  271. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  272. };
  273. //
  274. // Cone
  275. //
  276. SEA3D.prototype.readCone = function ( sea ) {
  277. var shape = new Ammo.btConeShape( sea.radius, sea.height );
  278. this.domain.shapes = this.shapes = this.shapes || [];
  279. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  280. };
  281. //
  282. // Cylinder
  283. //
  284. SEA3D.prototype.readCylinder = function ( sea ) {
  285. var shape = new Ammo.btCylinderShape( new Ammo.btVector3( sea.height, sea.radius, sea.radius ) );
  286. this.domain.shapes = this.shapes = this.shapes || [];
  287. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  288. };
  289. //
  290. // Capsule
  291. //
  292. SEA3D.prototype.readCapsule = function ( sea ) {
  293. var shape = new Ammo.btCapsuleShape( sea.radius, sea.height );
  294. this.domain.shapes = this.shapes = this.shapes || [];
  295. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  296. };
  297. //
  298. // Convex Geometry
  299. //
  300. SEA3D.prototype.readConvexGeometry = function ( sea ) {
  301. if ( this.config.convexHull ) {
  302. var shape = AMMO.createConvexHull( sea.geometry.tag, sea.subGeometryIndex );
  303. } else {
  304. var triMesh = AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
  305. var shape = new Ammo.btConvexTriangleMeshShape( triMesh, true );
  306. }
  307. this.domain.shapes = this.shapes = this.shapes || [];
  308. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  309. };
  310. //
  311. // Triangle Geometry
  312. //
  313. SEA3D.prototype.readTriangleGeometry = function ( sea ) {
  314. var triMesh = AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
  315. var shape = new Ammo.btBvhTriangleMeshShape( triMesh, true, true );
  316. this.domain.shapes = this.shapes = this.shapes || [];
  317. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  318. };
  319. //
  320. // Compound
  321. //
  322. SEA3D.prototype.readCompound = function ( sea ) {
  323. var shape = new Ammo.btCompoundShape();
  324. for ( var i = 0; i < sea.compounds.length; i ++ ) {
  325. var compound = sea.compounds[ i ];
  326. SEA3D.MTXBUF.elements = compound.transform;
  327. var transform = AMMO.getTransformFromMatrix( SEA3D.MTXBUF );
  328. shape.addChildShape( transform, compound.shape.tag );
  329. }
  330. this.domain.shapes = this.shapes = this.shapes || [];
  331. this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
  332. };
  333. //
  334. // Rigid Body Base
  335. //
  336. SEA3D.prototype.readRigidBodyBase = function ( sea ) {
  337. var shape = sea.shape.tag,
  338. transform, target;
  339. if ( sea.target ) {
  340. target = sea.target.tag;
  341. target.physics = { enabled: true };
  342. target.updateMatrix();
  343. transform = AMMO.getTransformFromMatrix( sea.target.tag.matrix );
  344. } else {
  345. SEA3D.MTXBUF.fromArray( sea.transform );
  346. transform = AMMO.getTransformFromMatrix( SEA3D.MTXBUF );
  347. }
  348. var motionState = new Ammo.btDefaultMotionState( transform );
  349. var localInertia = new Ammo.btVector3( 0, 0, 0 );
  350. shape.calculateLocalInertia( sea.mass, localInertia );
  351. var info = new Ammo.btRigidBodyConstructionInfo( sea.mass, motionState, shape, localInertia );
  352. info.set_m_friction( sea.friction );
  353. info.set_m_restitution( sea.restitution );
  354. info.set_m_linearDamping( sea.linearDamping );
  355. info.set_m_angularDamping( sea.angularDamping );
  356. var rb = new Ammo.btRigidBody( info );
  357. if ( target ) {
  358. target.physics.rigidBody = rb;
  359. if ( sea.offset ) {
  360. var offset = new Matrix4();
  361. offset.fromArray( sea.offset );
  362. target.physics.offset = offset;
  363. }
  364. }
  365. Ammo.destroy( info );
  366. this.domain.rigidBodies = this.rigidBodies = this.rigidBodies || [];
  367. this.rigidBodies.push( this.objects[ "rb/" + sea.name ] = sea.tag = rb );
  368. return rb;
  369. };
  370. //
  371. // Rigid Body
  372. //
  373. SEA3D.prototype.readRigidBody = function ( sea ) {
  374. var rb = this.readRigidBodyBase( sea );
  375. AMMO.addRigidBody( rb, sea.target ? sea.target.tag : undefined, this.config.enabledPhysics );
  376. };
  377. //
  378. // Car Controller
  379. //
  380. SEA3D.prototype.readCarController = function ( sea ) {
  381. var body = this.readRigidBodyBase( sea );
  382. body.setActivationState( AMMO.DISABLE_DEACTIVATION );
  383. // Car
  384. var vehicleRayCaster = new Ammo.btDefaultVehicleRaycaster( AMMO.world );
  385. var tuning = new Ammo.btVehicleTuning();
  386. tuning.set_m_suspensionStiffness( sea.suspensionStiffness );
  387. tuning.set_m_suspensionDamping( sea.suspensionDamping );
  388. tuning.set_m_suspensionCompression( sea.suspensionCompression );
  389. tuning.set_m_maxSuspensionTravelCm( sea.maxSuspensionTravelCm );
  390. tuning.set_m_maxSuspensionForce( sea.maxSuspensionForce );
  391. tuning.set_m_frictionSlip( sea.frictionSlip );
  392. var vehicle = new Ammo.btRaycastVehicle( tuning, body, vehicleRayCaster ),
  393. wheels = [];
  394. vehicle.setCoordinateSystem( 0, 1, 2 );
  395. for ( var i = 0; i < sea.wheel.length; i ++ ) {
  396. var wheel = sea.wheel[ i ];
  397. var wheelInfo = vehicle.addWheel(
  398. this.toAmmoVec3( wheel.pos ),
  399. this.toAmmoVec3( wheel.dir ),
  400. this.toAmmoVec3( wheel.axle ),
  401. wheel.suspensionRestLength,
  402. wheel.radius,
  403. tuning,
  404. wheel.isFront
  405. );
  406. var target = wheels[ i ] = wheel.target ? wheel.target.tag : undefined;
  407. if ( target ) {
  408. target.physics = { enabled: true, rigidBody: wheelInfo };
  409. if ( wheel.offset ) {
  410. var offset = new Matrix4();
  411. offset.fromArray( wheel.offset );
  412. target.physics.offset = offset;
  413. }
  414. if ( target.parent ) {
  415. target.parent.remove( target );
  416. }
  417. if ( this.container ) {
  418. this.container.add( target );
  419. }
  420. }
  421. wheelInfo.set_m_suspensionStiffness( sea.suspensionStiffness );
  422. wheelInfo.set_m_wheelsDampingRelaxation( sea.dampingRelaxation );
  423. wheelInfo.set_m_wheelsDampingCompression( sea.dampingCompression );
  424. wheelInfo.set_m_frictionSlip( sea.frictionSlip );
  425. }
  426. AMMO.addVehicle( vehicle, wheels );
  427. AMMO.addRigidBody( body, sea.target ? sea.target.tag : undefined, this.config.enabledPhysics );
  428. this.domain.vehicles = this.vehicles = this.vehicles || [];
  429. this.vehicles.push( this.objects[ "vhc/" + sea.name ] = sea.tag = vehicle );
  430. };
  431. //
  432. // P2P Constraint
  433. //
  434. SEA3D.prototype.readP2PConstraint = function ( sea ) {
  435. var ctrt;
  436. if ( sea.targetB ) {
  437. ctrt = new Ammo.btPoint2PointConstraint(
  438. sea.targetA.tag,
  439. sea.targetB.tag,
  440. this.toAmmoVec3( sea.pointA ),
  441. this.toAmmoVec3( sea.pointB )
  442. );
  443. } else {
  444. ctrt = new Ammo.btPoint2PointConstraint(
  445. sea.targetA.tag,
  446. this.toAmmoVec3( sea.pointA )
  447. );
  448. }
  449. AMMO.addConstraint( ctrt );
  450. this.domain.constraints = this.constraints = this.constraints || [];
  451. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  452. };
  453. //
  454. // Hinge Constraint
  455. //
  456. SEA3D.prototype.readHingeConstraint = function ( sea ) {
  457. var ctrt;
  458. if ( sea.targetB ) {
  459. ctrt = new Ammo.btHingeConstraint(
  460. sea.targetA.tag,
  461. sea.targetB.tag,
  462. this.toAmmoVec3( sea.pointA ),
  463. this.toAmmoVec3( sea.pointB ),
  464. this.toAmmoVec3( sea.axisA ),
  465. this.toAmmoVec3( sea.axisB ),
  466. false
  467. );
  468. } else {
  469. ctrt = new Ammo.btHingeConstraint(
  470. sea.targetA.tag,
  471. this.toAmmoVec3( sea.pointA ),
  472. this.toAmmoVec3( sea.axisA ),
  473. false
  474. );
  475. }
  476. if ( sea.limit ) {
  477. ctrt.setLimit( sea.limit.low, sea.limit.high, sea.limit.softness, sea.limit.biasFactor, sea.limit.relaxationFactor );
  478. }
  479. if ( sea.angularMotor ) {
  480. ctrt.enableAngularMotor( true, sea.angularMotor.velocity, sea.angularMotor.impulse );
  481. }
  482. AMMO.addConstraint( ctrt );
  483. this.domain.constraints = this.constraints = this.constraints || [];
  484. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  485. };
  486. //
  487. // Cone Twist Constraint
  488. //
  489. SEA3D.prototype.readConeTwistConstraint = function ( sea ) {
  490. var ctrt;
  491. if ( sea.targetB ) {
  492. ctrt = new Ammo.btConeTwistConstraint(
  493. sea.targetA.tag,
  494. sea.targetB.tag,
  495. this.toAmmoVec3( sea.pointA ),
  496. this.toAmmoVec3( sea.pointB ),
  497. false
  498. );
  499. } else {
  500. ctrt = new Ammo.btConeTwistConstraint(
  501. sea.targetA.tag,
  502. this.toAmmoVec3( sea.pointA ),
  503. false
  504. );
  505. }
  506. AMMO.addConstraint( ctrt );
  507. this.domain.constraints = this.constraints = this.constraints || [];
  508. this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
  509. };
  510. //
  511. // Domain
  512. //
  513. SEA3D.Domain.prototype.enabledPhysics = function ( enabled ) {
  514. var i = this.rigidBodies ? this.rigidBodies.length : 0;
  515. while ( i -- ) {
  516. AMMO.setEnabledRigidBody( this.rigidBodies[ i ], enabled );
  517. }
  518. };
  519. SEA3D.Domain.prototype.applyContainerTransform = function () {
  520. this.container.updateMatrix();
  521. var matrix = this.container.matrix.clone();
  522. this.container.position.set( 0, 0, 0 );
  523. this.container.quaternion.set( 0, 0, 0, 1 );
  524. this.container.scale.set( 1, 1, 1 );
  525. this.applyTransform( matrix );
  526. };
  527. SEA3D.Domain.prototype.applyTransform = function ( matrix ) {
  528. var mtx = SEA3D.MTXBUF, vec = SEA3D.VECBUF;
  529. var i = this.rigidBodies ? this.rigidBodies.length : 0,
  530. childs = this.container ? this.container.children : [],
  531. targets = [];
  532. while ( i -- ) {
  533. var rb = this.rigidBodies[ i ],
  534. target = AMMO.getTargetByRigidBody( rb ),
  535. transform = rb.getWorldTransform(),
  536. transformMatrix = AMMO.getMatrixFromTransform( transform );
  537. transformMatrix.multiplyMatrices( transformMatrix, matrix );
  538. transform = AMMO.getTransformFromMatrix( transformMatrix );
  539. rb.setWorldTransform( transform );
  540. if ( target ) targets.push( target );
  541. }
  542. for ( i = 0; i < childs.length; i ++ ) {
  543. var obj3d = childs[ i ];
  544. if ( targets.indexOf( obj3d ) > - 1 ) continue;
  545. obj3d.updateMatrix();
  546. mtx.copy( obj3d.matrix );
  547. mtx.multiplyMatrices( matrix, mtx );
  548. obj3d.position.setFromMatrixPosition( mtx );
  549. obj3d.scale.setFromMatrixScale( mtx );
  550. // ignore rotation scale
  551. mtx.scale( vec.set( 1 / obj3d.scale.x, 1 / obj3d.scale.y, 1 / obj3d.scale.z ) );
  552. obj3d.quaternion.setFromRotationMatrix( mtx );
  553. }
  554. };
  555. //
  556. // Extension
  557. //
  558. SEA3D.Domain.prototype.getShape = SEA3D.prototype.getShape = function ( name ) {
  559. return this.objects[ "shpe/" + name ];
  560. };
  561. SEA3D.Domain.prototype.getRigidBody = SEA3D.prototype.getRigidBody = function ( name ) {
  562. return this.objects[ "rb/" + name ];
  563. };
  564. SEA3D.Domain.prototype.getConstraint = SEA3D.prototype.getConstraint = function ( name ) {
  565. return this.objects[ "ctnt/" + name ];
  566. };
  567. SEA3D.EXTENSIONS_LOADER.push( {
  568. parse: function () {
  569. delete this.shapes;
  570. delete this.rigidBodies;
  571. delete this.vehicles;
  572. delete this.constraints;
  573. },
  574. setTypeRead: function () {
  575. // CONFIG
  576. this.config.physics = this.config.physics !== undefined ? this.config.physics : true;
  577. this.config.convexHull = this.config.convexHull !== undefined ? this.config.convexHull : true;
  578. this.config.enabledPhysics = this.config.enabledPhysics !== undefined ? this.config.enabledPhysics : true;
  579. if ( this.config.physics ) {
  580. // SHAPES
  581. this.file.typeRead[ SEA3DSDK.Sphere.prototype.type ] = this.readSphere;
  582. this.file.typeRead[ SEA3DSDK.Box.prototype.type ] = this.readBox;
  583. this.file.typeRead[ SEA3DSDK.Capsule.prototype.type ] = this.readCapsule;
  584. this.file.typeRead[ SEA3DSDK.Cone.prototype.type ] = this.readCone;
  585. this.file.typeRead[ SEA3DSDK.Cylinder.prototype.type ] = this.readCylinder;
  586. this.file.typeRead[ SEA3DSDK.ConvexGeometry.prototype.type ] = this.readConvexGeometry;
  587. this.file.typeRead[ SEA3DSDK.TriangleGeometry.prototype.type ] = this.readTriangleGeometry;
  588. this.file.typeRead[ SEA3DSDK.Compound.prototype.type ] = this.readCompound;
  589. // CONSTRAINTS
  590. this.file.typeRead[ SEA3DSDK.P2PConstraint.prototype.type ] = this.readP2PConstraint;
  591. this.file.typeRead[ SEA3DSDK.HingeConstraint.prototype.type ] = this.readHingeConstraint;
  592. this.file.typeRead[ SEA3DSDK.ConeTwistConstraint.prototype.type ] = this.readConeTwistConstraint;
  593. // PHYSICS
  594. this.file.typeRead[ SEA3DSDK.RigidBody.prototype.type ] = this.readRigidBody;
  595. this.file.typeRead[ SEA3DSDK.CarController.prototype.type ] = this.readCarController;
  596. }
  597. }
  598. } );
  599. SEA3D.EXTENSIONS_DOMAIN.push( {
  600. dispose: function () {
  601. var i;
  602. i = this.rigidBodies ? this.rigidBodies.length : 0;
  603. while ( i -- ) AMMO.removeRigidBody( this.rigidBodies[ i ], true );
  604. i = this.vehicles ? this.vehicles.length : 0;
  605. while ( i -- ) AMMO.removeVehicle( this.vehicles[ i ], true );
  606. i = this.constraints ? this.constraints.length : 0;
  607. while ( i -- ) AMMO.removeConstraint( this.constraints[ i ], true );
  608. i = this.shapes ? this.shapes.length : 0;
  609. while ( i -- ) Ammo.destroy( this.shapes[ i ] );
  610. }
  611. } );
  612. export { AMMO };