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:
1 parent
d4a260ac92
commit
b2deca31be
4 files changed
+63
-24
No files matched your search
+19
-7
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user