Search Unity

Oculus hand momentum/inertia

Discussion in 'AR/VR (XR) Discussion' started by y0kkaboom, Mar 7, 2019.

  1. y0kkaboom

    y0kkaboom

    Joined:
    Oct 18, 2018
    Posts:
    18
    Okay so I'm currently working on a Vr project and I used Oculus Sample FrameWork in order to get the hands working.
    So I didn't write that part:
    When my character moves, the hands have inertia, like they are a bit late with any of the movement (just when I walk, when I move my hands alone no problem). And to be honest it's quite annoying.

    I found That:

    Code (CSharp):
    1. // Hands follow the touch anchors by calling MovePosition each frame to reach the anchor.
    2. // This is done instead of parenting to achieve workable physics. If you don't require physics on
    3. // your hands or held objects, you may wish to switch to parenting.
    4. void OnUpdatedAnchors()
    5. {
    6. Vector3 handPos = OVRInput.GetLocalControllerPosition(m_controller);
    7. Quaternion handRot = OVRInput.GetLocalControllerRotation(m_controller);
    8. Vector3 destPos = m_parentTransform.TransformPoint(m_anchorOffsetPosition + handPos);
    9. Quaternion destRot = m_parentTransform.rotation * handRot * m_anchorOffsetRotation;
    10. GetComponent<Rigidbody>().MovePosition(destPos);
    11. GetComponent<Rigidbody>().MoveRotation(destRot);

    12. if (!m_parentHeldObject)
    13. {
    14. MoveGrabbedObject(destPos, destRot);
    15. }
    16. m_lastPos = transform.position;
    17. m_lastRot = transform.rotation;

    18. float prevFlex = m_prevFlex;
    19. // Update values from inputs
    20. m_prevFlex = OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, m_controller);

    21. CheckForGrabOrRelease(prevFlex);
    22. }
    I'm quite sure the problem comes from here...
    But to be honest I have no idea how to switch to parenting because if I do it via the editor, My hands are just elsewhere, and not even moving accordingly but far...
    If you Have any ideas I would be super glade ^^
    Thank you very much!
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    No, I don't believe the above code is the problem.

    More likely it's some sort of smoothing that happens when you move. How exactly are you doing character movement?
     
  3. y0kkaboom

    y0kkaboom

    Joined:
    Oct 18, 2018
    Posts:
    18
    I have A character Controller in order to move my "cameras" and my hands anchor.
    However My "physical" hands are not parented to that, they are the children of an other gameObject... To be honest I did'nt make that part.
    I fond this part of code in the script attached to the "physical" hands and it seems like it is what actually manage the "physical" hands position. It's called each frame And I do believe that my hand could be a frame late on the moving of my character.
     
  4. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    302
    Code (CSharp):
    1. GetComponent<Rigidbody>().MovePosition(destPos);
    2. GetComponent<Rigidbody>().MoveRotation(destRot);
    MovePosition and MoveRotation use interpolation:
    https://docs.unity3d.com/ScriptReference/Rigidbody.MovePosition.html

    You could try and set the pos/rot immediately per frame and see if it's less laggy:

    Code (CSharp):
    1. GetComponent<Rigidbody>().position = destPos;
    2. GetComponent<Rigidbody>().rotation = destRot;
     
  5. y0kkaboom

    y0kkaboom

    Joined:
    Oct 18, 2018
    Posts:
    18
    I'll try! Thanks you very much @SiliconDroid
    However if it happens to "unsmooth" the movement when I just move my hands, for instance to grab an object, Would it be possible to lower the time to travel from point A to B with Move position? So when I walk it's less laggy? I'll try to and keep you posted!

    Thanks guys
     
  6. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    302
    I don't know the quality of the data for the hand movement, I've had no experience with VR other than 3DOF headsets and 3DOF controllers, but the data they give is nicely preconditioned, no further smoothing required. Do keep us posted I'm interested in your result...
     
  7. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    MovePosition and MoveRotation do _instant_ interpolation. All this means is that the physics engine has a chance to see whether the proposed movement/rotation collides with anything. It doesn't mean that it applies any smoothing, or otherwise introduces any lag (assuming your physics engine is running at at least frame rates).

    I still believe the problem is in the character controller. It's probably doing some Lerp abuse or similar, and this is causing the apparent lag in the hands.
     
    SiliconDroid likes this.
  8. y0kkaboom

    y0kkaboom

    Joined:
    Oct 18, 2018
    Posts:
    18
    Okay Guys, so I tried
    Code (CSharp):
    1. GetComponent<Rigidbody>().position = destPos;
    2. GetComponent<Rigidbody>().rotation = destRot;
    Well it did'nt change ANYTHING same movement, same lag...
    I think parenting could maybe do something? The positioning would'nt be dependant on FixedUpdate()
    But to be honest I really don't know how to do that in that case... When I do iy via the editor it breaks everything and via script I'm Kind of lost because of all the variables that are necessary or not for so much different things?
    Could you help me? Please?

    Thanks Guys for your help @JoeStrout and @SiliconDroid
     
  9. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    No, parenting won't help. The current code moves the controllers instantly to the proper position relative to the character controller.

    I still suspect the problem is in the character controller code. But there's nothing more I can do from here to help you pin that down.
     
  10. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    302
    In OVRGrabber.cs, could try changing:

    Code (CSharp):
    1.     void FixedUpdate()
    2.     {
    3.         if (operatingWithoutOVRCameraRig)
    4.             OnUpdatedAnchors();
    5.     }
    to:

    Code (CSharp):
    1.     void LateUpdate()
    2.     {
    3.         if (operatingWithoutOVRCameraRig)
    4.             OnUpdatedAnchors();
    5.     }
     
  11. y0kkaboom

    y0kkaboom

    Joined:
    Oct 18, 2018
    Posts:
    18
    Thanks Guys!
    @SiliconDroid
    Well I tried, Still the same lag, I'm trying to fix that to but, nothing works. T-T
    @JoeStrout
    May be you're right...


    I think That the way my hands are just makes lag.. I dunno! I'll keep you posted if I find something.
    I just saw that, the faster I go, the more the hands stay behind! Maybe Something to understand from that! ^^ Still thinking

    Thanks youuuu <3
     
  12. StayTalm_Unity

    StayTalm_Unity

    Unity Technologies

    Joined:
    May 3, 2017
    Posts:
    182
    It sounds like you have a hierarchy like this:
    VisualCharacter
    -->Camera (Is this directly mapped, or using a second object like the hands)
    -->LeftHandVisual (A visual mapped to the position of RealLeftHand)
    -->RightHandVisual (A visual mapped to the position of RealRightHand)
    OculusCharacter
    -->RealLeftHand (Actual Oculus Tracking data based, using Rigidbody.MovePosition/Rotation)
    -->RealRightHand (Actual Oculus Tracking data based, using Rigidbody.MovePosition/Rotation)

    Am I correct?
     
  13. y0kkaboom

    y0kkaboom

    Joined:
    Oct 18, 2018
    Posts:
    18
    @StayTalm_Unity Here's my hierarchy: Hierrarchy.JPG
    I have 2 groups independent from one another: The yellow one and the other.
    In the first one I have: My three cameras,(a menu but we don't care), and the transform of my real hands : the tracking data from the sensors on my desk IRL.

    Then I have, in Dynamic, my physical and visual hands (those should be mapped to my tracking data but not following those really well) in the game, they have the mesh renderer and many different colliders for different purpose I guess
     
  14. StayTalm_Unity

    StayTalm_Unity

    Unity Technologies

    Joined:
    May 3, 2017
    Posts:
    182
    So, it's the dynamic hands that feel like they are lagging behind?

    Both Rigidbody.MovePosition and Rigidbody.Position are going to move your controller a frame late.

    This is because OnAnchorsUpdated will be called at least during Monobehaviour::Update, and Application.OnBeforeRender. The former being good for doing gameplay code, and the latter to line up the visuals so they are as close to render time as possible. However physics steps are run during https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html which is before both of those calls in the update loop. And so if you set the position of the object in OnAnchorsUdpated (presumably Application.OnBeforeRender), you will render a frame, run the physics step and move the hands to the position you wanted on the last frame, get the current frames updated anchors, render a frame, and then move the hands again during the physics step.

    Does it seem like 1 frame delay is about right? Or is it even slower. Physics with XR is complicated, since physics is often operating from past frames and running at the beginning of the frame, and XR rendering, in order to get the hands as close to accurate as possible is trying to get it's tracking state as late in the frame as possible.

    Try putting a visual on the actual anchors themselves and seeing if those are moving more accurately. I'm not really familiar with the Oculus framework so I'm making quite a few assumptions that they did things like we did.
     
  15. y0kkaboom

    y0kkaboom

    Joined:
    Oct 18, 2018
    Posts:
    18
    Hello @StayTalm_Unity
    Yes the dynamic hands feels laggy with what could happen to be a 1 frame delay.
    When I put the visual like you said the anchors are just lost somewhere in my scene.. I don't understand nothing anymore to be honest...
    I'll just keep twiking some stuff and we we'll see

    Thanks mate for your help!
     
  16. StayTalm_Unity

    StayTalm_Unity

    Unity Technologies

    Joined:
    May 3, 2017
    Posts:
    182
    Things that can cause your hands to be 'elsewhere':
    1) Do you have scale modified to not be 1 in your hierarchy? If you scale out the parent of an anchor, the movement of that anchor will be scaled (e.g. if you have a scale of 2, then an anchor as a child, then your visual, the visual will move 2m for every 1m in the real world.
    2) setting .parent of a transform preserves the global position. So if you parent the hands from the dynamic to the OVR object, and the 2 parents are 2m apart, the local position of the hands will shift by 2m, meaning they will track with an offset. This also applies if you drag and drop in the editor hierarchy view, so double check the local positions.

    Best of luck!
     
  17. y0kkaboom

    y0kkaboom

    Joined:
    Oct 18, 2018
    Posts:
    18
    Thanks mate!
    My hands are not elsewhere, they are just laggy. No scaling, but I will definitely try to check the local positions if I do something with parenting.

    Thanks you @StayTalm_Unity