"use strict"; const FrameCollider = (function(){ const FrameCollider = function(hollow_bond, model){ const self = this; this.model = model; const is_horiz = model.axis === "horizontal"; const floor_h = hollow_bond.room_height || 3; const pad_y = hollow_bond.room_padding || 0; const base_y = (model.y * floor_h) + pad_y; const pass_w = model.width; const wall_depth = pad_y * 2; const min_x = is_horiz ? model.x : model.x - wall_depth / 2; const max_x = is_horiz ? model.x + pass_w : model.x + wall_depth / 2; const min_z = is_horiz ? model.z - wall_depth / 2 : model.z; const max_z = is_horiz ? model.z + wall_depth / 2 : model.z + pass_w; this.bounds = { min_x: min_x, max_x: max_x, min_z: min_z, max_z: max_z, min_y: base_y, max_y: base_y + model.height }; this.contains = (x, z) => { return ( x >= self.bounds.min_x && x <= self.bounds.max_x && z >= self.bounds.min_z && z <= self.bounds.max_z ); }; this.resolve_player = (position, controls, player_radius = 0.22) => { if(!self.contains(position.x, position.z)) return; const eye_height = controls.current_height || 1.75; // 1. Apoyo sólido en el umbral mientras cruza el túnel const target_eye_y = self.bounds.min_y + eye_height; if(position.y <= target_eye_y){ position.y = target_eye_y; controls.velocity_y = 0; controls.is_grounded = true; } // 2. Dintel if(position.y >= self.bounds.max_y){ position.y = self.bounds.max_y; if(controls.velocity_y > 0) controls.velocity_y = 0; } // 3. Jambas laterales del marco if(is_horiz){ const min_x = self.bounds.min_x + player_radius; const max_x = self.bounds.max_x - player_radius; if(position.x < min_x) position.x = min_x; else if(position.x > max_x) position.x = max_x; } else { const min_z = self.bounds.min_z + player_radius; const max_z = self.bounds.max_z - player_radius; if(position.z < min_z) position.z = min_z; else if(position.z > max_z) position.z = max_z; } }; }; return FrameCollider; })();