PrismaticConstraint reaching limits, then slowing to extending beyond

This is a small bug with Prismatic Constraints, the constraints will move towards its desired location and then slow down and creep beyond it within roughly .05

I have a repro available ReproPrismatic.rbxl (15.0 KB)

Give the Lift constraint (Found within the Max part) a velocity of 10/-10. It will then move towards its destination. Once it reaches it it will seemingly stop, then move at an incredibly slow speed beyond the constraints limits.
The constraint on the left has a restitution of 1 and will fix itself sharply after reaching its goal, but will still be slightly outside its limits.

I have enabled CustomPhysicsProperties on both lifts, there was no change in the issue.

Hm, so the way the collision detection + resolution works is that when a collision is first detected, the solver will apply an impulse in the direction of the normal of the surface to counteract the impacts velocity. This happens as soon as the object touched the surface.

Since ROBLOX uses Discrete Collision Detection (meaning, we step a finite amount of time every frame) it is possible that the next frame an object is already interpenetrated when we first detect the collision. When this happens, if the velocity impulse is strong enough the object will bounce away itself. However in the case of inelastic collisions, the object will ONLY be de-penetrated if it’s depth into the other object is > 0.05.

Prismatic does a similar thing to this.

The reason for this system is so that we have a “Stable Depth” for objects laying on top of each other to be colliding without being forced out of collision every frame. Imagine a stack of bricks 10 bricks high. If we de-penetrated all the way out of the object (depth 0), it will lose collision, fall down again, and be stopped next frame, where it will be de-penetrated. And this cycle will happen indefinitely, causing issues for performance.

Additionally, this system is a bit more complicated. If an object ROLLS along the surface of a part, this “de-penetration” depth slowly shrinks to near 0 so that we don’t create edge collisions between the object and the next brick it may be transferring to (in case you have a floor made of tiles).

When the you move it to the bottom, are you still applying a force/velocity down into the object to make it penetrate a bit further?

2 Likes

There is a constant application of the velocity property within the constraint (motor). It’s CanCollide property is also set to false, so it shouldn’t be colliding with anything. I’ve put a feature request up to have Prismatics fire a ReachedLimit event when they are at their upper/lower limits, would being able to detect this and removing the velocity work?
Additionally, what is the restitution doing for prismatics?

Sorry for long response, I had to look at the code before answer it so that I didn’t give a made up answer.

Restitution is very similar concept to Elasticity. Energy conserved in the collision.

  • Restitution of 0 will make it so that colliding with the “edge” of the constraint will not cause bounce or consume energy.
  • Restitution of 1 will make it so that colliding with the “edge” of the constraint will bounce in the opposite direction with conserved energy.

Essentially the same thing as having 2 objects with Elasticity 0 collide vs 2 objects with Elasticity 1 collide.

Have you considered adding a 2nd object that is can collide false at the limit with a touch event to stop your velocity?

1 Like

I’d have to add an additional 2 (Upper and Lower) to stop the velocity.
Even then, wouldn’t the Touched connection require it to be partially penetrating?

The restitution explanation makes a fair amount of sense, it just doesn’t appear to do much with how I’ve got it set up.

No matter what detection system you use, collisions (with limits, or objects) are generally detected AFTER the collision has happened due to the discrete nature of the system. So any collision you detect will happen once you’ve crossed the threshold a bit.

@chefdeletat would be a good person to ask for a potential “limit reached” event, so that you don’t have to rely on Touched on unrelated parts.

I’m discussing with the rest of the team on whether collision margins (like this 0.05) make sense on pure constraint interactions.

subtle cough Prismatic Constraints: ReachedLimit(Upper/Lower) Event