The center of a compound shape can be computed as:
(shape1Center * shape1Weight + shape2Center * shape2Weight + ... + shapeNCenter * shapeNWeight) / (shape1Weight + shape2Weight + ... + shapeNWeight)
So, using the default bodies:
Code: Select all
var bodies = new List<CompoundShapeEntry>
{
new CompoundShapeEntry(new BoxShape(2.5f, .75f, 4.5f), new Vector3(0, 0, 0), 60),
new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new Vector3(0, .75f / 2 + .3f / 2, .5f), 1)
};
The center position is ((0,0,0) * 60 + (0, .75f / 2 + .3f / 2, .5f) * 1) / (60 + 1) = (0, 0.008606557f, 0.008196721f)
This can be verified by checking the body.Position immediately after creation (the compound shape is
recentered around zero; the recentering offset is used as the entity position so that the shape is in the same spot in world space).
Using the same approach for the modified body:
Code: Select all
var bodies = new List<CompoundShapeEntry>
{
new CompoundShapeEntry(new BoxShape(2.5f, .75f, 4.5f), new Vector3(0, 0, 0), 60),
new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new Vector3(0, .75f / 2 + .3f / 2, 3.5f), 60)
};
The center position is ((0,0,0) * 60 + (0, .75f / 2 + .3f / 2, 3.5f) * 60) / (60 + 60) = (0, 0.2625f, 1.75f)
Once again, this can be verified by checking the body.Position after construction.
The positions of wheels are specified relative to the center of the entity. So, to put the wheels in the same spot relative to the bottom box of the compound shape as they are in the unmodified shape, they must be scooted using the offset oldCenter - newCenter.
Here's the complete modified initialization. Note that this uses the
in-development version; the CylinderCastWheelShape does not exist in the main branch.
Code: Select all
var bodies = new List<CompoundShapeEntry>
{
new CompoundShapeEntry(new BoxShape(2.5f, .75f, 4.5f), new Vector3(0, 0, 0), 60),
new CompoundShapeEntry(new BoxShape(2.5f, .3f, 2f), new Vector3(0, .75f / 2 + .3f / 2, 3.5f), 60)
};
var body = new CompoundBody(bodies, 120);
var originalCenter = new Vector3(0, 0.008606557f, 0.008196721f);
var modifiedCenter = body.Position;
var wheelOffset = originalCenter - modifiedCenter;
body.CollisionInformation.LocalPosition = new Vector3(0, .5f, 0);
body.Position = position; //At first, just keep it out of the way.
Vehicle = new Vehicle(body);
var localWheelRotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2);
//The wheel model used is not aligned initially with how a wheel would normally look, so rotate them.
Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);
Vehicle.AddWheel(new Wheel(
new CylinderCastWheelShape(.375f, 0.2f, localWheelRotation, wheelGraphicRotation, false),
new WheelSuspension(2000, 100f, Vector3.Down, .8f - .375f, new Vector3(-1.1f, 0, 1.8f) + wheelOffset),
new WheelDrivingMotor(2.5f, 30000, 10000),
new WheelBrake(1.5f, 2, .02f),
new WheelSlidingFriction(4, 5)));
Vehicle.AddWheel(new Wheel(
new CylinderCastWheelShape(.375f, 0.2f, localWheelRotation, wheelGraphicRotation, false),
new WheelSuspension(2000, 100f, Vector3.Down, .8f - .375f, new Vector3(-1.1f, 0, -1.8f) + wheelOffset),
new WheelDrivingMotor(2.5f, 30000, 10000),
new WheelBrake(1.5f, 2, .02f),
new WheelSlidingFriction(4, 5)));
Vehicle.AddWheel(new Wheel(
new CylinderCastWheelShape(.375f, 0.2f, localWheelRotation, wheelGraphicRotation, false),
new WheelSuspension(2000, 100f, Vector3.Down, .8f - .375f, new Vector3(1.1f, 0, 1.8f) + wheelOffset),
new WheelDrivingMotor(2.5f, 30000, 10000),
new WheelBrake(1.5f, 2, .02f),
new WheelSlidingFriction(4, 5)));
Vehicle.AddWheel(new Wheel(
new CylinderCastWheelShape(.375f, 0.2f, localWheelRotation, wheelGraphicRotation, false),
new WheelSuspension(2000, 100f, Vector3.Down, .8f - .375f, new Vector3(1.1f, 0, -1.8f) + wheelOffset),
new WheelDrivingMotor(2.5f, 30000, 10000),
new WheelBrake(1.5f, 2, .02f),
new WheelSlidingFriction(4, 5)));