diff --git a/src/main.js b/src/main.js index 46fd1da..d377c1f 100644 --- a/src/main.js +++ b/src/main.js @@ -362,18 +362,16 @@ function setCameraView(direction, animate = true) { } } - // Calcular offset de la vista (diferencia entre posición y target) + // Calcular offset de la vista (diferencia entre posición y target definidos en CAMERA_VIEWS) const viewOffset = view.position.clone().sub(view.target); // Nueva posición de cámara centrada en el jugador - const newPosition = playerPosition.clone().add(viewOffset); - const newTarget = playerPosition.clone(); + const targetPosition = playerPosition.clone().add(viewOffset); + const targetLookAt = playerPosition.clone(); if (animate && SESSION.currentView !== direction) { - // Animación suave de transición - const startPos = camera.position.clone(); - const startQuat = camera.quaternion.clone(); - const startTarget = controls.target.clone(); + const startPosition = camera.position.clone(); + const startLookAt = controls.target.clone(); const duration = 600; // ms const startTime = Date.now(); @@ -382,48 +380,47 @@ function setCameraView(direction, animate = true) { const elapsed = Date.now() - startTime; const progress = Math.min(elapsed / duration, 1); - // Easing suave (ease-in-out) + // Easing suave const eased = progress < 0.5 ? 2 * progress * progress : 1 - Math.pow(-2 * progress + 2, 2) / 2; - // Interpolar posición - camera.position.lerpVectors(startPos, newPosition, eased); + // Interpolación LINEAL de posición y target + const currentPos = new THREE.Vector3().lerpVectors(startPosition, targetPosition, eased); + const currentLookAt = new THREE.Vector3().lerpVectors(startLookAt, targetLookAt, eased); - // Interpolar quaternion (rotación suave) - camera.quaternion.slerpQuaternions(startQuat, view.quaternion, eased); + camera.position.copy(currentPos); + camera.up.set(0, 1, 0); // FORZAR UP VECTOR SIEMPRE + camera.lookAt(currentLookAt); - // Interpolar target - controls.target.lerpVectors(startTarget, newTarget, eased); - - camera.up.copy(view.up); + controls.target.copy(currentLookAt); controls.update(); if (progress < 1) { requestAnimationFrame(animateTransition); } else { - // Asegurar valores finales exactos - camera.position.copy(newPosition); - camera.quaternion.copy(view.quaternion); - camera.up.copy(view.up); - controls.target.copy(newTarget); + // Asegurar estado final perfecto + camera.position.copy(targetPosition); + camera.up.set(0, 1, 0); + camera.lookAt(targetLookAt); + controls.target.copy(targetLookAt); controls.update(); } }; animateTransition(); } else { - // Sin animación (cambio instantáneo) - camera.position.copy(newPosition); - camera.quaternion.copy(view.quaternion); - camera.up.copy(view.up); - controls.target.copy(newTarget); + // Cambio inmediato + camera.position.copy(targetPosition); + camera.up.set(0, 1, 0); // FORZAR UP VECTOR + camera.lookAt(targetLookAt); + controls.target.copy(targetLookAt); controls.update(); } SESSION.currentView = direction; updateCompassUI(); - updateWallOpacities(); // Actualizar opacidades de paredes según nueva vista + updateWallOpacities(); } // Establecer vista inicial