Overte C++ Documentation
Quat.h
1 //
2 // Quat.h
3 // libraries/script-engine/src
4 //
5 // Created by Brad Hefta-Gaub on 1/29/14.
6 // Copyright 2014 High Fidelity, Inc.
7 // Copyright 2023 Overte e.V.
8 //
9 // Scriptable Quaternion class library.
10 //
11 // Distributed under the Apache License, Version 2.0.
12 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
13 // SPDX-License-Identifier: Apache-2.0
14 //
15 
18 
19 #ifndef hifi_Quat_h
20 #define hifi_Quat_h
21 
22 #include <glm/gtc/quaternion.hpp>
23 
24 #include <QObject>
25 #include <QString>
26 
27 #include <GLMHelpers.h>
28 
29 #include "Scriptable.h"
30 
31 /*@jsdoc
32  * A quaternion value. See also the {@link Quat(0)|Quat} API.
33  * @typedef {object} Quat
34  * @property {number} x - Imaginary component i.
35  * @property {number} y - Imaginary component j.
36  * @property {number} z - Imaginary component k.
37  * @property {number} w - Real component.
38  */
39 
40 /*@jsdoc
41  * The <code>Quat</code> API provides facilities for generating and manipulating quaternions.
42  * Quaternions should be used in preference to Euler angles wherever possible because quaternions don't suffer from the problem
43  * of gimbal lock.
44  *
45  * @namespace Quat
46  * @variation 0
47  *
48  * @hifi-interface
49  * @hifi-client-entity
50  * @hifi-avatar
51  * @hifi-server-entity
52  * @hifi-assignment-client
53  *
54  * @property {Quat} IDENTITY - <code>{ x: 0, y: 0, z: 0, w: 1 }</code> : The identity rotation, i.e., no rotation.
55  * <em>Read-only.</em>
56  * @example <caption>Print the <code>IDENTITY</code> value.</caption>
57  * print(JSON.stringify(Quat.IDENTITY)); // { x: 0, y: 0, z: 0, w: 1 }
58  * print(JSON.stringify(Quat.safeEulerAngles(Quat.IDENTITY))); // { x: 0, y: 0, z: 0 }
59  */
61 class Quat : public QObject, protected Scriptable {
62  Q_OBJECT
63  Q_PROPERTY(glm::quat IDENTITY READ IDENTITY CONSTANT)
64 
65 public slots:
66 
67  /*@jsdoc
68  * Multiplies two quaternions.
69  * @function Quat(0).multiply
70  * @param {Quat} q1 - The first quaternion.
71  * @param {Quat} q2 - The second quaternion.
72  * @returns {Quat} <code>q1</code> multiplied with <code>q2</code>.
73  * @example <caption>Calculate the orientation of your avatar's right hand in world coordinates.</caption>
74  * var handController = Controller.Standard.RightHand;
75  * var handPose = Controller.getPoseValue(handController);
76  * if (handPose.valid) {
77  * var handOrientation = Quat.multiply(MyAvatar.orientation, handPose.rotation);
78  * }
79  */
80  glm::quat multiply(const glm::quat& q1, const glm::quat& q2);
81 
82  /*@jsdoc
83  * Normalizes a quaternion.
84  * @function Quat(0).normalize
85  * @param {Quat} q - The quaternion to normalize.
86  * @returns {Quat} <code>q</code> normalized to have unit length.
87  * @example <caption>Normalize a repeated delta rotation so that maths rounding errors don't accumulate.</caption>
88  * var deltaRotation = Quat.fromPitchYawRollDegrees(0, 0.1, 0);
89  * var currentRotation = Quat.ZERO;
90  * while (Quat.safeEulerAngles(currentRotation).y < 180) {
91  * currentRotation = Quat.multiply(deltaRotation, currentRotation);
92  * currentRotation = Quat.normalize(currentRotation);
93  * // Use currentRotatation for something.
94  * }
95  */
96  glm::quat normalize(const glm::quat& q);
97 
98  /*@jsdoc
99  * Calculates the conjugate of a quaternion. For a unit quaternion, its conjugate is the same as its
100  * {@link Quat(0).inverse|Quat.inverse}.
101  * @function Quat(0).conjugate
102  * @param {Quat} q - The quaternion to conjugate.
103  * @returns {Quat} The conjugate of <code>q</code>.
104  * @example <caption>A unit quaternion multiplied by its conjugate is a zero rotation.</caption>
105  * var quaternion = Quat.fromPitchYawRollDegrees(10, 20, 30);
106  * Quat.print("quaternion", quaternion, true); // dvec3(10.000000, 20.000004, 30.000004)
107  * var conjugate = Quat.conjugate(quaternion);
108  * Quat.print("conjugate", conjugate, true); // dvec3(1.116056, -22.242186, -28.451778)
109  * var identity = Quat.multiply(conjugate, quaternion);
110  * Quat.print("identity", identity, true); // dvec3(0.000000, 0.000000, 0.000000)
111  */
112  glm::quat conjugate(const glm::quat& q);
113 
114  /*@jsdoc
115  * Calculates a camera orientation given an eye position, point of interest, and "up" direction. The camera's negative
116  * z-axis is the forward direction. The result has zero roll about its forward direction with respect to the given "up"
117  * direction.
118  * @function Quat(0).lookAt
119  * @param {Vec3} eye - The eye position.
120  * @param {Vec3} target - The point to look at.
121  * @param {Vec3} up - The "up" direction.
122  * @returns {Quat} A quaternion that orients the negative z-axis to point along the eye-to-target vector and the x-axis to
123  * be the cross product of the eye-to-target and up vectors.
124  * @example <caption>Rotate your view in independent mode to look at the world origin upside down.</caption>
125  * Camera.mode = "independent";
126  * Camera.orientation = Quat.lookAt(Camera.position, Vec3.ZERO, Vec3.UNIT_NEG_Y);
127  */
128  glm::quat lookAt(const glm::vec3& eye, const glm::vec3& center, const glm::vec3& up);
129 
130  /*@jsdoc
131  * Calculates a camera orientation given an eye position and point of interest. The camera's negative z-axis is the forward
132  * direction. The result has zero roll about its forward direction.
133  * @function Quat(0).lookAtSimple
134  * @param {Vec3} eye - The eye position.
135  * @param {Vec3} target - The point to look at.
136  * @returns {Quat} A quaternion that orients the negative z-axis to point along the eye-to-target vector and the x-axis to be
137  * the cross product of the eye-to-target and an "up" vector. The "up" vector is the y-axis unless the eye-to-target
138  * vector is nearly aligned with it (i.e., looking near vertically up or down), in which case the x-axis is used as the
139  * "up" vector.
140  * @example <caption>Rotate your view in independent mode to look at the world origin.</caption>
141  * Camera.mode = "independent";
142  * Camera.orientation = Quat.lookAtSimple(Camera.position, Vec3.ZERO);
143  */
144  glm::quat lookAtSimple(const glm::vec3& eye, const glm::vec3& center);
145 
146  /*@jsdoc
147  * Calculates the shortest rotation from a first vector onto a second.
148  * @function Quat(0).rotationBetween
149  * @param {Vec3} v1 - The first vector.
150  * @param {Vec3} v2 - The second vector.
151  * @returns {Quat} The rotation from <code>v1</code> onto <code>v2</code>.
152  * @example <caption>Apply a change in velocity to an entity and rotate it to face the direction it's travelling.</caption>
153  * var newVelocity = Vec3.sum(entityVelocity, deltaVelocity);
154  * var properties = { velocity: newVelocity };
155  * if (Vec3.length(newVelocity) > 0.001) {
156  * properties.rotation = Quat.rotationBetween(entityVelocity, newVelocity);
157  * }
158  * Entities.editEntity(entityID, properties);
159  * entityVelocity = newVelocity;
160  */
161  glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2);
162 
163  /*@jsdoc
164  * Generates a quaternion from a {@link Vec3} of Euler angles in degrees.
165  * @function Quat(0).fromVec3Degrees
166  * @param {Vec3} vector - A vector of three Euler angles in degrees, the angles being the rotations about the x, y, and z
167  * axes.
168  * @returns {Quat} A quaternion created from the Euler angles in <code>vector</code>.
169  * @example <caption>Zero out pitch and roll from an orientation.</caption>
170  * var eulerAngles = Quat.safeEulerAngles(orientation);
171  * eulerAngles.x = 0;
172  * eulerAngles.z = 0;
173  * var newOrientation = Quat.fromVec3Degrees(eulerAngles);
174  */
175  glm::quat fromVec3Degrees(const glm::vec3& vec3);
176 
177  /*@jsdoc
178  * Generates a quaternion from a {@link Vec3} of Euler angles in radians.
179  * @function Quat(0).fromVec3Radians
180  * @param {Vec3} vector - A vector of three Euler angles in radians, the angles being the rotations about the x, y, and z
181  * axes.
182  * @returns {Quat} A quaternion created using the Euler angles in <code>vector</code>.
183  * @example <caption>Create a rotation of 180 degrees about the y axis.</caption>
184  * var rotation = Quat.fromVec3Radians({ x: 0, y: Math.PI, z: 0 });
185  */
186  glm::quat fromVec3Radians(const glm::vec3& vec3);
187 
188  /*@jsdoc
189  * Generates a quaternion from pitch, yaw, and roll values in degrees.
190  * @function Quat(0).fromPitchYawRollDegrees
191  * @param {number} pitch - The pitch angle in degrees.
192  * @param {number} yaw - The yaw angle in degrees.
193  * @param {number} roll - The roll angle in degrees.
194  * @returns {Quat} A quaternion created using the <code>pitch</code>, <code>yaw</code>, and <code>roll</code> Euler angles.
195  * @example <caption>Create a rotation of 180 degrees about the y axis.</caption>
196  * var rotation = Quat.fromPitchYawRollDegrees(0, 180, 0 );
197  */
198  glm::quat fromPitchYawRollDegrees(float pitch, float yaw, float roll);
199 
200  /*@jsdoc
201  * Generates a quaternion from pitch, yaw, and roll values in radians.
202  * @function Quat(0).fromPitchYawRollRadians
203  * @param {number} pitch - The pitch angle in radians.
204  * @param {number} yaw - The yaw angle in radians.
205  * @param {number} roll - The roll angle in radians.
206  * @returns {Quat} A quaternion created from the <code>pitch</code>, <code>yaw</code>, and <code>roll</code> Euler angles.
207  * @example <caption>Create a rotation of 180 degrees about the y axis.</caption>
208  * var rotation = Quat.fromPitchYawRollRadians(0, Math.PI, 0);
209  */
210  glm::quat fromPitchYawRollRadians(float pitch, float yaw, float roll);
211 
212  /*@jsdoc
213  * Calculates the inverse of a quaternion. For a unit quaternion, its inverse is the same as its
214  * {@link Quat(0).conjugate|Quat.conjugate}.
215  * @function Quat(0).inverse
216  * @param {Quat} q - The quaternion.
217  * @returns {Quat} The inverse of <code>q</code>.
218  * @example <caption>A quaternion multiplied by its inverse is a zero rotation.</caption>
219  * var quaternion = Quat.fromPitchYawRollDegrees(10, 20, 30);
220  * Quat.print("quaternion", quaternion, true); // dvec3(10.000000, 20.000004, 30.000004)
221  * var inverse = Quat.invserse(quaternion);
222  * Quat.print("inverse", inverse, true); // dvec3(1.116056, -22.242186, -28.451778)
223  * var identity = Quat.multiply(inverse, quaternion);
224  * Quat.print("identity", identity, true); // dvec3(0.000000, 0.000000, 0.000000)
225  */
226  glm::quat inverse(const glm::quat& q);
227 
228  /*@jsdoc
229  * Gets the "front" direction that the camera would face if its orientation was set to the quaternion value.
230  * This is a synonym for {@link Quat(0).getForward|Quat.getForward}.
231  * The Overte camera has axes <code>x</code> = right, <code>y</code> = up, <code>-z</code> = forward.
232  * @function Quat(0).getFront
233  * @param {Quat} orientation - A quaternion representing an orientation.
234  * @returns {Vec3} The negative z-axis rotated by <code>orientation</code>.
235  */
236  glm::vec3 getFront(const glm::quat& orientation) { return getForward(orientation); }
237 
238  /*@jsdoc
239  * Gets the "forward" direction that the camera would face if its orientation was set to the quaternion value.
240  * This is a synonym for {@link Quat(0).getFront|Quat.getFront}.
241  * The Overte camera has axes <code>x</code> = right, <code>y</code> = up, <code>-z</code> = forward.
242  * @function Quat(0).getForward
243  * @param {Quat} orientation - A quaternion representing an orientation.
244  * @returns {Vec3} The negative z-axis rotated by <code>orientation</code>.
245  * @example <caption>Demonstrate that the "forward" vector is for the negative z-axis.</caption>
246  * var forward = Quat.getForward(Quat.IDENTITY);
247  * print(JSON.stringify(forward)); // {"x":0,"y":0,"z":-1}
248  */
249  glm::vec3 getForward(const glm::quat& orientation);
250 
251  /*@jsdoc
252  * Gets the "right" direction that the camera would have if its orientation was set to the quaternion value.
253  * The Overte camera has axes <code>x</code> = right, <code>y</code> = up, <code>-z</code> = forward.
254  * @function Quat(0).getRight
255  * @param {Quat} orientation - A quaternion representing an orientation.
256  * @returns {Vec3} The x-axis rotated by <code>orientation</code>.
257  */
258  glm::vec3 getRight(const glm::quat& orientation);
259 
260  /*@jsdoc
261  * Gets the "up" direction that the camera would have if its orientation was set to the quaternion value.
262  * The Overte camera has axes <code>x</code> = right, <code>y</code> = up, <code>-z</code> = forward.
263  * @function Quat(0).getUp
264  * @param {Quat} orientation - A quaternion representing an orientation.
265  * @returns {Vec3} The y-axis rotated by <code>orientation</code>.
266  */
267  glm::vec3 getUp(const glm::quat& orientation);
268 
269  /*@jsdoc
270  * Calculates the Euler angles for the quaternion, in degrees. (The "safe" in the name signifies that the angle results
271  * will not be garbage even when the rotation is particularly difficult to decompose with pitches around +/-90 degrees.)
272  * @function Quat(0).safeEulerAngles
273  * @param {Quat} orientation - A quaternion representing an orientation.
274  * @returns {Vec3} A {@link Vec3} of Euler angles for the <code>orientation</code>, in degrees, the angles being the
275  * rotations about the x, y, and z axes.
276  * @example <caption>Report the camera yaw.</caption>
277  * var eulerAngles = Quat.safeEulerAngles(Camera.orientation);
278  * print("Camera yaw: " + eulerAngles.y);
279  */
280  glm::vec3 safeEulerAngles(const glm::quat& orientation);
281 
282  /*@jsdoc
283  * Generates a quaternion given an angle to rotate through and an axis to rotate about.
284  * @function Quat(0).angleAxis
285  * @param {number} angle - The angle to rotate through, in degrees.
286  * @param {Vec3} axis - The unit axis to rotate about.
287  * @returns {Quat} A quaternion that is a rotation through <code>angle</code> degrees about the <code>axis</code>.
288  * <strong>WARNING:</strong> This value is in degrees whereas the value returned by {@link Quat(0).angle|Quat.angle} is
289  * in radians.
290  * @example <caption>Calculate a rotation of 90 degrees about the direction your camera is looking.</caption>
291  * var rotation = Quat.angleAxis(90, Quat.getForward(Camera.orientation));
292  */
293  glm::quat angleAxis(float angle, const glm::vec3& v);
294 
295  /*@jsdoc
296  * Gets the rotation axis for a quaternion.
297  * @function Quat(0).axis
298  * @param {Quat} q - The quaternion.
299  * @returns {Vec3} The normalized rotation axis for <code>q</code>.
300  * @example <caption>Get the rotation axis of a quaternion.</caption>
301  * var forward = Quat.getForward(Camera.orientation);
302  * var rotation = Quat.angleAxis(90, forward);
303  * var axis = Quat.axis(rotation);
304  * print("Forward: " + JSON.stringify(forward));
305  * print("Axis: " + JSON.stringify(axis)); // Same value as forward.
306  */
307  glm::vec3 axis(const glm::quat& orientation);
308 
309  /*@jsdoc
310  * Gets the rotation angle for a quaternion.
311  * @function Quat(0).angle
312  * @param {Quat} q - The quaternion.
313  * @returns {number} The rotation angle for <code>q</code>, in radians. <strong>WARNING:</strong> This value is in radians
314  * whereas the value used by {@link Quat(0).angleAxis|Quat.angleAxis} is in degrees.
315  * @example <caption>Get the rotation angle of a quaternion.</caption>
316  * var forward = Quat.getForward(Camera.orientation);
317  * var rotation = Quat.angleAxis(90, forward);
318  * var angle = Quat.angle(rotation);
319  * print("Angle: " + angle * 180 / Math.PI); // 90 degrees.
320  */
321  float angle(const glm::quat& orientation);
322 
323  // spherical linear interpolation
324  // alpha: 0.0 to 1.0?
325  /*@jsdoc
326  * Computes a spherical linear interpolation between two rotations, safely handling two rotations that are very similar.
327  * See also, {@link Quat(0).slerp|Quat.slerp}.
328  * @function Quat(0).mix
329  * @param {Quat} q1 - The beginning rotation.
330  * @param {Quat} q2 - The ending rotation.
331  * @param {number} alpha - The mixture coefficient between <code>0.0</code> and <code>1.0</code>. Specifies the proportion
332  * of <code>q2</code>'s value to return in favor of <code>q1</code>'s value. A value of <code>0.0</code> returns
333  * <code>q1</code>'s value; <code>1.0</code> returns <code>q2s</code>'s value.
334  * @returns {Quat} A spherical linear interpolation between rotations <code>q1</code> and <code>q2</code>.
335  * @example <caption>Animate between one rotation and another.</caption>
336  * var dt = amountOfTimeThatHasPassed;
337  * var mixFactor = amountOfTimeThatHasPassed / TIME_TO_COMPLETE;
338  * if (mixFactor > 1) {
339  * mixFactor = 1;
340  * }
341  * var newRotation = Quat.mix(startRotation, endRotation, mixFactor);
342  */
343  glm::quat mix(const glm::quat& q1, const glm::quat& q2, float alpha);
344 
345  /*@jsdoc
346  * Computes a spherical linear interpolation between two rotations, for rotations that are not very similar.
347  * See also, {@link Quat(0).mix|Quat.mix}.
348  * @function Quat(0).slerp
349  * @param {Quat} q1 - The beginning rotation.
350  * @param {Quat} q2 - The ending rotation.
351  * @param {number} alpha - The mixture coefficient between <code>0.0</code> and <code>1.0</code>. Specifies the proportion
352  * of <code>q2</code>'s value to return in favor of <code>q1</code>'s value. A value of <code>0.0</code> returns
353  * <code>q1</code>'s value; <code>1.0</code> returns <code>q2s</code>'s value.
354  * @returns {Quat} A spherical linear interpolation between rotations <code>q1</code> and <code>q2</code>.
355  */
356  glm::quat slerp(const glm::quat& q1, const glm::quat& q2, float alpha);
357 
358  /*@jsdoc
359  * Computes a spherical quadrangle interpolation between two rotations along a path oriented toward two other rotations.
360  * Equivalent to: <code>Quat.slerp(Quat.slerp(q1, q2, alpha), Quat.slerp(s1, s2, alpha), 2 * alpha * (1.0 - alpha))</code>.
361  * @function Quat(0).squad
362  * @param {Quat} q1 - Initial rotation.
363  * @param {Quat} q2 - Final rotation.
364  * @param {Quat} s1 - First control point.
365  * @param {Quat} s2 - Second control point.
366  * @param {number} alpha - The mixture coefficient between <code>0.0</code> and <code>1.0</code>. A value of
367  * <code>0.0</code> returns <code>q1</code>'s value; <code>1.0</code> returns <code>q2s</code>'s value.
368  * @returns {Quat} A spherical quadrangle interpolation between rotations <code>q1</code> and <code>q2</code> using control
369  * points <code>s1</code> and <code>s2</code>.
370  */
371  glm::quat squad(const glm::quat& q1, const glm::quat& q2, const glm::quat& s1, const glm::quat& s2, float h);
372 
373  /*@jsdoc
374  * Calculates the dot product of two quaternions. The closer the quaternions are to each other the more non-zero the value
375  * is (either positive or negative). Identical unit rotations have a dot product of +/-1.
376  * @function Quat(0).dot
377  * @param {Quat} q1 - The first quaternion.
378  * @param {Quat} q2 - The second quaternion.
379  * @returns {number} The dot product of <code>q1</code> and <code>q2</code>.
380  * @example <caption>Testing unit quaternions for equality.</caption>
381  * var q1 = Quat.fromPitchYawRollDegrees(0, 0, 0);
382  * var q2 = Quat.fromPitchYawRollDegrees(0, 0, 0);
383  * print(Quat.equal(q1, q2)); // true
384  * var q3 = Quat.fromPitchYawRollDegrees(0, 0, 359.95);
385  * print(Quat.equal(q1, q3)); // false
386  *
387  * var dot = Quat.dot(q1, q3);
388  * print(dot); // -0.9999999403953552
389  * var equal = Math.abs(1 - Math.abs(dot)) < 0.000001;
390  * print(equal); // true
391  */
392  float dot(const glm::quat& q1, const glm::quat& q2);
393 
394  /*@jsdoc
395  * Prints to the program log a text label followed by a quaternion's pitch, yaw, and roll Euler angles.
396  * @function Quat(0).print
397  * @param {string} label - The label to print.
398  * @param {Quat} q - The quaternion to print.
399  * @param {boolean} [asDegrees=false] - If <code>true</code> the angle values are printed in degrees, otherwise they are
400  * printed in radians.
401  * @example <caption>Two ways of printing a label plus a quaternion's Euler angles.</caption>
402  * var quaternion = Quat.fromPitchYawRollDegrees(0, 45, 0);
403  *
404  * // Quaternion: dvec3(0.000000, 45.000004, 0.000000)
405  * Quat.print("Quaternion:", quaternion, true);
406  *
407  * // Quaternion: {"x":0,"y":45.000003814697266,"z":0}
408  * print("Quaternion: " + JSON.stringify(Quat.safeEulerAngles(quaternion)));
409  */
410  void print(const QString& label, const glm::quat& q, bool asDegrees = false);
411 
412  /*@jsdoc
413  * Tests whether two quaternions are equal.
414  * <p><strong>Note:</strong> The quaternions must be exactly equal in order for <code>true</code> to be returned; it is
415  * often better to use {@link Quat(0).dot|Quat.dot} and test for closeness to +/-1.</p>
416  * @function Quat(0).equal
417  * @param {Quat} q1 - The first quaternion.
418  * @param {Quat} q2 - The second quaternion.
419  * @returns {boolean} <code>true</code> if the quaternions are equal, otherwise <code>false</code>.
420  * @example <caption>Testing unit quaternions for equality.</caption>
421  * var q1 = Quat.fromPitchYawRollDegrees(0, 0, 0);
422  * var q2 = Quat.fromPitchYawRollDegrees(0, 0, 0);
423  * print(Quat.equal(q1, q2)); // true
424  * var q3 = Quat.fromPitchYawRollDegrees(0, 0, 359.95);
425  * print(Quat.equal(q1, q3)); // false
426  *
427  * var dot = Quat.dot(q1, q3);
428  * print(dot); // -0.9999999403953552
429  * var equal = Math.abs(1 - Math.abs(dot)) < 0.000001;
430  * print(equal); // true
431  */
432  bool equal(const glm::quat& q1, const glm::quat& q2);
433 
434  /*@jsdoc
435  * Cancels out the roll and pitch component of a quaternion so that its completely horizontal with a yaw pointing in the
436  * given quaternion's direction.
437  * @function Quat(0).cancelOutRollAndPitch
438  * @param {Quat} orientation - A quaternion representing an orientation.
439  * @returns {Quat} <code>orientation</code> with its roll and pitch canceled out.
440  * @example <caption>Two ways of calculating a camera orientation in the x-z plane with a yaw pointing in the direction of
441  * a given quaternion.</caption>
442  * var quaternion = Quat.fromPitchYawRollDegrees(10, 20, 30);
443  *
444  * var noRollOrPitch = Quat.cancelOutRollAndPitch(quaternion);
445  * Quat.print("", noRollOrPitch, true); // dvec3(0.000000, 22.245995, 0.000000)
446  *
447  * var front = Quat.getFront(quaternion);
448  * var lookAt = Quat.lookAtSimple(Vec3.ZERO, { x: front.x, y: 0, z: front.z });
449  * Quat.print("", lookAt, true); // dvec3(0.000000, 22.245996, 0.000000)
450  *
451  */
452  glm::quat cancelOutRollAndPitch(const glm::quat& q);
453 
454  /*@jsdoc
455  * Cancels out the roll component of a quaternion so that its horizontal axis is level.
456  * @function Quat(0).cancelOutRoll
457  * @param {Quat} orientation - A quaternion representing an orientation.
458  * @returns {Quat} <code>orientation</code> with its roll canceled out.
459  * @example <caption>Two ways of calculating a camera orientation that points in the direction of a given quaternion but
460  * keeps the camera's horizontal axis level.</caption>
461  * var quaternion = Quat.fromPitchYawRollDegrees(10, 20, 30);
462  *
463  * var noRoll = Quat.cancelOutRoll(quaternion);
464  * Quat.print("", noRoll, true); // dvec3(-1.033004, 22.245996, -0.000000)
465  *
466  * var front = Quat.getFront(quaternion);
467  * var lookAt = Quat.lookAtSimple(Vec3.ZERO, front);
468  * Quat.print("", lookAt, true); // dvec3(-1.033004, 22.245996, -0.000000)
469  */
470  glm::quat cancelOutRoll(const glm::quat& q);
471 
472 private:
473  const glm::quat& IDENTITY() const { return Quaternions::IDENTITY; }
474 
475 };
476 
477 #endif // hifi_Quat_h
478 
Provides the Quat scripting interface.
Definition: Quat.h:61
glm::quat slerp(const glm::quat &q1, const glm::quat &q2, float alpha)
Spherical Linear Interpolation.
Definition: Quat.cpp:108
[ScriptInterface] Provides an engine-independent interface for QScriptable
Definition: Scriptable.h:29