Refactor: Unify door positioning logic
- Created getDoorWorldPosition() function that calculates both mesh position and wall offset - Eliminated duplicate positioning logic between wall gaps and door meshes - Removed inconsistent sign inversions that caused misalignment - Both wall gaps and door meshes now use the same coordinate system - Fixes issue where doors and gaps were positioned differently on S and W walls
This commit is contained in:
110
src/main.js
110
src/main.js
@@ -885,6 +885,60 @@ function getDoorGridPosition(room, door) {
|
||||
}
|
||||
}
|
||||
|
||||
// Calcula la posición completa de la puerta en el mundo 3D
|
||||
// Devuelve: { worldPos: {x, z}, meshPos: {x, y, z}, rotation: number, wallOffset: number }
|
||||
function getDoorWorldPosition(room, door, centerX, centerZ, halfSizeX, halfSizeZ) {
|
||||
const doorGridPos = getDoorGridPosition(room, door);
|
||||
const doorWorldPos = gridToWorld(doorGridPos.x, doorGridPos.y);
|
||||
|
||||
const doorHeight = 2.0;
|
||||
let meshPos = { x: 0, y: doorHeight / 2, z: 0 };
|
||||
let rotation = 0;
|
||||
let wallOffset = 0;
|
||||
|
||||
switch (door.side) {
|
||||
case 'N':
|
||||
// Pared Norte: puerta alineada en X, Z en el borde norte
|
||||
meshPos.x = doorWorldPos.x;
|
||||
meshPos.z = centerZ - halfSizeZ;
|
||||
rotation = 0;
|
||||
// Offset relativo al centro de la pared (para el hueco)
|
||||
wallOffset = doorWorldPos.x - centerX;
|
||||
break;
|
||||
case 'S':
|
||||
// Pared Sur: puerta alineada en X, Z en el borde sur
|
||||
meshPos.x = doorWorldPos.x;
|
||||
meshPos.z = centerZ + halfSizeZ;
|
||||
rotation = 0;
|
||||
// Para pared Sur, el offset es directo (sin inversión)
|
||||
wallOffset = doorWorldPos.x - centerX;
|
||||
break;
|
||||
case 'E':
|
||||
// Pared Este: puerta alineada en Z, X en el borde este
|
||||
meshPos.x = centerX + halfSizeX;
|
||||
meshPos.z = doorWorldPos.z;
|
||||
rotation = Math.PI / 2;
|
||||
// Offset relativo al centro de la pared
|
||||
wallOffset = doorWorldPos.z - centerZ;
|
||||
break;
|
||||
case 'W':
|
||||
// Pared Oeste: puerta alineada en Z, X en el borde oeste
|
||||
meshPos.x = centerX - halfSizeX;
|
||||
meshPos.z = doorWorldPos.z;
|
||||
rotation = Math.PI / 2;
|
||||
// Para pared Oeste, el offset es directo (sin inversión)
|
||||
wallOffset = doorWorldPos.z - centerZ;
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
worldPos: doorWorldPos,
|
||||
meshPos: meshPos,
|
||||
rotation: rotation,
|
||||
wallOffset: wallOffset
|
||||
};
|
||||
}
|
||||
|
||||
// --- CARGA Y RENDERIZADO ---
|
||||
const textureLoader = new THREE.TextureLoader();
|
||||
|
||||
@@ -1047,27 +1101,9 @@ async function renderRoom(room) {
|
||||
const doorWidth = 1.5;
|
||||
const doorHeight = 2.0;
|
||||
|
||||
// Calcular posición relativa de la puerta en la pared
|
||||
// config.width es el ancho total. El rango local es [-W/2, W/2]
|
||||
|
||||
// Obtener coordenadas de la puerta
|
||||
const doorGridPos = getDoorGridPosition(room, door);
|
||||
const doorWorldPos = gridToWorld(doorGridPos.x, doorGridPos.y);
|
||||
|
||||
// Necesitamos proyectar la posición de la puerta sobre el eje de la pared para saber su offset
|
||||
// Pared N/S: Offset es diferencia en X.
|
||||
// Pared E/W: Offset es diferencia en Z (pero ojo con la dirección del plano).
|
||||
|
||||
let doorOffset = 0; // Offset del centro de la puerta respecto al centro de la pared
|
||||
if (config.side === 'N') {
|
||||
doorOffset = doorWorldPos.x - centerX;
|
||||
} else if (config.side === 'S') {
|
||||
doorOffset = -(doorWorldPos.x - centerX); // S wall is rotated 180, local X is opposite world X
|
||||
} else if (config.side === 'E') {
|
||||
doorOffset = doorWorldPos.z - centerZ;
|
||||
} else if (config.side === 'W') {
|
||||
doorOffset = -(doorWorldPos.z - centerZ); // W wall is rotated 90, local X is opposite world Z
|
||||
}
|
||||
// Usar función unificada para obtener la posición de la puerta
|
||||
const doorInfo = getDoorWorldPosition(room, door, centerX, centerZ, halfSizeX, halfSizeZ);
|
||||
const doorOffset = doorInfo.wallOffset;
|
||||
|
||||
const w = config.width;
|
||||
|
||||
@@ -1088,10 +1124,6 @@ async function renderRoom(room) {
|
||||
createWallSegment(rightWidth, wallHeight, rightCenter, wallHeight / 2, opacity, "RightSeg");
|
||||
|
||||
// Dintel (Arriba de la puerta)
|
||||
// Ancho: doorWidth
|
||||
// Altura: wallHeight - doorHeight (2.5 - 2.0 = 0.5)
|
||||
// Centro X: doorOffset
|
||||
// Centro Y: doorHeight + (dintelHeight / 2) -> 2.0 + 0.25 = 2.25
|
||||
const lintelHeight = wallHeight - doorHeight;
|
||||
if (lintelHeight > 0) {
|
||||
createWallSegment(doorWidth, lintelHeight, doorOffset, doorHeight + (lintelHeight / 2), opacity, "Lintel");
|
||||
@@ -1123,31 +1155,11 @@ async function renderRoom(room) {
|
||||
const doorMesh = new THREE.Mesh(doorGeometry, doorMaterial);
|
||||
doorMesh.userData.id = door.id;
|
||||
doorMesh.visible = !door.isOpen; // Ocultar si ya está abierta
|
||||
const doorGridPos = getDoorGridPosition(room, door);
|
||||
const doorWorldPos = gridToWorld(doorGridPos.x, doorGridPos.y);
|
||||
|
||||
switch (door.side) {
|
||||
case 'N':
|
||||
// Pared Norte: Alinear X con worldPos, Z con borde norte
|
||||
doorMesh.position.set(doorWorldPos.x, doorHeight / 2, centerZ - halfSizeZ);
|
||||
doorMesh.rotation.y = 0;
|
||||
break;
|
||||
case 'S':
|
||||
// Pared Sur
|
||||
doorMesh.position.set(doorWorldPos.x, doorHeight / 2, centerZ + halfSizeZ);
|
||||
doorMesh.rotation.y = 0; // O Math.PI, visualmente igual para puerta plana 1.5x2
|
||||
break;
|
||||
case 'E':
|
||||
// Pared Este: Alinear Z con worldPos, X con borde este
|
||||
doorMesh.position.set(centerX + halfSizeX, doorHeight / 2, doorWorldPos.z);
|
||||
doorMesh.rotation.y = Math.PI / 2;
|
||||
break;
|
||||
case 'W':
|
||||
// Pared Oeste
|
||||
doorMesh.position.set(centerX - halfSizeX, doorHeight / 2, doorWorldPos.z);
|
||||
doorMesh.rotation.y = Math.PI / 2;
|
||||
break;
|
||||
}
|
||||
// Usar función unificada para posicionar la puerta
|
||||
const doorInfo = getDoorWorldPosition(room, door, centerX, centerZ, halfSizeX, halfSizeZ);
|
||||
doorMesh.position.set(doorInfo.meshPos.x, doorInfo.meshPos.y, doorInfo.meshPos.z);
|
||||
doorMesh.rotation.y = doorInfo.rotation;
|
||||
|
||||
scene.add(doorMesh);
|
||||
roomMeshes.doors.push(doorMesh);
|
||||
|
||||
Reference in New Issue
Block a user