fix(ignore): 栅栏判定加入高度门槛,避免把地面一起忽略导致掉出地图
上一版 skippedFence 达 4.6 万,说明地面三角也被忽略。现规则:静态形状最高点必须高于本地坦克中心 1m 才可能是栅栏;三角形再要求 |法线z|<0.6。新增 byType 统计(cat/type → 忽略次数)便于确认命中对象。
This commit is contained in:
1 parent
bfc3821dc7
commit
580a456032
3 files changed
+126
-24
No files matched your search
@@ -6587,6 +6587,7 @@
|
||||
ignoreFence: false,
|
||||
skippedTank: 0,
|
||||
skippedFence: 0,
|
||||
byType: {}, // cat/type → 被忽略次数(诊断)
|
||||
patched: false
|
||||
};
|
||||
|
||||
@@ -6672,13 +6673,41 @@
|
||||
return !IsTankShape(Shape);
|
||||
}
|
||||
|
||||
// 「栅栏类」= 静态几何里除地面/缓坡以外的部分:
|
||||
// · 三角形:法线接近水平(墙/栅栏/悬崖立面)→ 忽略;法线朝上(地面/缓坡)→ 保留
|
||||
// · 非三角形静态碰撞代理(盒/柱等):地图里这类基本都不是可站立地面 → 忽略
|
||||
var FPhysicsPosition = Fld('Physics.Position', 'bzr_1'); // 本地坦克世界位置
|
||||
|
||||
// 「栅栏类」= 静态几何中「明显高于车体中心」的那部分:
|
||||
// · 三角形:|法线 z| < 0.6(立面)且最高点高于车体中心 1m → 墙/栅栏
|
||||
// · 非三角形(盒/柱等代理):中心高于车体中心 1m → 障碍
|
||||
// · 地面/缓坡(最高点不高于车体中心)→ 一律保留,避免掉出地图
|
||||
function LocalTankZ() {
|
||||
var Phys = GetLocalPhysics();
|
||||
var P = Phys && Phys[FPhysicsPosition];
|
||||
return (P && typeof P.h20_1 === 'number') ? P.h20_1 : null;
|
||||
}
|
||||
|
||||
function ShapeMaxZ(Shape) {
|
||||
if (IsTriangle(Shape)) {
|
||||
var A = Shape[FV0], B = Shape[FV1], C = Shape[FV2];
|
||||
if (!A || !B || !C) return null;
|
||||
var Max = Math.max(A.h20_1, B.h20_1, C.h20_1);
|
||||
return isFinite(Max) ? Max : null;
|
||||
}
|
||||
var Body = Shape[FShapeBody];
|
||||
var State = Body && Body[FBodyState];
|
||||
var P = State && State[FBodyPosVec];
|
||||
return (P && typeof P.h20_1 === 'number') ? P.h20_1 : null;
|
||||
}
|
||||
|
||||
function IsFenceLike(Shape) {
|
||||
if (!IsStaticShape(Shape)) return false;
|
||||
if (!IsTriangle(Shape)) return true;
|
||||
return IsSteepTriangle(Shape);
|
||||
var TankZ = LocalTankZ();
|
||||
if (TankZ === null) return false;
|
||||
var MaxZ = ShapeMaxZ(Shape);
|
||||
if (MaxZ === null) return false;
|
||||
if (MaxZ < TankZ + 100) return false; // 不高于车体中心 1m → 地面/缓坡/低矮物
|
||||
if (!IsTriangle(Shape)) return true; // 高于车体中心的盒/柱代理 → 障碍
|
||||
var Nz = TriangleNormalZ(Shape);
|
||||
return Nz !== null && Math.abs(Nz) < 0.6; // 立面才算墙/栅栏
|
||||
}
|
||||
|
||||
// ===== 诊断:识别「正在和什么物体重叠」=====
|
||||
@@ -6799,9 +6828,13 @@
|
||||
|
||||
// ② 忽略栅栏(静态障碍;地面/缓坡保留)
|
||||
if (Stat.ignoreFence && Local) {
|
||||
if ((TankA && OwnerOf(ShapeA) === Local && IsFenceLike(ShapeB)) ||
|
||||
(TankB && OwnerOf(ShapeB) === Local && IsFenceLike(ShapeA))) {
|
||||
var FenceShape = null;
|
||||
if (TankA && OwnerOf(ShapeA) === Local) FenceShape = ShapeB;
|
||||
else if (TankB && OwnerOf(ShapeB) === Local) FenceShape = ShapeA;
|
||||
if (FenceShape && IsFenceLike(FenceShape)) {
|
||||
Stat.skippedFence++;
|
||||
var Key = FenceShape[FShapeCategory] + '/' + FenceShape[FShapeType];
|
||||
Stat.byType[Key] = (Stat.byType[Key] || 0) + 1;
|
||||
return true;
|
||||
}
|
||||
// 诊断:本车与任意非坦克形状配对但没跳过 → 记录样本(含被挡住的栅栏)
|
||||
@@ -6931,7 +6964,8 @@
|
||||
GetStat: function () {
|
||||
return {
|
||||
running: Stat.running, mode: Stat.mode, ignoreFence: Stat.ignoreFence,
|
||||
skippedTank: Stat.skippedTank, skippedFence: Stat.skippedFence, patched: Stat.patched
|
||||
skippedTank: Stat.skippedTank, skippedFence: Stat.skippedFence,
|
||||
byType: Stat.byType, patched: Stat.patched
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
+42
-8
@@ -6587,6 +6587,7 @@
|
||||
ignoreFence: false,
|
||||
skippedTank: 0,
|
||||
skippedFence: 0,
|
||||
byType: {}, // cat/type → 被忽略次数(诊断)
|
||||
patched: false
|
||||
};
|
||||
|
||||
@@ -6672,13 +6673,41 @@
|
||||
return !IsTankShape(Shape);
|
||||
}
|
||||
|
||||
// 「栅栏类」= 静态几何里除地面/缓坡以外的部分:
|
||||
// · 三角形:法线接近水平(墙/栅栏/悬崖立面)→ 忽略;法线朝上(地面/缓坡)→ 保留
|
||||
// · 非三角形静态碰撞代理(盒/柱等):地图里这类基本都不是可站立地面 → 忽略
|
||||
var FPhysicsPosition = Fld('Physics.Position', 'bzr_1'); // 本地坦克世界位置
|
||||
|
||||
// 「栅栏类」= 静态几何中「明显高于车体中心」的那部分:
|
||||
// · 三角形:|法线 z| < 0.6(立面)且最高点高于车体中心 1m → 墙/栅栏
|
||||
// · 非三角形(盒/柱等代理):中心高于车体中心 1m → 障碍
|
||||
// · 地面/缓坡(最高点不高于车体中心)→ 一律保留,避免掉出地图
|
||||
function LocalTankZ() {
|
||||
var Phys = GetLocalPhysics();
|
||||
var P = Phys && Phys[FPhysicsPosition];
|
||||
return (P && typeof P.h20_1 === 'number') ? P.h20_1 : null;
|
||||
}
|
||||
|
||||
function ShapeMaxZ(Shape) {
|
||||
if (IsTriangle(Shape)) {
|
||||
var A = Shape[FV0], B = Shape[FV1], C = Shape[FV2];
|
||||
if (!A || !B || !C) return null;
|
||||
var Max = Math.max(A.h20_1, B.h20_1, C.h20_1);
|
||||
return isFinite(Max) ? Max : null;
|
||||
}
|
||||
var Body = Shape[FShapeBody];
|
||||
var State = Body && Body[FBodyState];
|
||||
var P = State && State[FBodyPosVec];
|
||||
return (P && typeof P.h20_1 === 'number') ? P.h20_1 : null;
|
||||
}
|
||||
|
||||
function IsFenceLike(Shape) {
|
||||
if (!IsStaticShape(Shape)) return false;
|
||||
if (!IsTriangle(Shape)) return true;
|
||||
return IsSteepTriangle(Shape);
|
||||
var TankZ = LocalTankZ();
|
||||
if (TankZ === null) return false;
|
||||
var MaxZ = ShapeMaxZ(Shape);
|
||||
if (MaxZ === null) return false;
|
||||
if (MaxZ < TankZ + 100) return false; // 不高于车体中心 1m → 地面/缓坡/低矮物
|
||||
if (!IsTriangle(Shape)) return true; // 高于车体中心的盒/柱代理 → 障碍
|
||||
var Nz = TriangleNormalZ(Shape);
|
||||
return Nz !== null && Math.abs(Nz) < 0.6; // 立面才算墙/栅栏
|
||||
}
|
||||
|
||||
// ===== 诊断:识别「正在和什么物体重叠」=====
|
||||
@@ -6799,9 +6828,13 @@
|
||||
|
||||
// ② 忽略栅栏(静态障碍;地面/缓坡保留)
|
||||
if (Stat.ignoreFence && Local) {
|
||||
if ((TankA && OwnerOf(ShapeA) === Local && IsFenceLike(ShapeB)) ||
|
||||
(TankB && OwnerOf(ShapeB) === Local && IsFenceLike(ShapeA))) {
|
||||
var FenceShape = null;
|
||||
if (TankA && OwnerOf(ShapeA) === Local) FenceShape = ShapeB;
|
||||
else if (TankB && OwnerOf(ShapeB) === Local) FenceShape = ShapeA;
|
||||
if (FenceShape && IsFenceLike(FenceShape)) {
|
||||
Stat.skippedFence++;
|
||||
var Key = FenceShape[FShapeCategory] + '/' + FenceShape[FShapeType];
|
||||
Stat.byType[Key] = (Stat.byType[Key] || 0) + 1;
|
||||
return true;
|
||||
}
|
||||
// 诊断:本车与任意非坦克形状配对但没跳过 → 记录样本(含被挡住的栅栏)
|
||||
@@ -6931,7 +6964,8 @@
|
||||
GetStat: function () {
|
||||
return {
|
||||
running: Stat.running, mode: Stat.mode, ignoreFence: Stat.ignoreFence,
|
||||
skippedTank: Stat.skippedTank, skippedFence: Stat.skippedFence, patched: Stat.patched
|
||||
skippedTank: Stat.skippedTank, skippedFence: Stat.skippedFence,
|
||||
byType: Stat.byType, patched: Stat.patched
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
+42
-8
@@ -63,6 +63,7 @@
|
||||
ignoreFence: false,
|
||||
skippedTank: 0,
|
||||
skippedFence: 0,
|
||||
byType: {}, // cat/type → 被忽略次数(诊断)
|
||||
patched: false
|
||||
};
|
||||
|
||||
@@ -148,13 +149,41 @@
|
||||
return !IsTankShape(Shape);
|
||||
}
|
||||
|
||||
// 「栅栏类」= 静态几何里除地面/缓坡以外的部分:
|
||||
// · 三角形:法线接近水平(墙/栅栏/悬崖立面)→ 忽略;法线朝上(地面/缓坡)→ 保留
|
||||
// · 非三角形静态碰撞代理(盒/柱等):地图里这类基本都不是可站立地面 → 忽略
|
||||
var FPhysicsPosition = Fld('Physics.Position', 'bzr_1'); // 本地坦克世界位置
|
||||
|
||||
// 「栅栏类」= 静态几何中「明显高于车体中心」的那部分:
|
||||
// · 三角形:|法线 z| < 0.6(立面)且最高点高于车体中心 1m → 墙/栅栏
|
||||
// · 非三角形(盒/柱等代理):中心高于车体中心 1m → 障碍
|
||||
// · 地面/缓坡(最高点不高于车体中心)→ 一律保留,避免掉出地图
|
||||
function LocalTankZ() {
|
||||
var Phys = GetLocalPhysics();
|
||||
var P = Phys && Phys[FPhysicsPosition];
|
||||
return (P && typeof P.h20_1 === 'number') ? P.h20_1 : null;
|
||||
}
|
||||
|
||||
function ShapeMaxZ(Shape) {
|
||||
if (IsTriangle(Shape)) {
|
||||
var A = Shape[FV0], B = Shape[FV1], C = Shape[FV2];
|
||||
if (!A || !B || !C) return null;
|
||||
var Max = Math.max(A.h20_1, B.h20_1, C.h20_1);
|
||||
return isFinite(Max) ? Max : null;
|
||||
}
|
||||
var Body = Shape[FShapeBody];
|
||||
var State = Body && Body[FBodyState];
|
||||
var P = State && State[FBodyPosVec];
|
||||
return (P && typeof P.h20_1 === 'number') ? P.h20_1 : null;
|
||||
}
|
||||
|
||||
function IsFenceLike(Shape) {
|
||||
if (!IsStaticShape(Shape)) return false;
|
||||
if (!IsTriangle(Shape)) return true;
|
||||
return IsSteepTriangle(Shape);
|
||||
var TankZ = LocalTankZ();
|
||||
if (TankZ === null) return false;
|
||||
var MaxZ = ShapeMaxZ(Shape);
|
||||
if (MaxZ === null) return false;
|
||||
if (MaxZ < TankZ + 100) return false; // 不高于车体中心 1m → 地面/缓坡/低矮物
|
||||
if (!IsTriangle(Shape)) return true; // 高于车体中心的盒/柱代理 → 障碍
|
||||
var Nz = TriangleNormalZ(Shape);
|
||||
return Nz !== null && Math.abs(Nz) < 0.6; // 立面才算墙/栅栏
|
||||
}
|
||||
|
||||
// ===== 诊断:识别「正在和什么物体重叠」=====
|
||||
@@ -275,9 +304,13 @@
|
||||
|
||||
// ② 忽略栅栏(静态障碍;地面/缓坡保留)
|
||||
if (Stat.ignoreFence && Local) {
|
||||
if ((TankA && OwnerOf(ShapeA) === Local && IsFenceLike(ShapeB)) ||
|
||||
(TankB && OwnerOf(ShapeB) === Local && IsFenceLike(ShapeA))) {
|
||||
var FenceShape = null;
|
||||
if (TankA && OwnerOf(ShapeA) === Local) FenceShape = ShapeB;
|
||||
else if (TankB && OwnerOf(ShapeB) === Local) FenceShape = ShapeA;
|
||||
if (FenceShape && IsFenceLike(FenceShape)) {
|
||||
Stat.skippedFence++;
|
||||
var Key = FenceShape[FShapeCategory] + '/' + FenceShape[FShapeType];
|
||||
Stat.byType[Key] = (Stat.byType[Key] || 0) + 1;
|
||||
return true;
|
||||
}
|
||||
// 诊断:本车与任意非坦克形状配对但没跳过 → 记录样本(含被挡住的栅栏)
|
||||
@@ -407,7 +440,8 @@
|
||||
GetStat: function () {
|
||||
return {
|
||||
running: Stat.running, mode: Stat.mode, ignoreFence: Stat.ignoreFence,
|
||||
skippedTank: Stat.skippedTank, skippedFence: Stat.skippedFence, patched: Stat.patched
|
||||
skippedTank: Stat.skippedTank, skippedFence: Stat.skippedFence,
|
||||
byType: Stat.byType, patched: Stat.patched
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user