ExtendRealityLtd / VRTK

An example of how to use the Tilia packages to create great content with VRTK v4.
https://www.vrtk.io/
MIT License
3.69k stars 993 forks source link

Rotational Transform Drive tries to snap to maximum values when in motion. #2064

Closed rynshar closed 5 years ago

rynshar commented 5 years ago

Environment

VRTK 4 from GitHub Unity 2019.2.2f1 Any Hardware, including the Simulated Camera Rig Currently using Oculus Quest, and have the Oculus SDK from the Unity Store for both desktop and Android. I also have the OpenVR sdk, but it is not in use. I am not using any of the optional pipelines, just base Unity.

Steps to reproduce

Create a new project/scene

Create a platform/cube place character camera rig/aliases on platform as child (in my case specifically, I have used a copy of the player rig as set up in the farm test scene, and the effect is consistent when playing in editor with the simulated rig, or with the Oculus Quest, which is working otherwise) place a rotational drive prefab on the platform as a child

after pressing play/building, the player should be able to rotate/interact with the drive as normal.

Using a custom script, apply motion to the platform in the same direction as the rotational drive axis. This motion can be applied in any way - to a rigidbody with force, with transform.translate, or by manually adjusting the transform.position.

Expected behavior

The rotational drive should continue working and interact as it does when static.

Current behavior

The wheel, when grabbed, attempts to snap to both the Follow point, and to it's maximum rotational values as described by the RotationalDriveFacade. When ungrabbed, it moves to the maximum value of the rotational drive with speed proportional to the current speed of the platform. The wheel will not move at all if it has not been interacted with, as expected.

Video of the issue: https://www.youtube.com/watch?v=6BQdFinVvuI&feature=youtu.be

Additional Notes

Using a StackTrace, it seems that this is caused by conflicting instances of RotationalDrive.Process. It also appears that the issue remains consistent when you keep the rotational drive outside of the platform hierarchy, and have it follow the platform with a FollowAction, or with a constraint.

thestonefox commented 5 years ago

I believe the issue is actually caused by TransformPositionDifferenceRotation

and the CalculateAngularVelocity method as it is using the source (interactor) and target (rotationaldrive) positions in world space.

It basically checks the source's current position against the previous source position (in world space)

but if you've moved the source by moving it's parent (e.g. moving the tracked alias) then the calculation is now incorrect.

thestonefox commented 5 years ago

potential fix for this is to be able to provide a RelativeTo parameter to the component that basically just removes that from the position calculation:

e.g.

public Transform RelativeTo;
protected virtual Vector3 CalculateAngularVelocity(GameObject source, GameObject target)
{
    Vector3 sourcePosition = source.transform.position - RelativeTo.transform.position;
    Vector3 targetPosition = target.transform.position - RelativeTo.transform.position;

Then you would specify the overall parent container as the relative to component.

rynshar commented 5 years ago

Thank you for the update! I have tried implementing your code around line 78 of TransformPositionDifferenceRotation.cs, but I am not sure of how I should set the RelativeTo now that the component exists, since it seems like this code is protected. Where would you recommend I set the value of the RelativeTo from? The zinnia nested scripts confuse me somewhat. Thanks!

thestonefox commented 5 years ago

I'm not suggesting you add the code to your install of vrtk. I'm just putting the notice here so I remember what the fix is when I get round to it ;)

thestonefox commented 5 years ago

There is a new Ancestor property now you can set as the parent which will prevent this issue.