import { __extends } from "tslib";
import { State } from "./State";
import { Vector } from "./Math/Vector";
import { isCloseTo } from "./Math/MathUtils";
/** Convenience function for creating a Ray, cloning the parameters */
export function createRay(origin, direction) {
    return {
        origin: Vector.CloneVec3(origin),
        direction: Vector.CloneVec3(direction),
    };
}
/** Convenience function for cloning a Ray */
export function cloneRay(ray) {
    return createRay(ray.origin, ray.direction);
}
/**
 * Returns the current Transformation of a component. Slightly smoothed for values near 0.
 * @param id the component id
 * @param setPositionCompatibility if true: ignore the movement of t3 itself, i.e.
 * @returns {Transformation}
 */
export function getWorldTransformation(id, setPositionCompatibility) {
    if (setPositionCompatibility === void 0) { setPositionCompatibility = false; }
    var transformation = State.API.GetBasicWorldTransformation(id, setPositionCompatibility);
    if (isCloseTo(Math.abs(transformation.rotation.x), Math.PI) &&
        isCloseTo(Math.abs(transformation.rotation.z), Math.PI)) {
        transformation.rotation = Vector.CreateVec3(0, Math.PI - transformation.rotation.y, 0);
    }
    return transformation;
}
/** Representation of two-dimensional numbers. */
var Float2 = /** @class */ (function () {
    function Float2(x, y) {
        this.x = x === undefined ? 0 : x;
        this.y = y === undefined ? 0 : y;
    }
    return Float2;
}());
export { Float2 };
/** Same as Float2, but introduced for better compatibility with ThreeJS. */
// TODO 2019-10-02 eliminate
var Vector2 = /** @class */ (function (_super) {
    __extends(Vector2, _super);
    function Vector2() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return Vector2;
}(Float2));
export { Vector2 };
/** Representation of three-dimensional numbers. */
var Float3 = /** @class */ (function () {
    function Float3(x, y, z) {
        this.x = x === undefined ? 0 : x;
        this.y = y === undefined ? 0 : y;
        this.z = z === undefined ? 0 : z;
    }
    /**
     * Takes two Float3's and returns the sum of them.
     * @param s1 First summand
     * @param s2 Second summand
     */
    Float3.add = function (s1, s2) {
        return new Float3(s1.x + s2.x, s1.y + s2.y, s1.z + s2.z);
    };
    /**
     * Compare two Float3's on equality (with optional deviation)
     * @param pF1 First Float3
     * @param pF2 Second Float3
     * @param pDeviation allowed deviation
     */
    Float3.isEqual = function (pF1, pF2, pDeviation) {
        if (pDeviation === void 0) { pDeviation = 0; }
        return (Math.abs(pF1.x - pF2.x) <= pDeviation &&
            Math.abs(pF1.y - pF2.y) <= pDeviation &&
            Math.abs(pF1.z - pF2.z) <= pDeviation);
    };
    return Float3;
}());
export { Float3 };
/** Same as Float3, but introduced for better compatibility with Unity-3D. */
// TODO 2019-10-02 eliminate
var Vector3 = /** @class */ (function (_super) {
    __extends(Vector3, _super);
    function Vector3() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return Vector3;
}(Float3));
export { Vector3 };
/** Representation of RGB colors. */
var ColorRGB = /** @class */ (function () {
    function ColorRGB(r, g, b) {
        this.r = r === undefined ? 0 : r;
        this.g = g === undefined ? 0 : g;
        this.b = b === undefined ? 0 : b;
    }
    return ColorRGB;
}());
export { ColorRGB };
/** Enumeration of ghost modes. */
export var EGhostMode;
(function (EGhostMode) {
    /** No ghost. */
    EGhostMode["None"] = "None";
    /** Global box. */
    EGhostMode["Box"] = "Box";
    /** Hierarchy of boxes. */
    EGhostMode["Boxes"] = "Boxes";
    /** 1:1 geometric representation. */
    EGhostMode["Geometric"] = "Geometric";
    /** No display: if a ghost exists, do not display it but keep in scene */
    EGhostMode["NoDisplay"] = "NoDisplay";
})(EGhostMode || (EGhostMode = {}));
export var VisibleGhostModes = [
    EGhostMode.Box,
    EGhostMode.Geometric,
];
export var RENDERKNECHT_PERSPECTIVE = "RENDERKNECHT_PERSPECTIVE";
export var RENDERKNECHT_ORTHOGRAPHIC = "RENDERKNECHT_ORTHOGRAPHIC";
/** Representing setup information for a perspective camera */
var PerspCameraSetup = /** @class */ (function () {
    function PerspCameraSetup() {
        this.near = 0.1;
        this.far = 100;
        this.position = Vector.CreateVec3(0, 1.5, 4);
        this.rotation = Vector.CreateVec3(0, 0, 0);
        this.lookAt = Vector.CreateVec3(0, 0, 0);
        /** the left value of the ortho rectangle, defaults to 45 */
        this.fov = 45;
    }
    return PerspCameraSetup;
}());
export { PerspCameraSetup };
/** Representing setup information for a OrthographicsCamera */
var OrthoCameraSetup = /** @class */ (function () {
    function OrthoCameraSetup() {
        this.near = 0.1;
        this.far = 50;
        this.position = Vector.CreateVec3(0, 20, 0);
        this.rotation = Vector.CreateVec3(0, 0, 0);
        this.lookAt = Vector.CreateVec3(0, 0, 0);
        /** The left value of the ortho rectangle, defaults to -5 */
        this.left = -5;
        /** The right value of the ortho rectangle, defaults to 5 */
        this.right = 5;
        /** The top value of the ortho rectangle, defaults to 5 */
        this.top = 5;
        /** The bottom value of the ortho rectangle, defaults to -5 */
        this.bottom = -5;
        /** Up vector of the camera */
        this.up = Vector.CreateVec3(0, 0, -1);
    }
    return OrthoCameraSetup;
}());
export { OrthoCameraSetup };
export var CameraType;
(function (CameraType) {
    CameraType[CameraType["Perspective"] = 0] = "Perspective";
    CameraType[CameraType["Orthographic"] = 1] = "Orthographic";
})(CameraType || (CameraType = {}));
