123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- import { Logger } from "../Misc/logger.js";
- import { SerializationHelper } from "../Misc/decorators.serialization.js";
- import { Camera } from "./camera.js";
- /**
- * @ignore
- * This is a list of all the different input types that are available in the application.
- * Fo instance: ArcRotateCameraGamepadInput...
- */
- // eslint-disable-next-line no-var, @typescript-eslint/naming-convention
- export var CameraInputTypes = {};
- /**
- * This represents the input manager used within a camera.
- * It helps dealing with all the different kind of input attached to a camera.
- * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs
- */
- export class CameraInputsManager {
- /**
- * Instantiate a new Camera Input Manager.
- * @param camera Defines the camera the input manager belongs to
- */
- constructor(camera) {
- /**
- * Defines the dom element the camera is collecting inputs from.
- * This is null if the controls have not been attached.
- */
- this.attachedToElement = false;
- this.attached = {};
- this.camera = camera;
- this.checkInputs = () => { };
- }
- /**
- * Add an input method to a camera
- * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs
- * @param input Camera input method
- */
- add(input) {
- const type = input.getSimpleName();
- if (this.attached[type]) {
- Logger.Warn("camera input of type " + type + " already exists on camera");
- return;
- }
- this.attached[type] = input;
- input.camera = this.camera;
- // for checkInputs, we are dynamically creating a function
- // the goal is to avoid the performance penalty of looping for inputs in the render loop
- if (input.checkInputs) {
- this.checkInputs = this._addCheckInputs(input.checkInputs.bind(input));
- }
- if (this.attachedToElement) {
- input.attachControl(this.noPreventDefault);
- }
- }
- /**
- * Remove a specific input method from a camera
- * example: camera.inputs.remove(camera.inputs.attached.mouse);
- * @param inputToRemove camera input method
- */
- remove(inputToRemove) {
- for (const cam in this.attached) {
- const input = this.attached[cam];
- if (input === inputToRemove) {
- input.detachControl();
- input.camera = null;
- delete this.attached[cam];
- this.rebuildInputCheck();
- return;
- }
- }
- }
- /**
- * Remove a specific input type from a camera
- * example: camera.inputs.remove("ArcRotateCameraGamepadInput");
- * @param inputType the type of the input to remove
- */
- removeByType(inputType) {
- for (const cam in this.attached) {
- const input = this.attached[cam];
- if (input.getClassName() === inputType) {
- input.detachControl();
- input.camera = null;
- delete this.attached[cam];
- this.rebuildInputCheck();
- }
- }
- }
- _addCheckInputs(fn) {
- const current = this.checkInputs;
- return () => {
- current();
- fn();
- };
- }
- /**
- * Attach the input controls to the currently attached dom element to listen the events from.
- * @param input Defines the input to attach
- */
- attachInput(input) {
- if (this.attachedToElement) {
- input.attachControl(this.noPreventDefault);
- }
- }
- /**
- * Attach the current manager inputs controls to a specific dom element to listen the events from.
- * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
- */
- attachElement(noPreventDefault = false) {
- if (this.attachedToElement) {
- return;
- }
- noPreventDefault = Camera.ForceAttachControlToAlwaysPreventDefault ? false : noPreventDefault;
- this.attachedToElement = true;
- this.noPreventDefault = noPreventDefault;
- for (const cam in this.attached) {
- this.attached[cam].attachControl(noPreventDefault);
- }
- }
- /**
- * Detach the current manager inputs controls from a specific dom element.
- * @param disconnect Defines whether the input should be removed from the current list of attached inputs
- */
- detachElement(disconnect = false) {
- for (const cam in this.attached) {
- this.attached[cam].detachControl();
- if (disconnect) {
- this.attached[cam].camera = null;
- }
- }
- this.attachedToElement = false;
- }
- /**
- * Rebuild the dynamic inputCheck function from the current list of
- * defined inputs in the manager.
- */
- rebuildInputCheck() {
- this.checkInputs = () => { };
- for (const cam in this.attached) {
- const input = this.attached[cam];
- if (input.checkInputs) {
- this.checkInputs = this._addCheckInputs(input.checkInputs.bind(input));
- }
- }
- }
- /**
- * Remove all attached input methods from a camera
- */
- clear() {
- if (this.attachedToElement) {
- this.detachElement(true);
- }
- this.attached = {};
- this.attachedToElement = false;
- this.checkInputs = () => { };
- }
- /**
- * Serialize the current input manager attached to a camera.
- * This ensures than once parsed,
- * the input associated to the camera will be identical to the current ones
- * @param serializedCamera Defines the camera serialization JSON the input serialization should write to
- */
- serialize(serializedCamera) {
- const inputs = {};
- for (const cam in this.attached) {
- const input = this.attached[cam];
- const res = SerializationHelper.Serialize(input);
- inputs[input.getClassName()] = res;
- }
- serializedCamera.inputsmgr = inputs;
- }
- /**
- * Parses an input manager serialized JSON to restore the previous list of inputs
- * and states associated to a camera.
- * @param parsedCamera Defines the JSON to parse
- */
- parse(parsedCamera) {
- const parsedInputs = parsedCamera.inputsmgr;
- if (parsedInputs) {
- this.clear();
- for (const n in parsedInputs) {
- const construct = CameraInputTypes[n];
- if (construct) {
- const parsedinput = parsedInputs[n];
- const input = SerializationHelper.Parse(() => {
- return new construct();
- }, parsedinput, null);
- this.add(input);
- }
- }
- }
- else {
- //2016-03-08 this part is for managing backward compatibility
- for (const n in this.attached) {
- const construct = CameraInputTypes[this.attached[n].getClassName()];
- if (construct) {
- const input = SerializationHelper.Parse(() => {
- return new construct();
- }, parsedCamera, null);
- this.remove(this.attached[n]);
- this.add(input);
- }
- }
- }
- }
- }
- //# sourceMappingURL=cameraInputsManager.js.map
|