|
@@ -1,279 +1,225 @@
|
|
|
var BABYLON;
|
|
|
(function (BABYLON) {
|
|
|
var OimoJSPlugin = (function () {
|
|
|
- function OimoJSPlugin() {
|
|
|
- this._registeredMeshes = [];
|
|
|
- this.name = "oimo";
|
|
|
- /**
|
|
|
- * Update the body position according to the mesh position
|
|
|
- * @param mesh
|
|
|
- */
|
|
|
- this.updateBodyPosition = function (mesh) {
|
|
|
- for (var index = 0; index < this._registeredMeshes.length; index++) {
|
|
|
- var registeredMesh = this._registeredMeshes[index];
|
|
|
- var body = registeredMesh.body.body;
|
|
|
- var updated = false;
|
|
|
- var newPosition;
|
|
|
- if (registeredMesh.mesh === mesh || registeredMesh.mesh === mesh.parent) {
|
|
|
- mesh.computeWorldMatrix(true);
|
|
|
- newPosition = mesh.getBoundingInfo().boundingBox.center;
|
|
|
- updated = true;
|
|
|
- }
|
|
|
- else if (registeredMesh.mesh.parent === mesh) {
|
|
|
- mesh.computeWorldMatrix(true);
|
|
|
- registeredMesh.mesh.computeWorldMatrix(true);
|
|
|
- newPosition = registeredMesh.mesh.getAbsolutePosition();
|
|
|
- updated = true;
|
|
|
- }
|
|
|
- if (updated) {
|
|
|
- body.setPosition(new OIMO.Vec3(newPosition.x, newPosition.y, newPosition.z));
|
|
|
- body.setQuaternion(mesh.rotationQuaternion);
|
|
|
- body.sleeping = false;
|
|
|
- //force Oimo to update the body's position
|
|
|
- body.updatePosition(1);
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
+ function OimoJSPlugin(iterations) {
|
|
|
+ this.name = "OimoJSPlugin";
|
|
|
+ this._tmpImpostorsArray = [];
|
|
|
+ this._tmpPositionVector = BABYLON.Vector3.Zero();
|
|
|
+ this.world = new OIMO.World(null, null, iterations);
|
|
|
+ this.world.clear();
|
|
|
}
|
|
|
- OimoJSPlugin.prototype._checkWithEpsilon = function (value) {
|
|
|
- return value < BABYLON.PhysicsEngine.Epsilon ? BABYLON.PhysicsEngine.Epsilon : value;
|
|
|
- };
|
|
|
- OimoJSPlugin.prototype.initialize = function (iterations) {
|
|
|
- this._world = new OIMO.World(null, null, iterations);
|
|
|
- this._world.clear();
|
|
|
- };
|
|
|
OimoJSPlugin.prototype.setGravity = function (gravity) {
|
|
|
- this._gravity = this._world.gravity = gravity;
|
|
|
- };
|
|
|
- OimoJSPlugin.prototype.getGravity = function () {
|
|
|
- return this._gravity;
|
|
|
- };
|
|
|
- OimoJSPlugin.prototype.registerMesh = function (mesh, impostor, options) {
|
|
|
- this.unregisterMesh(mesh);
|
|
|
- if (!mesh.rotationQuaternion) {
|
|
|
- mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(mesh.rotation.y, mesh.rotation.x, mesh.rotation.z);
|
|
|
- }
|
|
|
- mesh.computeWorldMatrix(true);
|
|
|
- var bbox = mesh.getBoundingInfo().boundingBox;
|
|
|
- // The delta between the mesh position and the mesh bounding box center
|
|
|
- var deltaPosition = mesh.position.subtract(bbox.center);
|
|
|
- //calculate rotation to fit Oimo's needs (Euler...)
|
|
|
- var rot = new OIMO.Euler().setFromQuaternion({ x: mesh.rotationQuaternion.x, y: mesh.rotationQuaternion.y, z: mesh.rotationQuaternion.z, s: mesh.rotationQuaternion.w });
|
|
|
- //get the correct bounding box
|
|
|
- var oldQuaternion = mesh.rotationQuaternion;
|
|
|
- mesh.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 1);
|
|
|
- mesh.computeWorldMatrix(true);
|
|
|
- var bodyConfig = {
|
|
|
- name: mesh.uniqueId,
|
|
|
- pos: [bbox.center.x, bbox.center.y, bbox.center.z],
|
|
|
- rot: [rot.x / OIMO.TO_RAD, rot.y / OIMO.TO_RAD, rot.z / OIMO.TO_RAD],
|
|
|
- move: options.mass != 0,
|
|
|
- config: [options.mass, options.friction, options.restitution],
|
|
|
- world: this._world
|
|
|
- };
|
|
|
- // register mesh
|
|
|
- switch (impostor) {
|
|
|
- case BABYLON.PhysicsEngine.SphereImpostor:
|
|
|
- var radiusX = bbox.maximumWorld.x - bbox.minimumWorld.x;
|
|
|
- var radiusY = bbox.maximumWorld.y - bbox.minimumWorld.y;
|
|
|
- var radiusZ = bbox.maximumWorld.z - bbox.minimumWorld.z;
|
|
|
- var size = Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2;
|
|
|
- bodyConfig.type = 'sphere';
|
|
|
- bodyConfig.size = [size];
|
|
|
- break;
|
|
|
- case BABYLON.PhysicsEngine.PlaneImpostor:
|
|
|
- //Oimo "fakes" a cylinder as a box, so why don't we!
|
|
|
- case BABYLON.PhysicsEngine.CylinderImpostor:
|
|
|
- case BABYLON.PhysicsEngine.BoxImpostor:
|
|
|
- var min = bbox.minimumWorld;
|
|
|
- var max = bbox.maximumWorld;
|
|
|
- var box = max.subtract(min);
|
|
|
- var sizeX = this._checkWithEpsilon(box.x);
|
|
|
- var sizeY = this._checkWithEpsilon(box.y);
|
|
|
- var sizeZ = this._checkWithEpsilon(box.z);
|
|
|
- bodyConfig.type = 'box';
|
|
|
- bodyConfig.size = [sizeX, sizeY, sizeZ];
|
|
|
- break;
|
|
|
- }
|
|
|
- var body = new OIMO.Body(bodyConfig);
|
|
|
- //We have to access the rigid body's properties to set the quaternion.
|
|
|
- //The setQuaternion function of Oimo only sets the newOrientation that is only set after an impulse is given or a collision.
|
|
|
- //body.body.orientation = new OIMO.Quat(mesh.rotationQuaternion.w, mesh.rotationQuaternion.x, mesh.rotationQuaternion.y, mesh.rotationQuaternion.z);
|
|
|
- //TEST
|
|
|
- //body.body.resetQuaternion(new OIMO.Quat(mesh.rotationQuaternion.w, mesh.rotationQuaternion.x, mesh.rotationQuaternion.y, mesh.rotationQuaternion.z));
|
|
|
- //update the internal rotation matrix
|
|
|
- //body.body.syncShapes();
|
|
|
- this._registeredMeshes.push({
|
|
|
- mesh: mesh,
|
|
|
- body: body,
|
|
|
- delta: deltaPosition
|
|
|
- });
|
|
|
- //for the sake of consistency.
|
|
|
- mesh.rotationQuaternion = oldQuaternion;
|
|
|
- return body;
|
|
|
+ this.world.gravity.copy(gravity);
|
|
|
};
|
|
|
- OimoJSPlugin.prototype.registerMeshesAsCompound = function (parts, options) {
|
|
|
- var types = [], sizes = [], positions = [], rotations = [];
|
|
|
- var initialMesh = parts[0].mesh;
|
|
|
- for (var index = 0; index < parts.length; index++) {
|
|
|
- var part = parts[index];
|
|
|
- var bodyParameters = this._createBodyAsCompound(part, options, initialMesh);
|
|
|
- types.push(bodyParameters.type);
|
|
|
- sizes.push.apply(sizes, bodyParameters.size);
|
|
|
- positions.push.apply(positions, bodyParameters.pos);
|
|
|
- rotations.push.apply(rotations, bodyParameters.rot);
|
|
|
- }
|
|
|
- var body = new OIMO.Body({
|
|
|
- name: initialMesh.uniqueId,
|
|
|
- type: types,
|
|
|
- size: sizes,
|
|
|
- pos: positions,
|
|
|
- rot: rotations,
|
|
|
- move: options.mass != 0,
|
|
|
- config: [options.mass, options.friction, options.restitution],
|
|
|
- world: this._world
|
|
|
+ OimoJSPlugin.prototype.executeStep = function (delta, impostors) {
|
|
|
+ impostors.forEach(function (impostor) {
|
|
|
+ impostor.beforeStep();
|
|
|
});
|
|
|
- //Reset the body's rotation to be of the initial mesh's.
|
|
|
- var rot = new OIMO.Euler().setFromQuaternion({ x: initialMesh.rotationQuaternion.x, y: initialMesh.rotationQuaternion.y, z: initialMesh.rotationQuaternion.z, s: initialMesh.rotationQuaternion.w });
|
|
|
- body.resetRotation(rot.x / OIMO.TO_RAD, rot.y / OIMO.TO_RAD, rot.z / OIMO.TO_RAD);
|
|
|
- this._registeredMeshes.push({
|
|
|
- mesh: initialMesh,
|
|
|
- body: body
|
|
|
+ this.world.step();
|
|
|
+ impostors.forEach(function (impostor) {
|
|
|
+ impostor.afterStep();
|
|
|
+ //update the ordered impostors array
|
|
|
+ this._tmpImpostorsArray[impostor.mesh.uniqueId] = impostor;
|
|
|
});
|
|
|
- return body;
|
|
|
- };
|
|
|
- OimoJSPlugin.prototype._createBodyAsCompound = function (part, options, initialMesh) {
|
|
|
- var mesh = part.mesh;
|
|
|
- if (!mesh.rotationQuaternion) {
|
|
|
- mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(mesh.rotation.y, mesh.rotation.x, mesh.rotation.z);
|
|
|
- }
|
|
|
- // We need the bounding box/sphere info to compute the physics body
|
|
|
- mesh.computeWorldMatrix(true);
|
|
|
- var rot = new OIMO.Euler().setFromQuaternion({ x: mesh.rotationQuaternion.x, y: mesh.rotationQuaternion.y, z: mesh.rotationQuaternion.z, s: mesh.rotationQuaternion.w });
|
|
|
- var bodyParameters = {
|
|
|
- name: mesh.uniqueId,
|
|
|
- pos: [mesh.position.x, mesh.position.y, mesh.position.z],
|
|
|
- //A bug in Oimo (Body class) prevents us from using rot directly.
|
|
|
- rot: [0, 0, 0],
|
|
|
- //For future reference, if the bug will ever be fixed.
|
|
|
- realRot: [rot.x / OIMO.TO_RAD, rot.y / OIMO.TO_RAD, rot.z / OIMO.TO_RAD]
|
|
|
- };
|
|
|
- var oldQuaternion = mesh.rotationQuaternion;
|
|
|
- mesh.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 1);
|
|
|
- mesh.computeWorldMatrix(true);
|
|
|
- switch (part.impostor) {
|
|
|
- case BABYLON.PhysicsEngine.SphereImpostor:
|
|
|
- var bbox = mesh.getBoundingInfo().boundingBox;
|
|
|
- var radiusX = bbox.maximumWorld.x - bbox.minimumWorld.x;
|
|
|
- var radiusY = bbox.maximumWorld.y - bbox.minimumWorld.y;
|
|
|
- var radiusZ = bbox.maximumWorld.z - bbox.minimumWorld.z;
|
|
|
- var size = Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2;
|
|
|
- bodyParameters.type = 'sphere';
|
|
|
- bodyParameters.size = [size, size, size];
|
|
|
- break;
|
|
|
- case BABYLON.PhysicsEngine.PlaneImpostor:
|
|
|
- case BABYLON.PhysicsEngine.CylinderImpostor:
|
|
|
- case BABYLON.PhysicsEngine.BoxImpostor:
|
|
|
- bbox = mesh.getBoundingInfo().boundingBox;
|
|
|
- var min = bbox.minimumWorld;
|
|
|
- var max = bbox.maximumWorld;
|
|
|
- var box = max.subtract(min);
|
|
|
- var sizeX = this._checkWithEpsilon(box.x);
|
|
|
- var sizeY = this._checkWithEpsilon(box.y);
|
|
|
- var sizeZ = this._checkWithEpsilon(box.z);
|
|
|
- bodyParameters.type = 'box';
|
|
|
- bodyParameters.size = [sizeX, sizeY, sizeZ];
|
|
|
- break;
|
|
|
- }
|
|
|
- mesh.rotationQuaternion = oldQuaternion;
|
|
|
- return bodyParameters;
|
|
|
- };
|
|
|
- OimoJSPlugin.prototype.unregisterMesh = function (mesh) {
|
|
|
- for (var index = 0; index < this._registeredMeshes.length; index++) {
|
|
|
- var registeredMesh = this._registeredMeshes[index];
|
|
|
- if (registeredMesh.mesh === mesh || registeredMesh.mesh === mesh.parent) {
|
|
|
- if (registeredMesh.body) {
|
|
|
- this._world.removeRigidBody(registeredMesh.body.body);
|
|
|
- this._unbindBody(registeredMesh.body);
|
|
|
- }
|
|
|
- this._registeredMeshes.splice(index, 1);
|
|
|
- return;
|
|
|
+ //check for collisions
|
|
|
+ var contact = this.world.contacts;
|
|
|
+ while (contact !== null) {
|
|
|
+ if (contact.touching && !contact.body1.sleeping && !contact.body2.sleeping) {
|
|
|
+ continue;
|
|
|
}
|
|
|
+ //is this body colliding with any other? get the impostor
|
|
|
+ var mainImpostor = this._tmpImpostorsArray[+contact.body1.name];
|
|
|
+ var collidingImpostor = this._tmpImpostorsArray[+contact.body2.name];
|
|
|
+ if (!mainImpostor || !collidingImpostor)
|
|
|
+ continue;
|
|
|
+ mainImpostor.onCollide({ body: collidingImpostor.physicsBody });
|
|
|
+ collidingImpostor.onCollide({ body: mainImpostor.physicsBody });
|
|
|
+ contact = contact.next;
|
|
|
}
|
|
|
};
|
|
|
- OimoJSPlugin.prototype._unbindBody = function (body) {
|
|
|
- for (var index = 0; index < this._registeredMeshes.length; index++) {
|
|
|
- var registeredMesh = this._registeredMeshes[index];
|
|
|
- if (registeredMesh.body === body) {
|
|
|
- registeredMesh.body = null;
|
|
|
- }
|
|
|
- }
|
|
|
+ OimoJSPlugin.prototype.applyImpulse = function (impostor, force, contactPoint) {
|
|
|
+ impostor.physicsBody.body.applyImpulse(contactPoint.scale(OIMO.INV_SCALE), force.scale(OIMO.INV_SCALE));
|
|
|
};
|
|
|
- OimoJSPlugin.prototype.applyImpulse = function (mesh, force, contactPoint) {
|
|
|
- for (var index = 0; index < this._registeredMeshes.length; index++) {
|
|
|
- var registeredMesh = this._registeredMeshes[index];
|
|
|
- if (registeredMesh.mesh === mesh || registeredMesh.mesh === mesh.parent) {
|
|
|
- // Get object mass to have a behaviour similar to cannon.js
|
|
|
- var mass = registeredMesh.body.body.massInfo.mass;
|
|
|
- // The force is scaled with the mass of object
|
|
|
- registeredMesh.body.body.applyImpulse(contactPoint.scale(OIMO.INV_SCALE), force.scale(OIMO.INV_SCALE * mass));
|
|
|
- return;
|
|
|
+ OimoJSPlugin.prototype.applyForce = function (impostor, force, contactPoint) {
|
|
|
+ BABYLON.Tools.Warn("Oimo doesn't support applying force. Using impule instead.");
|
|
|
+ this.applyImpulse(impostor, force, contactPoint);
|
|
|
+ };
|
|
|
+ OimoJSPlugin.prototype.generatePhysicsBody = function (impostor) {
|
|
|
+ //parent-child relationship. Does this impostor has a parent impostor?
|
|
|
+ if (impostor.parent) {
|
|
|
+ if (impostor.physicsBody) {
|
|
|
+ this.removePhysicsBody(impostor);
|
|
|
+ //TODO is that needed?
|
|
|
+ impostor.forceUpdate();
|
|
|
}
|
|
|
+ return;
|
|
|
}
|
|
|
- };
|
|
|
- OimoJSPlugin.prototype.createLink = function (mesh1, mesh2, pivot1, pivot2, options) {
|
|
|
- var body1 = null, body2 = null;
|
|
|
- for (var index = 0; index < this._registeredMeshes.length; index++) {
|
|
|
- var registeredMesh = this._registeredMeshes[index];
|
|
|
- if (registeredMesh.mesh === mesh1) {
|
|
|
- body1 = registeredMesh.body.body;
|
|
|
+ impostor.mesh.computeWorldMatrix(true);
|
|
|
+ if (impostor.isBodyInitRequired()) {
|
|
|
+ if (!impostor.mesh.rotationQuaternion) {
|
|
|
+ impostor.mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(impostor.mesh.rotation.y, impostor.mesh.rotation.x, impostor.mesh.rotation.z);
|
|
|
}
|
|
|
- else if (registeredMesh.mesh === mesh2) {
|
|
|
- body2 = registeredMesh.body.body;
|
|
|
+ var deltaPosition = impostor.mesh.position.subtract(impostor.mesh.getBoundingInfo().boundingBox.center);
|
|
|
+ //calculate rotation to fit Oimo's needs (Euler...)
|
|
|
+ var bodyConfig = {
|
|
|
+ name: impostor.mesh.uniqueId,
|
|
|
+ //pos: [bbox.center.x, bbox.center.y, bbox.center.z],
|
|
|
+ //rot: [rot.x / OIMO.TO_RAD, rot.y / OIMO.TO_RAD, rot.z / OIMO.TO_RAD],
|
|
|
+ config: [impostor.getParam("mass"), impostor.getParam("friction"), impostor.getParam("restitution")],
|
|
|
+ size: [],
|
|
|
+ type: [],
|
|
|
+ pos: [],
|
|
|
+ rot: []
|
|
|
+ };
|
|
|
+ var impostors = [impostor];
|
|
|
+ function addToArray(parent) {
|
|
|
+ parent.getChildMeshes().forEach(function (m) {
|
|
|
+ if (m.physicImpostor) {
|
|
|
+ impostors.push(m.physicImpostor);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
+ addToArray(impostor.mesh);
|
|
|
+ impostors.forEach(function (i) {
|
|
|
+ //get the correct bounding box
|
|
|
+ var oldQuaternion = i.mesh.rotationQuaternion;
|
|
|
+ i.mesh.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 1);
|
|
|
+ i.mesh.computeWorldMatrix(true);
|
|
|
+ var bbox = i.mesh.getBoundingInfo().boundingBox;
|
|
|
+ var rot = new OIMO.Euler().setFromQuaternion({ x: impostor.mesh.rotationQuaternion.x, y: impostor.mesh.rotationQuaternion.y, z: impostor.mesh.rotationQuaternion.z, s: impostor.mesh.rotationQuaternion.w });
|
|
|
+ if (i === impostor) {
|
|
|
+ //Can also use Array.prototype.push.apply
|
|
|
+ bodyConfig.pos.push(bbox.center.x);
|
|
|
+ bodyConfig.pos.push(bbox.center.y);
|
|
|
+ bodyConfig.pos.push(bbox.center.z);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ bodyConfig.pos.push(i.mesh.position.x);
|
|
|
+ bodyConfig.pos.push(i.mesh.position.y);
|
|
|
+ bodyConfig.pos.push(i.mesh.position.z);
|
|
|
+ }
|
|
|
+ bodyConfig.rot.push(rot.x / OIMO.TO_RAD);
|
|
|
+ bodyConfig.rot.push(rot.y / OIMO.TO_RAD);
|
|
|
+ bodyConfig.rot.push(rot.z / OIMO.TO_RAD);
|
|
|
+ // register mesh
|
|
|
+ switch (i.type) {
|
|
|
+ case BABYLON.PhysicsEngine.SphereImpostor:
|
|
|
+ var radiusX = bbox.maximumWorld.x - bbox.minimumWorld.x;
|
|
|
+ var radiusY = bbox.maximumWorld.y - bbox.minimumWorld.y;
|
|
|
+ var radiusZ = bbox.maximumWorld.z - bbox.minimumWorld.z;
|
|
|
+ var size = Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2;
|
|
|
+ bodyConfig.type.push('sphere');
|
|
|
+ //due to the way oimo works with compounds, add 3 times
|
|
|
+ bodyConfig.size.push(size);
|
|
|
+ bodyConfig.size.push(size);
|
|
|
+ bodyConfig.size.push(size);
|
|
|
+ break;
|
|
|
+ case BABYLON.PhysicsEngine.PlaneImpostor:
|
|
|
+ //TODO Oimo now supports cylinder!
|
|
|
+ case BABYLON.PhysicsEngine.CylinderImpostor:
|
|
|
+ case BABYLON.PhysicsEngine.BoxImpostor:
|
|
|
+ var min = bbox.minimumWorld;
|
|
|
+ var max = bbox.maximumWorld;
|
|
|
+ var box = max.subtract(min);
|
|
|
+ var sizeX = this._checkWithEpsilon(box.x);
|
|
|
+ var sizeY = this._checkWithEpsilon(box.y);
|
|
|
+ var sizeZ = this._checkWithEpsilon(box.z);
|
|
|
+ bodyConfig.type.push('box');
|
|
|
+ bodyConfig.size.push(sizeX);
|
|
|
+ bodyConfig.size.push(sizeY);
|
|
|
+ bodyConfig.size.push(sizeZ);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ //actually not needed, but hey...
|
|
|
+ i.mesh.rotationQuaternion = oldQuaternion;
|
|
|
+ });
|
|
|
+ impostor.physicsBody = this.world.add(bodyConfig);
|
|
|
+ impostor.setDeltaPosition(deltaPosition);
|
|
|
}
|
|
|
- if (!body1 || !body2) {
|
|
|
- return false;
|
|
|
+ else {
|
|
|
+ this._tmpPositionVector.copyFromFloats(0, 0, 0);
|
|
|
}
|
|
|
- if (!options) {
|
|
|
- options = {};
|
|
|
+ this._tmpPositionVector.addInPlace(impostor.mesh.getBoundingInfo().boundingBox.center);
|
|
|
+ this.setPhysicsBodyTransformation(impostor, this._tmpPositionVector, impostor.mesh.rotationQuaternion);
|
|
|
+ };
|
|
|
+ OimoJSPlugin.prototype._checkWithEpsilon = function (value) {
|
|
|
+ return value < BABYLON.PhysicsEngine.Epsilon ? BABYLON.PhysicsEngine.Epsilon : value;
|
|
|
+ };
|
|
|
+ OimoJSPlugin.prototype.removePhysicsBody = function (impostor) {
|
|
|
+ this.world.removeRigidBody(impostor.physicsBody);
|
|
|
+ };
|
|
|
+ OimoJSPlugin.prototype.generateJoint = function (impostorJoint) {
|
|
|
+ var mainBody = impostorJoint.mainImpostor.physicsBody;
|
|
|
+ var connectedBody = impostorJoint.connectedImpostor.physicsBody;
|
|
|
+ if (!mainBody || !connectedBody) {
|
|
|
+ return;
|
|
|
}
|
|
|
- new OIMO.Link({
|
|
|
- type: options.type,
|
|
|
- body1: body1,
|
|
|
- body2: body2,
|
|
|
+ var jointData = impostorJoint.joint.jointData;
|
|
|
+ var options = jointData.nativeParams || {};
|
|
|
+ var type;
|
|
|
+ switch (impostorJoint.joint.type) {
|
|
|
+ case BABYLON.PhysicsJoint.BallAndSocketJoint:
|
|
|
+ type = "jointBall";
|
|
|
+ break;
|
|
|
+ case BABYLON.PhysicsJoint.DistanceJoint:
|
|
|
+ type = "jointDistance";
|
|
|
+ break;
|
|
|
+ case BABYLON.PhysicsJoint.PrismaticJoint:
|
|
|
+ type = "jointPrisme";
|
|
|
+ break;
|
|
|
+ case BABYLON.PhysicsJoint.SliderJoint:
|
|
|
+ type = "jointSlide";
|
|
|
+ break;
|
|
|
+ case BABYLON.PhysicsJoint.WheelJoint:
|
|
|
+ type = "jointWheel";
|
|
|
+ break;
|
|
|
+ case BABYLON.PhysicsJoint.HingeJoint:
|
|
|
+ default:
|
|
|
+ type = "jointHinge";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ impostorJoint.joint.physicsJoint = this.world.add({
|
|
|
+ type: type,
|
|
|
+ body1: mainBody.body,
|
|
|
+ body2: connectedBody.body,
|
|
|
min: options.min,
|
|
|
max: options.max,
|
|
|
- axe1: options.axe1,
|
|
|
- axe2: options.axe2,
|
|
|
- pos1: [pivot1.x, pivot1.y, pivot1.z],
|
|
|
- pos2: [pivot2.x, pivot2.y, pivot2.z],
|
|
|
+ axe1: jointData.mainAxis ? jointData.mainAxis.asArray() : null,
|
|
|
+ axe2: jointData.connectedAxis ? jointData.connectedAxis.asArray() : null,
|
|
|
+ pos1: jointData.mainPivot ? jointData.mainPivot.asArray() : null,
|
|
|
+ pos2: jointData.connectedPivot ? jointData.connectedPivot.asArray() : null,
|
|
|
collision: options.collision,
|
|
|
- spring: options.spring,
|
|
|
- world: this._world
|
|
|
+ spring: options.spring
|
|
|
});
|
|
|
- return true;
|
|
|
};
|
|
|
- OimoJSPlugin.prototype.dispose = function () {
|
|
|
- this._world.clear();
|
|
|
- while (this._registeredMeshes.length) {
|
|
|
- this.unregisterMesh(this._registeredMeshes[0].mesh);
|
|
|
- }
|
|
|
+ OimoJSPlugin.prototype.removeJoint = function (joint) {
|
|
|
+ //TODO
|
|
|
};
|
|
|
OimoJSPlugin.prototype.isSupported = function () {
|
|
|
return OIMO !== undefined;
|
|
|
};
|
|
|
- OimoJSPlugin.prototype.getWorldObject = function () {
|
|
|
- return this._world;
|
|
|
- };
|
|
|
- OimoJSPlugin.prototype.getPhysicsBodyOfMesh = function (mesh) {
|
|
|
- for (var index = 0; index < this._registeredMeshes.length; index++) {
|
|
|
- var registeredMesh = this._registeredMeshes[index];
|
|
|
- if (registeredMesh.mesh === mesh) {
|
|
|
- return registeredMesh.body;
|
|
|
+ OimoJSPlugin.prototype.setTransformationFromPhysicsBody = function (impostor) {
|
|
|
+ if (!impostor.physicsBody.sleeping) {
|
|
|
+ //TODO check that
|
|
|
+ if (impostor.physicsBody.shapes.next) {
|
|
|
+ var parentShape = this._getLastShape(impostor.physicsBody);
|
|
|
+ impostor.mesh.position.x = parentShape.position.x * OIMO.WORLD_SCALE;
|
|
|
+ impostor.mesh.position.y = parentShape.position.y * OIMO.WORLD_SCALE;
|
|
|
+ impostor.mesh.position.z = parentShape.position.z * OIMO.WORLD_SCALE;
|
|
|
}
|
|
|
+ else {
|
|
|
+ impostor.mesh.position.copyFrom(impostor.physicsBody.getPosition());
|
|
|
+ }
|
|
|
+ impostor.mesh.rotationQuaternion.copyFrom(impostor.physicsBody.getQuaternion());
|
|
|
}
|
|
|
- return null;
|
|
|
+ };
|
|
|
+ OimoJSPlugin.prototype.setPhysicsBodyTransformation = function (impostor, newPosition, newRotation) {
|
|
|
+ var body = impostor.physicsBody;
|
|
|
+ body.setPosition(newPosition);
|
|
|
+ body.setQuaternion(newRotation);
|
|
|
+ body.sleeping = false;
|
|
|
+ //force Oimo to update the body's position
|
|
|
+ body.updatePosition(1);
|
|
|
};
|
|
|
OimoJSPlugin.prototype._getLastShape = function (body) {
|
|
|
var lastShape = body.shapes;
|
|
@@ -282,50 +228,10 @@ var BABYLON;
|
|
|
}
|
|
|
return lastShape;
|
|
|
};
|
|
|
- OimoJSPlugin.prototype.runOneStep = function (time) {
|
|
|
- this._world.step();
|
|
|
- // Update the position of all registered meshes
|
|
|
- var i = this._registeredMeshes.length;
|
|
|
- var m;
|
|
|
- while (i--) {
|
|
|
- var body = this._registeredMeshes[i].body.body;
|
|
|
- var mesh = this._registeredMeshes[i].mesh;
|
|
|
- if (!this._registeredMeshes[i].delta) {
|
|
|
- this._registeredMeshes[i].delta = BABYLON.Vector3.Zero();
|
|
|
- }
|
|
|
- if (!body.sleeping) {
|
|
|
- //TODO check that
|
|
|
- if (body.shapes.next) {
|
|
|
- var parentShape = this._getLastShape(body);
|
|
|
- mesh.position.x = parentShape.position.x * OIMO.WORLD_SCALE;
|
|
|
- mesh.position.y = parentShape.position.y * OIMO.WORLD_SCALE;
|
|
|
- mesh.position.z = parentShape.position.z * OIMO.WORLD_SCALE;
|
|
|
- }
|
|
|
- else {
|
|
|
- mesh.position.copyFrom(body.getPosition()).addInPlace(this._registeredMeshes[i].delta);
|
|
|
- }
|
|
|
- mesh.rotationQuaternion.copyFrom(body.getQuaternion());
|
|
|
- mesh.computeWorldMatrix();
|
|
|
- }
|
|
|
- //check if the collide callback is set.
|
|
|
- if (mesh.onPhysicsCollide) {
|
|
|
- var meshUniqueName = mesh.uniqueId;
|
|
|
- var contact = this._world.contacts;
|
|
|
- while (contact !== null) {
|
|
|
- //is this body colliding with any other?
|
|
|
- if ((contact.body1.name == mesh.uniqueId || contact.body2.name == mesh.uniqueId) && contact.touching && !contact.body1.sleeping && !contact.body2.sleeping) {
|
|
|
- var otherUniqueId = contact.body1.name == mesh.uniqueId ? contact.body2.name : contact.body1.name;
|
|
|
- //get the mesh and execute the callback
|
|
|
- var otherMesh = mesh.getScene().getMeshByUniqueID(otherUniqueId);
|
|
|
- if (otherMesh)
|
|
|
- mesh.onPhysicsCollide(otherMesh, contact);
|
|
|
- }
|
|
|
- contact = contact.next;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ OimoJSPlugin.prototype.dispose = function () {
|
|
|
+ this.world.clear();
|
|
|
};
|
|
|
return OimoJSPlugin;
|
|
|
- })();
|
|
|
+ }());
|
|
|
BABYLON.OimoJSPlugin = OimoJSPlugin;
|
|
|
})(BABYLON || (BABYLON = {}));
|