TA159

Notas, resueltos y trabajos practicos de la materia Sistemas Gráficos
Index Commits Files Refs Submodules README LICENSE
commit 081aee5eb625cbd4efbdda476ce5ed2b67aabf57
parent 35b0fc20ed38f25957540280bbbab655cdd428a9
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date:   Thu,  4 Jul 2024 14:28:11 -0300

add first person camera instructions and controls

Diffstat:
Mtp/scene.html | 45++++++++++++++++++++++++++++++++++++++++++++-
Mtp/src/scene.js | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 124 insertions(+), 3 deletions(-)
diff --git a/tp/scene.html b/tp/scene.html
@@ -9,10 +9,53 @@
                 padding: 0;
                 margin: 0;
                 height: 100%;
+
+            #blocker {
+                position: absolute;
+                width: 100%;
+                height: 100%;
+                background-color: rgba(0,0,0,0.5);
+                backdrop-filter: blur(5px);
+            }
+
+            #instructions {
+                width: 100%;
+                height: 100%;
+
+                /* display: flex; */
+                display: none;
+                flex-direction: column;
+                justify-content: center;
+                align-items: center;
+
+                padding-top: 0;
+                text-align: center;
+                font-size: 20px;
+                cursor: pointer;
+
+                text-shadow: 1px 1px 2px white;
+            }
+
+            #click-to-play {
+                font-size: 42px;
+                padding: 0em;
+                margin: 0em;
+            }
         </style>
     </head>
     <body>
-        <div id="mainContainer"></div>
+        <div id="blocker">
+            <div id="instructions">
+                <p id="click-to-play">
+                    Click to play
+                </p>
+                <p>
+                    Move: WASD<br/>
+                    Jump: SPACE<br/>
+                    Look: MOUSE
+                </p>
+            </div>
+        </div>
         <script type="module" src="/src/scene.js"></script>
     </body>
 </html>
diff --git a/tp/src/scene.js b/tp/src/scene.js
@@ -1,6 +1,8 @@
 import * as THREE from 'three';
 import * as dat from 'dat.gui';
 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
+import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
+import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
 import { vertexShader, fragmentShader } from '/assets/shaders.js';
 
 import { generateTunnelGeometry } from '/src/tunnel.js';
@@ -18,6 +20,8 @@ import { updateTrainCrankPosition } from '/src/train.js';
 let scene, camera, renderer, terrainMaterial, terrainGeometry, terrain, time;
 let treesForbiddenMapData, treesForbiddenMap, elevationMap, elevationMapData;
 
+let firstPersonControls, orbitControls;
+
 let train, gui;
 let cameras = [];
 
@@ -62,12 +66,51 @@ function onResize() {
 function nextCamera() {
     const camerasCount = cameras.length;
 
+    if(cameras[settings.currCameraIndex].name == "firstPersonCamera") {
+        firstPersonControls.unlock();
+        blocker.style.display = 'none';
+        instructions.style.display = 'flex';
+    }
+
     if(settings.currCameraIndex == (camerasCount - 1)) {
-        console.log("Restarting cameras");
         settings.currCameraIndex = 0;
     } else {
         settings.currCameraIndex += 1;
     }
+
+    if(cameras[settings.currCameraIndex].name == "firstPersonCamera") {
+        firstPersonControls.unlock();
+        blocker.style.display = 'block';
+        instructions.style.display = 'flex';
+    }
+}
+
+const blocker = document.getElementById( 'blocker' );
+const instructions = document.getElementById( 'instructions' );
+
+function firstPersonCameraHandler(eventName) {
+    // if(cameras[settings.currCameraIndex].name != "firstPersonCamera") {
+    //     console.log(cameras[settings.currCameraIndex].name);
+    //     return;
+    // }
+
+    // console.log(eventName);
+    switch(eventName) {
+        case 'click':
+            console.log('click');
+            firstPersonControls.lock();
+            break;
+        case 'lock':
+            console.log('lock');
+            instructions.style.display = 'none';
+            blocker.style.display = 'none';
+            break;
+        case 'unlock':
+            console.log('unlock');
+            blocker.style.display = 'block';
+            instructions.style.display = 'flex';
+            break;
+    }
 }
 
 function setupThreeJs() {
@@ -89,7 +132,7 @@ function setupThreeJs() {
     topView.name = "topView"
     cameras.push(topView);
 
-    const controls = new OrbitControls(topView, renderer.domElement);
+    orbitControls = new OrbitControls(topView, renderer.domElement);
 
     const firstPersonCamera = new THREE.PerspectiveCamera(
         50, window.innerWidth / window.innerHeight, 0.1, 1000);
@@ -99,6 +142,25 @@ function setupThreeJs() {
     firstPersonCamera.name = "firstPersonCamera"
     cameras.push(firstPersonCamera);
 
+    firstPersonControls = new PointerLockControls(firstPersonCamera, document.body);
+
+
+    instructions.addEventListener('click', function() {
+        // console.log(event);
+        firstPersonCameraHandler('click');
+    });
+
+    firstPersonControls.addEventListener('lock', function() {
+        // console.log(event);
+        firstPersonCameraHandler('lock');
+    });
+
+    firstPersonControls.addEventListener('unlock', function() {
+        // console.log(event);
+        firstPersonCameraHandler('unlock');
+    });
+    scene.add(firstPersonControls.getObject());
+
     const ambientLight = new THREE.AmbientLight(0xFFFFFF);
     scene.add(ambientLight);
 
@@ -389,6 +451,22 @@ function buildScene() {
 
 function mainLoop() {
     let currCamera = cameras[settings.currCameraIndex];
+    switch(currCamera.name) {
+        case "topView":
+            orbitControls.enabled = true;
+            blocker.style.display = 'none';
+            instructions.style.display = 'none';
+            break;
+        case "firstPersonCamera":
+            orbitControls.enabled = false;
+            break;
+        default:
+            orbitControls.enabled = false;
+            blocker.style.display = 'none';
+            instructions.style.display = 'none';
+            break;
+    }
+
 
     requestAnimationFrame(mainLoop);
     renderer.render(scene, currCamera);