Skip to content

Commit

Permalink
feat(Interaction): rotate transform grab mechanic
Browse files Browse the repository at this point in the history
The Rotate Transform Grab Mechanic allows an Interactable Object to be
rotated around a specified local transform axis between given angle
limits. It doesn't use any physics to rotate the object and simply
changes the local rotation based on the position of the controller in
relation to the circular motion around the object.

A couple of reusable methods have been extracted into the SharedMethods
script such as the NormalizeValue method which takes a given value and
the range and then normalizes the value between `0f` and `1f`. The
DividerToMultiplier method takes a value that is to be used as a
divider and converts it in to the value to use for the multiplication
operation which would result in the same answer. This is helpful as
it prevents division by zero errors.

The relevant scripts have been updated to utilise these new methods.
  • Loading branch information
thestonefox committed Oct 3, 2017
1 parent d4901ba commit a24ae46
Show file tree
Hide file tree
Showing 9 changed files with 736 additions and 22 deletions.
166 changes: 165 additions & 1 deletion Assets/VRTK/Documentation/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -5138,6 +5138,7 @@ This directory contains scripts that are used to provide different mechanics to
* [Climbable Grab Attach](#climbable-grab-attach-vrtk_climbablegrabattach)
* [Control Animation Grab Attach](#control-animation-grab-attach-vrtk_controlanimationgrabattach)
* [Move Transform Grab Attach](#move-transform-grab-attach-vrtk_movetransformgrabattach)
* [Rotate Transform Grab Attach](#rotate-transform-grab-attach-vrtk_rotatetransformgrabattach)

---

Expand Down Expand Up @@ -5748,7 +5749,7 @@ Moves the Transform of the Interactable Object towards the interacting object wi

### Class Variables

* `public Vector3 localOrigin` - The default local position of the Interactable Object in world space.
* `public Vector3 localOrigin` - The default local position of the Interactable Object.

### Class Events

Expand Down Expand Up @@ -5899,6 +5900,144 @@ The GetWorldLimits method returns an array of minimum and maximum axis limits fo

---

## Rotate Transform Grab Attach (VRTK_RotateTransformGrabAttach)
> extends [VRTK_BaseGrabAttach](#base-grab-attach-vrtk_basegrabattach)

### Overview

Rotates the Transform of the Interactable Object around a specified transform local axis within the given limits.

> To allow unrestricted movement, set the angle limits minimum to `-infinity` and the angle limits maximum to `infinity`.

**Script Usage:**
* Place the `VRTK_RotateTransformGrabAttach` script on either:
* The GameObject of the Interactable Object to detect interactions on.
* Any other scene GameObject and then link that GameObject to the Interactable Objects `Grab Attach Mechanic Script` parameter to denote use of the grab mechanic.

### Inspector Parameters

* **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 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.
* **Angle Limits:** The negative `(x)` and positive `(y)` limits the axis can be rotated to.
* **Min Max Threshold:** The threshold the rotation value needs to be within to register a min or max rotation value.
* **Min Max Normalized Threshold:** The threshold the normalized rotation value needs to be within to register a min or max normalized rotation value.

### Class Variables

* `public enum RotationAxis` - The local axis for rotation.
* `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 Quaternion originRotation` - The default local rotation of the Interactable Object.

### Class Events

* `AngleChanged` - Emitted when the angle changes.
* `MinAngleReached` - Emitted when the angle reaches the minimum angle.
* `MinAngleExited` - Emitted when the angle exits the minimum angle state.
* `MaxAngleReached` - Emitted when the angle reaches the maximum angle.
* `MaxAngleExited` - Emitted when the angle exits the maximum angle state.

### Unity Events

Adding the `VRTK_RotateTransformGrabAttach_UnityEvents` component to `VRTK_RotateTransformGrabAttach` object allows access to `UnityEvents` that will react identically to the Class Events.

* All C# delegate events are mapped to a Unity Event with the `On` prefix. e.g. `MyEvent` -> `OnMyEvent`.

### Event Payload

* `GameObject interactingObject` - The GameObject that is performing the interaction (e.g. a controller).
* `float currentAngle` - The current angle the Interactable Object is rotated to.
* `float normalizedAngle` - The normalized angle (between `0f` and `1f`) the Interactable Object is rotated to.
* `Vector3 rotationSpeed` - The speed in which the rotation is occuring.

### Class Methods

#### StartGrab/3

> `public override bool StartGrab(GameObject grabbingObject, GameObject givenGrabbedObject, Rigidbody givenControllerAttachPoint)`

* Parameters
* `GameObject grabbingObject` - The GameObject that is doing the grabbing.
* `GameObject givenGrabbedObject` - The GameObject that is being grabbed.
* `Rigidbody givenControllerAttachPoint` - The point on the grabbing object that the grabbed object should be attached to after grab occurs.
* Returns
* `bool` - Returns `true` if the grab is successful, `false` if the grab is unsuccessful.

The StartGrab method sets up the grab attach mechanic as soon as an Interactable Object is grabbed.

#### StopGrab/1

> `public override void StopGrab(bool applyGrabbingObjectVelocity)`

* Parameters
* `bool applyGrabbingObjectVelocity` - If `true` will apply the current velocity of the grabbing object to the grabbed object on release.
* Returns
* _none_

The StopGrab method ends the grab of the current Interactable Object and cleans up the state.

#### ProcessUpdate/0

> `public override void ProcessUpdate()`

* Parameters
* _none_
* Returns
* _none_

The ProcessUpdate method is run in every Update method on the Interactable Object.

#### ResetRotation/0

> `public virtual void ResetRotation()`

* Parameters
* _none_
* Returns
* _none_

The ResetRotation method will rotate the transform back to the origin rotation.

#### GetAngle/0

> `public virtual float GetAngle()`

* Parameters
* _none_
* Returns
* `float` - The current rotated angle.

The GetAngle method returns the current angle the Interactable Object is rotated to.

#### GetNormalizedAngle/0

> `public virtual float GetNormalizedAngle()`

* Parameters
* _none_
* Returns
* `float` - The normalized rotated angle. Will return `0f` if either limit is set to `infinity`.

The GetNormalizedAngle returns the normalized current angle between the minimum and maximum angle limits.

#### GetRotationSpeed/0

> `public virtual Vector3 GetRotationSpeed()`

* Parameters
* _none_
* Returns
* `Vector3` - A Vector3 containing the speed each axis is rotating in.

The GetRotationSpeed returns the current speed in which the Interactable Object is rotating.

---

# Secondary Controller Grab Actions (VRTK/Source/Scripts/Interactions/SecondaryControllerGrabActions)

This directory contains scripts that are used to provide different actions when a secondary controller grabs a grabbed object.
Expand Down Expand Up @@ -8336,6 +8475,31 @@ The VectorHeading method calculates the current heading of the target position i

The VectorDirection method calculates the direction the target position is in relation to the origin position.

#### DividerToMultiplier/1

> `public static float DividerToMultiplier(float value)`

* Parameters
* `float value` - The number to convert into the multplier value.
* Returns
* `float` - The calculated number that can replace the divider number in a multiplication sum.

The DividerToMultiplier method takes a number to be used in a division and converts it to be used for multiplication. (e.g. 2 / 2 becomes 2 * 0.5)

#### NormalizeValue/4

> `public static float NormalizeValue(float value, float minValue, float maxValue, float threshold = 0f)`

* Parameters
* `float value` - The actual value to normalize.
* `float minValue` - The minimum value the actual value can be.
* `float maxValue` - The maximum value the actual value can be.
* `float threshold` - The threshold to force to the minimum or maximum value if the normalized value is within the threhold limits.
* Returns
* `float` -

The NormalizeValue method takes a given value between a specified range and returns the normalized value between 0f and 1f.

#### GetTypeUnknownAssembly/1

> `public static Type GetTypeUnknownAssembly(string typeName)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ public class VRTK_MoveTransformGrabAttach : VRTK_BaseGrabAttach
[Tooltip("The threshold the position value needs to be within to register a min or max position value.")]
public float minMaxThreshold = 0.01f;
[Tooltip("The threshold the normalized position value needs to be within to register a min or max normalized position value.")]
[Range(0f, 0.99f)]
public float minMaxNormalizedThreshold = 0.01f;

/// <summary>
/// The default local position of the Interactable Object in world space.
/// The default local position of the Interactable Object.
/// </summary>
[HideInInspector]
public Vector3 localOrigin;
Expand Down Expand Up @@ -430,18 +431,11 @@ protected virtual void ClampPosition()

protected virtual Vector3 NormalizePosition(Vector3 givenHeading)
{
return new Vector3(NormalizeRange(givenHeading.x, xAxisLimits.x, xAxisLimits.y), NormalizeRange(givenHeading.y, yAxisLimits.x, yAxisLimits.y), NormalizeRange(givenHeading.z, zAxisLimits.x, zAxisLimits.y));
}

protected virtual float NormalizeRange(float currentValue, float rangeMin, float rangeMax)
{
float normalizedMax = rangeMax - rangeMin;
float normalizedValue = normalizedMax - (rangeMax - currentValue);
float multplier = (normalizedMax != 0 ? (1f / normalizedMax) : 1f);
float result = normalizedValue * multplier;
result = (result < minMaxNormalizedThreshold ? 0f : result);
result = (result > 1f - minMaxNormalizedThreshold ? 1f : result);
return Mathf.Clamp(result, 0f, 1f);
return new Vector3(
VRTK_SharedMethods.NormalizeValue(givenHeading.x, xAxisLimits.x, xAxisLimits.y, minMaxNormalizedThreshold),
VRTK_SharedMethods.NormalizeValue(givenHeading.y, yAxisLimits.x, yAxisLimits.y, minMaxNormalizedThreshold),
VRTK_SharedMethods.NormalizeValue(givenHeading.z, zAxisLimits.x, zAxisLimits.y, minMaxNormalizedThreshold)
);
}

protected virtual void CancelResetPosition()
Expand Down
Loading

0 comments on commit a24ae46

Please sign in to comment.