<commit_before>/*global define*/
define([
        '../Core/destroyObject',
        '../Core/Ellipsoid',
        '../Core/Cartesian3',
        '../Core/Cartesian4',
        '../Core/Matrix4',
        '../Core/Transforms',
        './CameraEventHandler',
        './CameraEventType',
        './CameraSpindleController',
        './CameraFreeLookController'
    ], function(
        destroyObject,
        Ellipsoid,
        Cartesian3,
        Cartesian4,
        Matrix4,
        Transforms,
        CameraEventHandler,
        CameraEventType,
        CameraSpindleController,
        CameraFreeLookController) {
    "use strict";

    /**
     * DOC_TBD
     * @name CameraCentralBodyController
     * @constructor
     */
    function CameraCentralBodyController(canvas, camera, ellipsoid) {
        this._canvas = canvas;
        this._camera = camera;

        this._spindleController = new CameraSpindleController(canvas, camera, ellipsoid);
        this._freeLookController = new CameraFreeLookController(canvas, camera);

        this._rotateHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG);

        this._transform = Matrix4.IDENTITY;
    }

    /**
     * @private
     */
    CameraCentralBodyController.prototype.update = function() {
        var rotate = this._rotateHandler;
        var rotating = rotate.isMoving() && rotate.getMovement();

        var rotateMovement = rotate.getMovement();
        if (rotate.isButtonDown() && typeof this._transform === 'undefined' && rotateMovement) {
            var center = this._camera.pickEllipsoid(rotateMovement.startPosition, this._spindleController.getEllipsoid());
            if (typeof center !== 'undefined') {
                this._transform = Transforms.eastNorthUpToFixedFrame(center);
            }
        } else if (!rotate.isButtonDown()) {
            this._transform = undefined;
        }

        if (rotating && typeof this._transform !== 'undefined') {
                this._rotate(rotateMovement);
        }

        this._spindleController.update();
        this._freeLookController.update();

        return true;
    };

    CameraCentralBodyController.prototype._rotate = function(movement) {
        var transform = this._transform;
        var camera = this._camera;
        var position = camera.position;
        var up = camera.up;
        var right = camera.right;
        var direction = camera.direction;

        var oldTransform = camera.transform;
        var oldEllipsoid = this._spindleController.getEllipsoid();
        var oldConstrainedZ = this._spindleController.constrainedAxis;

        this._spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE);
        this._spindleController.constrainedAxis = Cartesian3.UNIT_Z;

        var invTransform = camera.getInverseTransform();
        camera.position = invTransform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ();
        camera.up = invTransform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ();
        camera.right = invTransform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ();
        camera.direction = invTransform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ();

        this._spindleController._rotate(movement);

        position = camera.position;
        up = camera.up;
        right = camera.right;
        direction = camera.direction;

        this._spindleController.setReferenceFrame(oldTransform, oldEllipsoid);
        this._spindleController.constrainedAxis = oldConstrainedZ;

        camera.position = transform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ();
        camera.up = transform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ();
        camera.right = transform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ();
        camera.direction = transform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ();
    };

    //TODO: Find a better solution for this
    CameraCentralBodyController.prototype.moveLeftWithConstrainedZ = function(angle) {
        var oldConstrainedZ = this._spindleController.constrainedAxis;
        this._spindleController.constrainedAxis = Cartesian3.UNIT_Z;
        this._spindleController.moveLeft(angle);
        this._spindleController.constrainedAxis = oldConstrainedZ;
    };

    /**
      * Returns true if this object was destroyed; otherwise, false.
      * <br /><br />
      * If this object was destroyed, it should not be used; calling any function other than
      * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
      *
      * @memberof CameraCentralBodyController
      *
      * @return {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
      *
      * @see CameraCentralBodyController#destroy<commit_msg>Add a matching moveRightWithConstrainedZ.<commit_after>/*global define*/
define([
        '../Core/destroyObject',
        '../Core/Ellipsoid',
        '../Core/Cartesian3',
        '../Core/Cartesian4',
        '../Core/Matrix4',
        '../Core/Transforms',
        './CameraEventHandler',
        './CameraEventType',
        './CameraSpindleController',
        './CameraFreeLookController'
    ], function(
        destroyObject,
        Ellipsoid,
        Cartesian3,
        Cartesian4,
        Matrix4,
        Transforms,
        CameraEventHandler,
        CameraEventType,
        CameraSpindleController,
        CameraFreeLookController) {
    "use strict";

    /**
     * DOC_TBD
     * @name CameraCentralBodyController
     * @constructor
     */
    function CameraCentralBodyController(canvas, camera, ellipsoid) {
        this._canvas = canvas;
        this._camera = camera;

        this._spindleController = new CameraSpindleController(canvas, camera, ellipsoid);
        this._freeLookController = new CameraFreeLookController(canvas, camera);

        this._rotateHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG);

        this._transform = Matrix4.IDENTITY;
    }

    /**
     * @private
     */
    CameraCentralBodyController.prototype.update = function() {
        var rotate = this._rotateHandler;
        var rotating = rotate.isMoving() && rotate.getMovement();

        var rotateMovement = rotate.getMovement();
        if (rotate.isButtonDown() && typeof this._transform === 'undefined' && rotateMovement) {
            var center = this._camera.pickEllipsoid(rotateMovement.startPosition, this._spindleController.getEllipsoid());
            if (typeof center !== 'undefined') {
                this._transform = Transforms.eastNorthUpToFixedFrame(center);
            }
        } else if (!rotate.isButtonDown()) {
            this._transform = undefined;
        }

        if (rotating && typeof this._transform !== 'undefined') {
                this._rotate(rotateMovement);
        }

        this._spindleController.update();
        this._freeLookController.update();

        return true;
    };

    CameraCentralBodyController.prototype._rotate = function(movement) {
        var transform = this._transform;
        var camera = this._camera;
        var position = camera.position;
        var up = camera.up;
        var right = camera.right;
        var direction = camera.direction;

        var oldTransform = camera.transform;
        var oldEllipsoid = this._spindleController.getEllipsoid();
        var oldConstrainedZ = this._spindleController.constrainedAxis;

        this._spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE);
        this._spindleController.constrainedAxis = Cartesian3.UNIT_Z;

        var invTransform = camera.getInverseTransform();
        camera.position = invTransform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ();
        camera.up = invTransform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ();
        camera.right = invTransform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ();
        camera.direction = invTransform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ();

        this._spindleController._rotate(movement);

        position = camera.position;
        up = camera.up;
        right = camera.right;
        direction = camera.direction;

        this._spindleController.setReferenceFrame(oldTransform, oldEllipsoid);
        this._spindleController.constrainedAxis = oldConstrainedZ;

        camera.position = transform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ();
        camera.up = transform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ();
        camera.right = transform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ();
        camera.direction = transform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ();
    };

    //TODO: Find a better solution for this
    CameraCentralBodyController.prototype.moveLeftWithConstrainedZ = function(angle) {
        var oldConstrainedZ = this._spindleController.constrainedAxis;
        this._spindleController.constrainedAxis = Cartesian3.UNIT_Z;
        this._spindleController.moveLeft(angle);
        this._spindleController.constrainedAxis = oldConstrainedZ;
    };

    CameraCentralBodyController.prototype.moveRightWithConstrainedZ = function(angle) {
        var oldConstrainedZ = this._spindleController.constrainedAxis;
        this._spindleController.constrainedAxis = Cartesian3.UNIT_Z;
        this._spindleController.moveRight(angle);
        this._spindleController.constrainedAxis = oldConstrainedZ;
    };

    /**
      * Returns true if this object was destroyed; otherwise, false.
      * <br /><br />
      * If this object was destroyed, it should not be used; calling any function other than
      * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
      *
      * @memberof CameraCentralBodyController
      *
      * @return {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
      *
      * @see CameraCentralBodyController#destroy
{'fraction_non_alphanumeric': 0.1101227883592768, 'fraction_numerical': 0.006477811079957459, 'mean_word_length': 2.83821892393321, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3006337', 'n_tokens_mistral': 2978, 'n_tokens_neox': 2823, 'n_words': 530}