Skip to content

Commit

Permalink
feat(Interaction): allow different rotation actions for rotate grab
Browse files Browse the repository at this point in the history
The Rotate Transform Grab Mechanic now has a new rotation action option
which allows the object to be rotated based on not only the angle in
difference between the origin of the object and the controller current
grab position but can also be based on the rotation of the controller
through one of it's axes (roll, pitch, yaw).

This can help with simulating other mechanics such as turning a screw
by swiveling the controller in the hand instead of grabbing and pulling
the object in the direction to move it.
  • Loading branch information
thestonefox committed Oct 5, 2017
1 parent 797b8fe commit 438af0e
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Assets/VRTK/Documentation/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -5945,6 +5945,7 @@ Rotates the Transform of the Interactable Object around a specified transform lo
* **Detach Distance:** The maximum distance the grabbing object is away from the Interactable Object before it is automatically dropped.
* **Origin Deadzone:** The distance between grabbing object and the centre of Interactable Object that is considered to be non grabbable. If the grabbing object is within the `Origin Deadzone` distance then it will be automatically ungrabbed.
* **Rotate Around:** The local axis in which to rotate the object around.
* **Rotation Action:** Determines how the rotation of the object is calculated based on the action of the grabbing object.
* **Rotation Friction:** The amount of friction to apply when rotating, simulates a tougher rotation.
* **Release Deceleration Damper:** The damper in which to slow the Interactable Object's rotation down when released to simulate continued momentum. The higher the number, the faster the Interactable Object will come to a complete stop on release.
* **Reset To Orign On Release Speed:** The speed in which the Interactable Object returns to it's origin rotation when released. If the `Reset To Orign On Release Speed` is `0f` then the rotation will not be reset.
Expand All @@ -5958,6 +5959,11 @@ Rotates the Transform of the Interactable Object around a specified transform lo
* `xAxis` - The local X Axis of the transform.
* `yAxis` - The local Y Axis of the transform.
* `zAxis` - The local Z Axis of the transform.
* `public enum RotationType` - The way in which rotation from the grabbing object is applied.
* `FollowAttachPoint` - The angle between the Interactable Object origin and the grabbing object attach point.
* `FollowLongitudinalAxis` - The angular velocity across the grabbing object's longitudinal axis (the roll axis).
* `FollowLateralAxis` - The angular velocity across the grabbing object's lateral axis (the pitch axis).
* `FollowPerpendicularAxis` - The angular velocity across the grabbing object's perpendicular axis (the yaw axis).
* `public Quaternion originRotation` - The default local rotation of the Interactable Object.

### Class Events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ public enum RotationAxis
zAxis
}

/// <summary>
/// The way in which rotation from the grabbing object is applied.
/// </summary>
public enum RotationType
{
/// <summary>
/// The angle between the Interactable Object origin and the grabbing object attach point.
/// </summary>
FollowAttachPoint,
/// <summary>
/// The angular velocity across the grabbing object's longitudinal axis (the roll axis).
/// </summary>
FollowLongitudinalAxis,
/// <summary>
/// The angular velocity across the grabbing object's lateral axis (the pitch axis).
/// </summary>
FollowLateralAxis,
/// <summary>
/// The angular velocity across the grabbing object's perpendicular axis (the yaw axis).
/// </summary>
FollowPerpendicularAxis
}

[Header("Detach Settings")]

[Tooltip("The maximum distance the grabbing object is away from the Interactable Object before it is automatically dropped.")]
Expand All @@ -70,6 +93,8 @@ public enum RotationAxis

[Tooltip("The local axis in which to rotate the object around.")]
public RotationAxis rotateAround = RotationAxis.xAxis;
[Tooltip("Determines how the rotation of the object is calculated based on the action of the grabbing object.")]
public RotationType rotationAction = RotationType.FollowAttachPoint;
[Tooltip("The amount of friction to apply when rotating, simulates a tougher rotation.")]
[Range(1f, 32f)]
public float rotationFriction = 1f;
Expand Down Expand Up @@ -122,6 +147,7 @@ public enum RotationAxis
protected Coroutine resetRotationRoutine;
protected Coroutine decelerateRotationRoutine;
protected bool[] limitsReached = new bool[2];
protected VRTK_ControllerReference grabbingObjectReference;

public virtual void OnAngleChanged(RotateTransformGrabAttachEventArgs e)
{
Expand Down Expand Up @@ -179,6 +205,7 @@ public override bool StartGrab(GameObject grabbingObject, GameObject givenGrabbe
grabbedObjectBounds = VRTK_SharedMethods.GetBounds(givenGrabbedObject.transform);
limitsReached = new bool[2];
CheckAngleLimits();
grabbingObjectReference = VRTK_ControllerReference.GetControllerReference(grabbingObject);
return grabResult;
}

Expand Down Expand Up @@ -210,7 +237,7 @@ public override void ProcessUpdate()
float distance = Vector3.Distance(transform.position, controllerAttachPoint.transform.position);
if (StillTouching() && distance >= originDeadzone)
{
Vector3 newRotation = CalculateAngle(transform.position, previousAttachPointPosition, controllerAttachPoint.transform.position);
Vector3 newRotation = GetNewRotation();
previousAttachPointPosition = controllerAttachPoint.transform.position;
currentRotationSpeed = newRotation;
UpdateRotation(newRotation, true, true);
Expand Down Expand Up @@ -292,6 +319,38 @@ protected override void Initialise()
currentRotation = Vector3.zero;
}

protected virtual Vector3 GetNewRotation()
{
Vector3 grabbingObjectAngularVelocity = Vector3.zero;
if (VRTK_ControllerReference.IsValid(grabbingObjectReference))
{
grabbingObjectAngularVelocity = VRTK_DeviceFinder.GetControllerAngularVelocity(grabbingObjectReference) * VRTK_SharedMethods.DividerToMultiplier(rotationFriction);
}

switch (rotationAction)
{
case RotationType.FollowAttachPoint:
return CalculateAngle(transform.position, previousAttachPointPosition, controllerAttachPoint.transform.position);
case RotationType.FollowLongitudinalAxis:
return BuildFollowAxisVector(grabbingObjectAngularVelocity.x);
case RotationType.FollowPerpendicularAxis:
return BuildFollowAxisVector(grabbingObjectAngularVelocity.y);
case RotationType.FollowLateralAxis:
return BuildFollowAxisVector(grabbingObjectAngularVelocity.z);
}

return Vector3.zero;
}

protected virtual Vector3 BuildFollowAxisVector(float givenAngle)
{
float xAngle = (rotateAround == RotationAxis.xAxis ? givenAngle : 0f);
float yAngle = (rotateAround == RotationAxis.yAxis ? givenAngle : 0f);
float zAngle = (rotateAround == RotationAxis.zAxis ? givenAngle : 0f);

return new Vector3(xAngle, yAngle, zAngle);
}

protected virtual Vector3 CalculateAngle(Vector3 originPoint, Vector3 originalGrabPoint, Vector3 currentGrabPoint)
{
float xRotated = (rotateAround == RotationAxis.xAxis ? CalculateAngle(originPoint, originalGrabPoint, currentGrabPoint, transform.right) : 0f);
Expand Down

0 comments on commit 438af0e

Please sign in to comment.