Skip to content

Commit ed8b71a

Browse files
committed
ConvexShape inertia computation now a little less annoying to use.
1 parent befdde9 commit ed8b71a

15 files changed

+63
-80
lines changed

BepuPhysics/Collidables/Box.cs

+8-7
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,18 @@ public bool RayTest(ref RigidPose pose, ref Vector3 origin, ref Vector3 directio
127127
return true;
128128
}
129129

130-
public void ComputeLocalInverseInertia(float inverseMass, out Triangular3x3 localInverseInertia)
130+
public void ComputeInertia(float mass, out BodyInertia inertia)
131131
{
132+
inertia.InverseMass = 1f / mass;
132133
var x2 = HalfWidth * HalfWidth;
133134
var y2 = HalfHeight * HalfHeight;
134135
var z2 = HalfLength * HalfLength;
135-
localInverseInertia.XX = inverseMass * 3 / (y2 + z2);
136-
localInverseInertia.YX = 0;
137-
localInverseInertia.YY = inverseMass * 3 / (x2 + z2);
138-
localInverseInertia.ZX = 0;
139-
localInverseInertia.ZY = 0;
140-
localInverseInertia.ZZ = inverseMass * 3 / (x2 + y2);
136+
inertia.InverseInertiaTensor.XX = inertia.InverseMass * 3 / (y2 + z2);
137+
inertia.InverseInertiaTensor.YX = 0;
138+
inertia.InverseInertiaTensor.YY = inertia.InverseMass * 3 / (x2 + z2);
139+
inertia.InverseInertiaTensor.ZX = 0;
140+
inertia.InverseInertiaTensor.ZY = 0;
141+
inertia.InverseInertiaTensor.ZZ = inertia.InverseMass * 3 / (x2 + y2);
141142
}
142143

143144
public ShapeBatch CreateShapeBatch(BufferPool pool, int initialCapacity, Shapes shapeBatches)

BepuPhysics/Collidables/Capsule.cs

+8-7
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,9 @@ public bool RayTest(ref RigidPose pose, ref Vector3 origin, ref Vector3 directio
144144

145145
}
146146

147-
public void ComputeLocalInverseInertia(float inverseMass, out Triangular3x3 localInverseInertia)
147+
public void ComputeInertia(float mass, out BodyInertia inertia)
148148
{
149+
inertia.InverseMass = 1f / mass;
149150
var r2 = Radius * Radius;
150151
var h2 = HalfLength * HalfLength;
151152
var cylinderVolume = 2 * HalfLength * r2 * MathHelper.Pi;
@@ -154,14 +155,14 @@ public void ComputeLocalInverseInertia(float inverseMass, out Triangular3x3 loca
154155
//Volume is in units of the capsule's whole volume.
155156
cylinderVolume *= inverseTotal;
156157
sphereVolume *= inverseTotal;
157-
localInverseInertia.XX = inverseMass / (
158+
inertia.InverseInertiaTensor.XX = inertia.InverseMass / (
158159
cylinderVolume * ((3f / 12f) * r2 + (4f / 12f) * h2) +
159160
sphereVolume * ((2f / 5f) * r2 + (6f / 8f) * Radius * HalfLength + h2));
160-
localInverseInertia.YX = 0;
161-
localInverseInertia.YY = inverseMass / (cylinderVolume * (1f / 2f) * r2 + sphereVolume * (2f / 5f) * r2);
162-
localInverseInertia.ZX = 0;
163-
localInverseInertia.ZY = 0;
164-
localInverseInertia.ZZ = localInverseInertia.XX;
161+
inertia.InverseInertiaTensor.YX = 0;
162+
inertia.InverseInertiaTensor.YY = inertia.InverseMass / (cylinderVolume * (1f / 2f) * r2 + sphereVolume * (2f / 5f) * r2);
163+
inertia.InverseInertiaTensor.ZX = 0;
164+
inertia.InverseInertiaTensor.ZY = 0;
165+
inertia.InverseInertiaTensor.ZZ = inertia.InverseInertiaTensor.XX;
165166
}
166167

167168
public ShapeBatch CreateShapeBatch(BufferPool pool, int initialCapacity, Shapes shapeBatches)

BepuPhysics/Collidables/CompoundHelpers.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ public void Add<TShape>(ref TShape shape, ref RigidPose localPose, float weight)
5656
child.LocalPose = localPose;
5757
child.ShapeIndex = Shapes.Add(ref shape);
5858
child.Weight = weight;
59-
shape.ComputeLocalInverseInertia(1f / weight, out child.Inertia);
60-
Triangular3x3.SymmetricInvert(ref child.Inertia, out child.Inertia);
59+
shape.ComputeInertia(weight, out var inertia);
60+
Triangular3x3.SymmetricInvert(ref inertia.InverseInertiaTensor, out child.Inertia);
6161
}
6262

6363
/// <summary>

BepuPhysics/Collidables/IShape.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public interface IConvexShape : IShape
2525
{
2626
void GetBounds(ref BepuUtilities.Quaternion orientation, out Vector3 min, out Vector3 max);
2727

28-
void ComputeLocalInverseInertia(float inverseMass, out Triangular3x3 localInverseInertia);
28+
void ComputeInertia(float mass, out BodyInertia inertia);
2929

3030
bool RayTest(ref RigidPose pose, ref Vector3 origin, ref Vector3 direction, out float t, out Vector3 normal);
3131
}

BepuPhysics/Collidables/Sphere.cs

+8-7
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,15 @@ public bool RayTest(ref RigidPose pose, ref Vector3 origin, ref Vector3 directio
6464
return true;
6565
}
6666

67-
public void ComputeLocalInverseInertia(float inverseMass, out Triangular3x3 localInverseInertia)
67+
public void ComputeInertia(float mass, out BodyInertia inertia)
6868
{
69-
localInverseInertia.XX = inverseMass / ((2f / 5f) * Radius * Radius);
70-
localInverseInertia.YX = 0;
71-
localInverseInertia.YY = localInverseInertia.XX;
72-
localInverseInertia.ZX = 0;
73-
localInverseInertia.ZY = 0;
74-
localInverseInertia.ZZ = localInverseInertia.XX;
69+
inertia.InverseMass = 1f / mass;
70+
inertia.InverseInertiaTensor.XX = inertia.InverseMass / ((2f / 5f) * Radius * Radius);
71+
inertia.InverseInertiaTensor.YX = 0;
72+
inertia.InverseInertiaTensor.YY = inertia.InverseInertiaTensor.XX;
73+
inertia.InverseInertiaTensor.ZX = 0;
74+
inertia.InverseInertiaTensor.ZY = 0;
75+
inertia.InverseInertiaTensor.ZZ = inertia.InverseInertiaTensor.XX;
7576
}
7677

7778
public ShapeBatch CreateShapeBatch(BufferPool pool, int initialCapacity, Shapes shapes)

Demos/Demos/BasicRagdollDemo.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,8 @@ public class BasicRagdollDemo : Demo
111111
{
112112
static BodyReference AddBody<TShape>(TShape shape, float mass, RigidPose pose, Simulation simulation) where TShape : struct, IConvexShape
113113
{
114-
BodyInertia inertia;
115-
inertia.InverseMass = mass > 0 ? 1f / mass : 0;
116114
var shapeIndex = simulation.Shapes.Add(ref shape);
117-
shape.ComputeLocalInverseInertia(inertia.InverseMass, out inertia.InverseInertiaTensor);
115+
shape.ComputeInertia(mass, out var inertia);
118116
var description = new BodyDescription
119117
{
120118
Activity = new BodyActivityDescription { SleepThreshold = 0.01f, MinimumTimestepCountUnderThreshold = 32 },

Demos/Demos/BlockChainDemo.cs

+2-6
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ public unsafe override void Initialize(Camera camera)
3030
Simulation.PoseIntegrator.Gravity = new Vector3(0, -10, 0);
3131

3232
var boxShape = new Box(1, 1, 1);
33-
BodyInertia boxInertia;
34-
boxInertia.InverseMass = 1;
35-
boxShape.ComputeLocalInverseInertia(boxInertia.InverseMass, out boxInertia.InverseInertiaTensor);
33+
boxShape.ComputeInertia(1, out var boxInertia);
3634
var boxIndex = Simulation.Shapes.Add(ref boxShape);
3735
const int forkCount = 20;
3836
const int blocksPerChain = 20;
@@ -93,9 +91,7 @@ public unsafe override void Initialize(Camera camera)
9391

9492
//Build the coin description for the ponz-I mean ICO.
9593
var coinShape = new Sphere(1f); //TODO: Obviously, when cylinders get added, this needs to be changed.
96-
BodyInertia coinInertia;
97-
coinInertia.InverseMass = 1f;
98-
coinShape.ComputeLocalInverseInertia(coinInertia.InverseMass, out coinInertia.InverseInertiaTensor);
94+
coinShape.ComputeInertia(1, out var coinInertia);
9995
coinDescription = new BodyDescription
10096
{
10197
LocalInertia = coinInertia,

Demos/Demos/CapsuleTestDemo.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ public unsafe override void Initialize(Camera camera)
2222
Simulation = Simulation.Create(BufferPool, new TestCallbacks());
2323

2424
var shape = new Capsule(.5f, 3.5f);
25-
BodyInertia localInertia;
26-
localInertia.InverseMass = 1f;
27-
shape.ComputeLocalInverseInertia(localInertia.InverseMass, out localInertia.InverseInertiaTensor);
25+
shape.ComputeInertia(1, out var localInertia);
2826
//capsuleInertia.InverseInertiaTensor = new Triangular3x3();
2927
var shapeIndex = Simulation.Shapes.Add(ref shape);
3028
const int width = 4;

Demos/Demos/CompoundTestDemo.cs

+16-16
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ public class CompoundTestDemo : Demo
1616
{
1717
public unsafe override void Initialize(Camera camera)
1818
{
19-
camera.Position = new Vector3(-3f, 3, -3f);
19+
camera.Position = new Vector3(-13f, 6, -13f);
2020
camera.Yaw = MathHelper.Pi * 3f / 4;
21-
camera.Pitch = MathHelper.Pi * 0.1f;
21+
camera.Pitch = MathHelper.Pi * 0.05f;
2222
Simulation = Simulation.Create(BufferPool, new TestCallbacks());
2323
Simulation.PoseIntegrator.Gravity = new Vector3(0, -10, 0);
2424

@@ -61,7 +61,7 @@ public unsafe override void Initialize(Camera camera)
6161
const float gridSpacing = 1.5f;
6262
const int gridWidth = 3;
6363
var gridShapeIndex = Simulation.Shapes.Add(ref gridShape);
64-
gridShape.ComputeLocalInverseInertia(1, out var gridBoxInertia);
64+
gridShape.ComputeInertia(1, out var gridBoxInertia);
6565
float localPoseOffset = -0.5f * gridSpacing * (gridWidth - 1);
6666
for (int i = 0; i < gridWidth; ++i)
6767
{
@@ -72,7 +72,7 @@ public unsafe override void Initialize(Camera camera)
7272
Orientation = BepuUtilities.Quaternion.Identity,
7373
Position = new Vector3(localPoseOffset, 0, localPoseOffset) + new Vector3(gridSpacing) * new Vector3(i, 0, j)
7474
};
75-
compoundBuilder.Add(gridShapeIndex, ref localPose, ref gridBoxInertia, 1);
75+
compoundBuilder.Add(gridShapeIndex, ref localPose, ref gridBoxInertia.InverseInertiaTensor, 1);
7676
}
7777
}
7878
compoundBuilder.BuildDynamicCompound(out var gridChildren, out var gridInertia, out var center);
@@ -104,16 +104,16 @@ public unsafe override void Initialize(Camera camera)
104104
//Build a table and use it for a couple of different tests.
105105
{
106106
var legShape = new Box(0.2f, 1, 0.2f);
107-
legShape.ComputeLocalInverseInertia(1f, out var legInverseInertia);
107+
legShape.ComputeInertia(1f, out var legInverseInertia);
108108
var legShapeIndex = Simulation.Shapes.Add(ref legShape);
109109
var legPose0 = new RigidPose { Position = new Vector3(-1.5f, 0, -1.5f), Orientation = BepuUtilities.Quaternion.Identity };
110110
var legPose1 = new RigidPose { Position = new Vector3(-1.5f, 0, 1.5f), Orientation = BepuUtilities.Quaternion.Identity };
111111
var legPose2 = new RigidPose { Position = new Vector3(1.5f, 0, -1.5f), Orientation = BepuUtilities.Quaternion.Identity };
112112
var legPose3 = new RigidPose { Position = new Vector3(1.5f, 0, 1.5f), Orientation = BepuUtilities.Quaternion.Identity };
113-
compoundBuilder.Add(legShapeIndex, ref legPose0, ref legInverseInertia, 1);
114-
compoundBuilder.Add(legShapeIndex, ref legPose1, ref legInverseInertia, 1);
115-
compoundBuilder.Add(legShapeIndex, ref legPose2, ref legInverseInertia, 1);
116-
compoundBuilder.Add(legShapeIndex, ref legPose3, ref legInverseInertia, 1);
113+
compoundBuilder.Add(legShapeIndex, ref legPose0, ref legInverseInertia.InverseInertiaTensor, 1);
114+
compoundBuilder.Add(legShapeIndex, ref legPose1, ref legInverseInertia.InverseInertiaTensor, 1);
115+
compoundBuilder.Add(legShapeIndex, ref legPose2, ref legInverseInertia.InverseInertiaTensor, 1);
116+
compoundBuilder.Add(legShapeIndex, ref legPose3, ref legInverseInertia.InverseInertiaTensor, 1);
117117
var tableTopPose = new RigidPose { Position = new Vector3(0, 0.6f, 0), Orientation = BepuUtilities.Quaternion.Identity };
118118
var tableTopShape = new Box(3.2f, 0.2f, 3.2f);
119119
compoundBuilder.Add(ref tableTopShape, ref tableTopPose, 3);
@@ -167,20 +167,20 @@ public unsafe override void Initialize(Camera camera)
167167
Simulation.Bodies.Add(ref tableDescription);
168168

169169
var clampPieceShape = new Box(2f, 0.1f, 0.3f);
170-
clampPieceShape.ComputeLocalInverseInertia(1f, out var clampPieceInverseInertia);
170+
clampPieceShape.ComputeInertia(1f, out var clampPieceInverseInertia);
171171
var clampPieceShapeIndex = Simulation.Shapes.Add(ref clampPieceShape);
172172
var clamp0 = new RigidPose { Position = new Vector3(0, -0.2f, -1.1f), Orientation = BepuUtilities.Quaternion.Identity };
173173
var clamp1 = new RigidPose { Position = new Vector3(0, 0.2f, -1.1f), Orientation = BepuUtilities.Quaternion.Identity };
174174
var clamp2 = new RigidPose { Position = new Vector3(0, -0.2f, 0), Orientation = BepuUtilities.Quaternion.Identity };
175175
var clamp3 = new RigidPose { Position = new Vector3(0, 0.2f, 0), Orientation = BepuUtilities.Quaternion.Identity };
176176
var clamp4 = new RigidPose { Position = new Vector3(0, -0.2f, 1.1f), Orientation = BepuUtilities.Quaternion.Identity };
177177
var clamp5 = new RigidPose { Position = new Vector3(0, 0.2f, 1.1f), Orientation = BepuUtilities.Quaternion.Identity };
178-
compoundBuilder.Add(clampPieceShapeIndex, ref clamp0, ref clampPieceInverseInertia, 1);
179-
compoundBuilder.Add(clampPieceShapeIndex, ref clamp1, ref clampPieceInverseInertia, 1);
180-
compoundBuilder.Add(clampPieceShapeIndex, ref clamp2, ref clampPieceInverseInertia, 1);
181-
compoundBuilder.Add(clampPieceShapeIndex, ref clamp3, ref clampPieceInverseInertia, 1);
182-
compoundBuilder.Add(clampPieceShapeIndex, ref clamp4, ref clampPieceInverseInertia, 1);
183-
compoundBuilder.Add(clampPieceShapeIndex, ref clamp5, ref clampPieceInverseInertia, 1);
178+
compoundBuilder.Add(clampPieceShapeIndex, ref clamp0, ref clampPieceInverseInertia.InverseInertiaTensor, 1);
179+
compoundBuilder.Add(clampPieceShapeIndex, ref clamp1, ref clampPieceInverseInertia.InverseInertiaTensor, 1);
180+
compoundBuilder.Add(clampPieceShapeIndex, ref clamp2, ref clampPieceInverseInertia.InverseInertiaTensor, 1);
181+
compoundBuilder.Add(clampPieceShapeIndex, ref clamp3, ref clampPieceInverseInertia.InverseInertiaTensor, 1);
182+
compoundBuilder.Add(clampPieceShapeIndex, ref clamp4, ref clampPieceInverseInertia.InverseInertiaTensor, 1);
183+
compoundBuilder.Add(clampPieceShapeIndex, ref clamp5, ref clampPieceInverseInertia.InverseInertiaTensor, 1);
184184

185185
compoundBuilder.BuildDynamicCompound(out var clampChildren, out var clampInertia, out var clampCenter);
186186
compoundBuilder.Reset();

Demos/Demos/PyramidDemo.cs

+2-6
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ public unsafe override void Initialize(Camera camera)
2525
Simulation.PoseIntegrator.Gravity = new Vector3(0, -10, 0);
2626

2727
var boxShape = new Box(1, 1, 1);
28-
BodyInertia boxInertia;
29-
boxInertia.InverseMass = 1;
30-
boxShape.ComputeLocalInverseInertia(boxInertia.InverseMass, out boxInertia.InverseInertiaTensor);
28+
boxShape.ComputeInertia(1, out var boxInertia);
3129
var boxIndex = Simulation.Shapes.Add(ref boxShape);
3230
const int pyramidCount = 20;
3331
for (int pyramidIndex = 0; pyramidIndex < pyramidCount; ++pyramidIndex)
@@ -86,7 +84,6 @@ public override void Update(Input input, float dt)
8684
{
8785
//Create the shape that we'll launch at the pyramids when the user presses a button.
8886
var bulletShape = new Sphere(0.5f + 5 * (float)random.NextDouble());
89-
BodyInertia bulletInertia;
9087
//Note that this can produce some pretty serious mass ratios. Observe what happens when a large ball sits on top of a few boxes with a fraction of the mass-
9188
//the collision appears much squishier and less stable. For most games, if you want to maintain rigidity, you'll want to use some combination of:
9289
//1) Limit the ratio of heavy object masses to light object masses when those heavy objects depend on the light objects.
@@ -95,8 +92,7 @@ public override void Update(Input input, float dt)
9592
//#2 and #3 can become very expensive. In pathological cases, it can end up slower than using a quality-focused solver for the same simulation.
9693
//Unfortunately, at the moment, bepuphysics v2 does not contain any alternative solvers, so if you can't afford to brute force the the problem away,
9794
//the best solution is to cheat as much as possible to avoid the corner cases.
98-
bulletInertia.InverseMass = 1f / (bulletShape.Radius * bulletShape.Radius * bulletShape.Radius);
99-
bulletShape.ComputeLocalInverseInertia(bulletInertia.InverseMass, out bulletInertia.InverseInertiaTensor);
95+
bulletShape.ComputeInertia(bulletShape.Radius * bulletShape.Radius * bulletShape.Radius, out var bulletInertia);
10096
var bulletShapeIndex = Simulation.Shapes.Add(ref bulletShape);
10197
var bodyDescription = new BodyDescription
10298
{

Demos/Demos/ShapePileDemo.cs

+4-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class ShapePileDemo : Demo
1515
{
1616
public unsafe override void Initialize(Camera camera)
1717
{
18-
camera.Position = new Vector3(-20, 10, -20);
18+
camera.Position = new Vector3(-30, 10, -30);
1919
//camera.Yaw = MathHelper.Pi ;
2020
camera.Yaw = MathHelper.Pi * 3f / 4;
2121
//camera.Pitch = MathHelper.PiOver2 * 0.999f;
@@ -24,11 +24,9 @@ public unsafe override void Initialize(Camera camera)
2424
var box = new Box(1f, 3f, 2f);
2525
var capsule = new Capsule(1f, 1f);
2626
var sphere = new Sphere(1.5f);
27-
BodyInertia boxInertia, capsuleInertia, sphereInertia;
28-
boxInertia.InverseMass = capsuleInertia.InverseMass = sphereInertia.InverseMass = 1f;
29-
box.ComputeLocalInverseInertia(boxInertia.InverseMass, out boxInertia.InverseInertiaTensor);
30-
capsule.ComputeLocalInverseInertia(capsuleInertia.InverseMass, out capsuleInertia.InverseInertiaTensor);
31-
sphere.ComputeLocalInverseInertia(sphereInertia.InverseMass, out sphereInertia.InverseInertiaTensor);
27+
box.ComputeInertia(1, out var boxInertia);
28+
capsule.ComputeInertia(1, out var capsuleInertia);
29+
sphere.ComputeInertia(1, out var sphereInertia);
3230
//capsuleInertia.InverseInertiaTensor = new Triangular3x3();
3331
var boxIndex = Simulation.Shapes.Add(ref box);
3432
var capsuleIndex = Simulation.Shapes.Add(ref capsule);

Demos/Demos/SphereBlobTestDemo.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ public unsafe override void Initialize(Camera camera)
2121
Simulation = Simulation.Create(BufferPool, new TestCallbacks());
2222

2323
var shape = new Sphere(0.5f);
24-
BodyInertia sphereInertia;
25-
sphereInertia.InverseMass = 1;
26-
shape.ComputeLocalInverseInertia(sphereInertia.InverseMass, out sphereInertia.InverseInertiaTensor);
24+
shape.ComputeInertia(1, out var sphereInertia);
2725
var shapeIndex = Simulation.Shapes.Add(ref shape);
2826
const int width = 16;
2927
const int height = 16;

Demos/SpecializedTests/ConstraintTestDemo.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ public class ConstraintTestDemo : Demo
1616
{
1717
static BodyReference AddBody<TShape>(TShape shape, float mass, RigidPose pose, Simulation simulation) where TShape : struct, IConvexShape
1818
{
19-
BodyInertia inertia;
20-
inertia.InverseMass = mass > 0 ? 1f / mass : 0;
2119
var shapeIndex = simulation.Shapes.Add(ref shape);
22-
shape.ComputeLocalInverseInertia(inertia.InverseMass, out inertia.InverseInertiaTensor);
20+
shape.ComputeInertia(mass, out var inertia);
2321
var description = new BodyDescription
2422
{
2523
Activity = new BodyActivityDescription { SleepThreshold = 0, MinimumTimestepCountUnderThreshold = 32 },

0 commit comments

Comments
 (0)