Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
quat.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/* $Header: /Commando/Code/wwmath/quat.h 29 5/11/01 7:11p Jani_p $ */
20/***************************************************************************
21 *** Confidential - Westwood Studios ***
22 ***************************************************************************
23 * *
24 * Project Name : Voxel Technology *
25 * *
26 * File Name : QUAT.H *
27 * *
28 * Programmer : Greg Hjelstrom *
29 * *
30 * Start Date : 02/24/97 *
31 * *
32 * Last Update : February 24, 1997 [GH] *
33 * *
34 *-------------------------------------------------------------------------*
35 * Functions: *
36 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
37
38#if defined(_MSC_VER)
39#pragma once
40#endif
41
42#ifndef QUAT_H
43#define QUAT_H
44
45#include "always.h"
46#include "wwmath.h"
47#include "matrix3.h"
48#include "vector3.h"
49#include "matrix3d.h"
50
51
53{
54private:
55
56public:
57
58 // X,Y,Z are the imaginary parts of the quaterion
59 // W is the real part
60 float X;
61 float Y;
62 float Z;
63 float W;
64
65public:
66
68 WWINLINE explicit Quaternion(bool init) { if (init) { X = 0.0f; Y = 0.0f; Z = 0.0f; W = 1.0f; } }
69 WWINLINE explicit Quaternion(float a, float b, float c, float d) { X=a; Y=b; Z=c; W=d; }
70 WWINLINE explicit Quaternion(const Vector3 & axis,float angle);
71 WWINLINE Quaternion & operator=(const Quaternion & source);
72
73 WWINLINE void Set(float a = 0.0, float b = 0.0, float c = 0.0, float d = 1.0) { X = a; Y = b; Z = c; W = d; }
74 WWINLINE void Make_Identity(void) { Set(); };
75 WWINLINE void Scale(float s) { X = (float)(s*X); Y = (float)(s*Y); Z = (float)(s*Z); W = (float)(s*W); }
76
77 // Array access
78 WWINLINE float & operator [](int i) { return (&X)[i]; }
79 WWINLINE const float & operator [](int i) const { return (&X)[i]; }
80
81 // Unary operators.
82 // Remember that q and -q represent the same 3D rotation.
83 WWINLINE Quaternion operator-() const { return(Quaternion(-X,-Y,-Z,-W)); }
84 WWINLINE Quaternion operator+() const { return *this; }
85
86 // Every 3D rotation can be expressed by two different quaternions, This
87 // function makes the current quaternion convert itself to the representation
88 // which is closer on the 4D unit-hypersphere to the given quaternion.
89 Quaternion & Make_Closest(const Quaternion & qto);
90
91 // Square of the magnitude of the quaternion
92 WWINLINE float Length2(void) const { return (X*X + Y*Y + Z*Z + W*W); }
93
94 // Magnitude of the quaternion
95 WWINLINE float Length(void) const { return WWMath::Sqrt(Length2()); }
96
97 // Make the quaternion unit length
98 void Normalize(void);
99
100 // post-concatenate rotations about the coordinate axes
101 void Rotate_X(float theta);
102 void Rotate_Y(float theta);
103 void Rotate_Z(float theta);
104
105 // initialize this quaternion randomly (creates a random *unit* quaternion)
106 void Randomize(void);
107
108 // transform (rotate) a vector with this quaternion
109 WWINLINE Vector3 Rotate_Vector(const Vector3 & v) const;
110 WWINLINE void Rotate_Vector(const Vector3 & v,Vector3 * set_result) const;
111
112 // verify that none of the members of this quaternion are invalid floats
113 bool Is_Valid(void) const;
114};
115
116// Inverse of the quaternion (1/q)
118{
119 return Quaternion(-a[0],-a[1],-a[2],a[3]);
120}
121
122// Conjugate of the quaternion
124{
125 return Quaternion(-a[0],-a[1],-a[2],a[3]);
126}
127
128// Add two quaternions
130{
131 return Quaternion(a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]);
132}
133
134// Subract two quaternions
136{
137 return Quaternion(a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]);
138}
139
140// Multiply a quaternion by a scalar:
142{
143 return Quaternion(scl*a[0], scl*a[1], scl*a[2], scl*a[3]);
144}
145
146// Multiply a quaternion by a scalar
148{
149 return scl*a;
150}
151
152// Multiply two quaternions
154{
155 return Quaternion
156 (
157 a.W*b.X + b.W*a.X + (a.Y*b.Z - b.Y*a.Z),
158 a.W*b.Y + b.W*a.Y - (a.X*b.Z - b.X*a.Z),
159 a.W*b.Z + b.W*a.Z + (a.X*b.Y - b.X*a.Y),
160 a.W * b.W - (a.X * b.X + a.Y * b.Y + a.Z * b.Z)
161 );
162}
163
164// Divide two quaternions
166{
167 return a * Inverse(b);
168}
169
170// Normalized version of the quaternion
172{
173 float mag = a.Length();
174 if (0.0f == mag) {
175 return a;
176 } else {
177 float oomag = 1.0f / mag;
178 return Quaternion(a[0] * oomag, a[1] * oomag, a[2] * oomag, a[3] * oomag);
179 }
180}
181
182// This function computes a quaternion based on an axis
183// (defined by the given Vector a) and an angle about
184// which to rotate. The angle is expressed in radians.
185Quaternion Axis_To_Quat(const Vector3 &a, float angle);
186
187// Pass the x and y coordinates of the last and current position
188// of the mouse, scaled so they are from -1.0 to 1.0
189// The quaternion is the computed as the rotation of a trackball
190// between the two points projected onto a sphere. This can
191// be used to implement an intuitive viewing control system.
192Quaternion Trackball(float x0, float y0, float x1, float y1, float sphsize);
193
194// Spherical Linear interpolation of quaternions
195//Quaternion Slerp(const Quaternion & a,const Quaternion & b,float t);
196void __cdecl Slerp(Quaternion& result, const Quaternion & a,const Quaternion & b,float t);
197// Fast slerp is innaccurate but multiple times faster
198void __cdecl Fast_Slerp(Quaternion& result, const Quaternion & a,const Quaternion & b,float t);
199
200// Convert a rotation matrix into a quaternion
202Quaternion Build_Quaternion(const Matrix3D & matrix);
204
205// Convert a quaternion into a rotation matrix
209{
210 out[0][0] = (float)(1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]));
211 out[0][1] = (float)(2.0 * (q[0] * q[1] - q[2] * q[3]));
212 out[0][2] = (float)(2.0 * (q[2] * q[0] + q[1] * q[3]));
213
214 out[1][0] = (float)(2.0 * (q[0] * q[1] + q[2] * q[3]));
215 out[1][1] = (float)(1.0 - 2.0f * (q[2] * q[2] + q[0] * q[0]));
216 out[1][2] = (float)(2.0 * (q[1] * q[2] - q[0] * q[3]));
217
218 out[2][0] = (float)(2.0 * (q[2] * q[0] - q[1] * q[3]));
219 out[2][1] = (float)(2.0 * (q[1] * q[2] + q[0] * q[3]));
220 out[2][2] =(float)(1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]));
221
222 // no translation
223 out[0][3] = out[1][3] = out[2][3] = 0.0f;
224
225 return out;
226}
227
229
230
231// Some values can be cached if you are performing multiple slerps
232// between the same two quaternions...
234{
235 float SinT;
236 float Theta;
237 bool Flip;
238 bool Linear;
239};
240
241// Cached slerp implementation
242void Slerp_Setup(const Quaternion & p,const Quaternion & q,SlerpInfoStruct * slerpinfo);
243void Cached_Slerp(const Quaternion & p,const Quaternion & q,float alpha,SlerpInfoStruct * slerpinfo,Quaternion * set_q);
244Quaternion Cached_Slerp(const Quaternion & p,const Quaternion & q,float alpha,SlerpInfoStruct * slerpinfo);
245
247{
248 float x = W*v.X + (Y*v.Z - v.Y*Z);
249 float y = W*v.Y - (X*v.Z - v.X*Z);
250 float z = W*v.Z + (X*v.Y - v.X*Y);
251 float w = -(X*v.X + Y*v.Y + Z*v.Z);
252
253 return Vector3
254 (
255 w*(-X) + W*x + (y*(-Z) - (-Y)*z),
256 w*(-Y) + W*y - (x*(-Z) - (-X)*z),
257 w*(-Z) + W*z + (x*(-Y) - (-X)*y)
258 );
259}
260
261WWINLINE void Quaternion::Rotate_Vector(const Vector3 & v,Vector3 * result) const
262{
263 assert(result != NULL);
264
265 float x = W*v.X + (Y*v.Z - v.Y*Z);
266 float y = W*v.Y - (X*v.Z - v.X*Z);
267 float z = W*v.Z + (X*v.Y - v.X*Y);
268 float w = -(X*v.X + Y*v.Y + Z*v.Z);
269
270 result->X = w*(-X) + W*x + (y*(-Z) - (-Y)*z);
271 result->Y = w*(-Y) + W*y - (x*(-Z) - (-X)*z);
272 result->Z = w*(-Z) + W*z + (x*(-Y) - (-X)*y);
273}
274
282
283WWINLINE bool Equal_Within_Epsilon(const Quaternion &a, const Quaternion &b, float epsilon)
284{
285 return( (WWMath::Fabs(a.X - b.X) < epsilon) &&
286 (WWMath::Fabs(a.Y - b.Y) < epsilon) &&
287 (WWMath::Fabs(a.Z - b.Z) < epsilon) &&
288 (WWMath::Fabs(a.W - b.W) < epsilon) );
289}
290
291/***********************************************************************************************
292 * Quaternion::operator= -- Assignment operator *
293 * *
294 * INPUT: *
295 * *
296 * OUTPUT: *
297 * *
298 * WARNINGS: *
299 * *
300 * HISTORY: *
301 * 02/24/1997 GH : Created. *
302 *=============================================================================================*/
304{
305 X = source[0];
306 Y = source[1];
307 Z = source[2];
308 W = source[3];
309
310 return *this;
311}
312
313
314#endif /* QUAT_H */
315
316
317
#define NULL
Definition BaseType.h:92
#define __cdecl
Definition IFF.H:44
#define WWINLINE
Definition always.h:172
WWINLINE Quaternion(float a, float b, float c, float d)
Definition quat.h:69
float X
Definition quat.h:60
WWINLINE Quaternion(void)
Definition quat.h:67
void Rotate_Y(float theta)
Definition quat.cpp:856
Quaternion & Make_Closest(const Quaternion &qto)
Definition quat.cpp:139
WWINLINE void Make_Identity(void)
Definition quat.h:74
void Normalize(void)
Definition quat.cpp:112
WWINLINE Vector3 Rotate_Vector(const Vector3 &v) const
Definition quat.h:246
WWINLINE Quaternion(bool init)
Definition quat.h:68
WWINLINE Quaternion operator+() const
Definition quat.h:84
WWINLINE float Length(void) const
Definition quat.h:95
WWINLINE Quaternion & operator=(const Quaternion &source)
Definition quat.h:303
float Z
Definition quat.h:62
WWINLINE void Scale(float s)
Definition quat.h:75
void Rotate_X(float theta)
Definition quat.cpp:850
WWINLINE float Length2(void) const
Definition quat.h:92
WWINLINE Quaternion operator-() const
Definition quat.h:83
float Y
Definition quat.h:61
void Rotate_Z(float theta)
Definition quat.cpp:862
WWINLINE float & operator[](int i)
Definition quat.h:78
bool Is_Valid(void) const
Definition quat.h:275
float W
Definition quat.h:63
void Randomize(void)
Definition quat.cpp:885
WWINLINE void Set(float a=0.0, float b=0.0, float c=0.0, float d=1.0)
Definition quat.h:73
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
static float Sqrt(float val)
Definition wwmath.h:568
static bool Is_Valid_Float(float x)
Definition wwmath.h:281
static WWINLINE float Fabs(float val)
Definition wwmath.h:113
int q
Definition test1.cpp:94
void Slerp_Setup(const Quaternion &p, const Quaternion &q, SlerpInfoStruct *slerpinfo)
Definition quat.cpp:545
Matrix4x4 Build_Matrix4(const Quaternion &quat)
Definition quat.cpp:824
void __cdecl Slerp(Quaternion &result, const Quaternion &a, const Quaternion &b, float t)
Definition quat.cpp:487
Quaternion Axis_To_Quat(const Vector3 &a, float angle)
Definition quat.cpp:222
WWINLINE Quaternion operator-(const Quaternion &a, const Quaternion &b)
Definition quat.h:135
WWINLINE bool Equal_Within_Epsilon(const Quaternion &a, const Quaternion &b, float epsilon)
Definition quat.h:283
void Cached_Slerp(const Quaternion &p, const Quaternion &q, float alpha, SlerpInfoStruct *slerpinfo, Quaternion *set_q)
Definition quat.cpp:621
WWINLINE Quaternion operator+(const Quaternion &a, const Quaternion &b)
Definition quat.h:129
Quaternion Trackball(float x0, float y0, float x1, float y1, float sphsize)
Definition quat.cpp:169
WWINLINE Quaternion Inverse(const Quaternion &a)
Definition quat.h:117
WWINLINE Quaternion Conjugate(const Quaternion &a)
Definition quat.h:123
Quaternion Build_Quaternion(const Matrix3x3 &matrix)
Definition quat.cpp:706
Matrix3D & Build_Matrix3D(const Quaternion &q, Matrix3D &out)
Definition quat.h:208
WWINLINE Quaternion operator*(float scl, const Quaternion &a)
Definition quat.h:141
Matrix3x3 Build_Matrix3(const Quaternion &quat)
Definition quat.cpp:805
WWINLINE Quaternion Normalize(const Quaternion &a)
Definition quat.h:171
void __cdecl Fast_Slerp(Quaternion &result, const Quaternion &a, const Quaternion &b, float t)
Definition quat.cpp:441
WWINLINE Quaternion operator/(const Quaternion &a, const Quaternion &b)
Definition quat.h:165
float Theta
Definition quat.h:236
bool Linear
Definition quat.h:238
float SinT
Definition quat.h:235