Newer
Older
Three.js / threeJsTemplate.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <div id="WebGL-output"></div>

    <script type="module">
        import * as THREE from "https://unpkg.com/three@0.126.1/build/three.module.js";
        import { PointerLockControls } from "https://unpkg.com/three@0.126.1/examples/jsm/controls/PointerLockControls.js";
        import { GLTFLoader } from "https://unpkg.com/three@0.126.1/examples/jsm/loaders/GLTFLoader.js";
        import { FBXLoader } from "https://unpkg.com/three@0.126.1/examples/jsm/loaders/FBXLoader.js";

        let camera;
        let scene;
        let renderer;
        let model;
        let mixer;
        let clock;
        let moveForward = false;
        let moveBackward = false;
        let moveLeft = false;
        let moveRight = false;
        let controls;

        //シーンの作成
        function fScene() {
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x111111); // 背景色
        }

        //カメラの作成
        function fCamera() {
            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
            //カメラセット
            camera.position.set(100, 500, 500); // カメラの位置
            camera.lookAt(new THREE.Vector3(0, 5, 0));
        }

        //ライトの作成
        function fLight() {
            const light = new THREE.SpotLight(0xffffff, 1.0);
            light.position.set(100, 500, 500);
            scene.add(light);
            light.castShadow = true;
            console.log(light);
        }

        // 補助線
        function fHelper() {
            const axesHelper = new THREE.AxesHelper(100);
            scene.add(axesHelper);
            const gridHelper = new THREE.GridHelper(50, 50);
            scene.add(gridHelper);
        }

        // カメラコントロールの作成
        function fCamaraControls() {
            controls = new PointerLockControls(camera, document.body);

            document.addEventListener("click", function () {
                controls.lock();
            });
            // controls.addEventListener("lock", function () { });
            // controls.addEventListener("unlock", function () { });

            // キーボードのキーを押したの際の処理
            document.addEventListener("keydown", function (event) {
                switch (event.key) {
                    case "w":
                    case "ArrowUp":
                        moveForward = true;
                        break;
                    case "s":
                    case "ArrowDown":
                        moveBackward = true;
                        break;
                    case "a":
                    case "ArrowLeft":
                        moveLeft = true;
                        break;
                    case "d":
                    case "ArrowRight":
                        moveRight = true;
                        break;
                }
            });

            // キーボードのキーを離した際の処理
            document.addEventListener("keyup", function (event) {
                switch (event.key) {
                    case "w":
                    case "ArrowUp":
                        moveForward = false;
                        break;
                    case "s":
                    case "ArrowDown":
                        moveBackward = false;
                        break;
                    case "a":
                    case "ArrowLeft":
                        moveLeft = false;
                        break;
                    case "d":
                    case "ArrowRight":
                        moveRight = false;
                        break;
                }
            });
        }

        // レンダラーの作成
        function fRenderer() {
            renderer = new THREE.WebGLRenderer({
                alpha: true,
                antialias: true,
            });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.physicallyCorrectLight = true;
        }

        //glbファイルの読み込み
        function fGlbLoader() {
            const gloader = new GLTFLoader();
            gloader.load("model/tohokukoekiGis.glb", function (gltf) {
                model = gltf.scene;
                model.position.set(0, 0.02, 0);
                scene.add(model);
            });
            
        }

        // fbxファイルの読み込み
        function fFbxLoader() {
            clock = new THREE.Clock();
            //fbxファイルの読み込み
            const loader = new FBXLoader();

            loader.load("model/box_move.fbx", function (object) {
                object.scale.set(0.01, 0.01, 0.01);
                object.position.set(0, 1, 0);
                mixer = new THREE.AnimationMixer(object);
                let action = mixer.clipAction(object.animations[0]);
                action.play();
                scene.add(object);
            });
        }

        function fVideotexture() {
            const video = document.createElement("video");
            video.src = "video/OkinawaSea.mp4";
            video.src = "video/OkinawaSea.webm";
            video.autoplay = true;
            video.loop = true;
            video.muted = true;
            video.load();
            video.play();
            const texture = new THREE.VideoTexture(video);
            // 動画の表示されているオブジェクトをなめらかにする。
            texture.minFilter = THREE.LinearFilter;
            texture.magFilter = THREE.LinearFilter;
            texture.wrapS = THREE.ClampToEdgeWrapping;
            texture.wrapT = THREE.ClampToEdgeWrapping;
            // ------------------------------------------------
            const material = new THREE.MeshBasicMaterial({ map: texture });
            const geometry = new THREE.PlaneGeometry(12, 8);
            const mesh = new THREE.Mesh(geometry, material);
            mesh.position.set(0, 5, 0);
            scene.add(mesh);
        }

        // function audio() {
        //     const listener = new THREE.Audiolistener();
        //     camera.add(listener);
        //     const audioLoader = new THREE.AudioLoader();
        //     const sound = new THREE.PositionalAudio(listener);
        //     audioLoader.load('mp3/OkinawaSea.mp3', function(buffer) {
        //         sound.setBuffer(buffer);
        //         sound.setRefDistance(20);
        //         sound.play();
        //     });
        //     fGlbLoader().model.add(sound);
        // }

        function init() {
            fScene();
            fCamera();
            fLight();
            fHelper();
            fCamaraControls();
            fRenderer();
            fGlbLoader();
            // fFbxLoader();
            // fVideotexture();

            document
                .getElementById("WebGL-output")
                .appendChild(renderer.domElement);
        }

        const mouse = new THREE.Vector2();

        function updateCameraPosition() {
            const speed = 10; // 移動速度
            const direction = new THREE.Vector3();
            const { x, y, z } = controls.getObject().position;
            direction.x = Number(moveRight) - Number(moveLeft);
            direction.z = Number(moveBackward) - Number(moveForward);
            direction.normalize();
            const delta = speed * 0.1; // 移動距離
            controls.getObject().translateX(direction.x * delta);
            controls.getObject().translateZ(direction.z * delta);
        }

        function animate() {
            requestAnimationFrame(animate);
            updateCameraPosition();
            if (mixer) mixer.update(clock.getDelta());
            renderer.render(scene, camera);
        }

        // クリックしたら呼ばれる
        function OnClick(event) {
            event.preventDefault();

            const raycaster = new THREE.Raycaster();
            const mouse = new THREE.Vector2();

            // マウスポインタの位置情報の取得
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

            console.log(mouse.x);
            // 光線を発射
            raycaster.setFromCamera(mouse, camera);
            // 光線と交わるオブジェクトを収集
            const intersects = raycaster.intersectObjects(scene.children, true);

            // 交わるオブジェクトが1個以上の場合
            if (intersects.length > 0) {
                if (intersects[0].object.name == "球") {
                    window.open("https://openai.com/blog/chatgpt");
                }
                console.log(intersects[0]);
            }
        }

        // 関数の実行
        init();
        animate();

    </script>
</body>

</html>