fix(ignore): 解包 type 4 克隆形状后再做三角形判定

type 4 是克隆包装(hu.c9w_1 = 原形状.d21()),地图三角形都以它出现,之前按三角形判定永远不命中。现在 IsTriangle/TriangleNormalZ/ShapeMaxZ/ShapePoint 统一先解包 c9w_1,再套「高于车体 1m + |法线z|<0.6」规则;schema 补 Shape.Clone。
This commit is contained in:
TermiNexus committed 2026-10-21 00:49:13 +08:00
1 parent d4a260ac92
commit b2deca31be
4 files changed
+63 -24

No files matched your search

+19 -7
View File
@@ -43,6 +43,7 @@
var FShapeName = Fld('Shape.Name', 'x9j_1'); // 形状名('hull-main')
var FShapeCategory = Fld('Shape.Category', 'y9j_1'); // category 位组
var FShapeType = Fld('Shape.Type', 'v9j_1'); // 形状类型位组(8 = 三角形)
var FShapeClone = Fld('Shape.Clone', 'c9w_1'); // 类型 4 包装里的真实形状
var FShapeBody = Fld('Shape.Body', 'b9k_1'); // 形状 → 刚体
var FBodyOwner = Fld('Body.Owner', 'x9i_1'); // 刚体 → 拥有者
var FV0 = Fld('Shape.Vertex0', 'u9x_1'); // 三角形顶点 0
@@ -121,14 +122,23 @@
}
// 三角形是否「陡」:法线 z 分量接近 0(墙/栅栏/悬崖立面)
// type 4 是「克隆包装」(hu: this.c9w_1 = 原形状.d21()),真实几何在 c9w_1 里,必须先解包
function UnwrapShape(Shape) {
var S = Shape, Guard = 0;
while (S && S[FShapeType] === 4 && S[FShapeClone] && Guard++ < 4) S = S[FShapeClone];
return S;
}
function IsTriangle(Shape) {
return !!(Shape && Shape[FShapeType] === TRIANGLE_TYPE);
var S = UnwrapShape(Shape);
return !!(S && S[FShapeType] === TRIANGLE_TYPE);
}
// 返回法线 z 分量(-1..1);读不到返回 null
function TriangleNormalZ(Shape) {
if (!IsTriangle(Shape)) return null;
var A = Shape[FV0], B = Shape[FV1], C = Shape[FV2];
var S = UnwrapShape(Shape);
if (!S || S[FShapeType] !== TRIANGLE_TYPE) return null;
var A = S[FV0], B = S[FV1], C = S[FV2];
if (!A || !B || !C) return null;
if (typeof A.f20_1 !== 'number' || typeof B.f20_1 !== 'number' || typeof C.f20_1 !== 'number') return null;
var ABx = B.f20_1 - A.f20_1, ABy = B.g20_1 - A.g20_1, ABz = B.h20_1 - A.h20_1;
@@ -162,8 +172,9 @@
}
function ShapeMaxZ(Shape) {
if (IsTriangle(Shape)) {
var A = Shape[FV0], B = Shape[FV1], C = Shape[FV2];
var S = UnwrapShape(Shape);
if (S && S[FShapeType] === TRIANGLE_TYPE) {
var A = S[FV0], B = S[FV1], C = S[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;
@@ -216,8 +227,9 @@
function ShapePoint(Shape) {
if (!Shape) return null;
if (IsTriangle(Shape)) {
var A = Shape[FV0], B = Shape[FV1], C = Shape[FV2];
var S = UnwrapShape(Shape);
if (S && S[FShapeType] === TRIANGLE_TYPE) {
var A = S[FV0], B = S[FV1], C = S[FV2];
if (A && B && C) {
return {
x: (A.f20_1 + B.f20_1 + C.f20_1) / 3,
+2 -1
View File
@@ -75,7 +75,8 @@
'Shape.Mask': 'z9j_1', // 愿意碰撞的分类位
'Shape.Ghost': 'g9k_1', // true = 只探测不产生碰撞响应
'Shape.Body': 'b9k_1', // 形状 → 所属刚体(Fn)
'Shape.Type': 'v9j_1', // 形状类型位组(1/2/4/8/16/32;8 = 三角形)
'Shape.Type': 'v9j_1', // 形状类型位组(1/2/4/8/16/32;8 = 三角形,4 = 克隆包装)
'Shape.Clone': 'c9w_1', // 类型 4 的克隆包装:真实几何在 c9w_1 里
'Shape.Vertex0': 'u9x_1', // 三角形顶点 0
'Shape.Vertex1': 'v9x_1', // 三角形顶点 1
'Shape.Vertex2': 'w9x_1', // 三角形顶点 2