Blame view

ios/cocos2d/cocos/math/Quaternion.h 13.9 KB
520389e3   xiaoyu   接入cocos源码,编译未通过,继续修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
  /**
   Copyright 2013 BlackBerry Inc.
   Copyright (c) 2014-2017 Chukong Technologies
   Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
   
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
  
   http://www.apache.org/licenses/LICENSE-2.0
  
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
  
   Original file from GamePlay3D: http://gameplay3d.org
  
   This file was modified to fit the cocos2d-x project
   */
  
  #ifndef QUATERNION_H_
  #define QUATERNION_H_
  
  #include "math/Vec3.h"
  #include "math/Mat4.h"
  //#include "Plane.h"
  
  /**
   * @addtogroup base
   * @{
   */
  
  NS_CC_MATH_BEGIN
  
  class Mat4;
  
  /**
   * Defines a 4-element quaternion that represents the orientation of an object in space.
   *
   * Quaternions are typically used as a replacement for euler angles and rotation matrices as a way to achieve smooth interpolation and avoid gimbal lock.
   *
   * Note that this quaternion class does not automatically keep the quaternion normalized. Therefore, care must be taken to normalize the quaternion when necessary, by calling the normalize method.
   * This class provides three methods for doing quaternion interpolation: lerp, slerp, and squad.
   *
   * lerp (linear interpolation): the interpolation curve gives a straight line in quaternion space. It is simple and fast to compute. The only problem is that it does not provide constant angular velocity. Note that a constant velocity is not necessarily a requirement for a curve;
   * slerp (spherical linear interpolation): the interpolation curve forms a great arc on the quaternion unit sphere. Slerp provides constant angular velocity;
   * squad (spherical spline interpolation): interpolating between a series of rotations using slerp leads to the following problems:
   * - the curve is not smooth at the control points;
   * - the angular velocity is not constant;
   * - the angular velocity is not continuous at the control points.
   *
   * Since squad is continuously differentiable, it remedies the first and third problems mentioned above.
   * The slerp method provided here is intended for interpolation of principal rotations. It treats +q and -q as the same principal rotation and is at liberty to use the negative of either input. The resulting path is always the shorter arc.
   *
   * The lerp method provided here interpolates strictly in quaternion space. Note that the resulting path may pass through the origin if interpolating between a quaternion and its exact negative.
   *
   * As an example, consider the following quaternions:
   *
   * q1 = (0.6, 0.8, 0.0, 0.0),
   * q2 = (0.0, 0.6, 0.8, 0.0),
   * q3 = (0.6, 0.0, 0.8, 0.0), and
   * q4 = (-0.8, 0.0, -0.6, 0.0).
   * For the point p = (1.0, 1.0, 1.0), the following figures show the trajectories of p using lerp, slerp, and squad.
   */
  class CC_DLL Quaternion
  {
      friend class Curve;
      friend class Transform;
  
  public:
  
      /**
       * The x-value of the quaternion's vector component.
       */
      float x;
      /**
       * The y-value of the quaternion's vector component.
       */
      float y;
      /**
       * The z-value of the quaternion's vector component.
       */
      float z;
      /**
       * The scalar component of the quaternion.
       */
      float w;
  
      /**
       * Constructs a quaternion initialized to (0, 0, 0, 1).
       */
      Quaternion();
  
      /**
       * Constructs a quaternion initialized to (0, 0, 0, 1).
       *
       * @param xx The x component of the quaternion.
       * @param yy The y component of the quaternion.
       * @param zz The z component of the quaternion.
       * @param ww The w component of the quaternion.
       */
      Quaternion(float xx, float yy, float zz, float ww);
  
      /**
       * Constructs a new quaternion from the values in the specified array.
       *
       * @param array The values for the new quaternion.
       */
      Quaternion(float* array);
  
      /**
       * Constructs a quaternion equal to the rotational part of the specified matrix.
       *
       * @param m The matrix.
       */
      Quaternion(const Mat4& m);
  
      /**
       * Constructs a quaternion equal to the rotation from the specified axis and angle.
       *
       * @param axis A vector describing the axis of rotation.
       * @param angle The angle of rotation (in radians).
       */
      Quaternion(const Vec3& axis, float angle);
  
      /**
       * Returns the identity quaternion.
       *
       * @return The identity quaternion.
       */
      static const Quaternion& identity();
  
      /**
       * Returns the quaternion with all zeros.
       *
       * @return The quaternion.
       */
      static const Quaternion& zero();
  
      /**
       * Determines if this quaternion is equal to the identity quaternion.
       *
       * @return true if it is the identity quaternion, false otherwise.
       */
      bool isIdentity() const;
  
      /**
       * Determines if this quaternion is all zeros.
       *
       * @return true if this quaternion is all zeros, false otherwise.
       */
      bool isZero() const;
  
      /**
       * Creates a quaternion equal to the rotational part of the specified matrix
       * and stores the result in dst.
       *
       * @param m The matrix.
       * @param dst A quaternion to store the conjugate in.
       */
      static void createFromRotationMatrix(const Mat4& m, Quaternion* dst);
  
      /**
       * Creates this quaternion equal to the rotation from the specified axis and angle
       * and stores the result in dst.
       *
       * @param axis A vector describing the axis of rotation.
       * @param angle The angle of rotation (in radians).
       * @param dst A quaternion to store the conjugate in.
       */
      static void createFromAxisAngle(const Vec3& axis, float angle, Quaternion* dst);
  
      /**
       * Sets this quaternion to the conjugate of itself.
       */
      void conjugate();
  
      /**
       * Gets the conjugate of this quaternion.
       *
       */
      Quaternion getConjugated() const;
  
      /**
       * Sets this quaternion to the inverse of itself.
       *
       * Note that the inverse of a quaternion is equal to its conjugate
       * when the quaternion is unit-length. For this reason, it is more
       * efficient to use the conjugate method directly when you know your
       * quaternion is already unit-length.
       *
       * @return true if the inverse can be computed, false otherwise.
       */
      bool inverse();
  
      /**
       * Gets the inverse of this quaternion.
       *
       * Note that the inverse of a quaternion is equal to its conjugate
       * when the quaternion is unit-length. For this reason, it is more
       * efficient to use the conjugate method directly when you know your
       * quaternion is already unit-length.
       */
      Quaternion getInversed() const;
  
      /**
       * Multiplies this quaternion by the specified one and stores the result in this quaternion.
       *
       * @param q The quaternion to multiply.
       */
      void multiply(const Quaternion& q);
  
      /**
       * Multiplies the specified quaternions and stores the result in dst.
       *
       * @param q1 The first quaternion.
       * @param q2 The second quaternion.
       * @param dst A quaternion to store the result in.
       */
      static void multiply(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
  
      /**
       * Normalizes this quaternion to have unit length.
       *
       * If the quaternion already has unit length or if the length
       * of the quaternion is zero, this method does nothing.
       */
      void normalize();
  
      /**
       * Get the normalized quaternion.
       *
       * If the quaternion already has unit length or if the length
       * of the quaternion is zero, this method simply copies
       * this vector.
       */
      Quaternion getNormalized() const;
  
      /**
       * Sets the elements of the quaternion to the specified values.
       *
       * @param xx The new x-value.
       * @param yy The new y-value.
       * @param zz The new z-value.
       * @param ww The new w-value.
       */
      void set(float xx, float yy, float zz, float ww);
  
      /**
       * Sets the elements of the quaternion from the values in the specified array.
       *
       * @param array An array containing the elements of the quaternion in the order x, y, z, w.
       */
      void set(float* array);
  
      /**
       * Sets the quaternion equal to the rotational part of the specified matrix.
       *
       * @param m The matrix.
       */
      void set(const Mat4& m);
  
      /**
       * Sets the quaternion equal to the rotation from the specified axis and angle.
       * 
       * @param axis The axis of rotation.
       * @param angle The angle of rotation (in radians).
       */
      void set(const Vec3& axis, float angle);
  
      /**
       * Sets the elements of this quaternion to a copy of the specified quaternion.
       *
       * @param q The quaternion to copy.
       */
      void set(const Quaternion& q);
  
      /**
       * Sets this quaternion to be equal to the identity quaternion.
       */
      void setIdentity();
  
      /**
       * Converts this Quaternion4f to axis-angle notation. The axis is normalized.
       *
       * @param e The Vec3f which stores the axis.
       * 
       * @return The angle (in radians).
       */
      float toAxisAngle(Vec3* e) const;
  
      /**
       * Interpolates between two quaternions using linear interpolation.
       *
       * The interpolation curve for linear interpolation between
       * quaternions gives a straight line in quaternion space.
       *
       * @param q1 The first quaternion.
       * @param q2 The second quaternion.
       * @param t The interpolation coefficient.
       * @param dst A quaternion to store the result in.
       */
      static void lerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
      
      /**
       * Interpolates between two quaternions using spherical linear interpolation.
       *
       * Spherical linear interpolation provides smooth transitions between different
       * orientations and is often useful for animating models or cameras in 3D.
       *
       * Note: For accurate interpolation, the input quaternions must be at (or close to) unit length.
       * This method does not automatically normalize the input quaternions, so it is up to the
       * caller to ensure they call normalize beforehand, if necessary.
       *
       * @param q1 The first quaternion.
       * @param q2 The second quaternion.
       * @param t The interpolation coefficient.
       * @param dst A quaternion to store the result in.
       */
      static void slerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
      
      /**
       * Interpolates over a series of quaternions using spherical spline interpolation.
       *
       * Spherical spline interpolation provides smooth transitions between different
       * orientations and is often useful for animating models or cameras in 3D.
       *
       * Note: For accurate interpolation, the input quaternions must be unit.
       * This method does not automatically normalize the input quaternions,
       * so it is up to the caller to ensure they call normalize beforehand, if necessary.
       *
       * @param q1 The first quaternion.
       * @param q2 The second quaternion.
       * @param s1 The first control point.
       * @param s2 The second control point.
       * @param t The interpolation coefficient.
       * @param dst A quaternion to store the result in.
       */
      static void squad(const Quaternion& q1, const Quaternion& q2, const Quaternion& s1, const Quaternion& s2, float t, Quaternion* dst);
  
      /**
       * Calculates the quaternion product of this quaternion with the given quaternion.
       * 
       * Note: this does not modify this quaternion.
       * 
       * @param q The quaternion to multiply.
       * @return The quaternion product.
       */
      inline Quaternion operator*(const Quaternion& q) const;
  
      /**
       * Calculates the quaternion product of this quaternion with the given vec3.
       * @param v The vec3 to multiply.
       * @return The vec3 product.
       */
      inline Vec3 operator*(const Vec3& v) const;
  
      /**
       * Multiplies this quaternion with the given quaternion.
       * 
       * @param q The quaternion to multiply.
       * @return This quaternion, after the multiplication occurs.
       */
      inline Quaternion& operator*=(const Quaternion& q);
      
      /** equals to Quaternion(0,0,0, 0) */
      static const Quaternion ZERO;
  
  private:
  
      /**
       * Interpolates between two quaternions using spherical linear interpolation.
       *
       * Spherical linear interpolation provides smooth transitions between different
       * orientations and is often useful for animating models or cameras in 3D.
       *
       * Note: For accurate interpolation, the input quaternions must be at (or close to) unit length.
       * This method does not automatically normalize the input quaternions, so it is up to the
       * caller to ensure they call normalize beforehand, if necessary.
       *
       * @param q1x The x component of the first quaternion.
       * @param q1y The y component of the first quaternion.
       * @param q1z The z component of the first quaternion.
       * @param q1w The w component of the first quaternion.
       * @param q2x The x component of the second quaternion.
       * @param q2y The y component of the second quaternion.
       * @param q2z The z component of the second quaternion.
       * @param q2w The w component of the second quaternion.
       * @param t The interpolation coefficient.
       * @param dstx A pointer to store the x component of the slerp in.
       * @param dsty A pointer to store the y component of the slerp in.
       * @param dstz A pointer to store the z component of the slerp in.
       * @param dstw A pointer to store the w component of the slerp in.
       */
      static void slerp(float q1x, float q1y, float q1z, float q1w, float q2x, float q2y, float q2z, float q2w, float t, float* dstx, float* dsty, float* dstz, float* dstw);
  
      static void slerpForSquad(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
  };
  
  NS_CC_MATH_END
  /**
   end of base group
   @}
   */
  #include "math/Quaternion.inl"
  
  #endif