Repository

js/Mobilizing/renderer/3D/three/scene/CubeMapCamera.js

import Node from "../shape/3D/primitive/Node";
import Camera from "../scene/Camera";
import Vector3 from "../types/Vector3";
import RenderTexture from "../texture/RenderTexture";
import Color from "../types/Color";
import Text from "../shape/3D/composite/Text";
import Rect from "../types/Rect";

export default class CubeMapCamera {

    constructor({
        renderer = null,
        typeface = null,
        makeTestScene = false,
        debugMode = false,
    } = {}) {
        this.renderer = renderer;
        this.typeface = typeface;
        this.makeTestScene = makeTestScene;
        this.debugMode = debugMode;
    }

    makeCubeCameraNode() {

        console.log("this.renderer", this.renderer);

        if (this.makeTestScene) {
            const scene = this.makeCubeCameraCheckScene();
            this.renderer.addToCurrentScene(scene);
        }

        this.cubeCameraNode = this.makeCubeCamera();
        this.renderer.addToCurrentScene(this.cubeCameraNode);
        //console.log("cubeCameraNode", cubeCameraNode);

        /* this.cubeCameraNode = this.makeCubeCamera({
            layerName: "cubemap",
            renderToTexture: true,
        });
        this.renderer.addToCurrentScene(this.cubeCameraNode);
        const cams = this.cubeCameraNode.transform.getChildren();
        const textures = [];
        cams.forEach((cam, index) => {

            const texture = cam.getRenderTexture();
            textures.push(texture);
            console.log("texture", texture);
            const plane = new Plane({
                "material": "basic",
                "width": 5,
                "height": 5,
            });
            plane.transform.setLocalPositionX(index * 5);
            plane.transform.setLocalPositionY(5);
            plane.material.setTexture(texture);

            this.renderer.setCurrentScene("default");
            this.renderer.addToCurrentScene(plane);
        }); */

        return this.cubeCameraNode;
    }

    makeCubeCamera({
        layerName = null,
        renderToTexture = null
    } = {}) {

        const cubeCameraNode = new Node();
        //this.renderer.addToCurrentScene(cubeCameraNode);

        const fov = 90; // negative fov is not an error
        const aspect = 1;
        const resolution = 512;

        const cameraRight = new Camera({
            name: "cameraRight",
            fov,
            aspect
        });
        cameraRight.transform.setUpDirection(new Vector3(0, 1, 0));
        cameraRight.transform.lookAt(new Vector3(1, 0, 0));

        const cameraLeft = new Camera({
            name: "cameraLeft",
            fov,
            aspect
        });
        cameraLeft.transform.setUpDirection(new Vector3(0, 1, 0));
        cameraLeft.transform.lookAt(new Vector3(- 1, 0, 0));

        const cameraTop = new Camera({
            name: "cameraTop",
            fov,
            aspect
        });
        cameraTop.transform.setUpDirection(new Vector3(0, 0, 1));
        cameraTop.transform.lookAt(new Vector3(0, 1, 0));

        const cameraBottom = new Camera({
            name: "cameraBottom",
            fov,
            aspect
        });
        cameraBottom.transform.setUpDirection(new Vector3(0, 0, 1));
        cameraBottom.transform.lookAt(new Vector3(0, - 1, 0));

        const cameraBack = new Camera({
            name: "cameraBack",
            fov,
            aspect
        });
        cameraBack.transform.setUpDirection(new Vector3(0, 1, 0));
        cameraBack.transform.lookAt(new Vector3(0, 0, 1));

        const cameraFront = new Camera({
            name: "cameraFront",
            fov,
            aspect
        });
        cameraFront.transform.setUpDirection(new Vector3(0, 1, 0));
        cameraFront.transform.lookAt(new Vector3(0, 0, - 1));

        // First line: right, back, left. - Second line: bottom, top, front.
        cubeCameraNode.transform.addChild(cameraBottom.transform);
        cubeCameraNode.transform.addChild(cameraTop.transform);
        cubeCameraNode.transform.addChild(cameraFront.transform);

        cubeCameraNode.transform.addChild(cameraRight.transform);
        cubeCameraNode.transform.addChild(cameraBack.transform);
        cubeCameraNode.transform.addChild(cameraLeft.transform);

        //RTT
        if (renderToTexture) {
            const cameraRightTexture = new RenderTexture({
                "width": resolution,
                "height": resolution,
            });
            cameraRight.setRenderTexture(cameraRightTexture);
            const cameraLeftTexture = new RenderTexture({
                "width": resolution,
                "height": resolution,
            });
            cameraLeft.setRenderTexture(cameraLeftTexture);
            const cameraTopTexture = new RenderTexture({
                "width": resolution,
                "height": resolution,
            });
            cameraTop.setRenderTexture(cameraTopTexture);
            const cameraBottomTexture = new RenderTexture({
                "width": resolution,
                "height": resolution,
            });
            cameraBottom.setRenderTexture(cameraBottomTexture);
            const cameraBackTexture = new RenderTexture({
                "width": resolution,
                "height": resolution,
            });
            cameraBack.setRenderTexture(cameraBackTexture);
            const cameraFrontTexture = new RenderTexture({
                "width": resolution,
                "height": resolution,
            });
            cameraFront.setRenderTexture(cameraFrontTexture);

            const cams = cubeCameraNode.transform.getChildren();
            cams.forEach((cam) => {
                cam.setLayer(layerName);
                const clearColor = Color.random();
                cam.setClearColor(clearColor);
                if (layerName) {
                    this.renderer.setCurrentScene(layerName);
                }
                this.renderer.addCamera(cam);
                console.log(cam.transform.getLocalRotation());
            });
            this.renderer.setCurrentScene("default");
        }
        else {
            //compute viewport values
            const viewports = this.computeViewports(window.innerWidth, window.innerHeight);

            const cams = cubeCameraNode.transform.getChildren();
            cams.forEach((cam, index) => {
                const rect = viewports[index];
                console.log("cam :", cam.name, "rect", rect);
                cam.viewport = rect;
                if (this.debugMode) {
                    const clearColor = Color.random();
                    cam.setClearColor(clearColor);
                }
                this.renderer.addCamera(cam);
            });
        }
        return cubeCameraNode;
    }

    computeViewports(width, height) {
        const squareSize = Math.min(width / 3, height / 2);
        const squares = [];
        for (let i = 0; i < 2; i++) {
            for (let j = 0; j < 3; j++) {
                const x = j * squareSize / width;
                const y = i * squareSize / height;
                const rect = new Rect({
                    x: x,
                    y: y,
                    width: squareSize / width,
                    height: squareSize / height
                });
                squares.push(rect);
            }
        }
        return squares;
    }

    makeCubeCameraCheckScene(layerName) {

        const checkNode = new Node();
        if (layerName) {
            this.renderer.setCurrentScene(layerName);
        }
        this.renderer.addToCurrentScene(checkNode);

        console.log("typeface", this.typeface);
        const front = new Text({
            text: "front",
            font: this.typeface,
            fontSize: 1,
            depth: 0,
            segments: 10,
            material: "basic"
        });
        checkNode.transform.addChild(front.transform);

        const back = new Text({
            text: "back",
            font: this.typeface,
            fontSize: 1,
            depth: 0,
            segments: 10,
            material: "basic"
        });
        checkNode.transform.addChild(back.transform);

        const left = new Text({
            text: "left",
            font: this.typeface,
            fontSize: 1,
            depth: 0,
            segments: 10,
            material: "basic"
        });
        checkNode.transform.addChild(left.transform);

        const right = new Text({
            text: "right",
            font: this.typeface,
            fontSize: 1,
            depth: 0,
            segments: 10,
            material: "basic"
        });
        checkNode.transform.addChild(right.transform);

        const top = new Text({
            text: "top",
            font: this.typeface,
            fontSize: 1,
            depth: 0,
            segments: 10,
            material: "basic"
        });
        checkNode.transform.addChild(top.transform);

        const bottom = new Text({
            text: "bottom",
            font: this.typeface,
            fontSize: 1,
            depth: 0,
            segments: 10,
            material: "basic"
        });
        checkNode.transform.addChild(bottom.transform);

        const children = checkNode.transform.getChildren();
        children.forEach((mesh) => {
            mesh.setCenter(0, 0, 0);
        });

        front.transform.setLocalPositionZ(-10);
        back.transform.setLocalPositionZ(10);
        back.transform.setLocalRotationY(-180);
        left.transform.setLocalPositionX(-10);
        left.transform.setLocalRotationY(90);
        right.transform.setLocalPositionX(10);
        right.transform.setLocalRotationY(-90);
        top.transform.setLocalPositionY(10);
        top.transform.setLocalRotationX(90);
        bottom.transform.setLocalPositionY(-10);
        bottom.transform.setLocalRotationY(180);
        bottom.transform.setLocalRotationX(90);

        return checkNode;
    }
}