From 38ff860c1517aa84b4e3dd112bde3957700805e2 Mon Sep 17 00:00:00 2001 From: David espinosa <104380606+davespser@users.noreply.github.com> Date: Tue, 10 Dec 2024 12:20:44 +0100 Subject: [PATCH] Update three-scene.js --- js/three-scene.js | 312 +++++++++++++++++++++++++--------------------- 1 file changed, 173 insertions(+), 139 deletions(-) diff --git a/js/three-scene.js b/js/three-scene.js index 623a1b38..549f7b85 100644 --- a/js/three-scene.js +++ b/js/three-scene.js @@ -8,17 +8,49 @@ let speed = 0.02; // Velocidad inicial let cameraOffset = new THREE.Vector3(0, 5, 10); // Offset de la cámara detrás del cubo const clock = new THREE.Clock(); -// Definir los vértices e índices para el terreno -const vertices = [ - -1.0, -1.0, 0.0, - 1.0, -1.0, 0.0, - 1.0, 1.0, 0.0, - -1.0, 1.0, 0.0 -]; -const indices = [ - 0, 1, 2, - 2, 3, 0 -]; +class TerrainGenerator { + constructor(segments, width, height) { + this.segments = segments; + this.width = width; + this.height = height; + } + + generateHeight(x, z) { + // Aquí puedes implementar tu propia lógica para generar alturas + return Math.sin(x * z); + } + + generate() { + const vertices = []; + const indices = []; + + // Generate vertices + for (let y = 0; y <= this.segments; y++) { + for (let x = 0; x <= this.segments; x++) { + const xPos = (x / this.segments - 0.5) * this.width; + const zPos = (y / this.segments - 0.5) * this.height; + const yPos = this.generateHeight(xPos, zPos); + + vertices.push(xPos, yPos, zPos); + } + } + + // Generate indices + for (let y = 0; y < this.segments; y++) { + for (let x = 0; x < this.segments; x++) { + const a = x + (this.segments + 1) * y; + const b = x + (this.segments + 1) * (y + 1); + const c = (x + 1) + (this.segments + 1) * (y + 1); + const d = (x + 1) + (this.segments + 1) * y; + + indices.push(a, b, d); + indices.push(b, c, d); + } + } + + return { vertices, indices }; + } +} // Crear malla de terreno function createTerrainMesh(vertices, indices) { @@ -27,155 +59,157 @@ function createTerrainMesh(vertices, indices) { // Función para cargar la escena principal export function loadThreeScene({ x = 0, y = 0, z = 0, color = 0xff4500, stats = {} }) { - // Crear escena - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x87ceeb); - - // Configurar cámara - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); - camera.position.set(x + 10, y + 5, z + 10); - camera.lookAt(x, y, z); - - // Configurar renderizador - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.shadowMap.enabled = true; - document.body.innerHTML = ""; // Limpiar la interfaz anterior - document.body.appendChild(renderer.domElement); - - // Agregar luces - const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); - directionalLight.position.set(10, 20, 10); - directionalLight.castShadow = true; - scene.add(directionalLight); - - light = new THREE.PointLight(0xffffff, 1, 100); - scene.add(light); - - // Crear malla de terreno y agregar a la escena - const terrain = createTerrainMesh(vertices, indices); - scene.add(terrain); - - // Crear cubo con specularMap - const textureLoader = new THREE.TextureLoader(); - const specularMap = textureLoader.load("./js/Specularbox.png"); - - const geometry = new THREE.BoxGeometry(); - const material = new THREE.MeshPhongMaterial({ - color, - specular: 0xffffff, - shininess: 100, - specularMap, - }); - - cube = new THREE.Mesh(geometry, material); - cube.position.set(x, y + 0.5, z); - cube.castShadow = true; - scene.add(cube); - - // Cargar modelo GLTF - const loader = new GLTFLoader(); - loader.load( - "./models/npc/robotauro_walk.glb", - (gltf) => { - robot = gltf.scene; - robot.position.set(x, y + 2.5, z); - robot.scale.set(0.05, 0.05, 0.05); - robot.traverse((child) => { - if (child.isMesh) { - child.castShadow = true; + // Crear escena + scene = new THREE.Scene(); + scene.background = new THREE.Color(0x87ceeb); + + // Configurar cámara + camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); + camera.position.set(x + 10, y + 5, z + 10); + camera.lookAt(x, y, z); + + // Configurar renderizador + renderer = new THREE.WebGLRenderer({ antialias: true }); + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.shadowMap.enabled = true; + document.body.innerHTML = ""; // Limpiar la interfaz anterior + document.body.appendChild(renderer.domElement); + + // Agregar luces + const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); + scene.add(ambientLight); + + const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); + directionalLight.position.set(10, 20, 10); + directionalLight.castShadow = true; + scene.add(directionalLight); + + light = new THREE.PointLight(0xffffff, 1, 100); + scene.add(light); + + // Crear terreno procedural + const terrainGenerator = new TerrainGenerator(64, 100, 100); // Ajusta los valores según tus necesidades + const { vertices, indices } = terrainGenerator.generate(); + const terrain = createTerrainMesh(vertices, indices); + scene.add(terrain); + + // Crear cubo con specularMap + const textureLoader = new THREE.TextureLoader(); + const specularMap = textureLoader.load("./js/Specularbox.png"); + + const geometry = new THREE.BoxGeometry(); + const material = new THREE.MeshPhongMaterial({ + color, + specular: 0xffffff, + shininess: 100, + specularMap, + }); + + cube = new THREE.Mesh(geometry, material); + cube.position.set(x, y + 0.5, z); + cube.castShadow = true; + scene.add(cube); + + // Cargar modelo GLTF + const loader = new GLTFLoader(); + loader.load( + "./models/npc/robotauro_walk.glb", + (gltf) => { + robot = gltf.scene; + robot.position.set(x, y + 2.5, z); + robot.scale.set(0.05, 0.05, 0.05); + robot.traverse((child) => { + if (child.isMesh) { + child.castShadow = true; + } + }); + scene.add(robot); + + // Configurar animaciones + mixer = new THREE.AnimationMixer(robot); + if (gltf.animations.length > 0) { + const walkAction = mixer.clipAction(gltf.animations[0]); + walkAction.play(); + } + }, + undefined, + (error) => { + console.error("Error al cargar el modelo: ", error); } - }); - scene.add(robot); - - // Configurar animaciones - mixer = new THREE.AnimationMixer(robot); - if (gltf.animations.length > 0) { - const walkAction = mixer.clipAction(gltf.animations[0]); - walkAction.play(); - } - }, - undefined, - (error) => { - console.error("Error al cargar el modelo: ", error); - } - ); + ); - // Configurar eventos de teclado para mover el cubo - window.addEventListener("keydown", handleKeyDown); + // Configurar eventos de teclado para mover el cubo + window.addEventListener("keydown", handleKeyDown); - // Crear menú y joypad desde ui.js - createJoypad((stickX, stickY) => { - if (cube) { - cube.position.x += stickX * 0.1; // Ajusta la sensibilidad del movimiento - cube.position.z += stickY * 0.1; - } - }); + // Crear menú y joypad desde ui.js + createJoypad((stickX, stickY) => { + if (cube) { + cube.position.x += stickX * 0.1; // Ajusta la sensibilidad del movimiento + cube.position.z += stickY * 0.1; + } + }); - // Crear estadísticas - createStats(stats); + // Crear estadísticas + createStats(stats); - // Crear menú - createMenu(); + // Crear menú + createMenu(); - animate(); + animate(); } // Manejar teclas function handleKeyDown(event) { - if (!cube) return; - - switch (event.key) { - case "ArrowUp": - cube.position.z -= speed; - break; - case "ArrowDown": - cube.position.z += speed; - break; - case "ArrowLeft": - cube.position.x -= speed; - break; - case "ArrowRight": - cube.position.x += speed; - break; - } + if (!cube) return; + + switch (event.key) { + case "ArrowUp": + cube.position.z -= speed; + break; + case "ArrowDown": + cube.position.z += speed; + break; + case "ArrowLeft": + cube.position.x -= speed; + break; + case "ArrowRight": + cube.position.x += speed; + break; + } } // Animar la escena function animate() { - requestAnimationFrame(animate); + requestAnimationFrame(animate); - const delta = clock.getDelta(); // Tiempo transcurrido desde el último frame + const delta = clock.getDelta(); // Tiempo transcurrido desde el último frame - // Actualizar el mixer (animaciones) - if (mixer) mixer.update(delta); + // Actualizar el mixer (animaciones) + if (mixer) mixer.update(delta); - // Actualizar posición del robot (si es necesario) - if (robot) { - robot.position.z -= speed / 2; - robot.rotation.y = Math.PI; // Ajustar orientación - } + // Actualizar posición del robot (si es necesario) + if (robot) { + robot.position.z -= speed / 2; + robot.rotation.y = Math.PI; // Ajustar orientación + } - // Actualizar la posición de la cámara para seguir al cubo - if (cube) { - const desiredPosition = new THREE.Vector3().addVectors(cube.position, cameraOffset); - camera.position.lerp(desiredPosition, 0.1); // Suavizar movimiento de la cámara - camera.lookAt(cube.position); // La cámara siempre mira al cubo - } + // Actualizar la posición de la cámara para seguir al cubo + if (cube) { + const desiredPosition = new THREE.Vector3().addVectors(cube.position, cameraOffset); + camera.position.lerp(desiredPosition, 0.1); // Suavizar movimiento de la cámara + camera.lookAt(cube.position); // La cámara siempre mira al cubo + } - // Actualizar posición de la luz para que siga al cubo - light.position.copy(cube.position).add(new THREE.Vector3(0, 2, 0)); + // Actualizar posición de la luz para que siga al cubo + light.position.copy(cube.position).add(new THREE.Vector3(0, 2, 0)); - // Renderizar la escena - renderer.render(scene, camera); + // Renderizar la escena + renderer.render(scene, camera); } export function unloadThreeScene() { - if (renderer) { - renderer.dispose(); - document.body.innerHTML = ""; // Limpiar la interfaz - } + if (renderer) { + renderer.dispose(); + document.body.innerHTML = ""; // Limpiar la interfaz + } }