HollowBond/Public/ecma/Geometries/Game/HoleGeometryGame.ecma.js

118 lines
4.1 KiB
JavaScript

"use strict";
const HoleGeometryGame = (function(){
const HoleGeometryGame = function(hollow_bond){
const cache = {};
/**
* Genera las caras verticales del forjado que conectan los pisos intermedios.
*
* @param {number} width - Ancho en X (xt - xf)
* @param {number} depth - Fondo en Z (zt - zf)
* @param {number} yf - Piso inferior
* @param {number} yt - Piso superior
* @param {number} floor_h - Altura de piso (room_height)
* @param {number} pad_y - Padding vertical de habitación
*/
this.get = (width, depth, yf, yt, floor_h, pad_y) => {
const slab_thick = pad_y * 2;
const key = `${width}_${depth}_${yf}_${yt}_${slab_thick}`;
if(cache[key]){
return cache[key];
}
const geometry = new THREE.BufferGeometry();
const hx = width / 2;
const hz = depth / 2;
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;
};
// Recorremos cada unión de forjado entre pisos
for(let floor = yf; floor < yt; floor++){
// Cota inferior: techo de la habitación inferior
const y_bottom = ((floor + 1) * floor_h) - pad_y;
// Cota superior: suelo de la habitación superior
const y_top = ((floor + 1) * floor_h) + pad_y;
if(slab_thick > 0.001){
// Pared Norte (Z = -hz, mirando hacia +Z)
add_quad(
[ hx, y_bottom, -hz],
[-hx, y_bottom, -hz],
[-hx, y_top, -hz],
[ hx, y_top, -hz],
[0, 0, 1], width, slab_thick
);
// Pared Sur (Z = +hz, mirando hacia -Z)
add_quad(
[-hx, y_bottom, hz],
[ hx, y_bottom, hz],
[ hx, y_top, hz],
[-hx, y_top, hz],
[0, 0, -1], width, slab_thick
);
// Pared Oeste (X = -hx, mirando hacia +X)
add_quad(
[-hx, y_bottom, hz],
[-hx, y_bottom, -hz],
[-hx, y_top, -hz],
[-hx, y_top, hz],
[1, 0, 0], depth, slab_thick
);
// Pared Este (X = +hx, mirando hacia -X)
add_quad(
[ hx, y_bottom, -hz],
[ hx, y_bottom, hz],
[ hx, y_top, hz],
[ hx, y_top, -hz],
[-1, 0, 0], depth, slab_thick
);
}
}
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 HoleGeometryGame;
})();