Spaces:
Running
Running
| /** _ _ _ _____ __ _______ ______ | |
| * | |___| |_| |__ /__ | | | | _ | * * | |
| * | / _ \ _| | __\ | | \ | _ | U _ | |
| * |_\___/\__|_||_| _ |____/____ |__ \_|_ |_|_____| | |
| * | |
| * @author LoTh / http://3dflashlo.wordpress.com/ | |
| * @author SUNAG / http://www.sunag.com.br/ | |
| * @author Ammo.lab / https://github.com/lo-th/Ammo.lab/ | |
| */ | |
| ; | |
| SEA3D.AMMO = { | |
| world: null, | |
| rigidBodies: [], | |
| rigidBodiesTarget: [], | |
| rigidBodiesEnabled: [], | |
| constraints: [], | |
| vehicles: [], | |
| vehiclesWheels: [], | |
| ACTIVE: 1, | |
| ISLAND_SLEEPING: 2, | |
| WANTS_DEACTIVATION: 3, | |
| DISABLE_DEACTIVATION: 4, | |
| DISABLE_SIMULATION: 5, | |
| VERSION: 0.8, | |
| init: function ( gravity, worldScale, broadphase ) { | |
| gravity = gravity !== undefined ? gravity : - 90.8; | |
| this.worldScale = worldScale == undefined ? 1 : worldScale; | |
| this.broadphase = broadphase == undefined ? 'bvt' : broadphase; | |
| this.solver = new Ammo.btSequentialImpulseConstraintSolver(); | |
| this.collisionConfig = new Ammo.btDefaultCollisionConfiguration(); | |
| this.dispatcher = new Ammo.btCollisionDispatcher( this.collisionConfig ); | |
| switch ( this.broadphase ) { | |
| case 'bvt': | |
| this.broadphase = new Ammo.btDbvtBroadphase(); | |
| break; | |
| case 'sap': | |
| this.broadphase = new Ammo.btAxisSweep3( | |
| new Ammo.btVector3( - this.worldScale, - this.worldScale, - this.worldScale ), | |
| new Ammo.btVector3( this.worldScale, this.worldScale, this.worldScale ), | |
| 4096 | |
| ); | |
| break; | |
| case 'simple': | |
| this.broadphase = new Ammo.btSimpleBroadphase(); | |
| break; | |
| } | |
| this.world = new Ammo.btDiscreteDynamicsWorld( this.dispatcher, this.broadphase, this.solver, this.collisionConfig ); | |
| this.setGravity( gravity ); | |
| console.log( "THREE.AMMO " + this.VERSION ); | |
| }, | |
| setGravity: function ( gravity ) { | |
| this.gravity = gravity; | |
| this.world.setGravity( new Ammo.btVector3( 0, gravity, 0 ) ); | |
| return this; | |
| }, | |
| getGravity: function () { | |
| return this.gravity; | |
| }, | |
| setEnabledRigidBody: function ( rb, enabled ) { | |
| var index = this.rigidBodies.indexOf( rb ); | |
| if ( this.rigidBodiesEnabled[ index ] == enabled ) return; | |
| if ( enabled ) this.world.addRigidBody( rb ); | |
| else this.world.removeRigidBody( rb ); | |
| this.rigidBodiesEnabled[ index ] = true; | |
| return this; | |
| }, | |
| getEnabledRigidBody: function ( rb ) { | |
| return this.rigidBodiesEnabled[ this.rigidBodies.indexOf( rb ) ]; | |
| }, | |
| addRigidBody: function ( rb, target, enabled ) { | |
| enabled = enabled !== undefined ? enabled : true; | |
| this.rigidBodies.push( rb ); | |
| this.rigidBodiesTarget.push( target ); | |
| this.rigidBodiesEnabled.push( false ); | |
| this.setEnabledRigidBody( rb, enabled ); | |
| return this; | |
| }, | |
| removeRigidBody: function ( rb, destroy ) { | |
| var index = this.rigidBodies.indexOf( rb ); | |
| this.setEnabledRigidBody( rb, false ); | |
| this.rigidBodies.splice( index, 1 ); | |
| this.rigidBodiesTarget.splice( index, 1 ); | |
| this.rigidBodiesEnabled.splice( index, 1 ); | |
| if ( destroy ) Ammo.destroy( rb ); | |
| return this; | |
| }, | |
| containsRigidBody: function ( rb ) { | |
| return this.rigidBodies.indexOf( rb ) > - 1; | |
| }, | |
| addConstraint: function ( ctrt, disableCollisionsBetweenBodies ) { | |
| disableCollisionsBetweenBodies = disableCollisionsBetweenBodies == undefined ? true : disableCollisionsBetweenBodies; | |
| this.constraints.push( ctrt ); | |
| this.world.addConstraint( ctrt, disableCollisionsBetweenBodies ); | |
| return this; | |
| }, | |
| removeConstraint: function ( ctrt, destroy ) { | |
| this.constraints.splice( this.constraints.indexOf( ctrt ), 1 ); | |
| this.world.removeConstraint( ctrt ); | |
| if ( destroy ) Ammo.destroy( ctrt ); | |
| return this; | |
| }, | |
| containsConstraint: function ( ctrt ) { | |
| return this.constraints.indexOf( rb ) > - 1; | |
| }, | |
| addVehicle: function ( vehicle, wheels ) { | |
| this.vehicles.push( vehicle ); | |
| this.vehiclesWheels.push( wheels != undefined ? wheels : [] ); | |
| this.world.addAction( vehicle ); | |
| return this; | |
| }, | |
| removeVehicle: function ( vehicle, destroy ) { | |
| var index = this.vehicles.indexOf( vehicle ); | |
| this.vehicles.splice( index, 1 ); | |
| this.vehiclesWheels.splice( index, 1 ); | |
| this.world.removeAction( vehicle ); | |
| if ( destroy ) Ammo.destroy( vehicle ); | |
| return this; | |
| }, | |
| containsVehicle: function ( vehicle ) { | |
| return this.vehicles.indexOf( vehicle ) > - 1; | |
| }, | |
| createTriangleMesh: function ( geometry, index, removeDuplicateVertices ) { | |
| index = index == undefined ? - 1 : index; | |
| removeDuplicateVertices = removeDuplicateVertices == undefined ? false : removeDuplicateVertices; | |
| var mTriMesh = new Ammo.btTriangleMesh(); | |
| var v0 = new Ammo.btVector3( 0, 0, 0 ); | |
| var v1 = new Ammo.btVector3( 0, 0, 0 ); | |
| var v2 = new Ammo.btVector3( 0, 0, 0 ); | |
| var vertex = geometry.getAttribute( 'position' ).array; | |
| var indexes = geometry.getIndex().array; | |
| var group = index >= 0 ? geometry.groups[ index ] : undefined, | |
| start = group ? group.start : 0, | |
| count = group ? group.count : indexes.length; | |
| var scale = 1 / this.worldScale; | |
| for ( var idx = start; idx < count; idx += 3 ) { | |
| var vx1 = indexes[ idx ] * 3, | |
| vx2 = indexes[ idx + 1 ] * 3, | |
| vx3 = indexes[ idx + 2 ] * 3; | |
| v0.setValue( vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale ); | |
| v1.setValue( vertex[ vx2 ] * scale, vertex[ vx2 + 1 ] * scale, vertex[ vx2 + 2 ] * scale ); | |
| v2.setValue( vertex[ vx3 ] * scale, vertex[ vx3 + 1 ] * scale, vertex[ vx3 + 2 ] * scale ); | |
| mTriMesh.addTriangle( v0, v1, v2, removeDuplicateVertices ); | |
| } | |
| return mTriMesh; | |
| }, | |
| createConvexHull: function ( geometry, index ) { | |
| index = index == undefined ? - 1 : index; | |
| var mConvexHull = new Ammo.btConvexHullShape(); | |
| var v0 = new Ammo.btVector3( 0, 0, 0 ); | |
| var vertex = geometry.getAttribute( 'position' ).array; | |
| var indexes = geometry.getIndex().array; | |
| var group = index >= 0 ? geometry.groups[ index ] : undefined, | |
| start = group ? group.start : 0, | |
| count = group ? group.count : indexes.length; | |
| var scale = 1 / this.worldScale; | |
| for ( var idx = start; idx < count; idx += 3 ) { | |
| var vx1 = indexes[ idx ] * 3; | |
| var point = new Ammo.btVector3( | |
| vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale | |
| ); | |
| mConvexHull.addPoint( point ); | |
| } | |
| return mConvexHull; | |
| }, | |
| getTargetByRigidBody: function ( rb ) { | |
| return this.rigidBodiesTarget[ this.rigidBodies.indexOf( rb ) ]; | |
| }, | |
| getRigidBodyByTarget: function ( target ) { | |
| return this.rigidBodies[ this.rigidBodiesTarget.indexOf( target ) ]; | |
| }, | |
| getTransformFromMatrix: function ( mtx ) { | |
| var transform = new Ammo.btTransform(); | |
| var pos = THREE.SEA3D.VECBUF.setFromMatrixPosition( mtx ); | |
| transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) ); | |
| var scl = THREE.SEA3D.VECBUF.setFromMatrixScale( mtx ); | |
| mtx.scale( scl.set( 1 / scl.x, 1 / scl.y, 1 / scl.z ) ); | |
| var quat = new THREE.Quaternion().setFromRotationMatrix( mtx ); | |
| var q = new Ammo.btQuaternion(); | |
| q.setValue( quat.x, quat.y, quat.z, quat.w ); | |
| transform.setRotation( q ); | |
| Ammo.destroy( q ); | |
| return transform; | |
| }, | |
| getMatrixFromTransform: function ( transform ) { | |
| var position = new THREE.Vector3(); | |
| var quaternion = new THREE.Quaternion(); | |
| var scale = new THREE.Vector3( 1, 1, 1 ); | |
| return function ( transform, matrix ) { | |
| matrix = matrix || new THREE.Matrix4(); | |
| var pos = transform.getOrigin(), | |
| quat = transform.getRotation(); | |
| position.set( pos.x(), pos.y(), pos.z() ); | |
| quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() ); | |
| matrix.compose( position, quaternion, scale ); | |
| return matrix; | |
| }; | |
| }(), | |
| updateTargetTransform: function () { | |
| var matrix = new THREE.Matrix4(); | |
| var position = new THREE.Vector3(); | |
| var quaternion = new THREE.Quaternion(); | |
| var scale = new THREE.Vector3( 1, 1, 1 ); | |
| return function ( obj3d, transform, offset ) { | |
| var pos = transform.getOrigin(), | |
| quat = transform.getRotation(); | |
| if ( offset ) { | |
| position.set( pos.x(), pos.y(), pos.z() ); | |
| quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() ); | |
| matrix.compose( position, quaternion, scale ); | |
| matrix.multiplyMatrices( matrix, offset ); | |
| obj3d.position.setFromMatrixPosition( matrix ); | |
| obj3d.quaternion.setFromRotationMatrix( matrix ); | |
| } else { | |
| obj3d.position.set( pos.x(), pos.y(), pos.z() ); | |
| obj3d.quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() ); | |
| } | |
| return this; | |
| }; | |
| }(), | |
| update: function ( delta, iteration, fixedDelta ) { | |
| this.world.stepSimulation( delta, iteration || 0, fixedDelta || ( 60 / 1000 ) ); | |
| var i, j; | |
| for ( i = 0; i < this.vehicles.length; i ++ ) { | |
| var vehicle = this.vehicles[ i ], | |
| numWheels = vehicle.getNumWheels(), | |
| wheels = this.vehiclesWheels[ i ]; | |
| for ( j = 0; j < numWheels; j ++ ) { | |
| vehicle.updateWheelTransform( j, true ); | |
| var wheelsTransform = vehicle.getWheelTransformWS( j ), | |
| wheelTarget = wheels[ j ]; | |
| if ( wheelTarget ) { | |
| this.updateTargetTransform( wheelTarget, wheelsTransform, wheelTarget.physics ? wheelTarget.physics.offset : null ); | |
| } | |
| } | |
| } | |
| for ( i = 0; i < this.rigidBodies.length; i ++ ) { | |
| var rb = this.rigidBodies[ i ], | |
| target = this.rigidBodiesTarget[ i ]; | |
| if ( target && rb.isActive() ) { | |
| this.updateTargetTransform( target, rb.getWorldTransform(), target.physics ? target.physics.offset : null ); | |
| } | |
| } | |
| return this; | |
| } | |
| }; | |