Skip to content

Commit 031788a

Browse files
author
Hugh Phoenix-Hulme
authored
Merge pull request #39 from NArnott/fixDestroyFixture
Fix Body.DestroyFixture()
2 parents 9ad1503 + 28e89a1 commit 031788a

2 files changed

Lines changed: 109 additions & 5 deletions

File tree

  • src/box2dx
    • Box2D.NetStandard.UnitTests/Dynamics/Bodies
    • Box2D.NetStandard/Dynamics/Bodies
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using Box2D.NetStandard.Collision.Shapes;
2+
using Box2D.NetStandard.Dynamics.Bodies;
3+
using Box2D.NetStandard.Dynamics.Fixtures;
4+
using Box2D.NetStandard.Dynamics.World;
5+
using Xunit;
6+
7+
namespace Box2D.NetStandard.UnitTests.Dynamics.Bodies
8+
{
9+
public class BodyTests
10+
{
11+
private readonly Body sut;
12+
13+
public BodyTests()
14+
{
15+
var world = new World();
16+
var bd = new BodyDef();
17+
18+
sut = world.CreateBody(bd);
19+
}
20+
21+
[Fact]
22+
public void CanDestroyTopFixture()
23+
{
24+
//arrange
25+
var fixtureDef = new FixtureDef() { shape = new PolygonShape(1, 1) };
26+
var fixture1 = sut.CreateFixture(fixtureDef);
27+
var fixture2 = sut.CreateFixture(fixtureDef);
28+
var fixture3 = sut.CreateFixture(fixtureDef);
29+
30+
Assert.Equal(fixture3, sut.GetFixtureList()); //ensure that fixture3 is still the first in the linked list, per current implementation
31+
32+
33+
//act
34+
sut.DestroyFixture(fixture3);
35+
36+
37+
//assert
38+
Assert.Null(fixture3.Body);
39+
Assert.Null(fixture3.Next);
40+
Assert.Equal(fixture2, sut.GetFixtureList());
41+
Assert.Equal(fixture1, fixture2.Next);
42+
}
43+
44+
[Fact]
45+
public void CanDestroyMiddleFixture()
46+
{
47+
//arrange
48+
var fixtureDef = new FixtureDef() { shape = new PolygonShape(1, 1) };
49+
var fixture1 = sut.CreateFixture(fixtureDef);
50+
var fixture2 = sut.CreateFixture(fixtureDef);
51+
var fixture3 = sut.CreateFixture(fixtureDef);
52+
53+
Assert.Equal(fixture2, sut.GetFixtureList().Next); //ensure that fixture2 is the second in the linked list, per current implementation
54+
55+
56+
//act
57+
sut.DestroyFixture(fixture2);
58+
59+
60+
//assert
61+
Assert.Null(fixture2.Body);
62+
Assert.Null(fixture2.Next);
63+
Assert.Equal(fixture3, sut.GetFixtureList());
64+
Assert.Equal(fixture1, fixture3.Next);
65+
}
66+
67+
[Fact]
68+
public void CanDestroyLastFixture()
69+
{
70+
//arrange
71+
var fixtureDef = new FixtureDef() { shape = new PolygonShape(1, 1) };
72+
var fixture1 = sut.CreateFixture(fixtureDef);
73+
var fixture2 = sut.CreateFixture(fixtureDef);
74+
var fixture3 = sut.CreateFixture(fixtureDef);
75+
76+
Assert.Equal(fixture1, sut.GetFixtureList().Next.Next); //ensure that fixture1 is the third in the linked list, per current implementation
77+
78+
79+
//act
80+
sut.DestroyFixture(fixture1);
81+
82+
83+
//assert
84+
Assert.Null(fixture1.Body);
85+
Assert.Null(fixture1.Next);
86+
Assert.Equal(fixture3, sut.GetFixtureList());
87+
Assert.Equal(fixture2, fixture3.Next);
88+
}
89+
}
90+
}

src/box2dx/Box2D.NetStandard/Dynamics/Bodies/Body.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,19 +268,30 @@ public void DestroyFixture(Fixture fixture)
268268
// Remove the fixture from this body's singly linked list.
269269
//Debug.Assert(_fixtureCount > 0);
270270
Fixture node = m_fixtureList;
271+
Fixture prevNode = null;
272+
bool found = false;
271273
while (node != null)
272274
{
273-
if (node.m_next == fixture)
275+
if (node == fixture)
274276
{
275-
node.m_next = fixture.m_next;
277+
if (prevNode == null)
278+
m_fixtureList = fixture.m_next;
279+
else
280+
prevNode.m_next = fixture.m_next;
281+
282+
found = true;
276283
break;
277284
}
278285

286+
prevNode = node;
279287
node = node.m_next;
280288
}
281289

282290
// You tried to remove a shape that is not attached to this body.
283-
//Debug.Assert(found);
291+
if (!found)
292+
throw new System.ArgumentException("Fixture does not belong to this Body.", nameof(fixture));
293+
294+
float density = fixture.m_density;
284295

285296
// Destroy any contacts associated with the fixture.
286297
ContactEdge edge = m_contactList;
@@ -311,8 +322,11 @@ public void DestroyFixture(Fixture fixture)
311322

312323
--m_fixtureCount;
313324

314-
// Reset the mass data.
315-
ResetMassData();
325+
if (density > 0.0f)
326+
{
327+
// Reset the mass data.
328+
ResetMassData();
329+
}
316330
}
317331

318332
public void SetTransform(in Vector2 position, float angle)

0 commit comments

Comments
 (0)