Test that the float2 radial falloff overload accumulates, not assigns
Soul's pass on 41440cb found BatchMath.cs:115
(AddRadialFalloffAcceleration2D(ReadOnlySpan<float2>, ...)) accumulates
onto the caller's acceleration buffer, but no test ever seeded that
buffer with nonzero values: mutating += to = passed all 133 tests. The
float-array overload already had this guard
(RadialFalloffAccumulatesOntoExistingAcceleration); add the float2
equivalent, with a nonzero, per-element-distinct starting buffer, mixing
in-range and out-of-range particles so both the accumulated and
unchanged-seed cases are checked.
Checked every other += site in BatchMath.cs for the same gap: the
array-overload's scalar tail and vector body, and both
IntegrateSemiImplicitEuler2D overloads, all already seed their
accumulator buffers (vx/vy/px/py, velocity/position) with nonzero,
per-element values in their existing tests. Only this one site was bare.
Verified by hand-mutating BatchMath.cs:115 (+= to =): the new test fails
(expected 6.78, actual 0.48); reverted the source byte-exactly after.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
41440cb538
commit
fd75c2acf9
1 changed files with 50 additions and 0 deletions
|
|
@ -299,6 +299,56 @@ public sealed class BatchMathTests
|
|||
Assert.True(outsideCount > 0, "fixture must include particles outside the radius");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Float2RadialFalloffAccumulatesOntoExistingAcceleration()
|
||||
{
|
||||
// Guards against a mutation that assigns instead of accumulating (BatchMath.cs:115):
|
||||
// seed a nonzero, per-element-distinct acceleration and confirm the falloff
|
||||
// contribution is added to it, not overwritten. An out-of-range particle must be left
|
||||
// exactly at its seed value, not reset to zero.
|
||||
var count = 5;
|
||||
var positions = new float2[count];
|
||||
var seedAcceleration = new float2[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
positions[i] = new float2(i * 1.1f - 2.0f, i * -0.8f + 1.0f);
|
||||
seedAcceleration[i] = new float2(i * 2.3f + 4.0f, i * -1.7f - 6.0f);
|
||||
}
|
||||
|
||||
var center = new float2(1.5f, -0.5f);
|
||||
const float strength = 3.0f;
|
||||
const float radius = 3.0f;
|
||||
var acceleration = (float2[])seedAcceleration.Clone();
|
||||
|
||||
BatchMath.AddRadialFalloffAcceleration2D(positions, center, strength, radius, acceleration);
|
||||
|
||||
var insideCount = 0;
|
||||
var outsideCount = 0;
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var delta = center - positions[i];
|
||||
var distanceSquared = Math.Max(delta.x * delta.x + delta.y * delta.y, 1.0e-8f);
|
||||
var distance = MathF.Sqrt(distanceSquared);
|
||||
|
||||
if (distance > radius)
|
||||
{
|
||||
outsideCount++;
|
||||
Assert.Equal(seedAcceleration[i].x, acceleration[i].x, Tolerance);
|
||||
Assert.Equal(seedAcceleration[i].y, acceleration[i].y, Tolerance);
|
||||
continue;
|
||||
}
|
||||
|
||||
insideCount++;
|
||||
var falloff = Math.Max(0.0f, 1.0f - distance / radius);
|
||||
var contribution = delta / distance * (strength * falloff);
|
||||
Assert.Equal(seedAcceleration[i].x + contribution.x, acceleration[i].x, Tolerance);
|
||||
Assert.Equal(seedAcceleration[i].y + contribution.y, acceleration[i].y, Tolerance);
|
||||
}
|
||||
|
||||
Assert.True(insideCount > 0, "fixture must include particles inside the radius");
|
||||
Assert.True(outsideCount > 0, "fixture must include particles outside the radius");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Float2EulerIntegrationMatchesScalarReferenceWithNonzeroYAndMask()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue