summaryrefslogtreecommitdiff
path: root/physi_js/physijs_worker.js
diff options
context:
space:
mode:
Diffstat (limited to 'physi_js/physijs_worker.js')
-rw-r--r--physi_js/physijs_worker.js1415
1 files changed, 1415 insertions, 0 deletions
diff --git a/physi_js/physijs_worker.js b/physi_js/physijs_worker.js
new file mode 100644
index 0000000..a6c3811
--- /dev/null
+++ b/physi_js/physijs_worker.js
@@ -0,0 +1,1415 @@
+'use strict';
+var
+ transferableMessage = self.webkitPostMessage || self.postMessage,
+
+ // enum
+ MESSAGE_TYPES = {
+ WORLDREPORT: 0,
+ COLLISIONREPORT: 1,
+ VEHICLEREPORT: 2,
+ CONSTRAINTREPORT: 3
+ },
+
+ // temp variables
+ _object,
+ _vector,
+ _transform,
+
+ // functions
+ public_functions = {},
+ getShapeFromCache,
+ setShapeCache,
+ createShape,
+ reportWorld,
+ reportVehicles,
+ reportCollisions,
+ reportConstraints,
+
+ // world variables
+ fixedTimeStep, // used when calling stepSimulation
+ rateLimit, // sets whether or not to sync the simulation rate with fixedTimeStep
+ last_simulation_time,
+ last_simulation_duration = 0,
+ world,
+ transform,
+ _vec3_1,
+ _vec3_2,
+ _vec3_3,
+ _quat,
+ // private cache
+ _objects = {},
+ _vehicles = {},
+ _constraints = {},
+ _materials = {},
+ _objects_ammo = {},
+ _num_objects = 0,
+ _num_wheels = 0,
+ _num_constraints = 0,
+ _object_shapes = {},
+
+ // The following objects are to track objects that ammo.js doesn't clean
+ // up. All are cleaned up when they're corresponding body is destroyed.
+ // Unfortunately, it's very difficult to get at these objects from the
+ // body, so we have to track them ourselves.
+ _motion_states = {},
+ // Don't need to worry about it for cached shapes.
+ _noncached_shapes = {},
+ // A body with a compound shape always has a regular shape as well, so we
+ // have track them separately.
+ _compound_shapes = {},
+
+ // object reporting
+ REPORT_CHUNKSIZE, // report array is increased in increments of this chunk size
+
+ WORLDREPORT_ITEMSIZE = 14, // how many float values each reported item needs
+ worldreport,
+
+ COLLISIONREPORT_ITEMSIZE = 5, // one float for each object id, and a Vec3 contact normal
+ collisionreport,
+
+ VEHICLEREPORT_ITEMSIZE = 9, // vehicle id, wheel index, 3 for position, 4 for rotation
+ vehiclereport,
+
+ CONSTRAINTREPORT_ITEMSIZE = 6, // constraint id, offset object, offset, applied impulse
+ constraintreport;
+
+var ab = new ArrayBuffer( 1 );
+
+transferableMessage( ab, [ab] );
+var SUPPORT_TRANSFERABLE = ( ab.byteLength === 0 );
+
+getShapeFromCache = function ( cache_key ) {
+ if ( _object_shapes[ cache_key ] !== undefined ) {
+ return _object_shapes[ cache_key ];
+ }
+ return null;
+};
+
+setShapeCache = function ( cache_key, shape ) {
+ _object_shapes[ cache_key ] = shape;
+}
+
+createShape = function( description ) {
+ var cache_key, shape;
+
+ _transform.setIdentity();
+ switch ( description.type ) {
+ case 'plane':
+ cache_key = 'plane_' + description.normal.x + '_' + description.normal.y + '_' + description.normal.z;
+ if ( ( shape = getShapeFromCache( cache_key ) ) === null ) {
+ _vec3_1.setX(description.normal.x);
+ _vec3_1.setY(description.normal.y);
+ _vec3_1.setZ(description.normal.z);
+ shape = new Ammo.btStaticPlaneShape(_vec3_1, 0 );
+ setShapeCache( cache_key, shape );
+ }
+ break;
+
+ case 'box':
+ cache_key = 'box_' + description.width + '_' + description.height + '_' + description.depth;
+ if ( ( shape = getShapeFromCache( cache_key ) ) === null ) {
+ _vec3_1.setX(description.width / 2);
+ _vec3_1.setY(description.height / 2);
+ _vec3_1.setZ(description.depth / 2);
+ shape = new Ammo.btBoxShape(_vec3_1);
+ setShapeCache( cache_key, shape );
+ }
+ break;
+
+ case 'sphere':
+ cache_key = 'sphere_' + description.radius;
+ if ( ( shape = getShapeFromCache( cache_key ) ) === null ) {
+ shape = new Ammo.btSphereShape( description.radius );
+ setShapeCache( cache_key, shape );
+ }
+ break;
+
+ case 'cylinder':
+ cache_key = 'cylinder_' + description.width + '_' + description.height + '_' + description.depth;
+ if ( ( shape = getShapeFromCache( cache_key ) ) === null ) {
+ _vec3_1.setX(description.width / 2);
+ _vec3_1.setY(description.height / 2);
+ _vec3_1.setZ(description.depth / 2);
+ shape = new Ammo.btCylinderShape(_vec3_1);
+ setShapeCache( cache_key, shape );
+ }
+ break;
+
+ case 'capsule':
+ cache_key = 'capsule_' + description.radius + '_' + description.height;
+ if ( ( shape = getShapeFromCache( cache_key ) ) === null ) {
+ // In Bullet, capsule height excludes the end spheres
+ shape = new Ammo.btCapsuleShape( description.radius, description.height - 2 * description.radius );
+ setShapeCache( cache_key, shape );
+ }
+ break;
+
+ case 'cone':
+ cache_key = 'cone_' + description.radius + '_' + description.height;
+ if ( ( shape = getShapeFromCache( cache_key ) ) === null ) {
+ shape = new Ammo.btConeShape( description.radius, description.height );
+ setShapeCache( cache_key, shape );
+ }
+ break;
+
+ case 'concave':
+ var i, triangle, triangle_mesh = new Ammo.btTriangleMesh;
+ if (!description.triangles.length) return false
+
+ for ( i = 0; i < description.triangles.length; i++ ) {
+ triangle = description.triangles[i];
+
+ _vec3_1.setX(triangle[0].x);
+ _vec3_1.setY(triangle[0].y);
+ _vec3_1.setZ(triangle[0].z);
+
+ _vec3_2.setX(triangle[1].x);
+ _vec3_2.setY(triangle[1].y);
+ _vec3_2.setZ(triangle[1].z);
+
+ _vec3_3.setX(triangle[2].x);
+ _vec3_3.setY(triangle[2].y);
+ _vec3_3.setZ(triangle[2].z);
+
+ triangle_mesh.addTriangle(
+ _vec3_1,
+ _vec3_2,
+ _vec3_3,
+ true
+ );
+ }
+
+ shape = new Ammo.btBvhTriangleMeshShape(
+ triangle_mesh,
+ true,
+ true
+ );
+ _noncached_shapes[description.id] = shape;
+ break;
+
+ case 'convex':
+ var i, point, shape = new Ammo.btConvexHullShape;
+ for ( i = 0; i < description.points.length; i++ ) {
+ point = description.points[i];
+
+ _vec3_1.setX(point.x);
+ _vec3_1.setY(point.y);
+ _vec3_1.setZ(point.z);
+
+ shape.addPoint(_vec3_1);
+
+ }
+ _noncached_shapes[description.id] = shape;
+ break;
+
+ case 'heightfield':
+
+ var ptr = Ammo.allocate(4 * description.xpts * description.ypts, "float", Ammo.ALLOC_NORMAL);
+
+ for (var f = 0; f < description.points.length; f++) {
+ Ammo.setValue(ptr + f, description.points[f] , 'float');
+ }
+
+ shape = new Ammo.btHeightfieldTerrainShape(
+ description.xpts,
+ description.ypts,
+ ptr,
+ 1,
+ -description.absMaxHeight,
+ description.absMaxHeight,
+ 2,
+ 0,
+ false
+ );
+
+ _vec3_1.setX(description.xsize/(description.xpts - 1));
+ _vec3_1.setY(description.ysize/(description.ypts - 1));
+ _vec3_1.setZ(1);
+
+ shape.setLocalScaling(_vec3_1);
+ _noncached_shapes[description.id] = shape;
+ break;
+
+ default:
+ // Not recognized
+ return;
+ break;
+ }
+
+ return shape;
+};
+
+public_functions.init = function( params ) {
+ importScripts( params.ammo );
+
+ _transform = new Ammo.btTransform;
+ _vec3_1 = new Ammo.btVector3(0,0,0);
+ _vec3_2 = new Ammo.btVector3(0,0,0);
+ _vec3_3 = new Ammo.btVector3(0,0,0);
+ _quat = new Ammo.btQuaternion(0,0,0,0);
+
+ REPORT_CHUNKSIZE = params.reportsize || 50;
+ if ( SUPPORT_TRANSFERABLE ) {
+ // Transferable messages are supported, take advantage of them with TypedArrays
+ worldreport = new Float32Array(2 + REPORT_CHUNKSIZE * WORLDREPORT_ITEMSIZE); // message id + # of objects to report + chunk size * # of values per object
+ collisionreport = new Float32Array(2 + REPORT_CHUNKSIZE * COLLISIONREPORT_ITEMSIZE); // message id + # of collisions to report + chunk size * # of values per object
+ vehiclereport = new Float32Array(2 + REPORT_CHUNKSIZE * VEHICLEREPORT_ITEMSIZE); // message id + # of vehicles to report + chunk size * # of values per object
+ constraintreport = new Float32Array(2 + REPORT_CHUNKSIZE * CONSTRAINTREPORT_ITEMSIZE); // message id + # of constraints to report + chunk size * # of values per object
+ } else {
+ // Transferable messages are not supported, send data as normal arrays
+ worldreport = [];
+ collisionreport = [];
+ vehiclereport = [];
+ constraintreport = [];
+ }
+ worldreport[0] = MESSAGE_TYPES.WORLDREPORT;
+ collisionreport[0] = MESSAGE_TYPES.COLLISIONREPORT;
+ vehiclereport[0] = MESSAGE_TYPES.VEHICLEREPORT;
+ constraintreport[0] = MESSAGE_TYPES.CONSTRAINTREPORT;
+
+ var collisionConfiguration = new Ammo.btDefaultCollisionConfiguration,
+ dispatcher = new Ammo.btCollisionDispatcher( collisionConfiguration ),
+ solver = new Ammo.btSequentialImpulseConstraintSolver,
+ broadphase;
+
+ if ( !params.broadphase ) params.broadphase = { type: 'dynamic' };
+ switch ( params.broadphase.type ) {
+ case 'sweepprune':
+
+ _vec3_1.setX(params.broadphase.aabbmin.x);
+ _vec3_1.setY(params.broadphase.aabbmin.y);
+ _vec3_1.setZ(params.broadphase.aabbmin.z);
+
+ _vec3_2.setX(params.broadphase.aabbmax.x);
+ _vec3_2.setY(params.broadphase.aabbmax.y);
+ _vec3_2.setZ(params.broadphase.aabbmax.z);
+
+ broadphase = new Ammo.btAxisSweep3(
+ _vec3_1,
+ _vec3_2
+ );
+
+ break;
+
+ case 'dynamic':
+ default:
+ broadphase = new Ammo.btDbvtBroadphase;
+ break;
+ }
+
+ world = new Ammo.btDiscreteDynamicsWorld( dispatcher, broadphase, solver, collisionConfiguration );
+
+ fixedTimeStep = params.fixedTimeStep;
+ rateLimit = params.rateLimit;
+
+ transferableMessage({ cmd: 'worldReady' });
+};
+
+public_functions.registerMaterial = function( description ) {
+ _materials[ description.id ] = description;
+};
+
+public_functions.unRegisterMaterial = function( description ) {
+ delete _materials[ description.id ];
+};
+
+public_functions.setFixedTimeStep = function( description ) {
+ fixedTimeStep = description;
+};
+
+public_functions.setGravity = function( description ) {
+ _vec3_1.setX(description.x);
+ _vec3_1.setY(description.y);
+ _vec3_1.setZ(description.z);
+ world.setGravity(_vec3_1);
+};
+
+public_functions.addObject = function( description ) {
+
+ var i,
+ localInertia, shape, motionState, rbInfo, body;
+
+shape = createShape( description );
+if (!shape) return
+// If there are children then this is a compound shape
+if ( description.children ) {
+ var compound_shape = new Ammo.btCompoundShape, _child;
+ compound_shape.addChildShape( _transform, shape );
+
+ for ( i = 0; i < description.children.length; i++ ) {
+ _child = description.children[i];
+
+ var trans = new Ammo.btTransform;
+ trans.setIdentity();
+
+ _vec3_1.setX(_child.position_offset.x);
+ _vec3_1.setY(_child.position_offset.y);
+ _vec3_1.setZ(_child.position_offset.z);
+ trans.setOrigin(_vec3_1);
+
+ _quat.setX(_child.rotation.x);
+ _quat.setY(_child.rotation.y);
+ _quat.setZ(_child.rotation.z);
+ _quat.setW(_child.rotation.w);
+ trans.setRotation(_quat);
+
+ shape = createShape( description.children[i] );
+ compound_shape.addChildShape( trans, shape );
+ Ammo.destroy(trans);
+ }
+
+ shape = compound_shape;
+ _compound_shapes[ description.id ] = shape;
+ }
+ _vec3_1.setX(0);
+ _vec3_1.setY(0);
+ _vec3_1.setZ(0);
+ shape.calculateLocalInertia( description.mass, _vec3_1 );
+
+ _transform.setIdentity();
+
+ _vec3_2.setX(description.position.x);
+ _vec3_2.setY(description.position.y);
+ _vec3_2.setZ(description.position.z);
+ _transform.setOrigin(_vec3_2);
+
+ _quat.setX(description.rotation.x);
+ _quat.setY(description.rotation.y);
+ _quat.setZ(description.rotation.z);
+ _quat.setW(description.rotation.w);
+ _transform.setRotation(_quat);
+
+ motionState = new Ammo.btDefaultMotionState( _transform ); // #TODO: btDefaultMotionState supports center of mass offset as second argument - implement
+ rbInfo = new Ammo.btRigidBodyConstructionInfo( description.mass, motionState, shape, _vec3_1 );
+
+ if ( description.materialId !== undefined ) {
+ rbInfo.set_m_friction( _materials[ description.materialId ].friction );
+ rbInfo.set_m_restitution( _materials[ description.materialId ].restitution );
+ }
+
+ body = new Ammo.btRigidBody( rbInfo );
+ Ammo.destroy(rbInfo);
+
+ if ( typeof description.collision_flags !== 'undefined' ) {
+ body.setCollisionFlags( description.collision_flags );
+ }
+
+ world.addRigidBody( body );
+
+ body.id = description.id;
+ _objects[ body.id ] = body;
+ _motion_states[ body.id ] = motionState;
+
+ var ptr = body.a != undefined ? body.a : body.ptr;
+ _objects_ammo[ptr] = body.id;
+ _num_objects++;
+
+ transferableMessage({ cmd: 'objectReady', params: body.id });
+};
+
+public_functions.addVehicle = function( description ) {
+ var vehicle_tuning = new Ammo.btVehicleTuning(),
+ vehicle;
+
+ vehicle_tuning.set_m_suspensionStiffness( description.suspension_stiffness );
+ vehicle_tuning.set_m_suspensionCompression( description.suspension_compression );
+ vehicle_tuning.set_m_suspensionDamping( description.suspension_damping );
+ vehicle_tuning.set_m_maxSuspensionTravelCm( description.max_suspension_travel );
+ vehicle_tuning.set_m_maxSuspensionForce( description.max_suspension_force );
+
+ vehicle = new Ammo.btRaycastVehicle( vehicle_tuning, _objects[ description.rigidBody ], new Ammo.btDefaultVehicleRaycaster( world ) );
+ vehicle.tuning = vehicle_tuning;
+
+ _objects[ description.rigidBody ].setActivationState( 4 );
+ vehicle.setCoordinateSystem( 0, 1, 2 );
+
+ world.addVehicle( vehicle );
+ _vehicles[ description.id ] = vehicle;
+};
+public_functions.removeVehicle = function( description ) {
+ delete _vehicles[ description.id ];
+};
+
+public_functions.addWheel = function( description ) {
+ if ( _vehicles[description.id] !== undefined ) {
+ var tuning = _vehicles[description.id].tuning;
+ if ( description.tuning !== undefined ) {
+ tuning = new Ammo.btVehicleTuning();
+ tuning.set_m_suspensionStiffness( description.tuning.suspension_stiffness );
+ tuning.set_m_suspensionCompression( description.tuning.suspension_compression );
+ tuning.set_m_suspensionDamping( description.tuning.suspension_damping );
+ tuning.set_m_maxSuspensionTravelCm( description.tuning.max_suspension_travel );
+ tuning.set_m_maxSuspensionForce( description.tuning.max_suspension_force );
+ }
+
+ _vec3_1.setX(description.connection_point.x);
+ _vec3_1.setY(description.connection_point.y);
+ _vec3_1.setZ(description.connection_point.z);
+
+ _vec3_2.setX(description.wheel_direction.x);
+ _vec3_2.setY(description.wheel_direction.y);
+ _vec3_2.setZ(description.wheel_direction.z);
+
+ _vec3_3.setX(description.wheel_axle.x);
+ _vec3_3.setY(description.wheel_axle.y);
+ _vec3_3.setZ(description.wheel_axle.z);
+
+ _vehicles[description.id].addWheel(
+ _vec3_1,
+ _vec3_2,
+ _vec3_3,
+ description.suspension_rest_length,
+ description.wheel_radius,
+ tuning,
+ description.is_front_wheel
+ );
+ }
+
+ _num_wheels++;
+
+ if ( SUPPORT_TRANSFERABLE ) {
+ vehiclereport = new Float32Array(1 + _num_wheels * VEHICLEREPORT_ITEMSIZE); // message id & ( # of objects to report * # of values per object )
+ vehiclereport[0] = MESSAGE_TYPES.VEHICLEREPORT;
+ } else {
+ vehiclereport = [ MESSAGE_TYPES.VEHICLEREPORT ];
+ }
+};
+
+public_functions.setSteering = function( details ) {
+ if ( _vehicles[details.id] !== undefined ) {
+ _vehicles[details.id].setSteeringValue( details.steering, details.wheel );
+ }
+};
+public_functions.setBrake = function( details ) {
+ if ( _vehicles[details.id] !== undefined ) {
+ _vehicles[details.id].setBrake( details.brake, details.wheel );
+ }
+};
+public_functions.applyEngineForce = function( details ) {
+ if ( _vehicles[details.id] !== undefined ) {
+ _vehicles[details.id].applyEngineForce( details.force, details.wheel );
+ }
+};
+
+public_functions.removeObject = function( details ) {
+ world.removeRigidBody( _objects[details.id] );
+ Ammo.destroy(_objects[details.id]);
+ Ammo.destroy(_motion_states[details.id]);
+ if (_compound_shapes[details.id]) Ammo.destroy(_compound_shapes[details.id]);
+ if (_noncached_shapes[details.id]) Ammo.destroy(_noncached_shapes[details.id]);
+ var ptr = _objects[details.id].a != undefined ? _objects[details.id].a : _objects[details.id].ptr;
+ delete _objects_ammo[ptr];
+ delete _objects[details.id];
+ delete _motion_states[details.id];
+ if (_compound_shapes[details.id]) delete _compound_shapes[details.id];
+ if (_noncached_shapes[details.id]) delete _noncached_shapes[details.id];
+ _num_objects--;
+};
+
+public_functions.updateTransform = function( details ) {
+ _object = _objects[details.id];
+ _object.getMotionState().getWorldTransform( _transform );
+
+ if ( details.pos ) {
+ _vec3_1.setX(details.pos.x);
+ _vec3_1.setY(details.pos.y);
+ _vec3_1.setZ(details.pos.z);
+ _transform.setOrigin(_vec3_1);
+ }
+
+ if ( details.quat ) {
+ _quat.setX(details.quat.x);
+ _quat.setY(details.quat.y);
+ _quat.setZ(details.quat.z);
+ _quat.setW(details.quat.w);
+ _transform.setRotation(_quat);
+ }
+
+ _object.setWorldTransform( _transform );
+ _object.activate();
+};
+
+public_functions.updateMass = function( details ) {
+ // #TODO: changing a static object into dynamic is buggy
+ _object = _objects[details.id];
+
+ // Per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=&f=9&t=3663#p13816
+ world.removeRigidBody( _object );
+
+ _vec3_1.setX(0);
+ _vec3_1.setY(0);
+ _vec3_1.setZ(0);
+
+ _object.setMassProps( details.mass, _vec3_1 );
+ world.addRigidBody( _object );
+ _object.activate();
+};
+
+public_functions.applyCentralImpulse = function ( details ) {
+
+ _vec3_1.setX(details.x);
+ _vec3_1.setY(details.y);
+ _vec3_1.setZ(details.z);
+
+ _objects[details.id].applyCentralImpulse(_vec3_1);
+ _objects[details.id].activate();
+};
+
+public_functions.applyImpulse = function ( details ) {
+
+ _vec3_1.setX(details.impulse_x);
+ _vec3_1.setY(details.impulse_y);
+ _vec3_1.setZ(details.impulse_z);
+
+ _vec3_2.setX(details.x);
+ _vec3_2.setY(details.y);
+ _vec3_2.setZ(details.z);
+
+ _objects[details.id].applyImpulse(
+ _vec3_1,
+ _vec3_2
+ );
+ _objects[details.id].activate();
+};
+
+public_functions.applyTorque = function ( details ) {
+
+ _vec3_1.setX(details.torque_x);
+ _vec3_1.setY(details.torque_y);
+ _vec3_1.setZ(details.torque_z);
+
+ _objects[details.id].applyTorque(
+ _vec3_1
+ );
+ _objects[details.id].activate();
+};
+
+public_functions.applyCentralForce = function ( details ) {
+
+ _vec3_1.setX(details.x);
+ _vec3_1.setY(details.y);
+ _vec3_1.setZ(details.z);
+
+ _objects[details.id].applyCentralForce(_vec3_1);
+ _objects[details.id].activate();
+};
+
+public_functions.applyForce = function ( details ) {
+
+ _vec3_1.setX(details.force_x);
+ _vec3_1.setY(details.force_y);
+ _vec3_1.setZ(details.force_z);
+
+ _vec3_2.setX(details.x);
+ _vec3_2.setY(details.y);
+ _vec3_2.setZ(details.z);
+
+ _objects[details.id].applyForce(
+ _vec3_1,
+ _vec3_2
+ );
+ _objects[details.id].activate();
+};
+
+public_functions.onSimulationResume = function( params ) {
+ last_simulation_time = Date.now();
+};
+
+public_functions.setAngularVelocity = function ( details ) {
+
+ _vec3_1.setX(details.x);
+ _vec3_1.setY(details.y);
+ _vec3_1.setZ(details.z);
+
+ _objects[details.id].setAngularVelocity(
+ _vec3_1
+ );
+ _objects[details.id].activate();
+};
+
+public_functions.setLinearVelocity = function ( details ) {
+
+ _vec3_1.setX(details.x);
+ _vec3_1.setY(details.y);
+ _vec3_1.setZ(details.z);
+
+ _objects[details.id].setLinearVelocity(
+ _vec3_1
+ );
+ _objects[details.id].activate();
+};
+
+public_functions.setAngularFactor = function ( details ) {
+
+ _vec3_1.setX(details.x);
+ _vec3_1.setY(details.y);
+ _vec3_1.setZ(details.z);
+
+ _objects[details.id].setAngularFactor(
+ _vec3_1
+ );
+};
+
+public_functions.setLinearFactor = function ( details ) {
+
+ _vec3_1.setX(details.x);
+ _vec3_1.setY(details.y);
+ _vec3_1.setZ(details.z);
+
+ _objects[details.id].setLinearFactor(
+ _vec3_1
+ );
+};
+
+public_functions.setDamping = function ( details ) {
+ _objects[details.id].setDamping( details.linear, details.angular );
+};
+
+public_functions.setCcdMotionThreshold = function ( details ) {
+ _objects[details.id].setCcdMotionThreshold( details.threshold );
+};
+
+public_functions.setCcdSweptSphereRadius = function ( details ) {
+ _objects[details.id].setCcdSweptSphereRadius( details.radius );
+};
+
+public_functions.addConstraint = function ( details ) {
+ var constraint;
+
+ switch ( details.type ) {
+
+ case 'point':
+ if ( details.objectb === undefined ) {
+
+ _vec3_1.setX(details.positiona.x);
+ _vec3_1.setY(details.positiona.y);
+ _vec3_1.setZ(details.positiona.z);
+
+ constraint = new Ammo.btPoint2PointConstraint(
+ _objects[ details.objecta ],
+ _vec3_1
+ );
+ } else {
+
+ _vec3_1.setX(details.positiona.x);
+ _vec3_1.setY(details.positiona.y);
+ _vec3_1.setZ(details.positiona.z);
+
+ _vec3_2.setX(details.positionb.x);
+ _vec3_2.setY(details.positionb.y);
+ _vec3_2.setZ(details.positionb.z);
+
+ constraint = new Ammo.btPoint2PointConstraint(
+ _objects[ details.objecta ],
+ _objects[ details.objectb ],
+ _vec3_1,
+ _vec3_2
+ );
+ }
+ break;
+
+ case 'hinge':
+ if ( details.objectb === undefined ) {
+
+ _vec3_1.setX(details.positiona.x);
+ _vec3_1.setY(details.positiona.y);
+ _vec3_1.setZ(details.positiona.z);
+
+ _vec3_2.setX(details.axis.x);
+ _vec3_2.setY(details.axis.y);
+ _vec3_2.setZ(details.axis.z);
+
+ constraint = new Ammo.btHingeConstraint(
+ _objects[ details.objecta ],
+ _vec3_1,
+ _vec3_2
+ );
+ } else {
+
+ _vec3_1.setX(details.positiona.x);
+ _vec3_1.setY(details.positiona.y);
+ _vec3_1.setZ(details.positiona.z);
+
+ _vec3_2.setX(details.positionb.x);
+ _vec3_2.setY(details.positionb.y);
+ _vec3_2.setZ(details.positionb.z);
+
+ _vec3_3.setX(details.axis.x);
+ _vec3_3.setY(details.axis.y);
+ _vec3_3.setZ(details.axis.z);
+
+ constraint = new Ammo.btHingeConstraint(
+ _objects[ details.objecta ],
+ _objects[ details.objectb ],
+ _vec3_1,
+ _vec3_2,
+ _vec3_3,
+ _vec3_3
+ );
+ }
+ break;
+
+ case 'slider':
+ var transforma, transformb, rotation;
+
+ transforma = new Ammo.btTransform();
+
+ _vec3_1.setX(details.positiona.x);
+ _vec3_1.setY(details.positiona.y);
+ _vec3_1.setZ(details.positiona.z);
+
+ transforma.setOrigin(_vec3_1);
+
+ var rotation = transforma.getRotation();
+ rotation.setEuler( details.axis.x, details.axis.y, details.axis.z );
+ transforma.setRotation( rotation );
+
+ if ( details.objectb ) {
+ transformb = new Ammo.btTransform();
+
+ _vec3_2.setX(details.positionb.x);
+ _vec3_2.setY(details.positionb.y);
+ _vec3_2.setZ(details.positionb.z);
+
+ transformb.setOrigin(_vec3_2);
+
+ rotation = transformb.getRotation();
+ rotation.setEuler( details.axis.x, details.axis.y, details.axis.z );
+ transformb.setRotation( rotation );
+
+ constraint = new Ammo.btSliderConstraint(
+ _objects[ details.objecta ],
+ _objects[ details.objectb ],
+ transforma,
+ transformb,
+ true
+ );
+ } else {
+ constraint = new Ammo.btSliderConstraint(
+ _objects[ details.objecta ],
+ transforma,
+ true
+ );
+ }
+
+ Ammo.destroy(transforma);
+ if (transformb != undefined) {
+ Ammo.destroy(transformb);
+ }
+ break;
+
+ case 'conetwist':
+ var transforma, transformb;
+
+ transforma = new Ammo.btTransform();
+ transforma.setIdentity();
+
+ transformb = new Ammo.btTransform();
+ transformb.setIdentity();
+
+ _vec3_1.setX(details.positiona.x);
+ _vec3_1.setY(details.positiona.y);
+ _vec3_1.setZ(details.positiona.z);
+
+ _vec3_2.setX(details.positionb.x);
+ _vec3_2.setY(details.positionb.y);
+ _vec3_2.setZ(details.positionb.z);
+
+ transforma.setOrigin(_vec3_1);
+ transformb.setOrigin(_vec3_2);
+
+ var rotation = transforma.getRotation();
+ rotation.setEulerZYX( -details.axisa.z, -details.axisa.y, -details.axisa.x );
+ transforma.setRotation( rotation );
+
+ rotation = transformb.getRotation();
+ rotation.setEulerZYX( -details.axisb.z, -details.axisb.y, -details.axisb.x );
+ transformb.setRotation( rotation );
+
+ constraint = new Ammo.btConeTwistConstraint(
+ _objects[ details.objecta ],
+ _objects[ details.objectb ],
+ transforma,
+ transformb
+ );
+
+ constraint.setLimit( Math.PI, 0, Math.PI );
+
+ Ammo.destroy(transforma);
+ Ammo.destroy(transformb);
+
+ break;
+
+ case 'dof':
+ var transforma, transformb, rotation;
+
+ transforma = new Ammo.btTransform();
+ transforma.setIdentity();
+
+ _vec3_1.setX(details.positiona.x);
+ _vec3_1.setY(details.positiona.y);
+ _vec3_1.setZ(details.positiona.z);
+
+ transforma.setOrigin(_vec3_1 );
+
+ rotation = transforma.getRotation();
+ rotation.setEulerZYX( -details.axisa.z, -details.axisa.y, -details.axisa.x );
+ transforma.setRotation( rotation );
+
+ if ( details.objectb ) {
+ transformb = new Ammo.btTransform();
+ transformb.setIdentity();
+
+ _vec3_2.setX(details.positionb.x);
+ _vec3_2.setY(details.positionb.y);
+ _vec3_2.setZ(details.positionb.z);
+
+ transformb.setOrigin(_vec3_2);
+
+ rotation = transformb.getRotation();
+ rotation.setEulerZYX( -details.axisb.z, -details.axisb.y, -details.axisb.x );
+ transformb.setRotation( rotation );
+
+ constraint = new Ammo.btGeneric6DofConstraint(
+ _objects[ details.objecta ],
+ _objects[ details.objectb ],
+ transforma,
+ transformb
+ );
+ } else {
+ constraint = new Ammo.btGeneric6DofConstraint(
+ _objects[ details.objecta ],
+ transforma
+ );
+ }
+ Ammo.destroy(transforma);
+ if (transformb != undefined) {
+ Ammo.destroy(transformb);
+ }
+ break;
+
+ default:
+ return;
+
+ };
+
+ world.addConstraint( constraint );
+
+ constraint.enableFeedback();
+ _constraints[ details.id ] = constraint;
+ _num_constraints++;
+
+ if ( SUPPORT_TRANSFERABLE ) {
+ constraintreport = new Float32Array(1 + _num_constraints * CONSTRAINTREPORT_ITEMSIZE); // message id & ( # of objects to report * # of values per object )
+ constraintreport[0] = MESSAGE_TYPES.CONSTRAINTREPORT;
+ } else {
+ constraintreport = [ MESSAGE_TYPES.CONSTRAINTREPORT ];
+ }
+};
+
+public_functions.removeConstraint = function( details ) {
+ var constraint = _constraints[ details.id ];
+ if ( constraint !== undefined ) {
+ world.removeConstraint( constraint );
+ delete _constraints[ details.id ];
+ _num_constraints--;
+ }
+};
+
+public_functions.constraint_setBreakingImpulseThreshold = function( details ) {
+ var constraint = _constraints[ details.id ];
+ if ( constraint !== undefind ) {
+ constraint.setBreakingImpulseThreshold( details.threshold );
+ }
+};
+
+public_functions.simulate = function simulate( params ) {
+ if ( world ) {
+ params = params || {};
+
+ if ( !params.timeStep ) {
+ if ( last_simulation_time ) {
+ params.timeStep = 0;
+ while ( params.timeStep + last_simulation_duration <= fixedTimeStep ) {
+ params.timeStep = ( Date.now() - last_simulation_time ) / 1000; // time since last simulation
+ }
+ } else {
+ params.timeStep = fixedTimeStep; // handle first frame
+ }
+ } else {
+ if ( params.timeStep < fixedTimeStep ) {
+ params.timeStep = fixedTimeStep;
+ }
+ }
+
+ params.maxSubSteps = params.maxSubSteps || Math.ceil( params.timeStep / fixedTimeStep ); // If maxSubSteps is not defined, keep the simulation fully up to date
+
+ last_simulation_duration = Date.now();
+ world.stepSimulation( params.timeStep, params.maxSubSteps, fixedTimeStep );
+
+ reportVehicles();
+ reportCollisions();
+ reportConstraints();
+ reportWorld();
+
+ last_simulation_duration = ( Date.now() - last_simulation_duration ) / 1000;
+ last_simulation_time = Date.now();
+ }
+};
+
+
+// Constraint functions
+public_functions.hinge_setLimits = function( params ) {
+ _constraints[ params.constraint ].setLimit( params.low, params.high, 0, params.bias_factor, params.relaxation_factor );
+};
+public_functions.hinge_enableAngularMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.enableAngularMotor( true, params.velocity, params.acceleration );
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.hinge_disableMotor = function( params ) {
+ _constraints[ params.constraint ].enableMotor( false );
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+
+public_functions.slider_setLimits = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.setLowerLinLimit( params.lin_lower || 0 );
+ constraint.setUpperLinLimit( params.lin_upper || 0 );
+
+ constraint.setLowerAngLimit( params.ang_lower || 0 );
+ constraint.setUpperAngLimit( params.ang_upper || 0 );
+};
+public_functions.slider_setRestitution = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.setSoftnessLimLin( params.linear || 0 );
+ constraint.setSoftnessLimAng( params.angular || 0 );
+};
+public_functions.slider_enableLinearMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.setTargetLinMotorVelocity( params.velocity );
+ constraint.setMaxLinMotorForce( params.acceleration );
+ constraint.setPoweredLinMotor( true );
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.slider_disableLinearMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.setPoweredLinMotor( false );
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.slider_enableAngularMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.setTargetAngMotorVelocity( params.velocity );
+ constraint.setMaxAngMotorForce( params.acceleration );
+ constraint.setPoweredAngMotor( true );
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.slider_disableAngularMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.setPoweredAngMotor( false );
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+
+public_functions.conetwist_setLimit = function( params ) {
+ _constraints[ params.constraint ].setLimit( params.z, params.y, params.x ); // ZYX order
+};
+public_functions.conetwist_enableMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.enableMotor( true );
+ constraint.getRigidBodyA().activate();
+ constraint.getRigidBodyB().activate();
+};
+public_functions.conetwist_setMaxMotorImpulse = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.setMaxMotorImpulse( params.max_impulse );
+ constraint.getRigidBodyA().activate();
+ constraint.getRigidBodyB().activate();
+};
+public_functions.conetwist_setMotorTarget = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+
+ _quat.setX(params.x);
+ _quat.setY(params.y);
+ _quat.setZ(params.z);
+ _quat.setW(params.w);
+
+ constraint.setMotorTarget(_quat);
+
+ constraint.getRigidBodyA().activate();
+ constraint.getRigidBodyB().activate();
+};
+public_functions.conetwist_disableMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+ constraint.enableMotor( false );
+ constraint.getRigidBodyA().activate();
+ constraint.getRigidBodyB().activate();
+};
+
+public_functions.dof_setLinearLowerLimit = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+
+ _vec3_1.setX(params.x);
+ _vec3_1.setY(params.y);
+ _vec3_1.setZ(params.z);
+
+ constraint.setLinearLowerLimit(_vec3_1);
+
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.dof_setLinearUpperLimit = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+
+ _vec3_1.setX(params.x);
+ _vec3_1.setY(params.y);
+ _vec3_1.setZ(params.z);
+
+ constraint.setLinearUpperLimit(_vec3_1);
+
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.dof_setAngularLowerLimit = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+
+ _vec3_1.setX(params.x);
+ _vec3_1.setY(params.y);
+ _vec3_1.setZ(params.z);
+
+ constraint.setAngularLowerLimit(_vec3_1);
+
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.dof_setAngularUpperLimit = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+
+ _vec3_1.setX(params.x);
+ _vec3_1.setY(params.y);
+ _vec3_1.setZ(params.z);
+
+ constraint.setAngularUpperLimit(_vec3_1);
+
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.dof_enableAngularMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+
+ var motor = constraint.getRotationalLimitMotor( params.which );
+ motor.set_m_enableMotor( true );
+
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.dof_configureAngularMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+
+ var motor = constraint.getRotationalLimitMotor( params.which );
+
+ motor.set_m_loLimit( params.low_angle );
+ motor.set_m_hiLimit( params.high_angle );
+ motor.set_m_targetVelocity( params.velocity );
+ motor.set_m_maxMotorForce( params.max_force );
+
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+public_functions.dof_disableAngularMotor = function( params ) {
+ var constraint = _constraints[ params.constraint ];
+
+ var motor = constraint.getRotationalLimitMotor( params.which );
+ motor.set_m_enableMotor( false );
+
+ constraint.getRigidBodyA().activate();
+ if ( constraint.getRigidBodyB() ) {
+ constraint.getRigidBodyB().activate();
+ }
+};
+
+reportWorld = function() {
+ var index, object,
+ transform, origin, rotation,
+ offset = 0,
+ i = 0;
+
+ if ( SUPPORT_TRANSFERABLE ) {
+ if ( worldreport.length < 2 + _num_objects * WORLDREPORT_ITEMSIZE ) {
+ worldreport = new Float32Array(
+ 2 + // message id & # objects in report
+ ( Math.ceil( _num_objects / REPORT_CHUNKSIZE ) * REPORT_CHUNKSIZE ) * WORLDREPORT_ITEMSIZE // # of values needed * item size
+ );
+ worldreport[0] = MESSAGE_TYPES.WORLDREPORT;
+ }
+ }
+
+ worldreport[1] = _num_objects; // record how many objects we're reporting on
+
+ //for ( i = 0; i < worldreport[1]; i++ ) {
+ for ( index in _objects ) {
+ if ( _objects.hasOwnProperty( index ) ) {
+ object = _objects[index];
+
+ // #TODO: we can't use center of mass transform when center of mass can change,
+ // but getMotionState().getWorldTransform() screws up on objects that have been moved
+ //object.getMotionState().getWorldTransform( transform );
+ transform = object.getCenterOfMassTransform();
+
+ origin = transform.getOrigin();
+ rotation = transform.getRotation();
+
+ // add values to report
+ offset = 2 + (i++) * WORLDREPORT_ITEMSIZE;
+
+ worldreport[ offset ] = object.id;
+
+ worldreport[ offset + 1 ] = origin.x();
+ worldreport[ offset + 2 ] = origin.y();
+ worldreport[ offset + 3 ] = origin.z();
+
+ worldreport[ offset + 4 ] = rotation.x();
+ worldreport[ offset + 5 ] = rotation.y();
+ worldreport[ offset + 6 ] = rotation.z();
+ worldreport[ offset + 7 ] = rotation.w();
+
+ _vector = object.getLinearVelocity();
+ worldreport[ offset + 8 ] = _vector.x();
+ worldreport[ offset + 9 ] = _vector.y();
+ worldreport[ offset + 10 ] = _vector.z();
+
+ _vector = object.getAngularVelocity();
+ worldreport[ offset + 11 ] = _vector.x();
+ worldreport[ offset + 12 ] = _vector.y();
+ worldreport[ offset + 13 ] = _vector.z();
+ }
+ }
+
+
+ if ( SUPPORT_TRANSFERABLE ) {
+ transferableMessage( worldreport.buffer, [worldreport.buffer] );
+ } else {
+ transferableMessage( worldreport );
+ }
+
+};
+
+reportCollisions = function() {
+ var i, offset,
+ dp = world.getDispatcher(),
+ num = dp.getNumManifolds(),
+ manifold, num_contacts, j, pt,
+ _collided = false;
+
+ if ( SUPPORT_TRANSFERABLE ) {
+ if ( collisionreport.length < 2 + num * COLLISIONREPORT_ITEMSIZE ) {
+ collisionreport = new Float32Array(
+ 2 + // message id & # objects in report
+ ( Math.ceil( _num_objects / REPORT_CHUNKSIZE ) * REPORT_CHUNKSIZE ) * COLLISIONREPORT_ITEMSIZE // # of values needed * item size
+ );
+ collisionreport[0] = MESSAGE_TYPES.COLLISIONREPORT;
+ }
+ }
+
+ collisionreport[1] = 0; // how many collisions we're reporting on
+
+ for ( i = 0; i < num; i++ ) {
+ manifold = dp.getManifoldByIndexInternal( i );
+
+ num_contacts = manifold.getNumContacts();
+ if ( num_contacts === 0 ) {
+ continue;
+ }
+
+ for ( j = 0; j < num_contacts; j++ ) {
+ pt = manifold.getContactPoint( j );
+ //if ( pt.getDistance() < 0 ) {
+ offset = 2 + (collisionreport[1]++) * COLLISIONREPORT_ITEMSIZE;
+ collisionreport[ offset ] = _objects_ammo[ manifold.getBody0() ];
+ collisionreport[ offset + 1 ] = _objects_ammo[ manifold.getBody1() ];
+
+ _vector = pt.get_m_normalWorldOnB();
+ collisionreport[ offset + 2 ] = _vector.x();
+ collisionreport[ offset + 3 ] = _vector.y();
+ collisionreport[ offset + 4 ] = _vector.z();
+ break;
+ //}
+
+ transferableMessage( _objects_ammo );
+
+ }
+ }
+
+
+ if ( SUPPORT_TRANSFERABLE ) {
+ transferableMessage( collisionreport.buffer, [collisionreport.buffer] );
+ } else {
+ transferableMessage( collisionreport );
+ }
+};
+
+reportVehicles = function() {
+ var index, vehicle,
+ transform, origin, rotation,
+ offset = 0,
+ i = 0, j = 0;
+
+ if ( SUPPORT_TRANSFERABLE ) {
+ if ( vehiclereport.length < 2 + _num_wheels * VEHICLEREPORT_ITEMSIZE ) {
+ vehiclereport = new Float32Array(
+ 2 + // message id & # objects in report
+ ( Math.ceil( _num_wheels / REPORT_CHUNKSIZE ) * REPORT_CHUNKSIZE ) * VEHICLEREPORT_ITEMSIZE // # of values needed * item size
+ );
+ vehiclereport[0] = MESSAGE_TYPES.VEHICLEREPORT;
+ }
+ }
+
+ for ( index in _vehicles ) {
+ if ( _vehicles.hasOwnProperty( index ) ) {
+ vehicle = _vehicles[index];
+
+ for ( j = 0; j < vehicle.getNumWheels(); j++ ) {
+
+ //vehicle.updateWheelTransform( j, true );
+
+ //transform = vehicle.getWheelTransformWS( j );
+ transform = vehicle.getWheelInfo( j ).get_m_worldTransform();
+
+ origin = transform.getOrigin();
+ rotation = transform.getRotation();
+
+ // add values to report
+ offset = 1 + (i++) * VEHICLEREPORT_ITEMSIZE;
+
+ vehiclereport[ offset ] = index;
+ vehiclereport[ offset + 1 ] = j;
+
+ vehiclereport[ offset + 2 ] = origin.x();
+ vehiclereport[ offset + 3 ] = origin.y();
+ vehiclereport[ offset + 4 ] = origin.z();
+
+ vehiclereport[ offset + 5 ] = rotation.x();
+ vehiclereport[ offset + 6 ] = rotation.y();
+ vehiclereport[ offset + 7 ] = rotation.z();
+ vehiclereport[ offset + 8 ] = rotation.w();
+
+ }
+
+ }
+ }
+
+ if ( j !== 0 ) {
+ if ( SUPPORT_TRANSFERABLE ) {
+ transferableMessage( vehiclereport.buffer, [vehiclereport.buffer] );
+ } else {
+ transferableMessage( vehiclereport );
+ }
+ }
+};
+
+reportConstraints = function() {
+ var index, constraint,
+ offset_body,
+ transform, origin,
+ offset = 0,
+ i = 0;
+
+ if ( SUPPORT_TRANSFERABLE ) {
+ if ( constraintreport.length < 2 + _num_constraints * CONSTRAINTREPORT_ITEMSIZE ) {
+ constraintreport = new Float32Array(
+ 2 + // message id & # objects in report
+ ( Math.ceil( _num_constraints / REPORT_CHUNKSIZE ) * REPORT_CHUNKSIZE ) * CONSTRAINTREPORT_ITEMSIZE // # of values needed * item size
+ );
+ constraintreport[0] = MESSAGE_TYPES.CONSTRAINTREPORT;
+ }
+ }
+
+ for ( index in _constraints ) {
+ if ( _constraints.hasOwnProperty( index ) ) {
+ constraint = _constraints[index];
+ offset_body = constraint.getRigidBodyA();
+ transform = constraint.getFrameOffsetA();
+ origin = transform.getOrigin();
+
+ // add values to report
+ offset = 1 + (i++) * CONSTRAINTREPORT_ITEMSIZE;
+
+ constraintreport[ offset ] = index;
+ constraintreport[ offset + 1 ] = offset_body.id;
+ constraintreport[ offset + 2 ] = origin.getX();
+ constraintreport[ offset + 3 ] = origin.getY();
+ constraintreport[ offset + 4 ] = origin.getZ();
+ constraintreport[ offset + 5 ] = constraint.getAppliedImpulse();
+ }
+ }
+
+
+ if ( i !== 0 ) {
+ if ( SUPPORT_TRANSFERABLE ) {
+ transferableMessage( constraintreport.buffer, [constraintreport.buffer] );
+ } else {
+ transferableMessage( constraintreport );
+ }
+ }
+
+};
+
+self.onmessage = function( event ) {
+
+ if ( event.data instanceof Float32Array ) {
+ // transferable object
+
+ switch ( event.data[0] ) {
+ case MESSAGE_TYPES.WORLDREPORT:
+ worldreport = new Float32Array( event.data );
+ break;
+
+ case MESSAGE_TYPES.COLLISIONREPORT:
+ collisionreport = new Float32Array( event.data );
+ break;
+
+ case MESSAGE_TYPES.VEHICLEREPORT:
+ vehiclereport = new Float32Array( event.data );
+ break;
+
+ case MESSAGE_TYPES.CONSTRAINTREPORT:
+ constraintreport = new Float32Array( event.data );
+ break;
+ }
+
+ return;
+ }
+
+ if ( event.data.cmd && public_functions[event.data.cmd] ) {
+ //if ( event.data.params.id !== undefined && _objects[event.data.params.id] === undefined && event.data.cmd !== 'addObject' && event.data.cmd !== 'registerMaterial' ) return;
+ public_functions[event.data.cmd]( event.data.params );
+ }
+
+};