Simulating Fixed and Line Joints in Farseer Physics Engine 3.5
Recently there was a new release of the excellent Farseer Physics Engine. Since my game is still in very early stage and I am still mucking around with samples and tweaking the settings I decided to upgrade since performance improvements is one of the things changed. Not that the old version was slow, but since I am inexperienced in game programming and quite likely doing some things in a non optimal way I though I could use those extra CPU cycles.
However version 3.5 is not backwards compatible and among other things it no longer includes fixed joints like FixedRevoluteJoint etc. and I have been using those in my proof of concept. As it turns out it is quite easy to achieve the things I used to use fixed joints for.
Firstly, credit where credit is due – a lot of my code is based on Farseer Samples and this post by Roy Triesscheijn.
Anyway I was testing various paddles as explained in the code that can be downloaded from the blog post mentioned above.
Here is how everything looks in action:
In Farseer 3.3, the code for the motorised paddle would look like this:
Body motorPaddle = CreateMotorPaddle();
var j = JointFactory.CreateFixedRevoluteJoint
(
World,
motorPaddle,
new Vector2(0.0f, 0.0f),
new Vector2(-14.0f, 10.0f)
);
// set motor speed
j.MotorSpeed = MathHelper.Pi;
// set torque and enable motor
j.MotorTorque = 100;
j.MotorEnabled = true;
j.MaxMotorTorque = 100;
In version 3.5 you can achieve the same thing by the code below. Note the use of another static body to act as an axle:
Body motorPaddle = CreateMotorPaddle();
Body motorPaddleAxle = BodyFactory.CreateCircle(World, 0.1f, 1f);
var j = JointFactory.CreateRevoluteJoint
(
World,
motorPaddle,
motorPaddleAxle,
new Vector2(0.0f, 0.0f),
new Vector2(-14.0f, 10.0f)
);
// set speed and torque
j.MotorSpeed = MathHelper.Pi;
j.MotorImpulse = 100;
j.MotorEnabled = true;
j.MaxMotorTorque = 100;
The code for free swinging paddle is more or less the same, except that the motor is not enabled and would look like the code below:
Body simplePaddle = CreateSimplePaddle();
Body simplePaddleAxle = BodyFactory.CreateCircle(World, 0.1f, 1f);
JointFactory.CreateRevoluteJoint
(
World,
simplePaddle,
simplePaddleAxle,
new Vector2(0.0f, -1.4f),
new Vector2(25.0f, 10.0f)
);
The trampoline was implemented using LineJoint in Farseer 3.3. That code looked like this:
Body trampolineAnchor1 = CreateTrampolineAnchor1();
Body trampolineAnchor2 = CreateTrampolineAnchor2();
Body trampolinePaddle = CreateTrampolinePaddle();
var spring1 = JointFactory.CreateLineJoint
(
trampolineAnchor1,
trampolinePaddle,
new Vector2(12.0f, 11.0f),
Vector2.UnitY
);
spring1.CollideConnected = true;
spring1.Frequency = 3.0f;
spring1.DampingRatio = 0.05f;
World.AddJoint(spring1);
var spring2 = JointFactory.CreateLineJoint
(
trampolineAnchor2,
trampolinePaddle,
new Vector2(16.0f, 11.0f),
Vector2.UnitY
);
spring2.CollideConnected = true;
spring2.Frequency = 3.0f;
spring2.DampingRatio = 0.05f;
World.AddJoint(spring2);
LineJoint is gone in Farseer 3.5, but there we can use WheelJoint instead, like in the code below. A wheel join allows rotation and suspension like movement along a specified axis.
Body trampolineAnchor1 = CreateTrampolineAnchor1();
Body trampolineAnchor2 = CreateTrampolineAnchor2();
Body trampolinePaddle = CreateTrampolinePaddle();
var spring1 = JointFactory.CreateWheelJoint
(
World,
trampolinePaddle,
trampolineAnchor1,
Vector2.UnitY
);
spring1.CollideConnected = false;
spring1.Frequency = 3.0f;
spring1.DampingRatio = 0.05f;
World.AddJoint(spring1);
var spring2 = JointFactory.CreateWheelJoint
(
World,
trampolinePaddle,
trampolineAnchor2,
Vector2.UnitY
);
spring2.CollideConnected = false;
spring2.Frequency = 3.0f;
spring2.DampingRatio = 0.05f;
World.AddJoint(spring2);
That is it!