Fix: Vistas isométricas con quaternions fijos para evitar degradación
- Precálculo de quaternions para cada vista (N, S, E, W) - Eliminado uso de lookAt() en cambios de vista - Uso de Vector3 nativos de Three.js - Sistema completamente determinista sin acumulación de errores
This commit is contained in:
58
src/main.js
58
src/main.js
@@ -157,27 +157,54 @@ document.querySelector('#app').appendChild(renderer.domElement);
|
||||
|
||||
// Cámara isométrica (zoom más cercano)
|
||||
const aspect = window.innerWidth / window.innerHeight;
|
||||
const d = 8; // Reducido de 10 a 8 para zoom aún más cercano
|
||||
const d = 8;
|
||||
const camera = new THREE.OrthographicCamera(-d * aspect, d * aspect, d, -d, 1, 1000);
|
||||
|
||||
// Vistas isométricas predefinidas
|
||||
// Vistas isométricas COMPLETAMENTE predefinidas (sin acumulación de errores)
|
||||
// Cada vista tiene posición, target Y quaternion fijo
|
||||
const CAMERA_VIEWS = {
|
||||
N: { position: { x: 20, y: 20, z: 20 }, target: { x: 0, y: 0, z: 0 } }, // Norte (default)
|
||||
S: { position: { x: -20, y: 20, z: -20 }, target: { x: 0, y: 0, z: 0 } }, // Sur
|
||||
E: { position: { x: -20, y: 20, z: 20 }, target: { x: 0, y: 0, z: 0 } }, // Este
|
||||
W: { position: { x: 20, y: 20, z: -20 }, target: { x: 0, y: 0, z: 0 } } // Oeste
|
||||
N: {
|
||||
position: new THREE.Vector3(20, 20, 20),
|
||||
target: new THREE.Vector3(0, 0, 0),
|
||||
up: new THREE.Vector3(0, 1, 0)
|
||||
},
|
||||
S: {
|
||||
position: new THREE.Vector3(-20, 20, -20),
|
||||
target: new THREE.Vector3(0, 0, 0),
|
||||
up: new THREE.Vector3(0, 1, 0)
|
||||
},
|
||||
E: {
|
||||
position: new THREE.Vector3(-20, 20, 20),
|
||||
target: new THREE.Vector3(0, 0, 0),
|
||||
up: new THREE.Vector3(0, 1, 0)
|
||||
},
|
||||
W: {
|
||||
position: new THREE.Vector3(20, 20, -20),
|
||||
target: new THREE.Vector3(0, 0, 0),
|
||||
up: new THREE.Vector3(0, 1, 0)
|
||||
}
|
||||
};
|
||||
|
||||
// Precalcular quaternions para cada vista (FIJOS, nunca cambian)
|
||||
Object.keys(CAMERA_VIEWS).forEach(key => {
|
||||
const view = CAMERA_VIEWS[key];
|
||||
const tempCamera = new THREE.PerspectiveCamera();
|
||||
tempCamera.position.copy(view.position);
|
||||
tempCamera.up.copy(view.up);
|
||||
tempCamera.lookAt(view.target);
|
||||
view.quaternion = tempCamera.quaternion.clone();
|
||||
});
|
||||
|
||||
// OrbitControls solo para zoom y paneo (sin rotación)
|
||||
const controls = new OrbitControls(camera, renderer.domElement);
|
||||
controls.enableRotate = false; // Deshabilitar rotación
|
||||
controls.enableRotate = false;
|
||||
controls.enableDamping = true;
|
||||
controls.dampingFactor = 0.05;
|
||||
controls.screenSpacePanning = true;
|
||||
controls.mouseButtons = {
|
||||
LEFT: null, // Click izquierdo libre para selección
|
||||
MIDDLE: THREE.MOUSE.PAN, // Paneo con botón central
|
||||
RIGHT: THREE.MOUSE.PAN // Paneo también con botón derecho
|
||||
LEFT: null,
|
||||
MIDDLE: THREE.MOUSE.PAN,
|
||||
RIGHT: THREE.MOUSE.PAN
|
||||
};
|
||||
controls.zoomToCursor = true;
|
||||
controls.minZoom = 0.5;
|
||||
@@ -185,10 +212,15 @@ controls.maxZoom = 3;
|
||||
|
||||
function setCameraView(direction) {
|
||||
const view = CAMERA_VIEWS[direction];
|
||||
camera.position.set(view.position.x, view.position.y, view.position.z);
|
||||
camera.lookAt(view.target.x, view.target.y, view.target.z);
|
||||
controls.target.set(view.target.x, view.target.y, view.target.z);
|
||||
|
||||
// Aplicar posición, quaternion y up FIJOS (sin lookAt que acumula errores)
|
||||
camera.position.copy(view.position);
|
||||
camera.quaternion.copy(view.quaternion);
|
||||
camera.up.copy(view.up);
|
||||
|
||||
controls.target.copy(view.target);
|
||||
controls.update();
|
||||
|
||||
SESSION.currentView = direction;
|
||||
updateCompassUI();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user