import * as THREE from 'three'; // Visitor navigation, not rigid-body physics. Radius is a comfortable 150 mm. export const WALK_OBSTACLES=[[-1350,750,-700,500],[-690,180,-1490,-650],[480,2680,669,1711],[870,2040,-180,730],[-2650,-380,1820,2440],[100,2050,1880,2440],[-1780,-1240,450,980]]; export function joystickVector(x,y){const length=Math.hypot(x,y);if(length<=.12)return {x:0,y:0};const magnitude=Math.min(1,(length-.12)/.88);return {x:x/length*magnitude,y:y/length*magnitude};} export function walkStep(position,delta){ const next=position.clone(); // Swept axis tests also prevent tunnelling if frame timing or movement speed changes. for(const axis of ['x','y']){ const other=axis==='x'?'y':'x',from=next[axis];let to=THREE.MathUtils.clamp(from+delta[axis],axis==='x'?-2530:-2810,axis==='x'?2530:2260); for(const [left,right,front,back] of WALK_OBSTACLES){ const min=axis==='x'?left:front,max=axis==='x'?right:back,otherMin=axis==='x'?front:left,otherMax=axis==='x'?back:right; if(next[other]<=otherMin||next[other]>=otherMax)continue; if(from<=min&&to>min)to=min;else if(from>=max&&tomin&&frommin&&to