6 # define INCLUDE_MATH_H
13 # include "Matrix.hpp"
27 Quaternion(
const Vec3& vec,
float aW ) : x( vec.x ), y( vec.y ), z( vec.z ), w( aW ) {}
47 resQuat = *
this * resQuat;
49 return Vec3( resQuat.x, resQuat.y, resQuat.z );
59 return Quaternion(
Vec3( w * aQ.x + x * aQ.w + y * aQ.z - z * aQ.y,
60 w * aQ.y + y * aQ.w + z * aQ.x - x * aQ.z,
61 w * aQ.z + z * aQ.w + x * aQ.y - y * aQ.x ),
62 w * aQ.w - x * aQ.x - y * aQ.y - z * aQ.z );
72 return x == q.x && y == q.y && z == q.z && w == q.w;
105 Vec3 orthonormal1, orthonormal2;
106 FindOrthonormals( axis, orthonormal1, orthonormal2 );
108 Vec3 transformed = *
this * orthonormal1;
111 Vec3 flattened = transformed - axis *
Vec3::Dot( transformed, axis );
115 return std::acos(
Vec3::Dot( orthonormal1, flattened ) );
124 const float scale = std::sqrt( x * x + y * y + z * z );
126 if (std::fabs( scale ) < 0.00001f)
128 outAxis =
Vec3( 0, 0, 0 );
132 outAxis.x = x / scale;
133 outAxis.y = y / scale;
134 outAxis.z = z / scale;
137 outAngleRad = std::acos( w ) * 2;
146 const Vec3 xAxis( 1, 0, 0 );
147 const Vec3 yAxis( 0, 1, 0 );
148 const Vec3 zAxis( 0, 0, 1 );
164 float angleRad = angleDeg * (3.1418693659f / 180.0f);
168 const float sinAngle = std::sin( angleRad );
170 x = axis.x * sinAngle;
171 y = axis.y * sinAngle;
172 z = axis.z * sinAngle;
173 w = std::cos( angleRad );
190 const float trace = 1.0f + mat.
m[0] + mat.
m[5] + mat.
m[10];
194 const float S = sqrtf( trace ) * 2.0f;
195 x = ( mat.
m[9] - mat.
m[6] ) / S;
196 y = ( mat.
m[2] - mat.
m[8] ) / S;
197 z = ( mat.
m[4] - mat.
m[1] ) / S;
200 else if (mat.
m[0] > mat.
m[5] && mat.
m[0] > mat.
m[10])
202 const float S = std::sqrt( 1.0f + mat.
m[0] - mat.
m[5] - mat.
m[10] ) * 2.0f;
204 y = (mat.
m[4] + mat.
m[1] ) / S;
205 z = (mat.
m[2] + mat.
m[8] ) / S;
206 w = (mat.
m[9] - mat.
m[6] ) / S;
208 else if (mat.
m[5] > mat.
m[10])
210 const float S = std::sqrt( 1.0f + mat.
m[5] - mat.
m[0] - mat.
m[10] ) * 2.0f;
211 x = (mat.
m[4] + mat.
m[1] ) / S;
213 z = (mat.
m[9] + mat.
m[6] ) / S;
214 w = (mat.
m[2] - mat.
m[8] ) / S;
218 const float S = std::sqrt( 1.0f + mat.
m[10] - mat.
m[0] - mat.
m[5] ) * 2.0f;
219 x = (mat.
m[2] + mat.
m[8] ) / S;
220 y = (mat.
m[9] + mat.
m[6] ) / S;
222 w = (mat.
m[4] - mat.
m[1] ) / S;
233 const float x2 = x * x;
234 const float y2 = y * y;
235 const float z2 = z * z;
236 const float xy = x * y;
237 const float xz = x * z;
238 const float yz = y * z;
239 const float wx = w * x;
240 const float wy = w * y;
241 const float wz = w * z;
243 outMatrix.
m[ 0] = 1 - 2 * (y2 + z2);
244 outMatrix.
m[ 1] = 2 * (xy - wz);
245 outMatrix.
m[ 2] = 2 * (xz + wy);
247 outMatrix.
m[ 4] = 2 * (xy + wz);
248 outMatrix.
m[ 5] = 1 - 2 * (x2 + z2);
249 outMatrix.
m[ 6] = 2 * (yz - wx);
251 outMatrix.
m[ 8] = 2 * (xz - wy);
252 outMatrix.
m[ 9] = 2 * (yz + wx);
253 outMatrix.
m[10] = 1 - 2 * (x2 + y2);
268 out.z = std::atan2( 2 * y * w - 2 * x * z, 1 - 2 * y * y - 2 * z * z );
269 out.y = std::asin( 2 * x * y + 2 * z * w );
270 out.x = std::atan2( 2 * x * w - 2 * y * z, 1 - 2 * x * x - 2 * z * z );
271 return out / (3.14159265358979f / 180.0f);
277 const float mag2 = w * w + x * x + y * y + z * z;
278 const float acceptableDelta = 0.00001f;
280 if (std::fabs( mag2 ) > acceptableDelta && std::fabs( mag2 - 1.0f ) > acceptableDelta)
282 const float oneOverMag = 1.0f / std::sqrt( mag2 );
296 void FindOrthonormals(
const Vec3& normal,
Vec3& orthonormal1,
Vec3& orthonormal2 )
const
303 const float dot =
Vec3::Dot( normal, ww );
305 if (std::fabs( dot ) > 0.6f)
314 orthonormal2 =
Vec3::Cross( normal, orthonormal1 );