原版物件矩阵变换与完整局部射线
完成内容
本批把622950的单物件射线数值链接通到核心:前置门 → 世界端点减去物件位置 → 逆矩阵变换 → 原版网格射线 → 命中点返回世界空间/法线旋转 → NOPATH输出覆盖。
1636组输入×PC24/53/64,共4908次完整原版函数对照:
- 前向矩阵16项、逆矩阵16项、局部端点6项、旋转法线3项:逐位一致。
- 命中布尔、世界命中点、世界法线和surface:逐位一致。
- 其中1710次命中,其余为不命中。
- 1615组输入的输出在不同x87精度下存在差异,因此不能统一用普通float或double矩阵替代。
这是单物件、给定实例输入的完整数值链,不是整张地图的遮挡验收。实际场景姿态、烘焙分支、分区候选、单位/装备遮挡和攻击型proc仍需接线。武器构造覆盖保持1053/1419,未虚增。
原始指令与算术顺序
使用发行OgreMain.dll:
974c1dc77ea2818276cc7eb94a8b95b2ccf8595e28fa3f14b2cd6d516fdb67a1。
本批转写五个直线数学函数:
| 函数 | 原地址 |
|---|---|
| Quaternion::ToRotationMatrix | 1014D0A0 |
| Matrix4矩阵相乘实现 | 10002DE0 |
| Matrix4::inverse(不是inverseAffine) | 100FABC0 |
| Matrix4乘Vector3 | 10003020 |
| Quaternion乘Vector3 | 1014D7D0 |
tools/lift_ogre_transform_math.py以符号状态跟踪寄存器、栈、FST副本与x87操作,生成core_sim/NativeOgreMath.Generated.cs。运行时是普通C#数值代码,不执行x86模拟器,也不依赖原DLL。
- 每个算术操作保留原顺序,使用既有X87Value处理PC精度和扩展指数。
- FST32产生新副本,不能把仍在寄存器中的值一起舍入。
- 不同矩阵分量的加法顺序确实不同,不能用一个“标准点积循环”覆盖所有分量。
- 生成器遇到未知指令、未初始化内存、栈不平衡就拒绝生成。
- 独立原生执行检查生成结果,而不是拿生成器自己的输出作为期望。
对照发现并修复了生成器初版的FXCH解释错误:Capstone的operand列表包含隐式ST0,但文本只显示目标ST(i)。误读会让换栈失效;原生对照在单位矩阵样本即发现错误。修正后全部4908次通过,回归还保留原生单位矩阵基准。
此外,现有pefile对该DLL的个别导出名称解码不完整。setScale等实际存在于原PE导出名称/序号表;新取证工具直接读取这些表,不以“库未列出名称”推断函数不存在。setScale为100036A0,Matrix4::IDENTITY为105B9B98。
接入的顺序
NativeRayMath.RoomTransform:
- 原四元数生成Matrix3,按Matrix4(Quaternion)方式嵌入IDENTITY。
- 创建单位缩放矩阵,设置piece自身scale。
- 按原顺序计算M=R*S。
- 调用原通用inverse的转写;不改为转置或inverseAffine。
RoomToLocal:
relative = f32(world - origin) // Ogre Vector3减法先存float
local = original_matrix_vector(inverse(M), relative)Matrix4乘Vector3仍保留原齐次除法与各坐标的不同求和顺序,不因为当前矩阵大多是仿射矩阵就删除这一段。
RoomToWorld:
world = f32(original_matrix_vector(M, local_hit) + origin)RoomNormalToWorld只执行原Quaternion乘Vector3:
- 不乘scale。
- 不采用非均匀缩放逆转置。
- 不重新归一化。
RoomPieceRay在给定前置标志下串联以上函数与已验证MeshRay;NOPATH为true时仅覆盖输出surface=100,不提前删面。 带姿态输入的入口先做前置门和终点范围,再构造矩阵,避免已排除物件因无关的零缩放报错。另保留可接收已构造临时矩阵的入口。
独立原生对照
tools/native_room_ray_oracle.c在独立32位进程中映射原始代码与常量,运行完整622950、61DCE0、467600及原Ogre数学函数。
没有截停在矩阵入口;相比上一批前置门oracle,这次真正执行了局部网格命中和世界输出。
明确夹具边界:
- 用小型测试vtable提供碰撞模型、派生位置和派生四元数;SceneNode可见性由夹具给定。
- 原游戏未attach、未注入、未启动完整Ogre渲染系统。
- 几何为给定单三角形,姿态为单位/90度/混合旋转及1600组随机单位四元数。
- 包含均匀、非均匀、负缩放,正反方向、不命中、NOPATH两值和三种x87精度。
- 原生中间矩阵及完整射线输出全部保存为float原始bits,不用小数容差。
EXE身份仍为:
186472c3057b38f4cdff4696959a943c396ae6166995f7418997b5ea853e8a5e。
输入、生成器/harness、EXE和Ogre哈希均受回归检查约束。已验证的是当前夹具域,不能据此宣称任意损坏矩阵/非有限值或全场景都等价。
奇异矩阵与存档
零缩放导致的奇异矩阵、非有限输出目前抛显式缺输入/未支持异常,不伪造为单位矩阵或无遮挡。原版在这些异常输入上的完整结果仍需后续补证。
NativeRoomTransform是查询内的派生数据,在SnapshotGates登记为Transient,不增加快照字段。以后若跨帧缓存,必须由真实姿态/精度变更驱动重建,不允许把这个临时分类当作可以丢失持久状态的理由。
默认存档未修改,SHA256保持:
9840fe858b6e311c73f8c2d4ed49912d59d71365f6278392811730e012d32a7f。
产物与验证
后续:双烘焙状态与静态组装已补静态矩阵平移合成、法线重建及基础/条件两遍顺序;真实实例生产方仍需继续。
- core_sim/NativeRoomTransform.cs:变换与完整单物件射线入口。
- core_sim/NativeOgreMath.Generated.cs:五个按指令生成的数学函数。
- tools/build_native_room_ray_oracle.py、tools/native_room_ray_oracle.c:独立原生对照。
- build/native_room_ray_oracle/results.json:4908次,数学与射线差异均0。
- build/native_room_transform_core.log:1176条核心断言通过。
- build/native_room_transform_python.log:120项相关检查通过。
- Godot C#构建0 warning/0 error;coresimlint通过。
- main原地工作,未提交;按godot-master分层,未改画面,不以旧截图充当本批验证。
下一步:生产真实实例输入和烘焙/独立物件名单,核对空间分区候选,接到世界LOS与攻击型触发技能。实际运行线程采用哪种精度仍保持显式待确认。