Match collision features object

This commit is contained in:
Jonas Volman committed 2026-08-13 05:54:03 -07:00
1 parent 1bf72e846d
commit cfe2aff70a
6 files changed
+1307 -272

No files matched your search

+1 -1
View File
@@ -510,7 +510,7 @@
{ "name": "source/physics/collision_usage.c", "index": 136, "status": "NonMatching" },
{ "name": "source/physics/collision_models.c", "index": 137, "status": "Matching" },
{ "name": "source/physics/collision_model_definitions.c", "index": 138, "status": "Matching" },
{ "name": "source/physics/collision_features.c", "index": 139, "status": "NonMatching" },
{ "name": "source/physics/collision_features.c", "index": 139, "status": "Matching" },
{ "name": "source/physics/collision_debug.c", "index": 140, "status": "NonMatching" },
{ "name": "source/physics/collision_bsp_definitions.c", "index": 141, "status": "Matching" },
{ "name": "source/physics/collision_bsp.c", "index": 142, "status": "NonMatching" },
@@ -0,0 +1,92 @@
# collision_features.obj matching log
## Result
- Upstream provenance: `punpckhdq/halo` commit `1aa21fd12d56a6fe737cd0e9ab4516e31f3a3f47` (`collision_features (#48)`).
- Compiler: XDK 3911 CL 13.00.9254.1 with the repository flags `/O2 /Oy- /DDEBUG /Dxbox`.
- Strict result after adaptation to the current campaign trunk: 20/20 functions pass `tools/coff_compare.py` (`section_infos_equal`).
- Upstream whole-object report: 6,929/6,929 meaningful code bytes and 896/896 data bytes; `.text` and `.rdata` are both 100%.
- No assembly, volatile codegen coercion, `__forceinline`, byte patching, undefined-behavior trick, compiler-flag change, or comparator exception is used.
## Integration and type audit
The upstream implementation was compiled and measured in a pristine worktree before any transplant. All 20 functions passed the hardened comparator, including relocation destination identity. The full upstream report also proved the 896-byte `.rdata` ownership and content.
The current campaign already had partial collision-feature structures. The completed upstream layout was retained and guarded with compile-time size/offset checks:
- `collision_feature`: `0x0C`
- `collision_sphere`: `0x1C`
- `collision_cylinder`: `0x28`
- `collision_prism`: `0x68`
- `collision_feature_list.spheres`: `0x08`
- `collision_feature_list.cylinders`: `0x1C08`
- `collision_feature_list.prisms`: `0x4408`
The source follows the project formatting rules: one parameter per line, explicit returns, no raw `tag_get`/`object_get` casts, and no gratuitous alignment directives. Several boolean collision routines retain multiple returns because that is the January control-flow shape; forcing a single exit would change the object, so this is one of the house rule's documented exceptions.
## Current-trunk codegen interaction
The pristine upstream patch was exact, but its first current-trunk build left only `_collision_prism_test_vector` nonexact. Size and relocation identity were already exact (`0x290`, 11/11). Two independent instruction-order differences were isolated:
1. The `vn` dot product evaluated the `j` product before `k`; January evaluates `k`, then `j`, then `i`.
2. At the inlined `point_from_line3d` boundary, `fstp p3d.z` and `lea &p3d` were transposed.
The accepted readable controls are:
- keep the upstream no-parentheses `point_from_line3d` body (`v*t + p`), which restores the January inline-boundary scheduling;
- accumulate `vn` sequentially in January order (`k`, then `j`, then `i`), which preserves the observed x87 evaluation order.
Together these restore strict equality for all 20 functions.
## Rejected forms
- The unadapted donor body under the current shared header: exact size/relocations, but two instruction-order regions differed.
- Reversing the one-line dot-product terms alone: VC7 reassociated them back to `j`, `k`, `i`; no improvement.
- Sequential `k`/`j`/`i` accumulation while retaining the parenthesized inline helper: fixed the dot product but left the `fstp`/`lea` transposition.
- A named pointer holding the return of `point_from_line3d`: optimized to the same remaining transposition.
- Longhand first or second point-from-line expansion: either had no effect on the transposition or introduced repeated `fchs` operations and a six-byte regression.
## Admission gate
Before admission, regenerate the full report on the integration worktree, compare the strict accepted-function ledger against the pre-transplant baseline, and require zero lost entries. Any data or sibling-function regression rejects the object despite its own 20/20 result.
## House-rule compliance re-audit (2026-08-07)
The completed source and header were re-read against `docs/house_rules.md` and
Berthalamew's guidance. Parameters are vertically formatted, typed structures
replace raw access casts, `void` functions end with explicit `return;`, and the
files contain no assembly, `volatile`, `__forceinline`, optimization pragma,
or gratuitous alignment directive. CRLF is consistent. The measured
multi-return collision predicates remain the documented exception: their
January control-flow graphs require those exits, and forcing a cosmetic single
exit would destroy strict equality.
## Current-campaign independent admission (2026-08-13)
The object was rebuilt from source on campaign commit `1bf72e84` with XDK
3911, not accepted from the donor's report alone. A target-owner sweep found
**30/30 strict-exact sections**: all 20 functions and all 10 owned `.rdata`
sections. This verifies padded bytes, relocation count/order/type/destination
and addend, string ownership, and storage class. There is no target-owned
`.data` or `.bss` in this translation unit.
The shared `real_math.h` correction has a deliberately large possible blast
radius, so the ordinary one-object check was not considered sufficient. A
clean baseline and the candidate were both fully rebuilt, then every
externally owned target section that was strict before the change was checked
again against January. The result was **6,963/6,963 prior-exact sections
retained**, with **0 strict regressions** and **0 ownership/type/value drifts**
across 7,111 checked owner symbols.
The `project_point3d` change fixes a defect in our prior reconstruction, not a
bug in the shipped game. The old helper returned the two integer axis indices
as coordinates; the January behavior indexes the input 3D point with those
axes. In plain English, projecting `(x,y,z)` must select two coordinates from
that point, not return values such as `0` and `2`. The corrected readable
expression also agrees with the recovered projection table and the January
callers.
Final campaign delta versus the clean baseline is exactly one completed Halo
object, 14 newly credited functions (six functions were already exact), 6,188
new exact code bytes, and 896 exact data bytes. The complete build and
semantic/progress reports pass with zero unit errors.
+7 -4
View File
@@ -909,7 +909,10 @@ __inline real_point2d *project_point3d(
match_assert("..\\math\\real_math.h", 859, projection>=_x && projection<=_z);
match_assert("..\\math\\real_math.h", 860, ~(sign&~1));
set_real_point2d(p2d, global_projection3d_mappings[projection][sign][0], global_projection3d_mappings[projection][sign][1]);
set_real_point2d(
p2d,
p3d->n[global_projection3d_mappings[projection][sign][0]],
p3d->n[global_projection3d_mappings[projection][sign][1]]);
return p2d;
}
@@ -973,9 +976,9 @@ __inline real_point3d *point_from_line3d(
real t,
real_point3d *result)
{
result->x = (v->i*t) + p->x;
result->y = (v->j*t) + p->y;
result->z = (v->k*t) + p->z;
result->x = v->i*t + p->x;
result->y = v->j*t + p->y;
result->z = v->k*t + p->z;
return result;
}
+5
View File
@@ -157,6 +157,11 @@ boolean collision_bsp_test_vector(
real maximum_t,
struct collision_bsp_test_vector_result *result);
short collision_surface_polygon(
struct collision_bsp const *bsp,
long surface_index,
real_point3d *points);
/* ---------- globals */
/* ---------- public code */
File diff suppressed because it is too large. Load diff
+192 -46
View File
@@ -10,6 +10,7 @@ header included in hcex build.
/* ---------- headers */
#include "cseries.h"
#include "math/real_math.h"
/* ---------- constants */
@@ -17,11 +18,12 @@ header included in hcex build.
enum
{
MAXIMUM_COLLISION_FEATURES_PER_TEST = 256,
MAXIMUM_POINTS_PER_COLLISION_PRISM = 8,
};
enum collision_feature_type
enum
{
_collision_feature_sphere,
_collision_feature_sphere = 0,
_collision_feature_cylinder,
_collision_feature_prism,
NUMBER_OF_COLLISION_FEATURE_TYPES,
@@ -31,53 +33,82 @@ enum collision_feature_type
/* ---------- structures */
struct collision_feature_common
struct collision_feature
{
long source_index;
long object_index;
long surface_index;
byte flags;
byte breakable_surface_index;
short material_index;
};
struct collision_feature_sphere
struct collision_sphere
{
struct collision_feature_common common;
union real_point3d center;
long object_index;
long surface_index;
byte flags;
byte breakable_surface_index;
short material_index;
real_point3d center;
real radius;
};
struct collision_feature_cylinder
struct collision_cylinder
{
struct collision_feature_common common;
union real_point3d point;
union real_vector3d height;
real radius;
long object_index;
long surface_index;
byte flags;
byte breakable_surface_index;
short material_index;
real_point3d base;
real_vector3d height;
real width;
};
struct collision_feature_prism
struct collision_prism
{
struct collision_feature_common common;
byte data[0x5C];
long object_index;
long surface_index;
byte flags;
byte breakable_surface_index;
short material_index;
real_plane3d plane;
real height;
short projection_axis;
boolean projection_sign;
byte pad;
long point_count;
real_point2d points[MAXIMUM_POINTS_PER_COLLISION_PRISM];
};
struct collision_feature_list
{
short count[NUMBER_OF_COLLISION_FEATURE_TYPES];
word pad;
struct collision_feature_sphere spheres[MAXIMUM_COLLISION_FEATURES_PER_TEST];
struct collision_feature_cylinder cylinders[MAXIMUM_COLLISION_FEATURES_PER_TEST];
struct collision_feature_prism prisms[MAXIMUM_COLLISION_FEATURES_PER_TEST];
struct collision_sphere spheres[MAXIMUM_COLLISION_FEATURES_PER_TEST];
struct collision_cylinder cylinders[MAXIMUM_COLLISION_FEATURES_PER_TEST];
struct collision_prism prisms[MAXIMUM_COLLISION_FEATURES_PER_TEST];
};
typedef char collision_feature_common_size_assert[
sizeof(struct collision_feature_common) == 0x0C ? 1 : -1];
typedef char collision_feature_sphere_size_assert[
sizeof(struct collision_feature_sphere) == 0x1C ? 1 : -1];
typedef char collision_feature_cylinder_size_assert[
sizeof(struct collision_feature_cylinder) == 0x28 ? 1 : -1];
typedef char collision_feature_prism_size_assert[
sizeof(struct collision_feature_prism) == 0x68 ? 1 : -1];
struct collision_plane
{
real t;
real_point3d point;
real_plane3d plane;
long object_index;
long surface_index;
byte flags;
byte breakable_surface_index;
short material_index;
};
typedef char collision_feature_size_assert[
sizeof(struct collision_feature) == 0x0C ? 1 : -1];
typedef char collision_sphere_size_assert[
sizeof(struct collision_sphere) == 0x1C ? 1 : -1];
typedef char collision_cylinder_size_assert[
sizeof(struct collision_cylinder) == 0x28 ? 1 : -1];
typedef char collision_prism_size_assert[
sizeof(struct collision_prism) == 0x68 ? 1 : -1];
typedef char collision_feature_list_spheres_offset_assert[
offsetof(struct collision_feature_list, spheres) == 0x08 ? 1 : -1];
typedef char collision_feature_list_cylinders_offset_assert[
@@ -89,29 +120,144 @@ typedef char collision_feature_list_prisms_offset_assert[
void collision_features_new(
struct collision_feature_list *features);
void render_debug_collision_sphere(
const struct collision_feature_sphere *sphere,
const real_argb_color *color);
void render_debug_collision_cylinder(
const struct collision_feature_cylinder *cylinder,
const real_argb_color *color);
void collision_features_from_vertex(
const struct collision_bsp *collision_bsp,
long vertex_index,
const real_matrix4x3 *transform,
real depth,
real radius,
long source_index,
struct collision_feature_list *features);
void collision_features_from_surface(
const struct collision_bsp *collision_bsp,
void collision_features_from_point(
real_point3d const *point,
real height,
real width,
long object_index,
long surface_index,
const real_matrix4x3 *transform,
real radius,
long source_index,
byte flags,
byte breakable_surface_index,
short material_index,
struct collision_feature_list *features);
void collision_features_from_line(
real_point3d const *point,
real_vector3d const *vector,
real height,
real width,
long object_index,
long surface_index,
byte flags,
byte breakable_surface_index,
short material_index,
struct collision_feature_list *features);
void collision_features_from_polygon(
short point_count,
real_point3d const *points,
real_plane3d const *plane,
real height,
real width,
long object_index,
long surface_index,
byte flags,
byte breakable_surface_index,
short material_index,
struct collision_feature_list *features);
void collision_features_from_vertex(
struct collision_bsp const *bsp,
long vertex_index,
real_matrix4x3 const *matrix,
real height,
real width,
long object_index,
struct collision_feature_list *features);
void collision_features_from_edge(
struct collision_bsp const *bsp,
long edge_index,
real_matrix4x3 const *matrix,
real height,
real width,
long object_index,
struct collision_feature_list *features);
void collision_features_from_surface(
struct collision_bsp const *bsp,
long surface_index,
real_matrix4x3 const *matrix,
real height,
real width,
long object_index,
struct collision_feature_list *features);
void collision_bsp_get_features_in_sphere(
struct collision_bsp const *bsp,
struct collision_bsp_test_sphere_result const *result,
real_matrix4x3 const *matrix,
real height,
real width,
long object_index,
struct collision_feature_list *features);
boolean collision_features_test_point(
struct collision_feature_list const *features,
real_point3d const *point,
struct collision_plane *collision);
boolean collision_sphere_test_point(
struct collision_sphere const *sphere,
real_point3d const *point,
real *depth,
real_plane3d *plane);
boolean collision_cylinder_test_point(
struct collision_cylinder const *cylinder,
real_point3d const *point,
real *depth,
real_plane3d *plane);
boolean collision_prism_test_point(
struct collision_prism const *prism,
real_point3d const *point,
real *depth,
real_plane3d *plane);
boolean collision_features_test_vector(
struct collision_feature_list const *features,
real_point3d const *point,
real_vector3d const *vector,
struct collision_plane *collision);
boolean collision_sphere_test_vector(
struct collision_sphere const *sphere,
real_point3d const *point,
real_vector3d const *vector,
real *t,
real_plane3d *plane);
boolean collision_cylinder_test_vector(
struct collision_cylinder const *cylinder,
real_point3d const *point,
real_vector3d const *vector,
real *t,
real_plane3d *plane);
boolean collision_prism_test_vector(
struct collision_prism const *prism,
real_point3d const *point,
real_vector3d const *vector,
real *t,
real_plane3d *plane);
void render_debug_collision_sphere(
struct collision_sphere const *sphere,
real_argb_color const *color);
void render_debug_collision_cylinder(
struct collision_cylinder const *cylinder,
real_argb_color const *color);
void render_debug_collision_prism(
struct collision_prism const *prism,
real_argb_color const *color);
void render_debug_collision_features(
struct collision_feature_list const *features);
/* ---------- globals */
/* ---------- public code */