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!