"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OrbitSceneRootUC = void 0;
exports.makeOrbitSceneRootUC = makeOrbitSceneRootUC;
const core_1 = require("@vived/core");
const core_2 = require("@vived/core");
const Babylon_1 = require("../../Babylon");
const Dispatcher_1 = require("../../Dispatcher");
const SceneRootEntity_1 = require("../Entities/SceneRootEntity");
class OrbitSceneRootUC extends core_1.AppObjectUC {
}
exports.OrbitSceneRootUC = OrbitSceneRootUC;
OrbitSceneRootUC.type = "OrbitSceneRootUC";
OrbitSceneRootUC.get = (appObjects) => (0, core_1.getSingletonComponent)(OrbitSceneRootUC.type, appObjects);
function makeOrbitSceneRootUC(appObject) {
    return new OrbitSceneRootImp(appObject);
}
class OrbitSceneRootImp extends OrbitSceneRootUC {
    constructor(appObject) {
        super(appObject, OrbitSceneRootUC.type);
        this.sensitivity = 0.1;
        this.lastPixelPos = core_2.Vector2.Zero();
        this.pickPoint = core_2.Vector3.Zero();
        this.localPickOffset = core_2.Vector3.Zero();
        this.initialQuat = core_2.Quaternion.Identity();
        this.hasBeenInitialized = false;
        this.doOrbit = (pixelPosition) => {
            if (!this.transformNode)
                return;
            if (!this.hasBeenInitialized)
                return;
            const pixelChange = core_2.Vector2.Subtract(pixelPosition, this.lastPixelPos);
            const pitchAngle = core_2.Angle.FromDegrees(pixelChange.y * this.sensitivity);
            const pitchQuaternion = core_2.Quaternion.FromAngleAxis(core_2.Vector3.Left(), pitchAngle);
            this.transformNode.worldRotation = core_2.Quaternion.Multiply(pitchQuaternion, this.transformNode.worldRotation);
            const worldUp = this.transformNode.localDirectionToWorld(core_2.Vector3.Up());
            let xMovement = pixelChange.x;
            if (worldUp.y < 0) {
                xMovement = -pixelChange.x;
            }
            const headingAngle = core_2.Angle.FromDegrees(xMovement * this.sensitivity);
            const headingQuaternion = core_2.Quaternion.FromAngleAxis(core_2.Vector3.Down(), headingAngle);
            this.transformNode.localRotation = core_2.Quaternion.Multiply(this.transformNode.localRotation, headingQuaternion);
            const worldPickOffset = this.transformNode.localPointToWorld(this.localPickOffset);
            const bump = core_2.Vector3.Subtract(this.pickPoint, worldPickOffset);
            this.transformNode.worldPosition = core_2.Vector3.Add(bump, this.transformNode.worldPosition);
            this.lastPixelPos = pixelPosition;
        };
        this.initializeOrbit = (initialPixelPos) => {
            if (!this.transformNode)
                return;
            this.lastPixelPos = initialPixelPos;
            const pick = (0, Babylon_1.scenePixelPick)(initialPixelPos, this.appObjects);
            this.pickPoint = pick?.worldPickPoint ?? core_2.Vector3.Zero();
            this.localPickOffset = this.transformNode.worldPointToLocal(this.pickPoint);
            this.transformNode.cancelLerp();
            this.hasBeenInitialized = true;
            this.initialQuat = this.transformNode.localRotation;
        };
        this.finishOrbit = () => {
            this.hasBeenInitialized = false;
            if (!this.transformNode)
                return;
            if (core_2.Quaternion.Equal(this.initialQuat, this.transformNode.localRotation))
                return;
            (0, Dispatcher_1.dispatchStateChange)(this.appObjects);
        };
        this.cancelOrbit = () => {
            this.hasBeenInitialized = false;
        };
        this.sceneRoot = appObject.getComponent(SceneRootEntity_1.SceneRootEntity.type);
        if (!this.sceneRoot) {
            this.warn("OrbitSceneRootImp UC has been added to an App Object that does not have a SceneRoot Entity");
            return;
        }
        this.transformNode = this.sceneRoot?.transform;
    }
}
//# sourceMappingURL=OrbitSceneRoot.js.map