"use strict"; const RailingCollider = (function(){ const RailingCollider = function(hollow_bond, segment){ const self = this; this.segment = segment; const th = (segment.thickness || 0.08) * 0.5; const min_x = Math.min(segment.xf, segment.xt); const max_x = Math.max(segment.xf, segment.xt); const min_z = Math.min(segment.zf, segment.zt); const max_z = Math.max(segment.zf, segment.zt); // Caja de colisión engrosada para impedir que el jugador la atraviese this.bounds = { min_x: (min_x === max_x) ? (min_x - th) : min_x, max_x: (min_x === max_x) ? (max_x + th) : max_x, min_z: (min_z === max_z) ? (min_z - th) : min_z, max_z: (min_z === max_z) ? (max_z + th) : max_z, min_y: segment.y, max_y: segment.y + (segment.height || 1.0) }; this.resolve_player = (position, controls, player_radius = 0.22) => { const eye_height = controls.current_height || 1.75; const feet_y = position.y - eye_height; // Si los pies están por encima de la barandilla (salto de jugador >= 2.0m), cruza libremente if(feet_y >= (self.bounds.max_y - 0.08) || feet_y < (self.bounds.min_y - 0.25)){ return; } const r = player_radius; const px = position.x; const pz = position.z; // Comprobación de contacto AABB expandido por el radio del jugador if( px + r > self.bounds.min_x && px - r < self.bounds.max_x && pz + r > self.bounds.min_z && pz - r < self.bounds.max_z ){ // Empujar hacia el lado firme de la habitación switch(self.segment.side){ case "north": // Foso hacia el Sur (+Z), suelo firme hacia el Norte (-Z) position.z = self.bounds.min_z - r; break; case "south": // Foso hacia el Norte (-Z), suelo firme hacia el Sur (+Z) position.z = self.bounds.max_z + r; break; case "west": // Foso hacia el Este (+X), suelo firme hacia el Oeste (-X) position.x = self.bounds.min_x - r; break; case "east": // Foso hacia el Oeste (-X), suelo firme hacia el Este (+X) position.x = self.bounds.max_x + r; break; } } }; }; return RailingCollider; })();