<commit_before>/**
 * @author <NAME> / www.kaisalmen.de
 */

"use strict";

KSX.apps.core.ThreeJsApp = (function () {

    function ThreeJsApp() {
        this.renderingEnabled = false;

        this.frameNumber = 0;
        this.initOk = true;

        this.asyncDone = false;

        this.platformVerification = new KSX.apps.core.prerequisites.PlatformVerification();
    }

    ThreeJsApp.prototype.configure = function (userDefinition) {
        this.definition = userDefinition;
        fillDefinition(KSX.apps.core.ThreeJsApp.DefaultDefinition, this.definition);

        this.canvas = new KSX.apps.core.Canvas(this.definition.htmlCanvas);

        if (this.definition.useScenePerspective) {
            this.scenePerspective = new KSX.apps.core.ThreeJsApp.ScenePerspective(this.canvas);
        }

        if (this.definition.useSceneOrtho) {
            this.sceneOrtho = new KSX.apps.core.ThreeJsApp.SceneOrtho(this.canvas);
        }

        if (this.definition.useScenePerspective && this.definition.useCube) {
            this.scenePerspective.useCube = true;
        }

        this.renderer = new THREE.WebGLRenderer({
            canvas: this.definition.renderers.regular.canvas,
            antialias: this.definition.renderers.regular.antialias
        });

        // auto-clear must not be used when both perspective and ortho scenes are active
        // otherwise: renderer clears 3d content
        if ( this.definition.useScenePerspective && this.definition.useSceneOrtho ) {
            this.renderer.autoClear = false;
        }

        if ( this.definition.verbose ) {
            this.canvas.verbose = this.definition.verbose;
            if ( this.definition.useScenePerspective ) {
                this.scenePerspective.verbose = this.definition.verbose;
            }

            if ( this.definition.useSceneOrtho ) {
                this.sceneOrtho.verbose = this.definition.verbose;
            }
        };
    };

    var fillDefinition = function (paramsPredefined, paramsUser) {

        for (var predefined in paramsPredefined) {
            // early exit
            if (!paramsPredefined.hasOwnProperty(predefined)) {
                continue;
            }

            // renderer definitions: special treatment as object fields need to be copied (no-refs)
            if (predefined === 'renderers') {

                if (!paramsUser.hasOwnProperty(predefined)) {
                    paramsUser[predefined] = {};
                }
                var userRenderers = paramsUser[predefined];

                if (paramsPredefined.hasOwnProperty(predefined)) {
                    var predefinedRenderers = paramsPredefined[predefined];

                    for (var predefinedRendererName in predefinedRenderers) {
                        // early exit
                        if (!predefinedRenderers.hasOwnProperty(predefinedRendererName)) {
                            continue;
                        }

                        if (!userRenderers.hasOwnProperty(predefinedRendererName)) {
                            userRenderers[predefinedRendererName] = {};
                        }

                        var predefinedRenderer = predefinedRenderers[predefinedRendererName];
                        var userRenderer = userRenderers[predefinedRendererName];
                        fillDefinition(predefinedRenderer, userRenderer);
                    }
                }
                if (userRenderers['regular'].canvas === undefined) {
                    userRenderers['regular'].canvas = paramsUser['htmlCanvas'];
                }
            }
            else {
                if (!paramsUser.hasOwnProperty(predefined)) {
                    paramsUser[predefined] = paramsPredefined[predefined];
                }
            }
        }
    };

    ThreeJsApp.prototype.init = function () {
        var scope = this;

        scope.initAsyncContent();

        var initSync = function () {
            console.log("ThreeJsApp (" + scope.definition.name + "): initPreGL");
            scope.initPreGL();

            if ( !scope.initOk ) { return; }
            console.log("ThreeJsApp (" + scope.definition.name + "): initGL");
            if (scope.definition.useScenePerspective) {
                scope.scenePerspective.initGL();
                if ( !scope.initOk ) { return; }
            }
            if (scope.definition.useSceneOrtho) {
                scope.sceneOrtho.initGL();
                if ( !scope.initOk ) { return; }
            }

            scope.initGL();
            if ( !scope.initOk ) { return; }

            console.log("ThreeJsApp (" + scope.definition.name + "): resizeDisplayGLBase");
            scope.resizeDisplayGLBase();

            console.log("ThreeJsApp (" + scope.definition.name + "): addEventHandlers");
            scope.addEventHandlers();

            console.log("ThreeJsApp (" + scope.definition.name + "): initPostGL");
            scope.renderingEnabled = scope.initPostGL();
            if ( !scope.initOk ) { return; }

            if ( scope.renderingEnabled ) {
                console.log("ThreeJsApp (" + scope.definition.name + "): Ready to start render loop!");
            }
        };

        var interval = 10;
        var count = 0;
        var divider = 50;
        var checkAsyncStatus = setInterval( checkAsyncStatusTimer, interval );

        function checkAsyncStatusTimer() {
            if ( scope.asyncDone ) {
                clearInterval(checkAsyncStatus);
                console.log( 'Async loading took approx. ' + interval * count  + 'ms.' );
                initSync();
            }
            else {
                if ( count % divider === 0 ) {
                    console.log( 'Waiting for async content to be loaded (' + interval * count  + 'ms)' );
                }
                count++;
            }
        }
    };

    ThreeJsApp.prototype.resizeDisplayGLBase = function () {
        this.canvas.recalcAspectRatio();

        this.resizeDisplayGL();

        this.renderer.setSize(this.canvas.getWidth(), this.canvas.getHeight(), false);

        if (this.definition.useScenePerspective) {
            this.scenePerspective.updateCamera();
        }

        if (this.definition.useSceneOrtho) {
            this.sceneOrtho.updateCamera();
        }
    };

    ThreeJsApp.prototype.render = function () {
        if (this.renderingEnabled) {
            this.frameNumber++;
            if ( !this.renderer.autoClear ) {
                this.renderer.clear();
            }

            this.renderPre();

            if (this.definition.useScenePerspective) {
                if (this.scenePerspective.useCube) {
                    this.scenePerspective.cameraCube.rotation.copy( this.scenePerspective.camera.rotation );
                    this.renderer.render(this.scenePerspective.sceneCube, this.scenePerspective.cameraCube);
                }

                this.renderer.render(this.scenePerspective.scene, this.scenePerspective.camera);
            }

            if (this.definition.useSceneOrtho) {
                this.renderer.render(this.sceneOrtho.scene, this.sceneOrtho.camera);
            }

            this.renderPost();
        }
    };

    ThreeJsApp.prototype.resetCamera = function () {
        if (this.definition.useScenePerspective) {
            this.scenePerspective.resetCamera();
        }

        if (this.definition.useSceneOrtho) {
            this.sceneOrtho.resetCamera();
        }
    };

    /**
     * Default implementation
     */
    ThreeJsApp.prototype.initAsyncContent = function () {
        this.asyncDone = true;
    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.initPreGL = function () {

    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.initGL = function () {

    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.addEventHandlers = function () {

    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.initPostGL = function () {
        return true;
    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.resizeDisplayGL = function () {

    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.renderPre = function () {
        if ( this.definition.verbose ) {
            console.log("ThreeJsApp DEFAULT (" + this.definition.name + "): renderPre");
        }
    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.renderPost = function () {
        if ( this.definition.verbose ) {
            console.log("ThreeJsApp DEFAULT (" + this.definition.name + "): renderPost");
        }
    };

    /**
     * Default implementation
     */
    ThreeJsApp.prototype.dispose = function () {

    };

    return ThreeJsApp;
})();


KSX.apps.core.Canvas = (function () {

    function Canvas( htmlCanvas ) {
        this.verbose = false;
        this.htmlCanvas = null;
        if ( htmlCanvas !== undefined && htmlCanvas !== null &&
            htmlCanvas.offsetWidth !== undefined && htmlCanvas.offsetHeight !== undefined ) {
            this.htmlCanvas = htmlCanvas;
        }
        else {
            console.error( 'htmlCanvas cannot be used: It is either undefined or its width and height are not available.' );
        }
        this.recalcAspectRatio();
    }

    Canvas.prototype.recalcAspectRatio = function () {
        if (this.verbose) {
            console.log("width: " + this.getWidth() + " height: " + this.getHeight());
        }
        var height = this.getHeight();
        if (height === 0) {
            this.aspectRatio = 1;
        }
        else {
            this.aspectRatio = this.getWidth() / height;
        }
    };

    Canvas.prototype.resetWidth = function ( width, height ) {
        if (this.htmlCanvas !== null ) {

            if ( this.htmlCanvas.style !== undefined && this.htmlCanvas.style !== null) {
                this.htmlCanvas.style.width = width + 'px';
                this.htmlCanvas.style.height = height + 'px';
            }
            this.htmlCanvas.offsetWidth = width;
            this.htmlCanvas.offsetHeight = height;
        }
        this.recalcAspectRatio();
    };

    Canvas.prototype.getWidth = function () {
        return this.htmlCanvas === null ? 0 : this.htmlCanvas.offsetWidth;
    };

    Canvas.prototype.getHeight = function () {
        return this.htmlCanvas === null ? 0 : this.htmlCanvas.offsetHeight;
    };

    Canvas.prototype.getPixelLeft = function () {
        return -this.getWidth() / 2;
    };

    Canvas.prototype.getPixelRight = function () {
        return this.getWidth() / 2;
    };

    Canvas.prototype.getPixelTop = function () {
        return this.getHeight() / 2;
    };

    Canvas.prototype.getPixelBottom = function () {
        return -this.getHeight() / 2;
    };

    return Canvas;

})();



KSX.apps.core.ThreeJsApp.ScenePerspective = (function () {

    function ScenePerspective( canvas, verbose ) {
        this.canvas = canvas;
        this.verbose = verbose === undefined ? false : verbose;
        this.canvas.verbose = this.verbose;
        this.camera = null;
        this.useCube = false;
        this.cameraCube = null;

        this.defaults = {
            posCamera: new THREE.Vector3(100, 100, 100),
            upVector: new THREE.Vector3(0, 1, 0),
            posCameraTarget: new THREE.Vector3(0, 0, 0),
            posCameraCube: new THREE.Vector3(0, 0, 0),
            near: 0.1,
            far: 10000,
            fov: 45
        };

        this.cameraTarget = this.defaults.posCameraTarget;
    }

    ScenePerspective.prototype.setCameraDefaults = function ( defaults ) {
        if ( defaults === null || defaults === undefined ) {
            return;
        }
        if ( defaults.posCamera !== undefined && defaults.posCamera !== null ) {
            this.defaults.posCamera.copy( defaults.posCamera );
        }
        if ( defaults.upVector !== undefined && defaults.upVector !== null ) {
            this.defaults.upVector.copy( defaults.upVector );
        }
        if ( defaults.posCameraTarget !== undefined && defaults.posCameraTarget !== null ) {
            this.defaults.posCameraTarget.copy( defaults.posCameraTarget );
        }
        if ( defaults.posCameraCube !== undefined && defaults.posCameraCube !== null ) {
            this.defaults.posCameraCube.copy( defaults.posCameraCube );
        }
        if ( defaults.near !== undefined && defaults.near !== null ) {
            this.defaults.near = defaults.near;
        }
        if ( defaults.far !== undefined && defaults.far !== null ) {
            this.defaults.far = defaults.far;
        }
        if ( defaults.fov !== undefined && defaults.fov !== null ) {
            this.defaults.fov = defaults.fov;
        }
        this.resetCamera();
    };

    ScenePerspective.prototype.initGL = function () {
        this.scene = new THREE.Scene();

        this.camera = new THREE.PerspectiveCamera( this.defaults.fov, this.canvas.aspectRatio, this.defaults.near, this.defaults.far );

        if (this.useCube) {
            this.cameraCube = new THREE.PerspectiveCamera( this.defaults.fov, this.canvas.aspectRatio, this.defaults.near, this.defaults.far );
            this.sceneCube = new THREE.Scene();
        }
        this.resetCamera();
    };

    ScenePerspective.prototype.resetCamera = function () {
        this.camera.position.copy(this.defaults.posCamera);
        this.camera.up.copy(this.defaults.upVector);
        this.cameraTarget.copy(this.defaults.posCameraTarget);

        if (this.useCube) {
            this.cameraCube.position.copy(this.defaults.posCameraCube);
        }
        this.updateCamera();
    };

    ScenePerspective.prototype.updateCamera = function () {
        this.camera.aspect = this.canvas.aspectRatio;
        this.camera.lookAt(this.cameraTarget);
        this.camera.updateProjectionMatrix();

        if (this.useCube) {
            this.cameraCube.rotation.copy( this.camera.rotation );
            this.cameraCube.aspectRatio = this.canvas.aspectRatio;
            this.cameraCube.updateProjectionMatrix();
        }
    };

    return ScenePerspective;

})();


KSX.apps.core.ThreeJsApp.SceneOrtho = (function () {

    function SceneOrtho( canvas, verbose ) {
        this.canvas = canvas;
        this.verbose = verbose === undefined ? false : verbose;
        this.canvas.verbose = this.verbose;

        this.defaults = {
            posCamera: new THREE.Vector3( 0, 0, 1 ),
            near: 10,
            far: -10
        };
    }

    SceneOrtho.prototype.setCameraDefaults = function ( defaults ) {
        if ( defaults === null || defaults === undefined ) {
            return;
        }
        if ( defaults.posCamera !== undefined && defaults.posCamera !== null ) {
            this.defaults.posCamera.copy( defaults.posCamera );
        }
        if ( defaults.near !== undefined && defaults.near !== null ) {
            this.defaults.near = defaults.near;
        }
        if ( defaults.far !== undefined && defaults.far !== null ) {
            this.defaults.far = defaults.far;
        }
        this.resetCamera();
    };

    SceneOrtho.prototype.initGL = function () {
        this.scene = new THREE.Scene();

        this.camera = new THREE.OrthographicCamera(
            this.canvas.getPixelLeft(),
            this.canvas.getPixelRight,
            this.canvas.getPixelTop(),
            this.canvas.getPixelBottom(),
            this.defaults.near,
            this.defaults.far
        );
    };

    SceneOrtho.prototype.resetCamera = function () {
        this.camera.position.set( this.defaults.posCamera.x, this.defaults.posCamera.y, this.defaults.posCamera.z );
        this.camera.near = this.defaults.near;
        this.camera.far = this.defaults.far;
        this.camera.updateProjectionMatrix();
    };

    SceneOrtho.prototype.updateCamera = function () {
        this.camera.left = this.canvas.getPixelLeft();
        this.camera.right = this.canvas.getPixelRight();
        this.camera.top = this.canvas.getPixelTop();
        this.camera.bottom = this.canvas.getPixelBottom();

        if (this.verbose) {
            console.log('Ortho Camera Dimensions: ' + this.camera.left + ' ' + this.camera.right + ' ' + this.camera.top + ' ' + this.camera.bottom);
        }

        this.camera.updateProjectionMatrix();
    };

    return SceneOrtho;

})();


KSX.apps.core.ThreeJsApp.DefaultDefinition = {
    user: undefined,
    name: 'None',
    htmlCanvas : undefined,
    renderers: {
        regular: {
            canvas: undefined,
            antialias: true
        }
    },
    useScenePerspective: true,
    useSceneOrtho: false,
    useCube: false,
    loader: false,
    verbose: false
};
<commit_msg>ThreeJsApp: Removed unneeded reference to PlatformVerification<commit_after>/**
 * @author <NAME> / www.kaisalmen.de
 */

"use strict";

KSX.apps.core.ThreeJsApp = (function () {

    function ThreeJsApp() {
        this.renderingEnabled = false;

        this.frameNumber = 0;
        this.initOk = true;

        this.asyncDone = false;
    }

    ThreeJsApp.prototype.configure = function (userDefinition) {
        this.definition = userDefinition;
        fillDefinition(KSX.apps.core.ThreeJsApp.DefaultDefinition, this.definition);

        this.canvas = new KSX.apps.core.Canvas(this.definition.htmlCanvas);

        if (this.definition.useScenePerspective) {
            this.scenePerspective = new KSX.apps.core.ThreeJsApp.ScenePerspective(this.canvas);
        }

        if (this.definition.useSceneOrtho) {
            this.sceneOrtho = new KSX.apps.core.ThreeJsApp.SceneOrtho(this.canvas);
        }

        if (this.definition.useScenePerspective && this.definition.useCube) {
            this.scenePerspective.useCube = true;
        }

        this.renderer = new THREE.WebGLRenderer({
            canvas: this.definition.renderers.regular.canvas,
            antialias: this.definition.renderers.regular.antialias
        });

        // auto-clear must not be used when both perspective and ortho scenes are active
        // otherwise: renderer clears 3d content
        if ( this.definition.useScenePerspective && this.definition.useSceneOrtho ) {
            this.renderer.autoClear = false;
        }

        if ( this.definition.verbose ) {
            this.canvas.verbose = this.definition.verbose;
            if ( this.definition.useScenePerspective ) {
                this.scenePerspective.verbose = this.definition.verbose;
            }

            if ( this.definition.useSceneOrtho ) {
                this.sceneOrtho.verbose = this.definition.verbose;
            }
        };
    };

    var fillDefinition = function (paramsPredefined, paramsUser) {

        for (var predefined in paramsPredefined) {
            // early exit
            if (!paramsPredefined.hasOwnProperty(predefined)) {
                continue;
            }

            // renderer definitions: special treatment as object fields need to be copied (no-refs)
            if (predefined === 'renderers') {

                if (!paramsUser.hasOwnProperty(predefined)) {
                    paramsUser[predefined] = {};
                }
                var userRenderers = paramsUser[predefined];

                if (paramsPredefined.hasOwnProperty(predefined)) {
                    var predefinedRenderers = paramsPredefined[predefined];

                    for (var predefinedRendererName in predefinedRenderers) {
                        // early exit
                        if (!predefinedRenderers.hasOwnProperty(predefinedRendererName)) {
                            continue;
                        }

                        if (!userRenderers.hasOwnProperty(predefinedRendererName)) {
                            userRenderers[predefinedRendererName] = {};
                        }

                        var predefinedRenderer = predefinedRenderers[predefinedRendererName];
                        var userRenderer = userRenderers[predefinedRendererName];
                        fillDefinition(predefinedRenderer, userRenderer);
                    }
                }
                if (userRenderers['regular'].canvas === undefined) {
                    userRenderers['regular'].canvas = paramsUser['htmlCanvas'];
                }
            }
            else {
                if (!paramsUser.hasOwnProperty(predefined)) {
                    paramsUser[predefined] = paramsPredefined[predefined];
                }
            }
        }
    };

    ThreeJsApp.prototype.init = function () {
        var scope = this;

        scope.initAsyncContent();

        var initSync = function () {
            console.log("ThreeJsApp (" + scope.definition.name + "): initPreGL");
            scope.initPreGL();

            if ( !scope.initOk ) { return; }
            console.log("ThreeJsApp (" + scope.definition.name + "): initGL");
            if (scope.definition.useScenePerspective) {
                scope.scenePerspective.initGL();
                if ( !scope.initOk ) { return; }
            }
            if (scope.definition.useSceneOrtho) {
                scope.sceneOrtho.initGL();
                if ( !scope.initOk ) { return; }
            }

            scope.initGL();
            if ( !scope.initOk ) { return; }

            console.log("ThreeJsApp (" + scope.definition.name + "): resizeDisplayGLBase");
            scope.resizeDisplayGLBase();

            console.log("ThreeJsApp (" + scope.definition.name + "): addEventHandlers");
            scope.addEventHandlers();

            console.log("ThreeJsApp (" + scope.definition.name + "): initPostGL");
            scope.renderingEnabled = scope.initPostGL();
            if ( !scope.initOk ) { return; }

            if ( scope.renderingEnabled ) {
                console.log("ThreeJsApp (" + scope.definition.name + "): Ready to start render loop!");
            }
        };

        var interval = 10;
        var count = 0;
        var divider = 50;
        var checkAsyncStatus = setInterval( checkAsyncStatusTimer, interval );

        function checkAsyncStatusTimer() {
            if ( scope.asyncDone ) {
                clearInterval(checkAsyncStatus);
                console.log( 'Async loading took approx. ' + interval * count  + 'ms.' );
                initSync();
            }
            else {
                if ( count % divider === 0 ) {
                    console.log( 'Waiting for async content to be loaded (' + interval * count  + 'ms)' );
                }
                count++;
            }
        }
    };

    ThreeJsApp.prototype.resizeDisplayGLBase = function () {
        this.canvas.recalcAspectRatio();

        this.resizeDisplayGL();

        this.renderer.setSize(this.canvas.getWidth(), this.canvas.getHeight(), false);

        if (this.definition.useScenePerspective) {
            this.scenePerspective.updateCamera();
        }

        if (this.definition.useSceneOrtho) {
            this.sceneOrtho.updateCamera();
        }
    };

    ThreeJsApp.prototype.render = function () {
        if (this.renderingEnabled) {
            this.frameNumber++;
            if ( !this.renderer.autoClear ) {
                this.renderer.clear();
            }

            this.renderPre();

            if (this.definition.useScenePerspective) {
                if (this.scenePerspective.useCube) {
                    this.scenePerspective.cameraCube.rotation.copy( this.scenePerspective.camera.rotation );
                    this.renderer.render(this.scenePerspective.sceneCube, this.scenePerspective.cameraCube);
                }

                this.renderer.render(this.scenePerspective.scene, this.scenePerspective.camera);
            }

            if (this.definition.useSceneOrtho) {
                this.renderer.render(this.sceneOrtho.scene, this.sceneOrtho.camera);
            }

            this.renderPost();
        }
    };

    ThreeJsApp.prototype.resetCamera = function () {
        if (this.definition.useScenePerspective) {
            this.scenePerspective.resetCamera();
        }

        if (this.definition.useSceneOrtho) {
            this.sceneOrtho.resetCamera();
        }
    };

    /**
     * Default implementation
     */
    ThreeJsApp.prototype.initAsyncContent = function () {
        this.asyncDone = true;
    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.initPreGL = function () {

    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.initGL = function () {

    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.addEventHandlers = function () {

    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.initPostGL = function () {
        return true;
    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.resizeDisplayGL = function () {

    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.renderPre = function () {
        if ( this.definition.verbose ) {
            console.log("ThreeJsApp DEFAULT (" + this.definition.name + "): renderPre");
        }
    };

    /**
     * default implementation
     */
    ThreeJsApp.prototype.renderPost = function () {
        if ( this.definition.verbose ) {
            console.log("ThreeJsApp DEFAULT (" + this.definition.name + "): renderPost");
        }
    };

    /**
     * Default implementation
     */
    ThreeJsApp.prototype.dispose = function () {

    };

    return ThreeJsApp;
})();


KSX.apps.core.Canvas = (function () {

    function Canvas( htmlCanvas ) {
        this.verbose = false;
        this.htmlCanvas = null;
        if ( htmlCanvas !== undefined && htmlCanvas !== null &&
            htmlCanvas.offsetWidth !== undefined && htmlCanvas.offsetHeight !== undefined ) {
            this.htmlCanvas = htmlCanvas;
        }
        else {
            console.error( 'htmlCanvas cannot be used: It is either undefined or its width and height are not available.' );
        }
        this.recalcAspectRatio();
    }

    Canvas.prototype.recalcAspectRatio = function () {
        if (this.verbose) {
            console.log("width: " + this.getWidth() + " height: " + this.getHeight());
        }
        var height = this.getHeight();
        if (height === 0) {
            this.aspectRatio = 1;
        }
        else {
            this.aspectRatio = this.getWidth() / height;
        }
    };

    Canvas.prototype.resetWidth = function ( width, height ) {
        if (this.htmlCanvas !== null ) {

            if ( this.htmlCanvas.style !== undefined && this.htmlCanvas.style !== null) {
                this.htmlCanvas.style.width = width + 'px';
                this.htmlCanvas.style.height = height + 'px';
            }
            this.htmlCanvas.offsetWidth = width;
            this.htmlCanvas.offsetHeight = height;
        }
        this.recalcAspectRatio();
    };

    Canvas.prototype.getWidth = function () {
        return this.htmlCanvas === null ? 0 : this.htmlCanvas.offsetWidth;
    };

    Canvas.prototype.getHeight = function () {
        return this.htmlCanvas === null ? 0 : this.htmlCanvas.offsetHeight;
    };

    Canvas.prototype.getPixelLeft = function () {
        return -this.getWidth() / 2;
    };

    Canvas.prototype.getPixelRight = function () {
        return this.getWidth() / 2;
    };

    Canvas.prototype.getPixelTop = function () {
        return this.getHeight() / 2;
    };

    Canvas.prototype.getPixelBottom = function () {
        return -this.getHeight() / 2;
    };

    return Canvas;

})();



KSX.apps.core.ThreeJsApp.ScenePerspective = (function () {

    function ScenePerspective( canvas, verbose ) {
        this.canvas = canvas;
        this.verbose = verbose === undefined ? false : verbose;
        this.canvas.verbose = this.verbose;
        this.camera = null;
        this.useCube = false;
        this.cameraCube = null;

        this.defaults = {
            posCamera: new THREE.Vector3(100, 100, 100),
            upVector: new THREE.Vector3(0, 1, 0),
            posCameraTarget: new THREE.Vector3(0, 0, 0),
            posCameraCube: new THREE.Vector3(0, 0, 0),
            near: 0.1,
            far: 10000,
            fov: 45
        };

        this.cameraTarget = this.defaults.posCameraTarget;
    }

    ScenePerspective.prototype.setCameraDefaults = function ( defaults ) {
        if ( defaults === null || defaults === undefined ) {
            return;
        }
        if ( defaults.posCamera !== undefined && defaults.posCamera !== null ) {
            this.defaults.posCamera.copy( defaults.posCamera );
        }
        if ( defaults.upVector !== undefined && defaults.upVector !== null ) {
            this.defaults.upVector.copy( defaults.upVector );
        }
        if ( defaults.posCameraTarget !== undefined && defaults.posCameraTarget !== null ) {
            this.defaults.posCameraTarget.copy( defaults.posCameraTarget );
        }
        if ( defaults.posCameraCube !== undefined && defaults.posCameraCube !== null ) {
            this.defaults.posCameraCube.copy( defaults.posCameraCube );
        }
        if ( defaults.near !== undefined && defaults.near !== null ) {
            this.defaults.near = defaults.near;
        }
        if ( defaults.far !== undefined && defaults.far !== null ) {
            this.defaults.far = defaults.far;
        }
        if ( defaults.fov !== undefined && defaults.fov !== null ) {
            this.defaults.fov = defaults.fov;
        }
        this.resetCamera();
    };

    ScenePerspective.prototype.initGL = function () {
        this.scene = new THREE.Scene();

        this.camera = new THREE.PerspectiveCamera( this.defaults.fov, this.canvas.aspectRatio, this.defaults.near, this.defaults.far );

        if (this.useCube) {
            this.cameraCube = new THREE.PerspectiveCamera( this.defaults.fov, this.canvas.aspectRatio, this.defaults.near, this.defaults.far );
            this.sceneCube = new THREE.Scene();
        }
        this.resetCamera();
    };

    ScenePerspective.prototype.resetCamera = function () {
        this.camera.position.copy(this.defaults.posCamera);
        this.camera.up.copy(this.defaults.upVector);
        this.cameraTarget.copy(this.defaults.posCameraTarget);

        if (this.useCube) {
            this.cameraCube.position.copy(this.defaults.posCameraCube);
        }
        this.updateCamera();
    };

    ScenePerspective.prototype.updateCamera = function () {
        this.camera.aspect = this.canvas.aspectRatio;
        this.camera.lookAt(this.cameraTarget);
        this.camera.updateProjectionMatrix();

        if (this.useCube) {
            this.cameraCube.rotation.copy( this.camera.rotation );
            this.cameraCube.aspectRatio = this.canvas.aspectRatio;
            this.cameraCube.updateProjectionMatrix();
        }
    };

    return ScenePerspective;

})();


KSX.apps.core.ThreeJsApp.SceneOrtho = (function () {

    function SceneOrtho( canvas, verbose ) {
        this.canvas = canvas;
        this.verbose = verbose === undefined ? false : verbose;
        this.canvas.verbose = this.verbose;

        this.defaults = {
            posCamera: new THREE.Vector3( 0, 0, 1 ),
            near: 10,
            far: -10
        };
    }

    SceneOrtho.prototype.setCameraDefaults = function ( defaults ) {
        if ( defaults === null || defaults === undefined ) {
            return;
        }
        if ( defaults.posCamera !== undefined && defaults.posCamera !== null ) {
            this.defaults.posCamera.copy( defaults.posCamera );
        }
        if ( defaults.near !== undefined && defaults.near !== null ) {
            this.defaults.near = defaults.near;
        }
        if ( defaults.far !== undefined && defaults.far !== null ) {
            this.defaults.far = defaults.far;
        }
        this.resetCamera();
    };

    SceneOrtho.prototype.initGL = function () {
        this.scene = new THREE.Scene();

        this.camera = new THREE.OrthographicCamera(
            this.canvas.getPixelLeft(),
            this.canvas.getPixelRight,
            this.canvas.getPixelTop(),
            this.canvas.getPixelBottom(),
            this.defaults.near,
            this.defaults.far
        );
    };

    SceneOrtho.prototype.resetCamera = function () {
        this.camera.position.set( this.defaults.posCamera.x, this.defaults.posCamera.y, this.defaults.posCamera.z );
        this.camera.near = this.defaults.near;
        this.camera.far = this.defaults.far;
        this.camera.updateProjectionMatrix();
    };

    SceneOrtho.prototype.updateCamera = function () {
        this.camera.left = this.canvas.getPixelLeft();
        this.camera.right = this.canvas.getPixelRight();
        this.camera.top = this.canvas.getPixelTop();
        this.camera.bottom = this.canvas.getPixelBottom();

        if (this.verbose) {
            console.log('Ortho Camera Dimensions: ' + this.camera.left + ' ' + this.camera.right + ' ' + this.camera.top + ' ' + this.camera.bottom);
        }

        this.camera.updateProjectionMatrix();
    };

    return SceneOrtho;

})();


KSX.apps.core.ThreeJsApp.DefaultDefinition = {
    user: undefined,
    name: 'None',
    htmlCanvas : undefined,
    renderers: {
        regular: {
            canvas: undefined,
            antialias: true
        }
    },
    useScenePerspective: true,
    useSceneOrtho: false,
    useCube: false,
    loader: false,
    verbose: false
};

{'fraction_non_alphanumeric': 0.11789561387847408, 'fraction_numerical': 0.003273225019341784, 'mean_word_length': 1.8635821404226312, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2729908', 'n_tokens_mistral': 9351, 'n_tokens_neox': 8888, 'n_words': 1538}