constructor( camera, domElement = null, scene = null ) {

		super( camera, domElement );

		/**
		 * The scene rendered by the camera. If not given, gizmos cannot be shown.
		 *
		 * @type {?Scene}
		 * @default null
		 */
		this.scene = scene;

		/**
		 * The control's focus point.
		 *
		 * @type {Vector3}
		 */
		this.target = new Vector3();
		this._currentTarget = new Vector3();

		/**
		 * The size of the gizmo relative to the screen width and height.
		 *
		 * @type {number}
		 * @default 0.67
		 */
		this.radiusFactor = 0.67;

		/**
		 * Holds the mouse actions of this controls. This property is maintained by the methods
		 * `setMouseAction()` and `unsetMouseAction()`.
		 *
		 * @type {Array<Object>}
		 */
		this.mouseActions = [];
		this._mouseOp = null;


		//global vectors and matrices that are used in some operations to avoid creating new objects every time (e.g. every time cursor moves)
		this._v2_1 = new Vector2();
		this._v3_1 = new Vector3();
		this._v3_2 = new Vector3();

		this._m4_1 = new Matrix4();
		this._m4_2 = new Matrix4();

		this._quat = new Quaternion();

		//transformation matrices
		this._translationMatrix = new Matrix4(); //matrix for translation operation
		this._rotationMatrix = new Matrix4(); //matrix for rotation operation
		this._scaleMatrix = new Matrix4(); //matrix for scaling operation

		this._rotationAxis = new Vector3(); //axis for rotate operation


		//camera state
		this._cameraMatrixState = new Matrix4();
		this._cameraProjectionState = new Matrix4();

		this._fovState = 1;
		this._upState = new Vector3();
		this._zoomState = 1;
		this._nearPos = 0;
		this._farPos = 0;

		this._gizmoMatrixState = new Matrix4();

		//initial values
		this._up0 = new Vector3();
		this._zoom0 = 1;
		this._fov0 = 0;
		this._initialNear = 0;
		this._nearPos0 = 0;
		this._initialFar = 0;
		this._farPos0 = 0;
		this._cameraMatrixState0 = new Matrix4();
		this._gizmoMatrixState0 = new Matrix4();
		this._target0 = new Vector3();

		//pointers array
		this._button = - 1;
		this._touchStart = [];
		this._touchCurrent = [];
		this._input = INPUT.NONE;

		//two fingers touch interaction
		this._switchSensibility = 32;	//minimum movement to be performed to fire single pan start after the second finger has been released
		this._startFingerDistance = 0; //distance between two fingers
		this._currentFingerDistance = 0;
		this._startFingerRotation = 0; //amount of rotation performed with two fingers
		this._currentFingerRotation = 0;

		//double tap
		this._devPxRatio = 0;
		this._downValid = true;
		this._nclicks = 0;
		this._downEvents = [];
		this._downStart = 0;	//pointerDown time
		this._clickStart = 0;	//first click time
		this._maxDownTime = 250;
		this._maxInterval = 300;
		this._posThreshold = 24;
		this._movementThreshold = 24;

		//cursor positions
		this._currentCursorPosition = new Vector3();
		this._startCursorPosition = new Vector3();

		//grid
		this._grid = null; //grid to be visualized during pan operation
		this._gridPosition = new Vector3();

		//gizmos
		this._gizmos = new Group();
		this._curvePts = 128;


		//animations
		this._timeStart = - 1; //initial time
		this._animationId = - 1;

		/**
		 * Duration of focus animations in ms.
		 *
		 * @type {number}
		 * @default 500
		 */
		this.focusAnimationTime = 500;

		//rotate animation
		this._timePrev = 0; //time at which previous rotate operation has been detected
		this._timeCurrent = 0; //time at which current rotate operation has been detected
		this._anglePrev = 0; //angle of previous rotation
		this._angleCurrent = 0; //angle of current rotation
		this._cursorPosPrev = new Vector3();	//cursor position when previous rotate operation has been detected
		this._cursorPosCurr = new Vector3();//cursor position when current rotate operation has been detected
		this._wPrev = 0; //angular velocity of the previous rotate operation
		this._wCurr = 0; //angular velocity of the current rotate operation

		//parameters

		/**
		 * If set to `true`, the camera's near and far values will be adjusted every time zoom is
		 * performed trying to maintain the same visible portion given by initial near and far
		 * values. Only works with perspective cameras.
		 *
		 * @type {boolean}
		 * @default false
		 */
		this.adjustNearFar = false;

		/**
		 * The scaling factor used when performing zoom operation.
		 *
		 * @type {number}
		 * @default 1.1
		 */
		this.scaleFactor = 1.1;

		/**
		 * The damping inertia used if 'enableAnimations` is set to `true`.
		 *
		 * @type {number}
		 * @default 25
		 */
		this.dampingFactor = 25;

		/**
		 * Maximum angular velocity allowed on rotation animation start.
		 *
		 * @type {number}
		 * @default 20
		 */
		this.wMax = 20;

		/**
		 * Set to `true` to enable animations for rotation (damping) and focus operation.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.enableAnimations = true;

		/**
		 * If set to `true`, a grid will appear when panning operation is being performed
		 * (desktop interaction only).
		 *
		 * @type {boolean}
		 * @default false
		 */
		this.enableGrid = false;

		/**
		 * Set to `true` to make zoom become cursor centered.
		 *
		 * @type {boolean}
		 * @default false
		 */
		this.cursorZoom = false;

		/**
		 * The minimum FOV in degrees.
		 *
		 * @type {number}
		 * @default 5
		 */
		this.minFov = 5;

		/**
		 * The maximum FOV in degrees.
		 *
		 * @type {number}
		 * @default 90
		 */
		this.maxFov = 90;

		/**
		 * Speed of rotation.
		 *
		 * @type {number}
		 * @default 1
		 */
		this.rotateSpeed = 1;

		/**
		 * Enable or disable camera panning.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.enablePan = true;

		/**
		 * Enable or disable camera rotation.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.enableRotate = true;

		/**
		 * Enable or disable camera zoom.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.enableZoom = true;

		/**
		 * Enable or disable gizmos.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.enableGizmos = true;

		/**
		 * Enable or disable camera focusing on double-tap (or click) operations.
		 *
		 * @type {boolean}
		 * @default true
		 */
		this.enableFocus = true;

		/**
		 * How far you can dolly in. For perspective cameras only.
		 *
		 * @type {number}
		 * @default 0
		 */
		this.minDistance = 0;

		/**
		 * How far you can dolly out. For perspective cameras only.
		 *
		 * @type {number}
		 * @default Infinity
		 */
		this.maxDistance = Infinity;

		/**
		 * How far you can zoom in. For orthographic cameras only.
		 *
		 * @type {number}
		 * @default 0
		 */
		this.minZoom = 0;

		/**
		 * How far you can zoom out. For orthographic cameras only.
		 *
		 * @type {number}
		 * @default Infinity
		 */
		this.maxZoom = Infinity;

		//trackball parameters
		this._tbRadius = 1;

		//FSA
		this._state = STATE.IDLE;

		this.setCamera( camera );

		if ( this.scene != null ) {

			this.scene.add( this._gizmos );

		}

		this.initializeMouseActions();

		// event listeners

		this._onContextMenu = onContextMenu.bind( this );
		this._onWheel = onWheel.bind( this );
		this._onPointerUp = onPointerUp.bind( this );
		this._onPointerMove = onPointerMove.bind( this );
		this._onPointerDown = onPointerDown.bind( this );
		this._onPointerCancel = onPointerCancel.bind( this );
		this._onWindowResize = onWindowResize.bind( this );

		if ( domElement !== null ) {

			this.connect( domElement );

		}

	}
Constructs a new controls instance.

@param {Camera} camera - The camera to be controlled. The camera must not be a child of another object, unless that object is the scene itself.
@param {?HTMLDOMElement} [domElement=null] - The HTML element used for event listeners.
@param {?Scene} [scene=null] The scene rendered by the camera. If not given, gizmos cannot be shown.