import { AppObjectUC } from "@vived/core";
import { Matrix, Quaternion, Vector3 } from "@vived/core";
import { XREntity } from "../../XR";
import { ZSpaceEntity } from "../Entities/ZSpaceEntity";
export class ViewFromPoseHook extends AppObjectUC {
}
ViewFromPoseHook.type = "ViewFromPoseHook";
export function makeViewFromPoseHook(appObj) {
    return new ViewFromPoseImp(appObj);
}
class ViewFromPoseImp extends ViewFromPoseHook {
    constructor(appObject) {
        super(appObject, ViewFromPoseHook.type);
        this.onNewXRFrame = () => {
            const frame = this.xrEntity.lastXRFrame;
            if (!frame)
                return;
            if (!this.xrEntity.xrReferenceSpace) {
                console.log("No reference space");
                return;
            }
            const pose = frame.getViewerPose(this.xrEntity.xrReferenceSpace);
            if (!pose) {
                console.log("No pose");
                return;
            }
            if (!pose.transform) {
                console.log("No Pose transform ");
                return;
            }
            const orientation = pose.transform.orientation;
            if (pose.transform.orientation.x === undefined) {
                console.log("Pose Orientation in undefined");
                return;
            }
            const pos = pose.transform.position;
            const headPos = new Vector3(pos.x, pos.y, -pos.z);
            const headRotation = new Quaternion(orientation.x, orientation.y, -orientation.z, -orientation.w);
            pose.views.forEach((view, i) => {
                const viewDTO = this.formViewDTO(view);
                if (view.eye === "right") {
                    this.zSpace.rightEyeView.update(viewDTO);
                }
                else {
                    this.zSpace.leftEyeView.update(viewDTO);
                    const headDTO = { ...viewDTO };
                    headDTO.position = headPos;
                    headDTO.rotation = headRotation;
                    this.zSpace.headView.update(headDTO);
                }
            });
        };
        this.formViewDTO = (view) => {
            const xrProjMatrix = Matrix.FromFloat32Array(view.projectionMatrix);
            const projectionMatrix = Matrix.FlipProjectionMatrixHand(xrProjMatrix);
            const xrPosition = view.transform.position;
            const xrOrientation = view.transform.orientation;
            const position = new Vector3(xrPosition.x, xrPosition.y, -xrPosition.z);
            const rotation = new Quaternion(xrOrientation.x, xrOrientation.y, -xrOrientation.z, -xrOrientation.w);
            return {
                position,
                rotation,
                projectionMatrix,
                view,
            };
        };
        const zSpaceEntity = appObject.getComponent(ZSpaceEntity.type);
        if (!zSpaceEntity) {
            throw new Error("No ZSpace Entity");
        }
        this.zSpace = zSpaceEntity;
        const xrEntity = zSpaceEntity.appObject.getComponent(XREntity.type);
        if (!xrEntity) {
            throw new Error("No XR Entity");
        }
        this.xrEntity = xrEntity;
        this.xrEntity.addChangeObserver(this.onNewXRFrame);
    }
}
//# sourceMappingURL=ViewFromPoseHook.js.map