123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- import { Nullable } from "../types";
- import { Logger } from "../Misc/logger";
- import { Observable, Observer } from "../Misc/observable";
- import { Vector3 } from "../Maths/math";
- import { Mesh } from "../Meshes/mesh";
- import { AbstractMesh } from "../Meshes/abstractMesh";
- import { ISceneComponent, SceneComponentConstants } from "../sceneComponent";
- import { Scene } from "../scene";
- import { Node } from "../node";
- import { IPhysicsEngine, IPhysicsEnginePlugin } from "./IPhysicsEngine";
- import { PhysicsEngine } from "./physicsEngine";
- import { PhysicsImpostor } from "./physicsImpostor";
- import { PhysicsJoint } from "./physicsJoint";
- declare module "../scene" {
- export interface Scene {
- /** @hidden (Backing field) */
- _physicsEngine: Nullable<IPhysicsEngine>;
- /**
- * Gets the current physics engine
- * @returns a IPhysicsEngine or null if none attached
- */
- getPhysicsEngine(): Nullable<IPhysicsEngine>;
- /**
- * Enables physics to the current scene
- * @param gravity defines the scene's gravity for the physics engine
- * @param plugin defines the physics engine to be used. defaults to OimoJS.
- * @return a boolean indicating if the physics engine was initialized
- */
- enablePhysics(gravity: Nullable<Vector3>, plugin?: IPhysicsEnginePlugin): boolean;
- /**
- * Disables and disposes the physics engine associated with the scene
- */
- disablePhysicsEngine(): void;
- /**
- * Gets a boolean indicating if there is an active physics engine
- * @returns a boolean indicating if there is an active physics engine
- */
- isPhysicsEnabled(): boolean;
- /**
- * Deletes a physics compound impostor
- * @param compound defines the compound to delete
- */
- deleteCompoundImpostor(compound: any): void;
- /**
- * An event triggered when physic simulation is about to be run
- */
- onBeforePhysicsObservable: Observable<Scene>;
- /**
- * An event triggered when physic simulation has been done
- */
- onAfterPhysicsObservable: Observable<Scene>;
- }
- }
- /**
- * Gets the current physics engine
- * @returns a IPhysicsEngine or null if none attached
- */
- Scene.prototype.getPhysicsEngine = function(): Nullable<IPhysicsEngine> {
- return this._physicsEngine;
- };
- /**
- * Enables physics to the current scene
- * @param gravity defines the scene's gravity for the physics engine
- * @param plugin defines the physics engine to be used. defaults to OimoJS.
- * @return a boolean indicating if the physics engine was initialized
- */
- Scene.prototype.enablePhysics = function(gravity: Nullable<Vector3> = null, plugin?: IPhysicsEnginePlugin): boolean {
- if (this._physicsEngine) {
- return true;
- }
- // Register the component to the scene
- let component = this._getComponent(SceneComponentConstants.NAME_PHYSICSENGINE) as PhysicsEngineSceneComponent;
- if (!component) {
- component = new PhysicsEngineSceneComponent(this);
- this._addComponent(component);
- }
- try {
- this._physicsEngine = new PhysicsEngine(gravity, plugin);
- return true;
- } catch (e) {
- Logger.Error(e.message);
- return false;
- }
- };
- /**
- * Disables and disposes the physics engine associated with the scene
- */
- Scene.prototype.disablePhysicsEngine = function(): void {
- if (!this._physicsEngine) {
- return;
- }
- this._physicsEngine.dispose();
- this._physicsEngine = null;
- };
- /**
- * Gets a boolean indicating if there is an active physics engine
- * @returns a boolean indicating if there is an active physics engine
- */
- Scene.prototype.isPhysicsEnabled = function(): boolean {
- return this._physicsEngine !== undefined;
- };
- /**
- * Deletes a physics compound impostor
- * @param compound defines the compound to delete
- */
- Scene.prototype.deleteCompoundImpostor = function(compound: any): void {
- var mesh: AbstractMesh = compound.parts[0].mesh;
- if (mesh.physicsImpostor) {
- mesh.physicsImpostor.dispose(/*true*/);
- mesh.physicsImpostor = null;
- }
- };
- /** @hidden */
- Scene.prototype._advancePhysicsEngineStep = function(step: number) {
- if (this._physicsEngine) {
- this.onBeforePhysicsObservable.notifyObservers(this);
- this._physicsEngine._step(step / 1000);
- this.onAfterPhysicsObservable.notifyObservers(this);
- }
- };
- declare module "../Meshes/abstractMesh" {
- export interface AbstractMesh {
- /** @hidden */
- _physicsImpostor: Nullable<PhysicsImpostor>;
- /**
- * Gets or sets impostor used for physic simulation
- * @see http://doc.babylonjs.com/features/physics_engine
- */
- physicsImpostor: Nullable<PhysicsImpostor>;
- /**
- * Gets the current physics impostor
- * @see http://doc.babylonjs.com/features/physics_engine
- * @returns a physics impostor or null
- */
- getPhysicsImpostor(): Nullable<PhysicsImpostor>;
- /** Apply a physic impulse to the mesh
- * @param force defines the force to apply
- * @param contactPoint defines where to apply the force
- * @returns the current mesh
- * @see http://doc.babylonjs.com/how_to/using_the_physics_engine
- */
- applyImpulse(force: Vector3, contactPoint: Vector3): AbstractMesh;
- /**
- * Creates a physic joint between two meshes
- * @param otherMesh defines the other mesh to use
- * @param pivot1 defines the pivot to use on this mesh
- * @param pivot2 defines the pivot to use on the other mesh
- * @param options defines additional options (can be plugin dependent)
- * @returns the current mesh
- * @see https://www.babylonjs-playground.com/#0BS5U0#0
- */
- setPhysicsLinkWith(otherMesh: Mesh, pivot1: Vector3, pivot2: Vector3, options?: any): AbstractMesh;
- /** @hidden */
- _disposePhysicsObserver: Nullable<Observer<Node>>;
- }
- }
- Object.defineProperty(AbstractMesh.prototype, "physicsImpostor", {
- get: function(this: AbstractMesh) {
- return this._physicsImpostor;
- },
- set: function(this: AbstractMesh, value: Nullable<PhysicsImpostor>) {
- if (this._physicsImpostor === value) {
- return;
- }
- if (this._disposePhysicsObserver) {
- this.onDisposeObservable.remove(this._disposePhysicsObserver);
- }
- this._physicsImpostor = value;
- if (value) {
- this._disposePhysicsObserver = this.onDisposeObservable.add(() => {
- // Physics
- if (this.physicsImpostor) {
- this.physicsImpostor.dispose(/*!doNotRecurse*/);
- this.physicsImpostor = null;
- }
- });
- }
- },
- enumerable: true,
- configurable: true
- });
- /**
- * Gets the current physics impostor
- * @see http://doc.babylonjs.com/features/physics_engine
- * @returns a physics impostor or null
- */
- AbstractMesh.prototype.getPhysicsImpostor = function(): Nullable<PhysicsImpostor> {
- return this.physicsImpostor;
- };
- /**
- * Apply a physic impulse to the mesh
- * @param force defines the force to apply
- * @param contactPoint defines where to apply the force
- * @returns the current mesh
- * @see http://doc.babylonjs.com/how_to/using_the_physics_engine
- */
- AbstractMesh.prototype.applyImpulse = function(force: Vector3, contactPoint: Vector3): AbstractMesh {
- if (!this.physicsImpostor) {
- return this;
- }
- this.physicsImpostor.applyImpulse(force, contactPoint);
- return this;
- };
- /**
- * Creates a physic joint between two meshes
- * @param otherMesh defines the other mesh to use
- * @param pivot1 defines the pivot to use on this mesh
- * @param pivot2 defines the pivot to use on the other mesh
- * @param options defines additional options (can be plugin dependent)
- * @returns the current mesh
- * @see https://www.babylonjs-playground.com/#0BS5U0#0
- */
- AbstractMesh.prototype.setPhysicsLinkWith = function(otherMesh: Mesh, pivot1: Vector3, pivot2: Vector3, options?: any): AbstractMesh {
- if (!this.physicsImpostor || !otherMesh.physicsImpostor) {
- return this;
- }
- this.physicsImpostor.createJoint(otherMesh.physicsImpostor, PhysicsJoint.HingeJoint, {
- mainPivot: pivot1,
- connectedPivot: pivot2,
- nativeParams: options
- });
- return this;
- };
- /**
- * Defines the physics engine scene component responsible to manage a physics engine
- */
- export class PhysicsEngineSceneComponent implements ISceneComponent {
- /**
- * The component name helpful to identify the component in the list of scene components.
- */
- public readonly name = SceneComponentConstants.NAME_PHYSICSENGINE;
- /**
- * The scene the component belongs to.
- */
- public scene: Scene;
- /**
- * Creates a new instance of the component for the given scene
- * @param scene Defines the scene to register the component in
- */
- constructor(scene: Scene) {
- this.scene = scene;
- this.scene.onBeforePhysicsObservable = new Observable<Scene>();
- this.scene.onAfterPhysicsObservable = new Observable<Scene>();
- // Replace the function used to get the deterministic frame time
- this.scene.getDeterministicFrameTime = () => {
- if (this.scene._physicsEngine) {
- return this.scene._physicsEngine.getTimeStep() * 1000;
- }
- return 1000.0 / 60.0;
- };
- }
- /**
- * Registers the component in a given scene
- */
- public register(): void {
- }
- /**
- * Rebuilds the elements related to this component in case of
- * context lost for instance.
- */
- public rebuild(): void {
- // Nothing to do for this component
- }
- /**
- * Disposes the component and the associated ressources
- */
- public dispose(): void {
- this.scene.onBeforePhysicsObservable.clear();
- this.scene.onAfterPhysicsObservable.clear();
- if (this.scene._physicsEngine) {
- this.scene.disablePhysicsEngine();
- }
- }
- }
|