|
@@ -7,8 +7,23 @@ module BABYLON {
|
|
|
nativeOptions?: any;
|
|
|
}
|
|
|
|
|
|
+ export interface IPhysicsEnabledObject {
|
|
|
+ position: Vector3;
|
|
|
+ rotationQuaternion: Quaternion;
|
|
|
+ scaling: Vector3;
|
|
|
+ rotation?: Vector3;
|
|
|
+ parent?: any;
|
|
|
+ getBoundingInfo?(): BoundingInfo;
|
|
|
+ computeWorldMatrix?(force: boolean): void;
|
|
|
+ getChildMeshes?(): Array<AbstractMesh>;
|
|
|
+ getVerticesData?(kind: string): Array<number> | Float32Array;
|
|
|
+ getIndices?(): Array<number>| Int32Array;
|
|
|
+ }
|
|
|
+
|
|
|
export class PhysicsImpostor {
|
|
|
|
|
|
+ public static DEFAULT_OBJECT_SIZE: Vector3 = new BABYLON.Vector3(1, 1, 1);
|
|
|
+
|
|
|
private _physicsEngine: PhysicsEngine;
|
|
|
//The native cannon/oimo/energy physics body object.
|
|
|
private _physicsBody: any;
|
|
@@ -21,27 +36,39 @@ module BABYLON {
|
|
|
private _deltaPosition: Vector3 = Vector3.Zero();
|
|
|
private _deltaRotation: Quaternion;
|
|
|
private _deltaRotationConjugated: Quaternion;
|
|
|
-
|
|
|
+
|
|
|
//If set, this is this impostor's parent
|
|
|
private _parent: PhysicsImpostor;
|
|
|
|
|
|
+ //set by the physics engine when adding this impostor to the array.
|
|
|
+ public uniqueId: number;
|
|
|
+
|
|
|
private _joints: Array<{
|
|
|
joint: PhysicsJoint,
|
|
|
otherImpostor: PhysicsImpostor
|
|
|
}>;
|
|
|
|
|
|
- constructor(private _mesh: AbstractMesh, public type: number, private _options: PhysicsImpostorParameters = { mass: 0 }) {
|
|
|
- this._physicsEngine = this._mesh.getScene().getPhysicsEngine();
|
|
|
+ constructor(public object: IPhysicsEnabledObject, public type: number, private _options: PhysicsImpostorParameters = { mass: 0 }, private _scene: Scene) {
|
|
|
+ this._physicsEngine = this._scene.getPhysicsEngine();
|
|
|
if (!this._physicsEngine) {
|
|
|
Tools.Error("Physics not enabled. Please use scene.enablePhysics(...) before creating impostors.")
|
|
|
} else {
|
|
|
+ //set the object's quaternion, if not set
|
|
|
+ if (!this.object.rotationQuaternion) {
|
|
|
+ if (this.object.rotation) {
|
|
|
+ this.object.rotationQuaternion = Quaternion.RotationYawPitchRoll(this.object.rotation.y, this.object.rotation.x, this.object.rotation.z);
|
|
|
+ } else {
|
|
|
+ this.object.rotationQuaternion = new Quaternion();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
//default options params
|
|
|
this._options.mass = (_options.mass === void 0) ? 0 : _options.mass
|
|
|
this._options.friction = (_options.friction === void 0) ? 0.2 : _options.friction
|
|
|
this._options.restitution = (_options.restitution === void 0) ? 0.2 : _options.restitution
|
|
|
this._joints = [];
|
|
|
//If the mesh has a parent, don't initialize the physicsBody. Instead wait for the parent to do that.
|
|
|
- if (!this._mesh.parent) {
|
|
|
+ if (!this.object.parent) {
|
|
|
this._init();
|
|
|
}
|
|
|
}
|
|
@@ -63,9 +90,9 @@ module BABYLON {
|
|
|
}
|
|
|
|
|
|
private _getPhysicsParent(): PhysicsImpostor {
|
|
|
- if (this.mesh.parent instanceof AbstractMesh) {
|
|
|
- var parentMesh: AbstractMesh = <AbstractMesh>this.mesh.parent;
|
|
|
- return parentMesh.getPhysicsImpostor();
|
|
|
+ if (this.object.parent instanceof AbstractMesh) {
|
|
|
+ var parentMesh: AbstractMesh = <AbstractMesh>this.object.parent;
|
|
|
+ return parentMesh.physicsImpostor;
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
@@ -92,9 +119,9 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public get mesh(): AbstractMesh {
|
|
|
+ /*public get mesh(): AbstractMesh {
|
|
|
return this._mesh;
|
|
|
- }
|
|
|
+ }*/
|
|
|
|
|
|
/**
|
|
|
* Gets the body that holds this impostor. Either its own, or its parent.
|
|
@@ -122,6 +149,23 @@ module BABYLON {
|
|
|
this._bodyUpdateRequired = false;
|
|
|
}
|
|
|
|
|
|
+ public getObjectExtendSize(): Vector3 {
|
|
|
+ if (this.object.getBoundingInfo) {
|
|
|
+ this.object.computeWorldMatrix && this.object.computeWorldMatrix(true);
|
|
|
+ return this.object.getBoundingInfo().boundingBox.extendSize.scale(2).multiply(this.object.scaling)
|
|
|
+ } else {
|
|
|
+ return PhysicsImpostor.DEFAULT_OBJECT_SIZE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public getObjectCenter(): Vector3 {
|
|
|
+ if (this.object.getBoundingInfo) {
|
|
|
+ return this.object.getBoundingInfo().boundingBox.center;
|
|
|
+ } else {
|
|
|
+ return this.object.position;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Get a specific parametes from the options parameter.
|
|
|
*/
|
|
@@ -136,7 +180,7 @@ module BABYLON {
|
|
|
this._options[paramName] = value;
|
|
|
this._bodyUpdateRequired = true;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Specifically change the body's mass option. Won't recreate the physics body object
|
|
|
*/
|
|
@@ -146,9 +190,9 @@ module BABYLON {
|
|
|
}
|
|
|
this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);
|
|
|
}
|
|
|
-
|
|
|
- public getLinearVelocity() : Vector3 {
|
|
|
- return this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this);
|
|
|
+
|
|
|
+ public getLinearVelocity(): Vector3 {
|
|
|
+ return this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -157,18 +201,18 @@ module BABYLON {
|
|
|
public setLinearVelocity(velocity: Vector3) {
|
|
|
this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
|
|
|
}
|
|
|
-
|
|
|
- public getAngularVelocity() : Vector3 {
|
|
|
- return this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this);
|
|
|
+
|
|
|
+ public getAngularVelocity(): Vector3 {
|
|
|
+ return this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Set the body's linear velocity.
|
|
|
*/
|
|
|
public setAngularVelocity(velocity: Vector3) {
|
|
|
this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Execute a function with the physics plugin native code.
|
|
|
* Provide a function the will have two variables - the world object and the physics body object.
|
|
@@ -238,12 +282,12 @@ module BABYLON {
|
|
|
*/
|
|
|
public beforeStep = () => {
|
|
|
|
|
|
- this.mesh.position.subtractToRef(this._deltaPosition, this._tmpPositionWithDelta);
|
|
|
+ this.object.position.subtractToRef(this._deltaPosition, this._tmpPositionWithDelta);
|
|
|
//conjugate deltaRotation
|
|
|
if (this._deltaRotationConjugated) {
|
|
|
- this.mesh.rotationQuaternion.multiplyToRef(this._deltaRotationConjugated, this._tmpRotationWithDelta);
|
|
|
+ this.object.rotationQuaternion.multiplyToRef(this._deltaRotationConjugated, this._tmpRotationWithDelta);
|
|
|
} else {
|
|
|
- this._tmpRotationWithDelta.copyFrom(this.mesh.rotationQuaternion);
|
|
|
+ this._tmpRotationWithDelta.copyFrom(this.object.rotationQuaternion);
|
|
|
}
|
|
|
|
|
|
this._physicsEngine.getPhysicsPlugin().setPhysicsBodyTransformation(this, this._tmpPositionWithDelta, this._tmpRotationWithDelta);
|
|
@@ -263,12 +307,12 @@ module BABYLON {
|
|
|
|
|
|
this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(this);
|
|
|
|
|
|
- this.mesh.position.addInPlace(this._deltaPosition)
|
|
|
+ this.object.position.addInPlace(this._deltaPosition)
|
|
|
if (this._deltaRotation) {
|
|
|
- this.mesh.rotationQuaternion.multiplyInPlace(this._deltaRotation);
|
|
|
+ this.object.rotationQuaternion.multiplyInPlace(this._deltaRotation);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
//event and body object due to cannon's event-based architecture.
|
|
|
public onCollide = (e: { body: any }) => {
|
|
|
var otherImpostor = this._physicsEngine.getImpostorWithPhysicsBody(e.body);
|
|
@@ -313,14 +357,14 @@ module BABYLON {
|
|
|
})
|
|
|
this._physicsEngine.addJoint(this, otherImpostor, joint);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Will keep this body still, in a sleep mode.
|
|
|
*/
|
|
|
public sleep() {
|
|
|
this._physicsEngine.getPhysicsPlugin().sleepBody(this);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Wake the body up.
|
|
|
*/
|
|
@@ -328,19 +372,19 @@ module BABYLON {
|
|
|
this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
|
|
|
}
|
|
|
|
|
|
- public dispose(disposeChildren: boolean = true) {
|
|
|
+ public dispose(/*disposeChildren: boolean = true*/) {
|
|
|
this.physicsBody = null;
|
|
|
if (this.parent) {
|
|
|
this.parent.forceUpdate();
|
|
|
} else {
|
|
|
- this.mesh.getChildMeshes().forEach(function(mesh) {
|
|
|
+ /*this._object.getChildMeshes().forEach(function(mesh) {
|
|
|
if (mesh.physicsImpostor) {
|
|
|
if (disposeChildren) {
|
|
|
mesh.physicsImpostor.dispose();
|
|
|
mesh.physicsImpostor = null;
|
|
|
}
|
|
|
}
|
|
|
- })
|
|
|
+ })*/
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -355,7 +399,7 @@ module BABYLON {
|
|
|
this._deltaRotation.copyFrom(rotation);
|
|
|
this._deltaRotationConjugated = this._deltaRotation.conjugate();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
//Impostor types
|
|
|
public static NoImpostor = 0;
|
|
|
public static SphereImpostor = 1;
|