1
///////////////////////////////////////////////////////////////////////////
3
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
6
// All rights reserved.
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
11
// * Redistributions of source code must retain the above copyright
12
// notice, this list of conditions and the following disclaimer.
13
// * Redistributions in binary form must reproduce the above
14
// copyright notice, this list of conditions and the following disclaimer
15
// in the documentation and/or other materials provided with the
17
// * Neither the name of Industrial Light & Magic nor the names of
18
// its contributors may be used to endorse or promote products derived
19
// from this software without specific prior written permission.
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
///////////////////////////////////////////////////////////////////////////
36
#include <testExtractSHRT.h>
37
#include <ImathMatrixAlgo.h>
38
#include <ImathEuler.h>
39
#include <ImathRandom.h>
48
#define debug(x) (printf x, fflush (stdout))
55
using namespace Imath;
59
float rad (float deg) {return deg * (M_PI / 180);}
60
float deg (float rad) {return rad * (180 / M_PI);}
64
testMatrix (const M33f M)
67
// Extract the rotation angle from M, and convert the
68
// angle back to a matrix, N.
74
extractSHRT (M, s, h, r, t, true);
78
N *= M33f().setScale (s);
79
N *= M33f().setShear (h);
80
N *= M33f().setRotation (r);
81
N *= M33f().setTranslation (t);
83
debug (("Re-scale: %f %f\n", s[0], s[1]));
84
debug (("Re-shear: %f\n", h));
85
debug (("Re-rot : %f\n", r));
86
debug (("Re-trans: %f %f\n", t[0], t[1]));
89
// Verify that the entries in M and N do not
95
for (int j = 0; j < 3; ++j)
97
for (int k = 0; k < 3; ++k)
99
if (abs (D[j][k]) > 0.00001)
101
cout << "unexpectedly large matrix to "
102
"euler angles conversion error: " <<
105
cout << j << " " << k << endl;
107
cout << "M\n" << M << endl;
108
cout << "N\n" << N << endl;
109
cout << "D\n" << D << endl;
119
testRandomAngles33 ()
123
for (int i = 0; i < 100000; ++i)
125
debug (("iteration: %d\n", i));
133
V2f s (random.nextf (0.000001, 2.0),
134
random.nextf (0.000001, 2.0));
136
for (int j=0; j < 2; j++)
137
if (random.nextf (0.0, 1.0) >= 0.5)
140
M *= M33f().setScale (s);
146
float h = random.nextf (0.000001, 2.);
147
if (random.nextf (0.0, 1.0) >= 0.5)
150
M *= M33f().setShear (h);
156
float r = rad (random.nextf (-180, 180));
158
M *= M33f().setRotation (r);
164
V2f t (random.nextf (-10, 10),
165
random.nextf (-10, 10));
167
M *= M33f().setTranslation (t);
170
// Add a small random error to the elements of M
173
for (int j = 0; j < 3; ++j)
174
for (int k = 0; k < 2; ++k)
175
M[j][k] += random.nextf (-1e-7, 1e-7);
178
debug (("Scale : %f %f\n", s[0], s[1]));
179
debug (("Shear : %f\n", h));
180
debug (("Rot : %f\n", r));
181
debug (("Trans : %f %f\n", t[0], t[1]));
185
// Extract Euler angles from M, convert the Euler angles
186
// back to a matrix, N, and verify that the entries in M
187
// and N do not differ too much.
198
testAngles33 (float angle)
201
M.setRotation (rad (angle));
204
// With rounding errors from e.toMatrix.
210
// Without rounding errors (assuming that
211
// all angles are multiples of 90 degrees).
214
for (int i = 0; i < 2; ++i)
215
for (int j = 0; j < 2; ++j)
218
else if (M[i][j] > 0.5)
228
testMatrix (const M44f M)
231
// Extract Euler angles from M, and convert the
232
// Euler angles back to a matrix, N.
237
extractSHRT (M, s, h, r, t, true);
241
N.translate (t); // ... matrix compositions
246
debug (("Re-scale: %f %f %f\n", s[0], s[1], s[2]));
247
debug (("Re-shear: %f %f %f\n", h[0], h[1], h[2]));
248
debug (("Re-rot : %f %f %f\n", r[0], r[1], r[2]));
249
debug (("Re-trans: %f %f %f\n", t[0], t[1], t[2]));
252
// Verify that the entries in M and N do not
258
for (int j = 0; j < 4; ++j)
260
for (int k = 0; k < 4; ++k)
262
if (abs (D[j][k]) > 0.00001)
264
cout << "unexpectedly large matrix to "
265
"euler angles conversion error: " <<
268
cout << j << " " << k << endl;
270
cout << "M\n" << M << endl;
271
cout << "N\n" << N << endl;
272
cout << "D\n" << D << endl;
282
testRandomAngles44 ()
286
for (int i = 0; i < 100000; ++i)
288
debug (("iteration: %d\n", i));
296
V3f t (random.nextf (-10, 10),
297
random.nextf (-10, 10),
298
random.nextf (-10, 10));
306
V3f r (rad (random.nextf (-180, 180)),
307
rad (random.nextf (-180, 180)),
308
rad (random.nextf (-180, 180)));
316
V3f h (random.nextf (0.000001, 2.0),
317
random.nextf (0.000001, 2.0),
318
random.nextf (0.000001, 2.0));
320
for (int j=0; j < 3; j++)
321
if (random.nextf (0.0, 1.0) >= 0.5)
330
V3f s (random.nextf (0.000001, 2.0),
331
random.nextf (0.000001, 2.0),
332
random.nextf (0.000001, 2.0));
334
for (int j=0; j < 3; j++)
335
if (random.nextf (0.0, 1.0) >= 0.5)
341
// Add a small random error to the elements of M
344
for (int j = 0; j < 4; ++j)
345
for (int k = 0; k < 3; ++k)
346
M[j][k] += random.nextf (-1e-7, 1e-7);
349
debug (("Scale : %f %f %f\n", s[0], s[1], s[2]));
350
debug (("Shear : %f %f %f\n", h[0], h[1], h[2]));
351
debug (("Rot : %f %f %f\n", r[0], r[1], r[2]));
352
debug (("Trans : %f %f %f\n", t[0], t[1], t[2]));
356
// Extract Euler angles from M, convert the Euler angles
357
// back to a matrix, N, and verify that the entries in M
358
// and N do not differ too much.
369
testAngles44 (V3f angles)
371
Eulerf e (rad (angles.x),
375
M44f M (e.toMatrix44());
378
// With rounding errors from e.toMatrix.
384
// Without rounding errors (assuming that
385
// all angles are multiples of 90 degrees).
388
for (int i = 0; i < 3; ++i)
389
for (int j = 0; j < 3; ++j)
392
else if (M[i][j] > 0.5)
404
cout << " random angles" << endl;
406
cout << " 3x3" << endl;
407
testRandomAngles33 ();
409
cout << " 4x4" << endl;
410
testRandomAngles44 ();
412
cout << " special angles" << endl;
414
cout << " 3x3" << endl;
415
for (int i = 0; i < 360; i += 90)
416
testAngles33 (float (i));
418
cout << " 4x4" << endl;
419
for (int i = 0; i < 360; i += 90)
420
for (int j = 0; j < 360; j += 90)
421
for (int k = 0; k < 360; k += 90)
422
testAngles44 (V3f (i, j, k));
434
cout << "Testing extraction of scale, shear, rotation, translation "
435
<< "from matrices" << endl;
437
cout << "Imath::extractSHRT()" << endl;
440
cout << "ok\n" << endl;
442
catch (std::exception &e)
444
cerr << " Caught exception: " << e.what () << endl;