Is there a way to get BallConstraint like behaviour in nphysics2d?
Because there is only one possible rotation axis in 2D, the equivalent of
BallConstraint in 2D is the
Thanks for the reply. I did try RevoluteConstraint and got very unexpected results.
I’m trying to make something like a pendulum. I have one static object and one dynamic object. I tried connecting them together with a revolute joint with one anchor at the origin of the static object and one anchor at the same world location but expressed relative to the dynamic object. I thought the dynamic object would then maintain a constant distance from the static one and swing like a weight on a string. Instead it started spinning rapidly and flew off at a great velocity.
Any ideas where I’m going wrong?
What you describe seems to be the right way of doing this. The best would be if you could show me the code of your attempt with the
RevoluteConstraint (or at least the setup of the constraint itself).
This is my code for creating the revolute constraint.
let static_body_desc = RigidBodyDesc::new() .translation(location1) .mass(1.0) .status(BodyStatus::Static) .build(); let static_body_handle = self.bodies.insert(static_body_desc); let dynamic_body_desc = RigidBodyDesc::new() .translation(location2) .mass(1.0) .status(BodyStatus::Dynamic) .build(); let dynamic_body_handle = self.bodies.insert(dynamic_body_desc); let revolute_constraint = RevoluteConstraint::new( BodyPartHandle(static_body_handle, 0), BodyPartHandle(dynamic_body_handle, 0), [0.0, 0.0].into(), (location2 - location1).into(), ); let revolute_constraint_handle = self.joint_constraints.insert(revolute_constraint);
The behaviour I see is that the dynamic object (which falls under gravity if I do not create the joint) remains frozen and does not move (if I do make the joint).
Thanks! I have two guesses:
- The location of the joint wrt the second body should be in the local coordinate space of the second body. So it should be
(location1 - location2).into()instead of
(location2 - location1).into(). This might explain the first problem you had with the object starting spinning.
- You are using rigid bodies without attaching colliders (with non-zero density) to them so the mass and angular inertia of the rigid body cannot be automatically computed. So it is your responsibility to set the mass and angular inertia of your rigid bodies. Here you did set a mass with
.mass(1.0)but you did not set the angular inertia (using
.angular_inertia(value)). Without an angular inertia set, a rigid body cannot rotate. And because it cannot rotate, it will end up blocked in place by your revolute joint.
Thanks for your quick reply!
- You are correct, this was actually a mistake I made when copying the code to this forum, the real code does what you said. In case its a clue, if I reverse to what I put in previous post (
location2-location1) then the effect of the joint is to make the dynamic body move smoothly to the world position on the opposite side of the static body.
- I tried setting the
1.0. This had no effect. The behaviour is same as previously described.
If you have any other ideas I’d be very pleased to hear them!
[EDIT] I’ve got it working by adding angular_inertia and changing the joint setup to this (pseudocode):
let p1 = dynamic_body translation let p2 = static_body translation let offset = p2 - p1; let joint = RevoluteJoint::new( dynamic_body, static_body, offset, (0,0) );
I think what I was doing wrong before is fixing the centre of the dynamic body to a point on the static body, meaning the dynamic body could only rotate about its own centre, and the static body, being static was unable to rotate to enable the centre of the dynamic body to move.
Thanks for all your help!