178 lines
9.8 KiB
JavaScript
178 lines
9.8 KiB
JavaScript
"use strict";
|
|
|
|
const FrameGeometryGame = (function(){
|
|
|
|
const FrameGeometryGame = function(hollow_bond){
|
|
|
|
const cache = {};
|
|
|
|
/**
|
|
* Construye el túnel del marco con moldura 3D sin solapamiento de suelo con la sala.
|
|
*
|
|
* @param {number} pass_w - Ancho libre del vano
|
|
* @param {number} height - Altura libre del vano
|
|
* @param {number} wall_depth - Grosor del tabique entre salas (room_padding * 2)
|
|
* @param {boolean} is_horiz - true si corre en X, false si corre en Z
|
|
*/
|
|
this.get = (pass_w, height, wall_depth, is_horiz) => {
|
|
|
|
const key = `${pass_w}_${height}_${wall_depth}_${is_horiz}`;
|
|
if(cache[key]){
|
|
return cache[key];
|
|
}
|
|
|
|
const geometry = new THREE.BufferGeometry();
|
|
|
|
// Medias dimensiones del vano libre
|
|
const hx = is_horiz ? pass_w / 2 : wall_depth / 2;
|
|
const hz = is_horiz ? wall_depth / 2 : pass_w / 2;
|
|
const hy = height / 2;
|
|
|
|
// Dimensiones de la moldura/tapajuntas
|
|
const casing_w = 0.06; // 6 cm de solape sobre la pared
|
|
const casing_t = 0.02; // 2 cm de relieve hacia el interior de la sala
|
|
|
|
const positions = [];
|
|
const normals = [];
|
|
const uvs = [];
|
|
const indices = [];
|
|
|
|
let index_offset = 0;
|
|
|
|
const add_quad = (p1, p2, p3, p4, normal, uv_w, uv_h) => {
|
|
positions.push(...p1, ...p2, ...p3, ...p4);
|
|
normals.push(...normal, ...normal, ...normal, ...normal);
|
|
uvs.push(0, 0, uv_w, 0, uv_w, uv_h, 0, uv_h);
|
|
indices.push(
|
|
index_offset, index_offset + 2, index_offset + 1,
|
|
index_offset, index_offset + 3, index_offset + 2
|
|
);
|
|
index_offset += 4;
|
|
};
|
|
|
|
if(is_horiz){
|
|
const total_z = hz + casing_t;
|
|
|
|
// 1. UMBRAL / SUELO TRANSITABLE (+Y)
|
|
// Se acota estrictamente a [-hz, hz] para que coincida justo con el final de la moqueta
|
|
add_quad(
|
|
[-hx, -hy, -hz], [ hx, -hy, -hz], [ hx, -hy, hz], [-hx, -hy, hz],
|
|
[0, 1, 0], pass_w, wall_depth
|
|
);
|
|
|
|
// 2. TECHO INTERIOR DEL VANO (-Y)
|
|
// Aquí sí cubre hasta total_z para sellar la parte baja de la moldura superior
|
|
add_quad(
|
|
[-hx, hy, total_z], [ hx, hy, total_z], [ hx, hy, -total_z], [-hx, hy, -total_z],
|
|
[0, -1, 0], pass_w, total_z * 2
|
|
);
|
|
|
|
// 3. JAMBAS INTERIORES LATERALES
|
|
// Izquierda (+X)
|
|
add_quad(
|
|
[-hx, -hy, -total_z], [-hx, -hy, total_z], [-hx, hy, total_z], [-hx, hy, -total_z],
|
|
[1, 0, 0], total_z * 2, height
|
|
);
|
|
// Derecha (-X)
|
|
add_quad(
|
|
[ hx, -hy, total_z], [ hx, -hy, -total_z], [ hx, hy, -total_z], [ hx, hy, total_z],
|
|
[-1, 0, 0], total_z * 2, height
|
|
);
|
|
|
|
// 4. MOLDURAS EXTERIORES
|
|
// Cara Sur (+Z)
|
|
const z_s = total_z;
|
|
add_quad([-hx - casing_w, -hy, z_s], [-hx, -hy, z_s], [-hx, hy + casing_w, z_s], [-hx - casing_w, hy + casing_w, z_s], [0, 0, 1], casing_w, height + casing_w);
|
|
add_quad([ hx, -hy, z_s], [ hx + casing_w, -hy, z_s], [ hx + casing_w, hy + casing_w, z_s], [ hx, hy + casing_w, z_s], [0, 0, 1], casing_w, height + casing_w);
|
|
add_quad([-hx, hy, z_s], [ hx, hy, z_s], [ hx, hy + casing_w, z_s], [-hx, hy + casing_w, z_s], [0, 0, 1], pass_w, casing_w);
|
|
|
|
// Cantos de cierre contra la pared (Sur)
|
|
add_quad([-hx - casing_w, -hy, hz], [-hx - casing_w, -hy, z_s], [-hx - casing_w, hy + casing_w, z_s], [-hx - casing_w, hy + casing_w, hz], [-1, 0, 0], casing_t, height + casing_w);
|
|
add_quad([ hx + casing_w, -hy, z_s], [ hx + casing_w, -hy, hz], [ hx + casing_w, hy + casing_w, hz], [ hx + casing_w, hy + casing_w, z_s], [1, 0, 0], casing_t, height + casing_w);
|
|
add_quad([-hx - casing_w, hy + casing_w, hz], [ hx + casing_w, hy + casing_w, hz], [ hx + casing_w, hy + casing_w, z_s], [-hx - casing_w, hy + casing_w, z_s], [0, 1, 0], pass_w + casing_w * 2, casing_t);
|
|
|
|
// Cara Norte (-Z)
|
|
const z_n = -total_z;
|
|
add_quad([-hx, -hy, z_n], [-hx - casing_w, -hy, z_n], [-hx - casing_w, hy + casing_w, z_n], [-hx, hy + casing_w, z_n], [0, 0, -1], casing_w, height + casing_w);
|
|
add_quad([ hx + casing_w, -hy, z_n], [ hx, -hy, z_n], [ hx, hy + casing_w, z_n], [ hx + casing_w, hy + casing_w, z_n], [0, 0, -1], casing_w, height + casing_w);
|
|
add_quad([ hx, hy, z_n], [-hx, hy, z_n], [-hx, hy + casing_w, z_n], [ hx, hy + casing_w, z_n], [0, 0, -1], pass_w, casing_w);
|
|
|
|
// Cantos de cierre contra la pared (Norte)
|
|
add_quad([-hx - casing_w, -hy, z_n], [-hx - casing_w, -hy, -hz], [-hx - casing_w, hy + casing_w, -hz], [-hx - casing_w, hy + casing_w, z_n], [-1, 0, 0], casing_t, height + casing_w);
|
|
add_quad([ hx + casing_w, -hy, -hz], [ hx + casing_w, -hy, z_n], [ hx + casing_w, hy + casing_w, z_n], [ hx + casing_w, hy + casing_w, -hz], [1, 0, 0], casing_t, height + casing_w);
|
|
add_quad([-hx - casing_w, hy + casing_w, z_n], [ hx + casing_w, hy + casing_w, z_n], [ hx + casing_w, hy + casing_w, -hz], [-hx - casing_w, hy + casing_w, -hz], [0, 1, 0], pass_w + casing_w * 2, casing_t);
|
|
|
|
} else {
|
|
const total_x = hx + casing_t;
|
|
|
|
// 1. UMBRAL / SUELO TRANSITABLE (+Y)
|
|
// Se acota a [-hx, hx] para alinearse de forma exacta a la moqueta
|
|
add_quad(
|
|
[-hx, -hy, -hz], [ hx, -hy, -hz], [ hx, -hy, hz], [-hx, -hy, hz],
|
|
[0, 1, 0], wall_depth, pass_w
|
|
);
|
|
|
|
// 2. TECHO INTERIOR (-Y)
|
|
add_quad(
|
|
[-total_x, hy, hz], [ total_x, hy, hz], [ total_x, hy, -hz], [-total_x, hy, -hz],
|
|
[0, -1, 0], total_x * 2, pass_w
|
|
);
|
|
|
|
// 3. JAMBAS INTERIORES LATERALES
|
|
// Izquierda (+Z)
|
|
add_quad(
|
|
[-total_x, -hy, -hz], [ total_x, -hy, -hz], [ total_x, hy, -hz], [-total_x, hy, -hz],
|
|
[0, 0, 1], total_x * 2, height
|
|
);
|
|
// Derecha (-Z)
|
|
add_quad(
|
|
[ total_x, -hy, hz], [-total_x, -hy, hz], [-total_x, hy, hz], [ total_x, hy, hz],
|
|
[0, 0, -1], total_x * 2, height
|
|
);
|
|
|
|
// 4. MOLDURAS EXTERIORES
|
|
// Cara Este (+X)
|
|
const x_e = total_x;
|
|
add_quad([x_e, -hy, hz], [x_e, -hy, hz + casing_w], [x_e, hy + casing_w, hz + casing_w], [x_e, hy + casing_w, hz], [1, 0, 0], casing_w, height + casing_w);
|
|
add_quad([x_e, -hy, -hz - casing_w], [x_e, -hy, -hz], [x_e, hy + casing_w, -hz], [x_e, hy + casing_w, -hz - casing_w], [1, 0, 0], casing_w, height + casing_w);
|
|
add_quad([x_e, hy, -hz], [x_e, hy, hz], [x_e, hy + casing_w, hz], [x_e, hy + casing_w, -hz], [1, 0, 0], pass_w, casing_w);
|
|
|
|
// Cantos Este
|
|
add_quad([hx, -hy, -hz - casing_w], [x_e, -hy, -hz - casing_w], [x_e, hy + casing_w, -hz - casing_w], [hx, hy + casing_w, -hz - casing_w], [0, 0, -1], casing_t, height + casing_w);
|
|
add_quad([x_e, -hy, hz + casing_w], [hx, -hy, hz + casing_w], [hx, hy + casing_w, hz + casing_w], [x_e, hy + casing_w, hz + casing_w], [0, 0, 1], casing_t, height + casing_w);
|
|
add_quad([hx, hy + casing_w, -hz - casing_w], [x_e, hy + casing_w, -hz - casing_w], [x_e, hy + casing_w, hz + casing_w], [hx, hy + casing_w, hz + casing_w], [0, 1, 0], casing_t, pass_w + casing_w * 2);
|
|
|
|
// Cara Oeste (-X)
|
|
const x_w = -total_x;
|
|
add_quad([x_w, -hy, hz + casing_w], [x_w, -hy, hz], [x_w, hy + casing_w, hz], [x_w, hy + casing_w, hz + casing_w], [-1, 0, 0], casing_w, height + casing_w);
|
|
add_quad([x_w, -hy, -hz], [x_w, -hy, -hz - casing_w], [x_w, hy + casing_w, -hz - casing_w], [x_w, hy + casing_w, -hz], [-1, 0, 0], casing_w, height + casing_w);
|
|
add_quad([x_w, hy, hz], [x_w, hy, -hz], [x_w, hy + casing_w, -hz], [x_w, hy + casing_w, hz], [-1, 0, 0], pass_w, casing_w);
|
|
|
|
// Cantos Oeste
|
|
add_quad([x_w, -hy, -hz - casing_w], [-hx, -hy, -hz - casing_w], [-hx, hy + casing_w, -hz - casing_w], [x_w, hy + casing_w, -hz - casing_w], [0, 0, -1], casing_t, height + casing_w);
|
|
add_quad([-hx, -hy, hz + casing_w], [x_w, -hy, hz + casing_w], [x_w, hy + casing_w, hz + casing_w], [-hx, hy + casing_w, hz + casing_w], [0, 0, 1], casing_t, height + casing_w);
|
|
add_quad([x_w, hy + casing_w, -hz - casing_w], [-hx, hy + casing_w, -hz - casing_w], [-hx, hy + casing_w, hz + casing_w], [x_w, hy + casing_w, hz + casing_w], [0, 1, 0], casing_t, pass_w + casing_w * 2);
|
|
}
|
|
|
|
geometry.setAttribute("position", new THREE.Float32BufferAttribute(positions, 3));
|
|
geometry.setAttribute("normal", new THREE.Float32BufferAttribute(normals, 3));
|
|
geometry.setAttribute("uv", new THREE.Float32BufferAttribute(uvs, 2));
|
|
geometry.setIndex(indices);
|
|
|
|
cache[key] = geometry;
|
|
return geometry;
|
|
};
|
|
|
|
this.reset = () => {
|
|
for(const key in cache){
|
|
if(cache[key]){
|
|
cache[key].dispose();
|
|
delete cache[key];
|
|
}
|
|
}
|
|
};
|
|
|
|
};
|
|
|
|
return FrameGeometryGame;
|
|
})(); |