fix: IK 全面审查三处修复——NaN 防线、实时拖拽被入场动画覆写、滚转角miss突跳

- 求解器 inLimit/evalAt 容差比较改否定式:原写法在 NaN 下比较恒假,
  NaN 目标/姿态曾产出 ok=true 且 q 含 NaN(UI 有 number 输入净化+isFinite
  双保险触不到,但公开 API 与将来的 MCU 端口会中招)
- glue setJoints(q,false) 补 anim=null:直接写入不再被在飞的 620ms 入场动画
  覆写、结尾不再跳回旧目标(实时追踪拖拽撞上入场动画的窗口期)
- glue rollAngleAt 射线错过平面改返回 null:原来返回 0 会让滚转角按 -a0 突跳,
  现在该帧直接跳过
- 回归:node 六项全绿;NaN/Inf 目标三种注入均 ok=false 且 q=null;
  40 组随机位形与 fast 副本仍逐位一致;浏览器冒烟已到达/零报错
This commit is contained in:
cbb
2026-09-29 00:24:58 +08:00
parent 4fdc37da9f
commit 208b37048b
5 changed files with 24 additions and 16 deletions
+3 -3
View File
@@ -226,10 +226,10 @@ function make(cfg) {
return out;
}
const inLimit = q => {
const inLimit = q => { // 取否定式:NaN 候选必须落选(原写法 NaN 比较全 false 会放行)
for (let i = 0; i < 5; i++) {
const t = LIM[ORDER[i]];
if (q[i] < t.lo - 1e-9 || q[i] > t.hi + 1e-9) return false;
if (!(q[i] >= t.lo - 1e-9 && q[i] <= t.hi + 1e-9)) return false;
}
return true;
};
@@ -309,7 +309,7 @@ function make(cfg) {
const p = fk(q, tool);
const dx = p[0] - target[0], dy = p[1] - target[1], dz = p[2] - target[2];
const e2 = dx * dx + dy * dy + dz * dz;
if (e2 > tol2) continue;
if (!(e2 <= tol2)) continue; // 否定式:e2 为 NaN(目标含 NaN/Inf)时继续走拒绝分支
const c = scoreBranch(q, Math.sqrt(e2));
if (c && (!best || c.rcost < best.rcost - 1e-12)) best = c;
}