VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
quaternion.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3//
4// Created by Arnis Lektauers on 24.07.2025.
5//
6#pragma once
7
8#include "defines.h"
9
10namespace visutwin::canvas
11{
12 struct Vector3;
13 struct Matrix4;
14
19 struct alignas(16) Quaternion
20 {
21 union
22 {
23#ifdef USE_SIMD_SSE
24 __m128 simd;
25#elif defined(USE_SIMD_APPLE)
26 simd_quatf simd;
27#elif defined(USE_SIMD_NEON)
28 float32x4_t simd;
29#else
30 struct
31 {
32 float x, y, z, w;
33 };
34 float q[4];
35#endif
36 };
37
39
40 Quaternion(float x, float y, float z, float w);
41
42#ifdef USE_SIMD_SSE
43 explicit Quaternion(__m128 simd) : simd(simd) {}
44#elif defined(USE_SIMD_APPLE)
45 explicit Quaternion(const simd_quatf& simd) : simd(simd) {}
46#elif defined(USE_SIMD_NEON)
47 explicit Quaternion(float32x4_t simd) : simd(simd) {}
48#endif
49
50 [[nodiscard]] float getX() const
51 {
52#if defined(USE_SIMD_SSE)
53 return _mm_cvtss_f32(simd);
54#elif defined(USE_SIMD_APPLE)
55 return simd.vector.x;
56#elif defined(USE_SIMD_NEON)
57 return vgetq_lane_f32(simd, 0);
58#else
59 return x;
60#endif
61 }
62
63 [[nodiscard]] float getY() const
64 {
65#if defined(USE_SIMD_SSE)
66 return _mm_cvtss_f32(_mm_shuffle_ps(simd, simd, _MM_SHUFFLE(1, 1, 1, 1)));
67#elif defined(USE_SIMD_APPLE)
68 return simd.vector.y;
69#elif defined(USE_SIMD_NEON)
70 return vgetq_lane_f32(simd, 1);
71#else
72 return y;
73#endif
74 }
75
76 [[nodiscard]] float getZ() const
77 {
78#if defined(USE_SIMD_SSE)
79 return _mm_cvtss_f32(_mm_shuffle_ps(simd, simd, _MM_SHUFFLE(2, 2, 2, 2)));
80#elif defined(USE_SIMD_APPLE)
81 return simd.vector.z;
82#elif defined(USE_SIMD_NEON)
83 return vgetq_lane_f32(simd, 2);
84#else
85 return z;
86#endif
87 }
88
89 [[nodiscard]] float getW() const
90 {
91#if defined(USE_SIMD_SSE)
92 return _mm_cvtss_f32(_mm_shuffle_ps(simd, simd, _MM_SHUFFLE(3, 3, 3, 3)));
93#elif defined(USE_SIMD_APPLE)
94 return simd.vector.w;
95#elif defined(USE_SIMD_NEON)
96 return vgetq_lane_f32(simd, 3);
97#else
98 return w;
99#endif
100 }
101
102 [[nodiscard]] Quaternion conjugate() const;
103
104 Quaternion operator*(const Quaternion& rhs) const;
105
106 Vector3 operator*(const Vector3& v) const;
107
108 Quaternion operator*(const float scalar) const;
109
110 [[nodiscard]] Quaternion normalized() const;
111
112 [[nodiscard]] Matrix4 toRotationMatrix() const;
113
117 float length() const;
118
119 /*
120 * Returns the magnitude squared of the specified quaternion
121 */
122 float lengthSquared() const;
123
128
129 friend std::ostream& operator<<(std::ostream& os, const Quaternion& q)
130 {
131 return os << "Quaternion(" << q.getX() << ", " << q.getY() << ", " << q.getZ() << ", " << q.getW() << ")";
132 }
133
134 /*
135 * Creates a quaternion from an angular rotation around an axis
136 */
137 static Quaternion fromAxisAngle(const Vector3& axis, float angle);
138
139 /*
140 * Creates a quaternion to represent a rotation specified by Euler angles in degrees
141 */
142 static Quaternion fromEulerAngles(float ax, float ay, float az);
143
148 };
149}
150
151#include "quaternion.inl"
4x4 column-major transformation matrix with SIMD acceleration.
Definition matrix4.h:31
Quaternion operator*(const Quaternion &rhs) const
Vector3 operator*(const Vector3 &v) const
friend std::ostream & operator<<(std::ostream &os, const Quaternion &q)
Definition quaternion.h:129
static Quaternion fromEulerAngles(float ax, float ay, float az)
Quaternion invert() const
Matrix4 toRotationMatrix() const
Quaternion conjugate() const
static Quaternion fromAxisAngle(const Vector3 &axis, float angle)
static Quaternion fromMatrix4(const Matrix4 &m)
Quaternion(float x, float y, float z, float w)
Quaternion operator*(const float scalar) const
Quaternion normalized() const
3D vector for positions, directions, and normals with multi-backend SIMD acceleration.
Definition vector3.h:29