en:vci:script:reference:quaternion

Quaternion

Quaternion is a class with three values: X, Y, Z and W.
It is a class to describe rotation. However, we do not specify Quaternion directly to change the values directly.
In most cases, we use methods listed below to change the values.

List of methods

For the latest list of the methods, refer to “types.lua” file in “EmbeddedScriptWorkspace” folder.
To shorten the description, Vector3 type is abbreviated as Vec and number type is abbreviated as num.
Arguments are shown in () and return values are shown after semicolons :.

Method name Description
_new fun(x: num, y: num, z: num, w: num): Quaternion Initialization
FromToRotation fun(fromDirection: Vec3, toDirection: Vec3): Quaternion Rotate from the fromDirection to the toDirection.
Inverse fun(rotation: Quaternion): Quaternion Create a Quaternion that is the opposite of the rotation.
Slerp fun(a: Quaternion, b: Quaternion, t: num): Quaternion Spherically interpolates between a and b by the coefficient t. The range of t is [0, 1].
SlerpUnclamped fun(a: Quaternion, b: Quaternion, t: num): Quaternion Same as Slerp, but doesn't restrict the t range to [0, 1]. Used for things like springs.
Lerp fun(a: Quaternion, b: Quaternion, t: num): Quaternion Linearly interpolates between a and b by the coefficient t. The range of t is [0, 1].
LerpUnclamped fun(a: Quaternion, b: Quaternion, t: num): Quaternion Same as Lerp, but doesn't restrict the t range to [0, 1]. Used for things like springs.
AngleAxis fun(angle: num, axis: Vec3): Quaternion Create a rotation of angle degrees, using vector of the axis as the center
LookRotation fun(forward: Vec3, upwards: Vec3): Quaternion Turn towards forward direction and upwards direction.
Dot fun(a: Quaternion, b: Quaternion): num Returns the inner product of two rotations: a and b.
Angle fun(a: Quaternion, b: Quaternion): num Returns the angle of two rotations: a and b.
Euler fun(x: num, y: num, z: num): Quaternion Create a Quaternion by specifying Euler angle
ToAngleAxis fun(angle: usertype, axis: usertype) Convert the rotation to a value of angle against the axis (AngleAxis).
RotateTowards fun(from: Quaternion, to: Quaternion, maxDegreesDelta: num): Quaternion Interpolate the largest rotation between the two Quaternions.
Normalize fun(q: Quaternion): Quaternion
GetHashCode fun(): num Not to be used.
ToString fun(): string
ToEuler fun(): Vec3
ToEulerAngles fun(): Vec3
identity Quaternion Create a basic Quaternion of (0.0, 0.0, 0.0, 1.0).
eulerAngles Vec3 Return rotation in value of Euler angle.
normalized Quaternion
x num In most cases, do not change Quaternion directly.
y num In most cases, do not change Quaternion directly.
z num In most cases, do not change Quaternion directly.
w num In most cases, do not change Quaternion directly.
kEpsilon num

About initialization

Example

main.lua
rotate = Quaternion.identity
print(rotate)

The result

(0.0, 0.0, 0.0, 1.0)

Basically, use Quaternion.identity to initialize a Quaternion.
You can also use __new() to declare, but it is very rare to handle a Quaternion directly. Also, in the example above, you can access each element directly like rotate.x = 1, but it is recommended to use methods provided to manipulate a quaternion.

Example

main.lua
-- The name of the SubItem game object and the argument string in GetTransform("") must match.
Subitem = vci.assets.GetTransform("Subitem")
function onUngrab()
    local rotate = Quaternion.identity
    local velocity = Vector3.zero
    Subitem.SetLocalRotation(rotate)
    Subitem.SetVelocity(velocity)
end

The result

(When you release the VCI from the grabbed state, its rotation will be set to the initial state (x = 0, y = 0, z = 0).)

By using SetLocalRotation(), you can set the attitude to the Quaternion created.
When doing so, after setting the attitude, SetVelocity() to 0 to avoid the attitude from being updated by Rigidbody.

Euler()

Euler fun(x: number, y: number, z: number): Quaternion

Example

main.lua
--- The name of the SubItem game object and the argument string in GetTransform("") must match.
Subitem = vci.assets.GetTransform("Subitem")
function onUngrab()
    local rotate = Quaternion.Euler(30, 45, 60)
    local velocity = Vector3.zero
    Subitem.SetLocalRotation(rotate)
    Subitem.SetVelocity(velocity)
end

The result

(When you release the VCI from grabbed state, its rotation will be set to (x = 30, y = 45, z = 60).)

Specify the rotation with Euler angle value (0 ~ 360 degrees) to create Quaternion.
Specification of elements shall be done in order of X, Y and Z.

eulerAngles

eulerAngles Vector3

Example

main.lua
euler = Quaternion.Euler(30, 45, 60)
print(euler)
print(euler.eulerAngles)
print(euler.eulerAngles.x)
print(euler.eulerAngles.y)
print(euler.eulerAngles.z)

The result

(0.4, 0.2, 0.4, 0.8)
(30.0, 45.0, 60.0)
30.0000019073486
45
60.0000038146973

Return a Quaternion value in form of Euler angle value. By specifying individual element after eulerAngles., you can access each element of the angles.

AxisAngle()

AngleAxis fun(angle: number, axis: Vector3): Quaternion

Example

main.lua
-- The name of the SubItem game object and the argument string in GetTransform("") must match.
Subitem = vci.assets.GetTransform("Subitem")
angle = 0
function onUngrab()
    angle = angle + math.pi / 180
    if angle > (2 * math.pi) then
        angle = 0
    end
    print(angle)
 
    local axis = Vector3.up
    local rotate = Quaternion.AxisAngle(axis, angle)
    Subitem.SetLocalRotation(rotate)
 
    local velocity = Vector3.zero
    Subitem.SetVelocity(velocity)
end

The result

(When you release the VCI from grabbed state, the y-axis rotation (Rotation.y) is incremented by 1 degree.)

Specify a direction with Vector3 to use as an axis of rotation and rotate by the value of “angle”.
In the example, axis = Vector3.up creates an axis that goes from down to up, which then is used as the axis of rotation.
The “angle” specifying the degrees of rotation, shall be specified with a value between 0~6.28318530718(2π).
2π divided by 360 is 0.01745329251. So by adding this value to the “angle,” the object will rotate by 1 degree.
To express π in Lua, use math.pi.

LookRotation()

LookRotation fun(forward: Vector3, upwards: Vector3): Quaternion

Example

main.lua
function onUngrab(target)
    local forward = vci.assets.GetTransform(target).GetForward()
    local up = vci.assets.GetTransform(target).GetUp()
    local rotate = Quaternion.LookRotation(forward, up)
    print(rotate)
    print(vci.assets.GetTransform(target).GetRotation())
end

The result

(0.0, -0.3, -0.1, 1.0)
(0.0, -0.3, -0.1, 1.0)
(0.0, 0.9, 0.0, 0.4)
(0.0, 0.9, 0.0, 0.4)

Create a Quaternion using an up vector and a forward vector.
In the example,rotate and vci.assets.GetTransform(target).GetRotation() take the same value.

Lerp()

Lerp fun(a: Quaternion, b: Quaternion, t: number): Quaternion

Example

main.lua
-- The name of the SubItem game object and the argument string in GetTransform("") must match.
Subitem = vci.assets.GetTransform("Subitem")
base = Quaternion.identity
target = Quaternion.Euler(0, 90, 0)
function update()
    local time = math.abs(math.sin((vci.me.FrameCount / 60)))
    local lerp = Quaternion.Lerp(base, target, time)
    Subitem.SetRotation(lerp)
end

The result

(The SubItem slowly oscillates by 90 degrees.)

Creates a Quaternion that interpolates between the base Quaternion and the target Quaternion.
By specifying a value in the range of 0-1, you get a Quaternion that corresponds to the quotient.
By changing it gradually, its attitude slowly changes from one attitude to the another.

Angle()

Angle fun(a: Quaternion, b: Quaternion): number

Example

main.lua
 

The result

 

Description

Dot

Dot fun(a: Quaternion, b: Quaternion): number

Example

main.lua
function onUngrab(target)
    local rotate = vci.assets.GetTransform(target).GetRotation()
    local base = Quaternion.identity
    print(Quaternion.Dot(rotate, base))
end

The result

0.886427819728851
-0.289039075374603
(When you release your hand from VCI, it acquires the inner product of the grabbed item and the base)

Compare two Quaternions and acquires the inner product.
The return value is in the range of -1~1.

Method name

Example

main.lua
 

The result

 

Description

en/vci/script/reference/quaternion.txt · Last modified: 2022/03/06 23:22 by Ramen

Page Tools