CCollisionModel 构造、装载门与失败状态

本批结果

新增 NativeCollisionModelLifecycle,连接 F2 碰撞模型后端,区分“模型对象存在”“几何列表已分配”“几何内容装载完成”。

  • 432 条原生状态观察一致,覆盖构造、再次 Load 和销毁。
  • 构造字段、文件/底层资源门、名称比较、几何发布顺序和析构回调观察匹配。
  • 已从 MSVC EH 元数据确认原捕获类型为 Ogre::Exception。
  • 累计 1,451 条核心断言、276 项相关 Python 回归通过。
  • Godot C# 构建零警告、零错误,coresimlint 通过;既有 26 项 GPU/资源回归继续通过。

本批不是整个 Ogre mesh lease/临时缓冲区生命周期的完成声明。原模型控制与这些后端动作的边界已明确列出。

构造:575BF0

CCollisionModel 是 96 字节对象,继承基础资源对象。

字节偏移字段构造值
+8解析后的 wstring 名称
+36独立 std::string 字段
+64Vector3(0,0,0)
+76Vector3(0,0,0)
+88CCollisionList 指针
+92调用方传入的 owner原样保存

输入请求非空时才调用 5757F0。空请求仍可得到一个合法模型对象,但没有几何列表;不能把“模型构造成功”当成“可碰撞”。

+64/+76 的两个向量不等于 CCollisionList 的 min/max。已经实现的碰撞计算仍从正确的几何列表读 bounds,没有用模型自己的零向量替代。

核心 Owner 是不持久化的 opaque 上下文引用。销毁后解除 managed owner 引用是宿主清理措施,不声称原释放后内存中的 owner DWORD 被原函数清零。

装载门:5757F0

顺序为:

  1. 查找请求对应的文件记录。
  2. 文件记录不存在则返回。
  3. 文件记录 +116 没有底层资源则返回。
  4. 第一次调用 41CCA0 获取解析名,与模型当前名称作精确 wstring 比较;相同则返回。
  5. 模型已有几何列表则返回。
  6. 分配并构造一个新的空 CCollisionList,将指针写到模型 +88。
  7. 清空旧名称。
  8. 第二次调用 41CCA0,保存这次返回的解析名。
  9. 进入资源准备、网格装载、提取、填充及临时资源释放阶段。

已有几何的情况下仍会先查文件、检查底层资源并进行第一次名称比较;不能把“已有模型”移到函数最前面。

这不是通用重载器:再次请求不同名称也不会替换已存在的几何列表。模型替换应由上一批已经实现的实例/共享缓存流程创建新模型身份。

空指针与空列表

NativeCollisionGeometryStorage 在填充之前就存在,初始值为:

  • 零 bounds。
  • 空顶点/面输入视图。
  • 原默认 skip surface 100000。

它与 Geometry=null 不同。填充阶段出现错误后保留下来的空列表不能自动改成 null,否则后续 Load 的行为会变化。

Ogre 异常捕获

原函数的 MSVC FuncInfo:

  • 2517120 指向 try map。
  • 251710C 的 try state 范围为 5–9。
  • handler 25170FC 指向类型描述符 287D9B0。
  • 类型名称为 .?AVException@Ogre@@。
  • 捕获处理入口为 575B4A。

捕获路径先记录错误,再把模型的 wstring 和独立 string 名称清空,不销毁已经分配的几何列表

结果可能是:

text
model exists
resolved name = empty
geometry storage exists
geometry may be empty or partially filled

后续再 Load,即使文件和名称不同,也会因已有几何列表而跳过填充。不能自动归零指针并重试。

核心只把 NativeOgreCollisionLoadException 视为这一已证实的捕获域。普通输入错误、分配错误等不笼统吞掉。错误日志回调在名称清空前执行。

managed 测试确认未表示为 Ogre 异常的错误会继续传播,并保留当时的中间状态。此测试不证明所有原 C++ SEH/OOM 展开均已复原。

销毁:575620

原顺序:

  1. 清空解析名称。
  2. 若几何列表存在,调用其析构/释放。
  3. 将几何指针清零。
  4. 析构独立 string 和 wstring。
  5. 处理基础资源对象析构。

几何销毁回调看到的是“名称已空、几何指针仍存在”的状态,而非已经全部清空的成品状态。

核心随后将 storage 标记退休并移除其几何引用。已退休 storage 不允许继续 Populate/读取 Mesh。C# Destroy 为幂等保护,不将原重复析构视为合法行为。

接入 F2 共享后端

F2CollisionModelCacheHost 现在为每个新 handle 建立对应生命周期对象:

  • 严格 F2 资产预检仍在模型创建前完成。
  • 已准备资产提供明确的文件记录、底层资源存在状态和解析名称。
  • Populate 使用既有原几何解析/面序/surface/法线生成。
  • 共享缓存销毁时先进入生命周期 Destroy,再释放 asset 映射及 handle 数据。

这个 backend 只拥有 managed 几何,不拥有真实 Ogre MeshPtr 或 Godot 视觉节点。因此不能把 Populate/DestroyGeometry 的 managed 实现当成完整原渲染资源租约流程。

未知或未导出 F2 数据仍属于准备输入缺口,不自动解释为“原包不存在”。模型层可以表示原缺文件状态,但实际 F2 预检与原 PackageMgr 是不同边界。

原生参考的精确范围

参考执行:

  • 原 575BF0 构造器。
  • 原 5757F0 文件门、几何分配/名称写入阶段。
  • 原 575620 析构顺序。
  • 实际 MSVCP90 字符串与 Ogre 零向量构造。

明确替换的边界:

  • 文件记录及 41CCA0 解析名。
  • CCollisionList 构造/填充/析构的测试存储。
  • 完整 Ogre 资源准备、MeshPtr、提取缓冲区与临时资源释放。
  • 已知 Ogre 错误注入直接进入原名称清空尾段;没有执行完整异常栈展开或日志系统。

因此 432 条观察证明控制和可见状态一致,不是对未执行的中间资源操作背书。此前的独立网格解析与数学对照仍有效,但组合层还需继续核对。

验证与文件

  • core_sim/NativeCollisionModelLifecycle.cs。
  • core_sim.io/F2CollisionModelCacheHost.cs。
  • core_sim.tests/NativeCollisionModelLifecycleChecks.cs。
  • tools/build_native_collision_model_lifecycle_oracle.py、native_collision_model_lifecycle_oracle.c。
  • tests/test_native_collision_model_lifecycle.py。
  • build/native_collision_model_lifecycle_oracle/results.json。
  • build/native_collision_model_lifecycle_mismatches.json(空)。
  • build/native_collision_model_lifecycle_core.log、native_collision_model_lifecycle_python.log、native_collision_model_lifecycle_godot.log、native_collision_model_lifecycle_visual.log。

EXE SHA256: 186472c3057b38f4cdff4696959a943c396ae6166995f7418997b5ea853e8a5e

OgreMain.dll SHA256: 974c1dc77ea2818276cc7eb94a8b95b2ccf8595e28fa3f14b2cd6d516fdb67a1

后续

继续 5757F0 中的完整 mesh lease/提取缓冲区所有权及销毁,装备与角色的实例生命周期,再接正式世界集合和攻击遮挡。构造字段、文件门、已有几何门和 Ogre 错误后的保留状态不再列为未知。

武器可构造覆盖保持 1,053/1,419,攻击型 proc、动画、缺导出资产、全地图与全武器实机验收仍未完成。UniverseComplete=false 没有放宽。

按 godot-master 的状态归属要求,模型身份、几何 storage 和输入/资源后端分开。main 原地工作,未提交、未 attach 原游戏、未修改正式地图/UI,快照 v29 未改。默认存档 SHA256 保持: 9840fe858b6e311c73f8c2d4ed49912d59d71365f6278392811730e012d32a7f