leapmotion / LeapUnrealModules

Leap Motion Unreal modules and example content.
Other
64 stars 22 forks source link

Grabbing items with physics friction? #9

Closed z3099644 closed 3 years ago

z3099644 commented 4 years ago

Hi @getnamo,

Your demos seem to be using the Leap (L) Grab and Leap (R) Grab events (gesture based) to pick up items. While that works well for simple shapes, I was just wondering if there's been any work done on using the physics engine (physx), and the friction effects that is part of that in order to pick up objects? I figure a physics based approach can mean that the user can more naturally interact with a wide range of objects (such as door handles).

This video demonstrating Physx 4 shows gripper robots picking up pieces of wood using contacts constraints which would be similar to what we're trying to do with our leap hands in VR: https://www.youtube.com/watch?v=K1rotbzekf0.

However, when I tried to grab things using physics in UE4, I'm finding that physics objects tend to behave erratically when clamped by my kinematic fingers. I believe this is because physx applies large impulses to objects when they overlap with other objects in order to keep them separated (see: https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/AdvancedCollisionDetection.html). I am guessing that if I can tweak the amount of impulse that is applied when objects overlap, then the physics object might behave more predictably when clamped between kinematic surfaces. Hopefully then the friction (that is already modelled, and can be increased using physics material properties) would allow me to pick up and manipulate the object.

The prior link has a section on 'contact modification' which I believe allows us to tweak these values:

For example to implement sticky contacts, give objects the appearance of floating or swimming inside each other, or making objects go through apparent holes in walls. A simple approach to achieve such effects is to let the user change the properties of contacts after they have been generated by collision detection, but before the contact solver. Because both of these steps occur within the scene simulate() function, a callback must be used.

It then talks about deriving from the class "PxContactModifyCallback" but this is way more advanced than what I can pull off! If this topic interests you also, would you be able to look into it and break this down for me a bit please? I believe it could be a big step forward to more interactive hands in unreal engine.

Thanks for reading!

getnamo commented 4 years ago

The correct way to interact with physics objects is to use non-kinematic (velocity based) control on the physics capsules defining the physical body. Instead of saying this is where the physics body should be by setting its position, you want to calculate the velocity it would take to move the object to that desired location and set the velocity on your next physics tick. You can then use various other methods to tune the velocity e.g. lowering it when touching objects and far away from your tracked positions. That should provide a stable interaction.

See the unreal Physics Handles: https://docs.unrealengine.com/en-US/BlueprintAPI/Physics/Components/PhysicsHandle/index.html for a way to apply this in a generic way.

Also keep in mind the awesome unity Interaction Engine: https://leapmotion.github.io/UnityModules/interaction-engine.html for more advanced examples

z3099644 commented 4 years ago

thanks getnamo, I did consider using physics handles actually. My initial plan was to try to detect on collision whether there are any bones on the other side of the object also colliding. If so then this is considered a grab and physics handles are created to connect those bones involved and the object.

The problem I'm facing currently is that the hit and end overlap events aren't firing reliably (even with sub-stepping and CCD enabled), I'm guessing because the finger bones are too small.

The interaction engine looks really neat. Is there any chance we can copy some of it in ue4?