Instead of relying on object identity or raw transform parameters, the hasher
now uses intrinsic geometric properties to determine cylinder equivalence.
The hash is computed from:
- G = R^T * R : encodes the cylinder's cross-sectional metric and axis direction
- v = R * d : encodes the axial offset in the radial plane
where R is the top-left 2x3 submatrix of the world_to_local linear part,
and d is its translation vector. This ensures that two cylinder faces
with the same shape, orientation, and central axis (even if parameterized
differently) produce the same hash.
Note: Cylinder's side surface defines its AABB, and z-axis scaling does not affect its radius.
Degeneracy checks only consider x/y directions (first two rows of the transform matrix), since z scaling does not change the essential geometry.
TODO: Consider redefining cylinder so the identity transform is always the first subface.