Room Piece碰撞资源选择与射线前置门
本批结果与边界
原版Room Piece碰撞不是“先找同名_COLLISION,找不到就用视觉MESH”。本批按发行EXE核对选择规则,导出完整有序列表,并接入CoreSim.IO选择/加载。另将622950射线前置门与61DCE0位置来源移植到核心,以原版机器码对照。
- 全量 4492个PIECE定义,GUID无重复。
- 220个定义含多个COLLISIONFILE,全部按序保留。
- 1839个无碰撞列表;2292个碰撞/视觉数量相同;361个数量不同。
- 2579个不同引用路径:2482个可导出,97个当前解包目录未找到。
- 2482个来源共 86586面,全部严格加载并有独立几何对照证据。
- 1526组输入×PC24/53/64,4578次前置门/位置来源机器码对照零差异。
- 1171条核心断言、116项相关Python检查通过;Godot C#构建零warning/error,coresimlint通过。
这仍不是完整场景LOS接通。矩阵构建/逆矩阵、实例变换生产方、分区候选、动态物件和完整施法执行仍待接;catalog明确保存instance_transforms_and_bake_state_complete=false。 武器构造覆盖仍 1053/1419(14成长),不将资源条目或机器码测试数量当成新增完成武器数。
取证身份
只读IDA数据库:E:/Torchlight 2/Torchlight2.exe.i64,端口13337。 EXE SHA256: 186472c3057b38f4cdff4696959a943c396ae6166995f7418997b5ea853e8a5e。
相关C/ASM保存在build/research_weapon_families:
- 654220/653B50:PIECE的FILE、COLLISIONFILE列表。
- 6234B0/622DF0/40E030:视觉变体解析与碰撞列表索引。
- 622360/649520/575BF0/5757F0:资源更换、共享缓存与MESH装载。
- 6A4650:两个直接调用的常量false函数。
- 622950/61DCE0:独立Room Piece射线入口与位置来源。
IDA中的CCharacter__hasChargeBar_vt104_false名字不代表这里涉及蓄力条。判断依据是6A4650的原始字节32 C0 C3以及6223CA/6224F8的直接E8调用,两处均确实返回false,不能因为反编译残留了分支就实现成可选行为。
FILE/COLLISIONFILE选择
654220分别把FILE装入定义+0x44列表,把COLLISIONFILE装入+0x54列表。653B50按数据字段顺序收集所有匹配项,不能只保存第一个COLLISIONFILE。
6234B0的正常显示分支:
| 条件 | 请求的碰撞资源 |
|---|---|
| 碰撞列表为空 | 空字符串;不自动借用FILE |
| 碰撞列表数量等于视觉列表数量 | 已解析视觉变体索引对应的COLLISIONFILE |
| 两个数量不同 | COLLISIONFILE[0] |
| 当前索引尚需622DF0随机解析 | 调用方必须提供解析结果;移植端不静默选零 |
622DF0:存储索引超出视觉数量时,单视觉返回0;多视觉才走原同步随机函数。FIXEDVARIATION影响原版是否写回选择,本批保留标志而不自行产生随机值。
实际例:CATACOMB的skull_convex_01,GUID=-6945459987568717345,有两套FILE和两套COLLISIONFILE。C#测试实际加载索引0/1,确认选中不同原始几何。
622360在请求变化时释放旧资源再加载;COLLISION ENABLED=false会阻止这条发行版路径装载。它不会在包查找失败后拿视觉网格补齐。其资源更换缓存状态机尚未接入Godot实例生命周期,当前IO接口负责显式选择和校验,不能冒充已实现整个状态机。
本规则限定Room Piece路径。角色/装备等另有加载函数,不能把这个“无自动回落”结论推广到它们,也不能把它们可能存在的回落推广到Room Piece。
资源目录而非文件名猜测
输出build/f2/native_room_pieces/catalog.json,包含原DAT路径/SHA256、块序号、GUID、名称、完整视觉及碰撞列表、ALWAYSBAKECOLLISION/NEVERBAKE/FIXEDVARIATION。每个可用碰撞源保留缓存和来源hash。
引用路径中有 62个不以_COLLISION.MESH结尾的可用资源。它们是原COLLISIONFILE明确指定的资源,并非我们的视觉回退。
独立几何核对:
- 2420个引用与上一批已验证缓存具有相同源文件hash及完整几何内容;复用之前的新鲜对照证据。
- 另62个逐个运行OgreXMLConverter,索引/材质/数量完全相同,坐标按XML小数输出容差核对。
- 2482个全部无差异;报告校验prior report、catalog、当前缓存及脚本hash。
- 97个“missing”仅表示当前已解包MEDIA按该路径无法解析。尚未证明PAK中缺失,也未证明这些定义一定被某个可玩关卡加载;不可据此为原版添加不存在的墙。
- 本批未修改原版文件、PAK或用户存档。
F2RoomPieceCollision.GetUnique拒绝未知/重复GUID,避免未来有重复定义时私自猜注册先后。 LoadCollision对缺源或不支持资源抛显式缺输入异常;空碰撞列表返回无模型。这是数据边界,不是完整世界查询“无遮挡”的结果。
622950前置门
按机器码原顺序:
- piece+0x108接口必须返回碰撞模型。
- 通常要求COLLISION ENABLED(+0x184)、实例+0x69、SceneNode::isPropagateVisible都为true;最后的override参数只能越过这三个门。
- piece+0x190必须为false。
- 定义+0x3E,即ALWAYSBAKECOLLISION,必须为false。
- piece+0x191必须为false。
- 按61DCE0取物件位置。
- 仅检查射线终点:abs(end.x-origin.x)<=50,abs(end.z-origin.z)<=50。无起点或Y轴的该项测试。
0x190/0x191保留原偏移命名,尚不把LAYOUT的BAKE直接当作其完整运行时值;完整写入者与烘焙生命周期需继续核对。 已烘焙物件不走这个独立物件分支,不等于它从世界碰撞中消失。
61DCE0(useDerived=true):当scene node和父对象均存在时,取节点+0xC4虚调用的派生位置;否则取piece+0x70存储位置。不能无条件用节点全局坐标。
数值边界:原版保留x87的减法结果后比较50,不能提前转float。例origin.x=-2^-25、end.x=50: PC24允许;PC53/64拒绝。核心实现与真实指令保持该差异。
原生对照范围
tools/native_room_gate_oracle.c在独立32位进程映射原版指令,运行:
- 原61DCE0位置读取。
- 原622950从入口到第一次Matrix4构造调用前的所有前置分支。
- 通过明示的测试vtable提供模型、可见性、派生位置输入;在Matrix4构造边界截停。
这不是完整622950射线命中oracle,也没有执行矩阵或碰撞叶子;报告scope明确记录这一点。原游戏未attach、未注入、未改内存。
夹具覆盖全部512种标志组合、X/Z正负50边界、微小超界、1000组不同存储/派生位置,以及全部三种x87精度。结果4578次与C#逐项一致。
已查明但尚待实现的变换
后续更新:矩阵与完整局部射线已实现下面的数值链,并通过4908次完整原生对照;实际场景生产方/分区仍未完成。下方为本篇初次记录时的状态。
622950通过节点派生四元数创建R,再乘piece自身+0x8C的scale矩阵,得到M=R*S。射线先减61DCE0的位置,再乘M的逆矩阵;碰撞点返回时乘M并加回位置。
法线返回只乘原四元数,不采用非均匀缩放的逆转置,也没有在这条返回支路重新归一化。NOPATH(+0x192)还会覆盖输出surface=100。
以上为已取证契约,本批没有用近似矩阵实现宣称这些步骤已跑通。下一批需要原Ogre矩阵/四元数数值对照和实际实例输入,再继续世界分区及施法接线。
验证命令与状态
python -m tools.build_native_room_pieces
python -m tools.audit_native_room_piece_geometry
python -m tools.build_native_room_gate_oracle
dotnet run --project core_sim.tests
python -m unittest tests.test_native_room_pieces
dotnet build torchlight-2-poc/TL2Poc.csproj
python -m tools.coresimlint完整相关回归:build/native_room_piece_python.log(116项);核心:build/native_room_piece_core.log(1171断言)。 本批按godot-master的数据/表现分层,只增资源输入和核心判定,未改画面。仍在main,未创建worktree、未提交。 默认存档SHA256: 9840fe858b6e311c73f8c2d4ed49912d59d71365f6278392811730e012d32a7f。