API Docs for: 2.0.0
Show:

File: src/viewer/input/cameraControl.js

/**
 A **CameraControl** allows you to pan, rotate and zoom a {{#crossLink "Camera"}}{{/crossLink}} using the mouse and keyboard,
 as well as switch it between preset left, right, anterior, posterior, superior and inferior views.

 ## Overview

 <ul>
 <li>You can have multiple CameraControls within the same {{#crossLink "Viewer"}}{{/crossLink}}.</li>
 <li>Multiple CameraControls can drive the same {{#crossLink "Camera"}}{{/crossLink}}, or can each drive their own separate {{#crossLink "Camera"}}Cameras{{/crossLink}}.</li>
 <li>At any instant, the CameraControl we're driving is the one whose {{#crossLink "Camera/active:property"}}active{{/crossLink}} property is true.</li>
 <li>You can switch a CameraControl to a different {{#crossLink "Camera"}}{{/crossLink}} at any time.</li>
 </ul>

 ## Example

 #### Controlling a Camera

 In this example we're viewing a {{#crossLink "RandomObjects"}}{{/crossLink}} with a {{#crossLink "Camera"}}{{/crossLink}} that's controlled by a CameraControl.

 <iframe style="width: 800px; height: 600px" src="../../examples/control_CameraControl.html"></iframe>

 ````Javascript
 var viewer = new BIMSURFER.Viewer({ element: "myDiv" });

 var camera = new BIMSURFER.Camera(viewer, {
        eye: [5, 5, -5]
    });

 var cameraControl = new BIMSURFER.CameraControl(viewer, {
        camera: camera
    });

 // Create a RandomObjects
 var randomObjects = new BIMSURFER.RandomObjects(viewer, {
        numObjects: 55
    });
 ````

 @class CameraControl
 @module BIMSURFER
 @submodule input
 @constructor
 @param [viewer] {Viewer} Parent {{#crossLink "Viewer"}}{{/crossLink}}.
 @param [cfg] {*} Configs
 @param [cfg.id] {String} Optional ID, unique among all components in the parent viewer, generated automatically when omitted.
 @param [cfg.meta] {String:Object} Optional map of user-defined metadata to attach to this CameraControl.
 @param [camera] {Camera} The Camera to control.
 @extends Component
 */
(function () {

    "use strict";

    BIMSURFER.CameraControl = BIMSURFER.Component.extend({

        /**
         JavaScript class name for this Component.

         @property className
         @type String
         @final
         */
        className: "BIMSURFER.CameraControl",

        /**
          Indicates that only one instance of a CameraControl may be active within
          its {{#crossLink "Viewer"}}{{/crossLink}} at a time. When a CameraControl is activated, that has
          a true value for this flag, then any other active CameraControl will be deactivated first.

         @property exclusive
         @type Boolean
         @final
         */
        exclusive: true,
        
        _init: function (cfg) {

            var self = this;

            var viewer = this.viewer;            

            this._keyboardAxis = new BIMSURFER.KeyboardAxisCamera(viewer, {
                camera: cfg.camera
            });

            this._keyboardOrbit = new BIMSURFER.KeyboardOrbitCamera(viewer, {
                camera: cfg.camera
            });
            
            this._mouseOrbit = new BIMSURFER.MouseOrbitCamera(viewer, {
                camera: cfg.camera
            });

            this._keyboardPan = new BIMSURFER.KeyboardPanCamera(viewer, {
                sensitivity: 1,
                camera: cfg.camera
            });

            this._mousePan = new BIMSURFER.MousePanCamera(viewer, {
                sensitivity: 1,
                camera: cfg.camera
            });

            this._keyboardZoom = new BIMSURFER.KeyboardZoomCamera(viewer, {
                sensitivity: 1,
                camera: cfg.camera
            });

            this._mouseZoom = new BIMSURFER.MouseZoomCamera(viewer, {
                sensitivity: 1,
                camera: cfg.camera
            });

            this._mousePickObject = new BIMSURFER.MousePickObject(viewer, {
                rayPick: true,
                camera: cfg.camera
            });

            this._cameraFly = new BIMSURFER.CameraFlyAnimation(viewer, {
                camera: cfg.camera
            });

            this._mousePickObject.on("pick",
                function (e) {

                    var diff = BIMSURFER.math.subVec3(self._cameraFly.camera.eye, self._cameraFly.camera.look, []);

                    self._cameraFly.flyTo({
                        look: e.worldPos,
                        eye: [e.worldPos[0] + diff[0], e.worldPos[1] + diff[1], e.worldPos[2] + diff[2]]
                    });
                });

            // Handle when nothing is picked
            this._mousePickObject.on("nopick", function (e) {
                // alert("Mothing picked");
            });

            this.camera = cfg.camera;
            
            this.firstPerson = cfg.firstPerson;

            this.active = cfg.active !== false;
        },

        _props: {

            firstPerson: {

                set: function (value) {

                    this._firstPerson = value;

                    this._keyboardOrbit.firstPerson = value;
                    this._mouseOrbit.firstPerson = value;
                },

                get: function () {
                    return this._firstPerson;
                }
            },

            /**
             * The {{#crossLink "Camera"}}{{/crossLink}} being controlled.
             *
             * Must be within the same {{#crossLink "Viewer"}}{{/crossLink}} as this Object. Defaults to the parent
             * {{#crossLink "Viewer"}}Viewer's{{/crossLink}} default {{#crossLink "Viewer/camera:property"}}camera{{/crossLink}} when set to
             * a null or undefined value.
             *
             * @property camera
             * @type Camera
             */
            camera: {

                set: function (value) {

                    var camera = value;

                    if (camera) {

                        if (BIMSURFER._isString(camera)) {
                            camera = this.viewer.components[camera];
                            if (!camera) {
                                this.error("camera", "Camera not found in Viewer: " + value);
                                return;
                            }
                        }

                        if (camera.className != "BIMSURFER.Camera") {
                            this.error("camera", "Value is not a BIMSURFER.Camera");
                            return;
                        }

                    } else {

                        // Default to Viewer's default Camera
                        camera = this.viewer.camera;
                    }

                    //   this._cameraFly.camera = camera;

                    this._camera = camera;

                    this._keyboardAxis.camera = camera;

                    this._keyboardOrbit.camera = camera;
                    this._mouseOrbit.camera = camera;

                    this._keyboardPan.camera = camera;
                    this._mousePan.camera = camera;

                    this._keyboardZoom.camera = camera;
                    this._mouseZoom.camera = camera;
                },

                get: function () {
                    return this._camera;
                }
            },

            /**
             * Flag which indicates whether this CameraControl is active or not.
             *
             * Fires an {{#crossLink "CameraControl/active:event"}}{{/crossLink}} event on change.
             *
             * @property active
             * @type Boolean
             */
            active: {

                set: function (value) {

                    if (this._active === value) {
                        return;
                    }

                    this._keyboardOrbit.active = value;
                    this._mouseOrbit.active = value;
                    this._keyboardPan.active = value;
                    this._mousePan.active = value;
                    this._mousePickObject.active = value;
                    this._cameraFly.active = value;

                    /**
                     * Fired whenever this CameraControl's {{#crossLink "CameraControl/active:property"}}{{/crossLink}} property changes.
                     * @event active
                     * @param value The property's new value
                     */
                    this.fire('active', this._active = value);
                },

                get: function () {
                    return this._active;
                }
            }
        },

        _destroy: function () {

            this._keyboardAxis.destroy();
            this._keyboardOrbit.destroy();
            this._mouseOrbit.destroy();
            this._keyboardPan.destroy();
            this._mousePan.destroy();
            this._keyboardZoom.destroy();
            this._mouseZoom.destroy();
            this._mousePickObject.destroy();
            this._cameraFly.destroy();

            this.active = false;
        }
    });

})();