|
@@ -64,13 +64,13 @@
|
|
}
|
|
}
|
|
|
|
|
|
var shape = this._createShape(impostor);
|
|
var shape = this._createShape(impostor);
|
|
-
|
|
|
|
|
|
+
|
|
//unregister events, if body is being changed
|
|
//unregister events, if body is being changed
|
|
var oldBody = impostor.physicsBody;
|
|
var oldBody = impostor.physicsBody;
|
|
if (oldBody) {
|
|
if (oldBody) {
|
|
this.removePhysicsBody(impostor);
|
|
this.removePhysicsBody(impostor);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
//create the body and material
|
|
//create the body and material
|
|
var material = this._addMaterial("mat-" + impostor.mesh.uniqueId, impostor.getParam("friction"), impostor.getParam("restitution"));
|
|
var material = this._addMaterial("mat-" + impostor.mesh.uniqueId, impostor.getParam("friction"), impostor.getParam("restitution"));
|
|
|
|
|
|
@@ -91,11 +91,11 @@
|
|
this.world.addEventListener("postStep", impostor.afterStep);
|
|
this.world.addEventListener("postStep", impostor.afterStep);
|
|
impostor.physicsBody.addShape(shape);
|
|
impostor.physicsBody.addShape(shape);
|
|
this.world.add(impostor.physicsBody);
|
|
this.world.add(impostor.physicsBody);
|
|
-
|
|
|
|
|
|
+
|
|
//try to keep the body moving in the right direction by taking old properties.
|
|
//try to keep the body moving in the right direction by taking old properties.
|
|
//Should be tested!
|
|
//Should be tested!
|
|
if (oldBody) {
|
|
if (oldBody) {
|
|
- ['force', 'torque', 'velocity', 'angularVelocity'].forEach(function (param) {
|
|
|
|
|
|
+ ['force', 'torque', 'velocity', 'angularVelocity'].forEach(function(param) {
|
|
impostor.physicsBody[param].copy(oldBody[param]);
|
|
impostor.physicsBody[param].copy(oldBody[param]);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
@@ -189,6 +189,8 @@
|
|
localAnchorB: constraintData.pivotB
|
|
localAnchorB: constraintData.pivotB
|
|
});
|
|
});
|
|
break;
|
|
break;
|
|
|
|
+ case PhysicsJoint.PointToPointJoint:
|
|
|
|
+ case PhysicsJoint.BallAndSocketJoint:
|
|
default:
|
|
default:
|
|
constraint = new CANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
|
|
constraint = new CANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
|
|
break;
|
|
break;
|
|
@@ -200,7 +202,7 @@
|
|
if (impostorJoint.joint.type !== PhysicsJoint.SpringJoint) {
|
|
if (impostorJoint.joint.type !== PhysicsJoint.SpringJoint) {
|
|
this.world.addConstraint(constraint);
|
|
this.world.addConstraint(constraint);
|
|
} else {
|
|
} else {
|
|
- impostorJoint.mainImpostor.registerAfterPhysicsStep(function () {
|
|
|
|
|
|
+ impostorJoint.mainImpostor.registerAfterPhysicsStep(function() {
|
|
constraint.applyForce();
|
|
constraint.applyForce();
|
|
});
|
|
});
|
|
}
|
|
}
|
|
@@ -236,17 +238,16 @@
|
|
|
|
|
|
private _createShape(impostor: PhysicsImpostor) {
|
|
private _createShape(impostor: PhysicsImpostor) {
|
|
var mesh = impostor.mesh;
|
|
var mesh = impostor.mesh;
|
|
-
|
|
|
|
|
|
+
|
|
//get the correct bounding box
|
|
//get the correct bounding box
|
|
var oldQuaternion = mesh.rotationQuaternion;
|
|
var oldQuaternion = mesh.rotationQuaternion;
|
|
mesh.rotationQuaternion = new Quaternion(0, 0, 0, 1);
|
|
mesh.rotationQuaternion = new Quaternion(0, 0, 0, 1);
|
|
mesh.computeWorldMatrix(true);
|
|
mesh.computeWorldMatrix(true);
|
|
|
|
|
|
var returnValue;
|
|
var returnValue;
|
|
-
|
|
|
|
|
|
+ var bbox = mesh.getBoundingInfo().boundingBox;
|
|
switch (impostor.type) {
|
|
switch (impostor.type) {
|
|
case PhysicsEngine.SphereImpostor:
|
|
case PhysicsEngine.SphereImpostor:
|
|
- var bbox = mesh.getBoundingInfo().boundingBox;
|
|
|
|
var radiusX = bbox.maximumWorld.x - bbox.minimumWorld.x;
|
|
var radiusX = bbox.maximumWorld.x - bbox.minimumWorld.x;
|
|
var radiusY = bbox.maximumWorld.y - bbox.minimumWorld.y;
|
|
var radiusY = bbox.maximumWorld.y - bbox.minimumWorld.y;
|
|
var radiusZ = bbox.maximumWorld.z - bbox.minimumWorld.z;
|
|
var radiusZ = bbox.maximumWorld.z - bbox.minimumWorld.z;
|
|
@@ -255,29 +256,34 @@
|
|
|
|
|
|
break;
|
|
break;
|
|
//TMP also for cylinder - TODO Cannon supports cylinder natively.
|
|
//TMP also for cylinder - TODO Cannon supports cylinder natively.
|
|
- case PhysicsEngine.CylinderImpostor:
|
|
|
|
- Tools.Warn("CylinderImposter not yet implemented, using BoxImposter instead");
|
|
|
|
- case PhysicsEngine.BoxImpostor:
|
|
|
|
- bbox = mesh.getBoundingInfo().boundingBox;
|
|
|
|
|
|
+ case PhysicsImpostor.CylinderImpostor:
|
|
|
|
+ var min = bbox.minimumWorld;
|
|
|
|
+ var max = bbox.maximumWorld;
|
|
|
|
+ var box = max.subtract(min);
|
|
|
|
+ returnValue = new CANNON.Cylinder(this._checkWithEpsilon(box.x) / 2, this._checkWithEpsilon(box.x) / 2, this._checkWithEpsilon(box.y), 16);
|
|
|
|
+ break;
|
|
|
|
+ case PhysicsImpostor.BoxImpostor:
|
|
var min = bbox.minimumWorld;
|
|
var min = bbox.minimumWorld;
|
|
var max = bbox.maximumWorld;
|
|
var max = bbox.maximumWorld;
|
|
var box = max.subtract(min).scale(0.5);
|
|
var box = max.subtract(min).scale(0.5);
|
|
returnValue = new CANNON.Box(new CANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));
|
|
returnValue = new CANNON.Box(new CANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));
|
|
break;
|
|
break;
|
|
- case PhysicsEngine.PlaneImpostor:
|
|
|
|
|
|
+ case PhysicsImpostor.PlaneImpostor:
|
|
Tools.Warn("Attention, PlaneImposter might not behave as you expect. Consider using BoxImposter instead");
|
|
Tools.Warn("Attention, PlaneImposter might not behave as you expect. Consider using BoxImposter instead");
|
|
returnValue = new CANNON.Plane();
|
|
returnValue = new CANNON.Plane();
|
|
break;
|
|
break;
|
|
- case PhysicsEngine.MeshImpostor:
|
|
|
|
|
|
+ case PhysicsImpostor.MeshImpostor:
|
|
var rawVerts = mesh.getVerticesData(VertexBuffer.PositionKind);
|
|
var rawVerts = mesh.getVerticesData(VertexBuffer.PositionKind);
|
|
var rawFaces = mesh.getIndices();
|
|
var rawFaces = mesh.getIndices();
|
|
Tools.Warn("MeshImpostor only collides against spheres.");
|
|
Tools.Warn("MeshImpostor only collides against spheres.");
|
|
returnValue = new CANNON.Trimesh(rawVerts, rawFaces);
|
|
returnValue = new CANNON.Trimesh(rawVerts, rawFaces);
|
|
break;
|
|
break;
|
|
- case PhysicsEngine.HeightmapImpostor:
|
|
|
|
|
|
+ case PhysicsImpostor.HeightmapImpostor:
|
|
returnValue = this._createHeightmap(mesh);
|
|
returnValue = this._createHeightmap(mesh);
|
|
break;
|
|
break;
|
|
-
|
|
|
|
|
|
+ case PhysicsImpostor.ParticleImpostor:
|
|
|
|
+ returnValue = new CANNON.Particle();
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
|
|
mesh.rotationQuaternion = oldQuaternion;
|
|
mesh.rotationQuaternion = oldQuaternion;
|
|
@@ -288,7 +294,7 @@
|
|
private _createHeightmap(mesh: AbstractMesh, pointDepth?: number) {
|
|
private _createHeightmap(mesh: AbstractMesh, pointDepth?: number) {
|
|
var pos = mesh.getVerticesData(VertexBuffer.PositionKind);
|
|
var pos = mesh.getVerticesData(VertexBuffer.PositionKind);
|
|
var matrix = [];
|
|
var matrix = [];
|
|
-
|
|
|
|
|
|
+
|
|
//For now pointDepth will not be used and will be automatically calculated.
|
|
//For now pointDepth will not be used and will be automatically calculated.
|
|
//Future reference - try and find the best place to add a reference to the pointDepth variable.
|
|
//Future reference - try and find the best place to add a reference to the pointDepth variable.
|
|
var arraySize = pointDepth || ~~(Math.sqrt(pos.length / 3) - 1);
|
|
var arraySize = pointDepth || ~~(Math.sqrt(pos.length / 3) - 1);
|
|
@@ -338,7 +344,7 @@
|
|
var shape = new CANNON.Heightfield(matrix, {
|
|
var shape = new CANNON.Heightfield(matrix, {
|
|
elementSize: elementSize
|
|
elementSize: elementSize
|
|
});
|
|
});
|
|
-
|
|
|
|
|
|
+
|
|
//For future reference, needed for body transformation
|
|
//For future reference, needed for body transformation
|
|
shape.minY = minY;
|
|
shape.minY = minY;
|
|
|
|
|
|
@@ -364,35 +370,35 @@
|
|
var quaternion = mesh.rotationQuaternion;
|
|
var quaternion = mesh.rotationQuaternion;
|
|
this._tmpPosition.copyFrom(mesh.getBoundingInfo().boundingBox.center);
|
|
this._tmpPosition.copyFrom(mesh.getBoundingInfo().boundingBox.center);
|
|
//is shape is a plane or a heightmap, it must be rotated 90 degs in the X axis.
|
|
//is shape is a plane or a heightmap, it must be rotated 90 degs in the X axis.
|
|
- if (impostor.type === PhysicsEngine.PlaneImpostor || impostor.type === PhysicsEngine.HeightmapImpostor) {
|
|
|
|
|
|
+ if (impostor.type === PhysicsImpostor.PlaneImpostor || impostor.type === PhysicsImpostor.HeightmapImpostor || impostor.type === PhysicsImpostor.CylinderImpostor) {
|
|
//-90 DEG in X, precalculated
|
|
//-90 DEG in X, precalculated
|
|
quaternion = quaternion.multiply(this._minus90X);
|
|
quaternion = quaternion.multiply(this._minus90X);
|
|
//Invert! (Precalculated, 90 deg in X)
|
|
//Invert! (Precalculated, 90 deg in X)
|
|
//No need to clone. this will never change.
|
|
//No need to clone. this will never change.
|
|
impostor.setDeltaRotation(this._plus90X);
|
|
impostor.setDeltaRotation(this._plus90X);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
//If it is a heightfield, if should be centered.
|
|
//If it is a heightfield, if should be centered.
|
|
if (impostor.type === PhysicsEngine.HeightmapImpostor) {
|
|
if (impostor.type === PhysicsEngine.HeightmapImpostor) {
|
|
-
|
|
|
|
|
|
+
|
|
//calculate the correct body position:
|
|
//calculate the correct body position:
|
|
var rotationQuaternion = mesh.rotationQuaternion;
|
|
var rotationQuaternion = mesh.rotationQuaternion;
|
|
mesh.rotationQuaternion = this._tmpUnityRotation;
|
|
mesh.rotationQuaternion = this._tmpUnityRotation;
|
|
mesh.computeWorldMatrix(true);
|
|
mesh.computeWorldMatrix(true);
|
|
-
|
|
|
|
|
|
+
|
|
//get original center with no rotation
|
|
//get original center with no rotation
|
|
var center = mesh.getBoundingInfo().boundingBox.center.clone();
|
|
var center = mesh.getBoundingInfo().boundingBox.center.clone();
|
|
|
|
|
|
var oldPivot = mesh.getPivotMatrix() || Matrix.Translation(0, 0, 0);
|
|
var oldPivot = mesh.getPivotMatrix() || Matrix.Translation(0, 0, 0);
|
|
-
|
|
|
|
|
|
+
|
|
//rotation is back
|
|
//rotation is back
|
|
mesh.rotationQuaternion = rotationQuaternion;
|
|
mesh.rotationQuaternion = rotationQuaternion;
|
|
-
|
|
|
|
|
|
+
|
|
//calculate the new center using a pivot (since Cannon.js doesn't center height maps)
|
|
//calculate the new center using a pivot (since Cannon.js doesn't center height maps)
|
|
var p = Matrix.Translation(mesh.getBoundingInfo().boundingBox.extendSize.x, 0, -mesh.getBoundingInfo().boundingBox.extendSize.z);
|
|
var p = Matrix.Translation(mesh.getBoundingInfo().boundingBox.extendSize.x, 0, -mesh.getBoundingInfo().boundingBox.extendSize.z);
|
|
mesh.setPivotMatrix(p);
|
|
mesh.setPivotMatrix(p);
|
|
mesh.computeWorldMatrix(true);
|
|
mesh.computeWorldMatrix(true);
|
|
-
|
|
|
|
|
|
+
|
|
//calculate the translation
|
|
//calculate the translation
|
|
var translation = mesh.getBoundingInfo().boundingBox.center.subtract(center).subtract(mesh.position).negate();
|
|
var translation = mesh.getBoundingInfo().boundingBox.center.subtract(center).subtract(mesh.position).negate();
|
|
|
|
|
|
@@ -435,7 +441,7 @@
|
|
public setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3) {
|
|
public setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3) {
|
|
impostor.physicsBody.angularVelocity.copy(velocity);
|
|
impostor.physicsBody.angularVelocity.copy(velocity);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
public getLinearVelocity(impostor: PhysicsImpostor): Vector3 {
|
|
public getLinearVelocity(impostor: PhysicsImpostor): Vector3 {
|
|
var v = impostor.physicsBody.velocity;
|
|
var v = impostor.physicsBody.velocity;
|
|
if (!v) return null;
|
|
if (!v) return null;
|
|
@@ -459,28 +465,28 @@
|
|
public wakeUpBody(impostor: PhysicsImpostor) {
|
|
public wakeUpBody(impostor: PhysicsImpostor) {
|
|
impostor.physicsBody.wakeUp();
|
|
impostor.physicsBody.wakeUp();
|
|
}
|
|
}
|
|
-
|
|
|
|
- public updateDistanceJoint(joint: PhysicsJoint, maxDistance:number, minDistance?: number) {
|
|
|
|
|
|
+
|
|
|
|
+ public updateDistanceJoint(joint: PhysicsJoint, maxDistance: number, minDistance?: number) {
|
|
joint.physicsJoint.distance = maxDistance;
|
|
joint.physicsJoint.distance = maxDistance;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
private enableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
|
|
private enableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
|
|
- if(!motorIndex) {
|
|
|
|
|
|
+ if (!motorIndex) {
|
|
joint.physicsJoint.enableMotor();
|
|
joint.physicsJoint.enableMotor();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
private disableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
|
|
private disableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
|
|
- if(!motorIndex) {
|
|
|
|
|
|
+ if (!motorIndex) {
|
|
joint.physicsJoint.disableMotor();
|
|
joint.physicsJoint.disableMotor();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
public setMotor(joint: IMotorEnabledJoint, speed?: number, maxForce?: number, motorIndex?: number) {
|
|
public setMotor(joint: IMotorEnabledJoint, speed?: number, maxForce?: number, motorIndex?: number) {
|
|
- if(!motorIndex) {
|
|
|
|
|
|
+ if (!motorIndex) {
|
|
joint.physicsJoint.enableMotor();
|
|
joint.physicsJoint.enableMotor();
|
|
joint.physicsJoint.setMotorSpeed(speed);
|
|
joint.physicsJoint.setMotorSpeed(speed);
|
|
- if(maxForce) {
|
|
|
|
|
|
+ if (maxForce) {
|
|
this.setLimit(joint, maxForce);
|
|
this.setLimit(joint, maxForce);
|
|
}
|
|
}
|
|
//a hack for force application
|
|
//a hack for force application
|
|
@@ -494,12 +500,12 @@
|
|
bodyTorque.vadd(torque, bodyTorque);*/
|
|
bodyTorque.vadd(torque, bodyTorque);*/
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
public setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number) {
|
|
public setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number) {
|
|
joint.physicsJoint.motorEquation.maxForce = upperLimit;
|
|
joint.physicsJoint.motorEquation.maxForce = upperLimit;
|
|
- joint.physicsJoint.motorEquation.minForce = lowerLimit || -upperLimit;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ joint.physicsJoint.motorEquation.minForce = lowerLimit === void 0 ? -upperLimit : lowerLimit;
|
|
|
|
+ }
|
|
|
|
+
|
|
public dispose() {
|
|
public dispose() {
|
|
//nothing to do, actually.
|
|
//nothing to do, actually.
|
|
}
|
|
}
|