65 lines
2.6 KiB
JavaScript
65 lines
2.6 KiB
JavaScript
"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;
|
|
})(); |