Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
w3dquat.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/Tools/max2w3d/w3dquat.h 27 2/03/00 4:55p Jason_a $ */
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 "wwmatrix3.h"
48#include "vector3.h"
49
50
51class Quaternion
52{
53private:
54
55public:
56
57 // X,Y,Z are the imaginary parts of the quaterion
58 // W is the real part
59 float X;
60 float Y;
61 float Z;
62 float W;
63
64public:
65
66 Quaternion(void) {};
67 explicit Quaternion(bool init) { if (init) { X = 0.0f; Y = 0.0f; Z = 0.0f; W = 1.0f; } }
68 explicit Quaternion(float a, float b, float c, float d) { X=a; Y=b; Z=c; W=d; }
69 explicit Quaternion(const Vector3 & axis,float angle);
70 Quaternion & operator=(const Quaternion & source);
71
72 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; }
73 void Make_Identity(void) { Set(); };
74 void Scale(float s) { X = (float)(s*X); Y = (float)(s*Y); Z = (float)(s*Z); W = (float)(s*W); }
75
76 // Array access
77 float & operator [](int i) { return (&X)[i]; }
78 const float & operator [](int i) const { return (&X)[i]; }
79
80 // Unary operators.
81 // Remember that q and -q represent the same 3D rotation.
82 Quaternion operator-() const { return(Quaternion(-X,-Y,-Z,-W)); }
83 Quaternion operator+() const { return *this; }
84
85 // Every 3D rotation can be expressed by two different quaternions, This
86 // function makes the current quaternion convert itself to the representation
87 // which is closer on the 4D unit-hypersphere to the given quaternion.
89
90 // Square of the magnitude of the quaternion
91 float Length2(void) const { return (X*X + Y*Y + Z*Z + W*W); }
92
93 // Magnitude of the quaternion
94 float Length(void) const { return WWMath::Sqrt(Length2()); }
95
96 // Make the quaternion unit length
97 void Normalize(void);
98
99 // post-concatenate rotations about the coordinate axes
100 void Rotate_X(float theta);
101 void Rotate_Y(float theta);
102 void Rotate_Z(float theta);
103
104 // initialize this quaternion randomly (creates a random *unit* quaternion)
105 void Randomize(void);
106
107 // transform (rotate) a vector with this quaternion
108 Vector3 Rotate_Vector(const Vector3 & v) const;
109 void Rotate_Vector(const Vector3 & v,Vector3 * set_result) const;
110
111 // verify that none of the members of this quaternion are invalid floats
112 bool Is_Valid(void) const;
113};
114
115// Inverse of the quaternion (1/q)
117{
118 return Quaternion(-a[0],-a[1],-a[2],a[3]);
119}
120
121// Conjugate of the quaternion
123{
124 return Quaternion(-a[0],-a[1],-a[2],a[3]);
125}
126
127// Add two quaternions
128inline Quaternion operator + (const Quaternion & a,const Quaternion & b)
129{
130 return Quaternion(a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]);
131}
132
133// Subract two quaternions
134inline Quaternion operator - (const Quaternion & a,const Quaternion & b)
135{
136 return Quaternion(a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]);
137}
138
139// Multiply a quaternion by a scalar:
140inline Quaternion operator * (float scl, const Quaternion & a)
141{
142 return Quaternion(scl*a[0], scl*a[1], scl*a[2], scl*a[3]);
143}
144
145// Multiply a quaternion by a scalar
146inline Quaternion operator * (const Quaternion & a, float scl)
147{
148 return scl*a;
149}
150
151// Multiply two quaternions
152inline Quaternion operator * (const Quaternion & a,const Quaternion & b)
153{
154 return Quaternion
155 (
156 a.W*b.X + b.W*a.X + (a.Y*b.Z - b.Y*a.Z),
157 a.W*b.Y + b.W*a.Y - (a.X*b.Z - b.X*a.Z),
158 a.W*b.Z + b.W*a.Z + (a.X*b.Y - b.X*a.Y),
159 a.W * b.W - (a.X * b.X + a.Y * b.Y + a.Z * b.Z)
160 );
161}
162
163// Divide two quaternions
164inline Quaternion operator / (const Quaternion & a,const Quaternion & b)
165{
166 return a * Inverse(b);
167}
168
169// Normalized version of the quaternion
171{
172 float mag = a.Length();
173 if (0.0f == mag) {
174 return a;
175 } else {
176 float oomag = 1.0f / mag;
177 return Quaternion(a[0] * oomag, a[1] * oomag, a[2] * oomag, a[3] * oomag);
178 }
179}
180
181// This function computes a quaternion based on an axis
182// (defined by the given Vector a) and an angle about
183// which to rotate. The angle is expressed in radians.
184Quaternion Axis_To_Quat(const Vector3 &a, float angle);
185
186// Pass the x and y coordinates of the last and current position
187// of the mouse, scaled so they are from -1.0 to 1.0
188// The quaternion is the computed as the rotation of a trackball
189// between the two points projected onto a sphere. This can
190// be used to implement an intuitive viewing control system.
191Quaternion Trackball(float x0, float y0, float x1, float y1, float sphsize);
192
193// Spherical Linear interpolation of quaternions
194Quaternion Slerp(const Quaternion & a,const Quaternion & b,float t);
195
196// Convert a rotation matrix into a quaternion
197Quaternion Build_Quaternion(const Matrix3 & matrix);
198Quaternion Build_Quaternion(const Matrix3D & matrix);
199Quaternion Build_Quaternion(const Matrix4 & matrix);
200
201// Convert a quaternion into a rotation matrix
202Matrix3 Build_Matrix3(const Quaternion & quat);
204Matrix4 Build_Matrix4(const Quaternion & quat);
205
206
207// Some values can be cached if you are performing multiple slerps
208// between the same two quaternions...
209struct SlerpInfoStruct
210{
211 float SinT;
212 float Theta;
213 bool Flip;
214 bool Linear;
215};
216
217// Cached slerp implementation
218void Slerp_Setup(const Quaternion & p,const Quaternion & q,SlerpInfoStruct * slerpinfo);
219void Cached_Slerp(const Quaternion & p,const Quaternion & q,float alpha,SlerpInfoStruct * slerpinfo,Quaternion * set_q);
220Quaternion Cached_Slerp(const Quaternion & p,const Quaternion & q,float alpha,SlerpInfoStruct * slerpinfo);
221
222inline Vector3 Quaternion::Rotate_Vector(const Vector3 & v) const
223{
224 float x = W*v.X + (Y*v.Z - v.Y*Z);
225 float y = W*v.Y - (X*v.Z - v.X*Z);
226 float z = W*v.Z + (X*v.Y - v.X*Y);
227 float w = -(X*v.X + Y*v.Y + Z*v.Z);
228
229 return Vector3
230 (
231 w*(-X) + W*x + (y*(-Z) - (-Y)*z),
232 w*(-Y) + W*y - (x*(-Z) - (-X)*z),
233 w*(-Z) + W*z + (x*(-Y) - (-X)*y)
234 );
235}
236
237inline void Quaternion::Rotate_Vector(const Vector3 & v,Vector3 * result) const
238{
239 assert(result != NULL);
240
241 float x = W*v.X + (Y*v.Z - v.Y*Z);
242 float y = W*v.Y - (X*v.Z - v.X*Z);
243 float z = W*v.Z + (X*v.Y - v.X*Y);
244 float w = -(X*v.X + Y*v.Y + Z*v.Z);
245
246 result->X = w*(-X) + W*x + (y*(-Z) - (-Y)*z);
247 result->Y = w*(-Y) + W*y - (x*(-Z) - (-X)*z);
248 result->Z = w*(-Z) + W*z + (x*(-Y) - (-X)*y);
249}
250
251inline bool Quaternion::Is_Valid(void) const
252{
253 return ( WWMath::Is_Valid_Float(X) &&
257}
258
259#endif /* QUAT_H */
260
261
262
#define NULL
Definition BaseType.h:92
float Length2(void) const
Definition w3dquat.h:91
Quaternion(bool init)
Definition w3dquat.h:67
float X
Definition quat.h:60
WWINLINE Quaternion(void)
Definition quat.h:67
void Rotate_Y(float theta)
void Rotate_Vector(const Vector3 &v, Vector3 *set_result) const
Quaternion & Make_Closest(const Quaternion &qto)
Quaternion(void)
Definition w3dquat.h:66
Quaternion(float a, float b, float c, float d)
Definition w3dquat.h:68
void Normalize(void)
Vector3 Rotate_Vector(const Vector3 &v) const
WWINLINE float Length(void) const
Definition quat.h:95
Quaternion & operator=(const Quaternion &source)
float Z
Definition quat.h:62
void Rotate_X(float theta)
WWINLINE float Length2(void) const
Definition quat.h:92
Quaternion operator+() const
Definition w3dquat.h:83
float Y
Definition quat.h:61
void Make_Identity(void)
Definition w3dquat.h:73
void Rotate_Z(float theta)
WWINLINE float & operator[](int i)
Definition quat.h:78
void Set(float a=0.0, float b=0.0, float c=0.0, float d=1.0)
Definition w3dquat.h:72
bool Is_Valid(void) const
float Length(void) const
Definition w3dquat.h:94
float W
Definition quat.h:63
void Randomize(void)
Quaternion(const Vector3 &axis, float angle)
void Scale(float s)
Definition w3dquat.h:74
WWINLINE void Set(float a=0.0, float b=0.0, float c=0.0, float d=1.0)
Definition quat.h:73
Quaternion operator-() const
Definition w3dquat.h:82
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
#define W(x)
Definition generals.cpp:204
int q
Definition test1.cpp:94
float Theta
Definition quat.h:236
bool Linear
Definition quat.h:238
float SinT
Definition quat.h:235
Matrix3 Build_Matrix3(const Quaternion &quat)
Definition quat.cpp:805
Quaternion operator-(const Quaternion &a, const Quaternion &b)
Definition w3dquat.h:134
void Slerp_Setup(const Quaternion &p, const Quaternion &q, SlerpInfoStruct *slerpinfo)
Definition quat.cpp:545
Quaternion Inverse(const Quaternion &a)
Definition w3dquat.h:116
Quaternion Slerp(const Quaternion &a, const Quaternion &b, float t)
Definition w3dquat.cpp:275
Quaternion Conjugate(const Quaternion &a)
Definition w3dquat.h:122
Quaternion operator/(const Quaternion &a, const Quaternion &b)
Definition w3dquat.h:164
Matrix3D Build_Matrix3D(const Quaternion &quat)
Definition w3dquat.cpp:615
Quaternion Axis_To_Quat(const Vector3 &a, float angle)
Definition quat.cpp:222
void Cached_Slerp(const Quaternion &p, const Quaternion &q, float alpha, SlerpInfoStruct *slerpinfo, Quaternion *set_q)
Definition quat.cpp:621
Quaternion Normalize(const Quaternion &a)
Definition w3dquat.h:170
Quaternion Trackball(float x0, float y0, float x1, float y1, float sphsize)
Definition quat.cpp:169
Quaternion operator+(const Quaternion &a, const Quaternion &b)
Definition w3dquat.h:128
Matrix4 Build_Matrix4(const Quaternion &quat)
Definition quat.cpp:824
Quaternion Build_Quaternion(const Matrix3 &matrix)
Definition w3dquat.cpp:497
Quaternion operator*(float scl, const Quaternion &a)
Definition w3dquat.h:140