00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <gtest/gtest.h>
00031 #include <sys/time.h>
00032 #include "LinearMath/btTransform.h"
00033 #include "LinearMath/btTransformUtil.h"
00034 #include "LinearMath/btVector3.h"
00035
00036 void seed_rand()
00037 {
00038
00039 timeval temp_time_struct;
00040 gettimeofday(&temp_time_struct,NULL);
00041 srand(temp_time_struct.tv_usec);
00042 };
00043
00044
00045 TEST(Bullet, QuaternionAngleScaling)
00046 {
00047 double epsilon = 1e-6;
00048
00049 btQuaternion id(0,0,0,1);
00050 btQuaternion ninty(0,0,sqrt(2.0)/2.0,sqrt(2.0)/2.0);
00051 EXPECT_NEAR(id.angle(ninty), SIMD_PI/4, epsilon);
00052
00053 btQuaternion id2(0,0,0);
00054 btQuaternion ninty2(SIMD_PI/2,0,0);
00055 EXPECT_NEAR(id2.angle(ninty2), SIMD_PI/4, epsilon);
00056 }
00057 TEST(Bullet, QuaternionAngleShortestPath)
00058 {
00059 btQuaternion q1 (SIMD_PI/4,0,0);
00060 btQuaternion q2(-q1.x(), -q1.y(), -q1.z()-.0001, -q1.w()+.0001);
00061 q2.normalize();
00062
00063
00064 EXPECT_NEAR(q2.angleShortestPath(q1), 0, 0.01);
00065 }
00066
00067 TEST(Bullet, QuaternionAngleIdentityShortestPath)
00068 {
00069 btQuaternion q1 (SIMD_PI/4,0,0);
00070 btQuaternion q2(-q1.x(), -q1.y(), -q1.z(), -q1.w());
00071 q2.normalize();
00072
00073
00074 EXPECT_NEAR(q2.angleShortestPath(q1), 0, 0.01);
00075 EXPECT_NEAR((q2*(q1.inverse())).getAngleShortestPath(), 0, 0.01);
00076 btQuaternion q3(-q1.x(), -q1.y(), -q1.z(), -q1.w());
00077 q3.normalize();
00078
00079
00080 EXPECT_NEAR(q3.angleShortestPath(q1), 0, 0.01);
00081 EXPECT_NEAR((q3*(q1.inverse())).getAngleShortestPath(), 0, 0.01);
00082
00083 }
00084
00085 TEST(Bullet, AngleQuaternionQuaternionShortestPath)
00086 {
00087 btQuaternion q1 (SIMD_PI/4,0,0);
00088 btQuaternion q2(-q1.x(), -q1.y(), -q1.z()-.0001, -q1.w()+.0001);
00089 q2.normalize();
00090
00091
00092
00093 EXPECT_NEAR(angleShortestPath(q1, q2), 0, 0.01);
00094 }
00095
00096 TEST(Bullet, EulerConventionsYPR)
00097 {
00098 double epsilon = 1e-6;
00099 double yaw, pitch, roll;
00100
00114
00115 yaw = M_PI/2;
00116 pitch = 0;
00117 roll = 0;
00118
00119 btQuaternion q(0,0,0,1);
00120 btVector3 v(1,0,0);
00121 q.setEulerZYX(yaw, pitch,roll);
00122 btTransform tr(q, btVector3(0,0,0));
00123
00124 btVector3 v2 = tr * v;
00125
00126 printf("%f, %f, %f: yaw by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), yaw, v2.x(), v2.y(), v2.z());
00127 EXPECT_NEAR(v2.x(), 0,epsilon);
00128 EXPECT_NEAR(v2.y(), 1,epsilon);
00129 EXPECT_NEAR(v2.z(), 0,epsilon);
00130
00131 btMatrix3x3 mat;
00132 mat.setEulerZYX(yaw, pitch,roll);
00133 tr = btTransform(mat, btVector3(0,0,0));
00134 v2 = tr * v;
00135
00136 printf("%f, %f, %f: yaw by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), yaw, v2.x(), v2.y(), v2.z());
00137 EXPECT_NEAR(v2.x(), 0,epsilon);
00138 EXPECT_NEAR(v2.y(), 1,epsilon);
00139 EXPECT_NEAR(v2.z(), 0,epsilon);
00140
00141 mat.setEulerYPR(yaw, pitch,roll);
00142 tr = btTransform(mat, btVector3(0,0,0));
00143 v2 = tr * v;
00144
00145 printf("%f, %f, %f: yaw by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), yaw, v2.x(), v2.y(), v2.z());
00146 EXPECT_NEAR(v2.x(), 0,epsilon);
00147 EXPECT_NEAR(v2.y(), 1,epsilon);
00148 EXPECT_NEAR(v2.z(), 0,epsilon);
00149
00150
00151 yaw = 0;
00152 pitch = M_PI/2;
00153 roll = 0;
00154
00155 q = btQuaternion(0,0,0);
00156 v = btVector3(1,0,0);
00157 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00158
00159 v2 = tr * v;
00160
00161 printf("%f, %f, %f: pitch by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00162 EXPECT_NEAR(v2.x(), 0,epsilon);
00163 EXPECT_NEAR(v2.y(), 0,epsilon);
00164 EXPECT_NEAR(v2.z(), -1,epsilon);
00165
00166
00167 yaw = 0;
00168 pitch = 0;
00169 roll = M_PI/2;
00170
00171 q = btQuaternion(0,0,0);
00172 v = btVector3(0,1,0);
00173 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00174
00175 v2 = tr * v;
00176
00177 printf("%f, %f, %f: roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), roll, v2.x(), v2.y(), v2.z());
00178 EXPECT_NEAR(v2.x(), 0,epsilon);
00179 EXPECT_NEAR(v2.y(), 0,epsilon);
00180 EXPECT_NEAR(v2.z(), 1,epsilon);
00181
00182
00183 yaw = M_PI/2;
00184 pitch = 0;
00185 roll = M_PI/2;
00186
00187 q = btQuaternion(0,0,0);
00188 v = btVector3(1,0,0);
00189 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00190
00191 v2 = tr * v;
00192
00193 printf("%f, %f, %f: yaw and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), roll, v2.x(), v2.y(), v2.z());
00194 EXPECT_NEAR(v2.x(), 0,epsilon);
00195 EXPECT_NEAR(v2.y(), 1,epsilon);
00196 EXPECT_NEAR(v2.z(), 0,epsilon);
00197
00198 q = btQuaternion(0,0,0);
00199 v = btVector3(0,1,0);
00200 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00201
00202 v2 = tr * v;
00203
00204 printf("%f, %f, %f: yaw and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), roll, v2.x(), v2.y(), v2.z());
00205 EXPECT_NEAR(v2.x(), 0,epsilon);
00206 EXPECT_NEAR(v2.y(), 0,epsilon);
00207 EXPECT_NEAR(v2.z(), 1,epsilon);
00208
00209 q = btQuaternion(0,0,0);
00210 v = btVector3(0,0,1);
00211 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00212
00213 v2 = tr * v;
00214
00215 printf("%f, %f, %f: yaw and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), roll, v2.x(), v2.y(), v2.z());
00216 EXPECT_NEAR(v2.x(), 1,epsilon);
00217 EXPECT_NEAR(v2.y(), 0,epsilon);
00218 EXPECT_NEAR(v2.z(), 0,epsilon);
00219
00220
00221 yaw = M_PI/2;
00222 pitch = M_PI/2;
00223 roll = 0;
00224
00225 q = btQuaternion(0,0,0);
00226 v = btVector3(1,0,0);
00227 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00228
00229 v2 = tr * v;
00230
00231 printf("%f, %f, %f: yaw and pitch by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00232 EXPECT_NEAR(v2.x(), 0,epsilon);
00233 EXPECT_NEAR(v2.y(), 0,epsilon);
00234 EXPECT_NEAR(v2.z(), -1,epsilon);
00235
00236 q = btQuaternion(0,0,0);
00237 v = btVector3(0,1,0);
00238 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00239
00240 v2 = tr * v;
00241
00242 printf("%f, %f, %f: yaw and pitch by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00243 EXPECT_NEAR(v2.x(), -1,epsilon);
00244 EXPECT_NEAR(v2.y(), 0,epsilon);
00245 EXPECT_NEAR(v2.z(), 0,epsilon);
00246
00247 q = btQuaternion(0,0,0);
00248 v = btVector3(0,0,1);
00249 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00250
00251 v2 = tr * v;
00252
00253 printf("%f, %f, %f: yaw and pitch by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00254 EXPECT_NEAR(v2.x(), 0,epsilon);
00255 EXPECT_NEAR(v2.y(), 1,epsilon);
00256 EXPECT_NEAR(v2.z(), 0,epsilon);
00257
00258
00259 yaw = 0;
00260 pitch = M_PI/2;
00261 roll = M_PI/2;
00262
00263 q = btQuaternion(0,0,0);
00264 v = btVector3(1,0,0);
00265 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00266
00267 v2 = tr * v;
00268
00269 printf("%f, %f, %f: pitch and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00270 EXPECT_NEAR(v2.x(), 0,epsilon);
00271 EXPECT_NEAR(v2.y(), 0,epsilon);
00272 EXPECT_NEAR(v2.z(), -1,epsilon);
00273
00274 q = btQuaternion(0,0,0);
00275 v = btVector3(0,1,0);
00276 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00277
00278 v2 = tr * v;
00279
00280 printf("%f, %f, %f: pitch and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00281 EXPECT_NEAR(v2.x(), 1,epsilon);
00282 EXPECT_NEAR(v2.y(), 0,epsilon);
00283 EXPECT_NEAR(v2.z(), 0,epsilon);
00284
00285 q = btQuaternion(0,0,0);
00286 v = btVector3(0,0,1);
00287 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00288
00289 v2 = tr * v;
00290
00291 printf("%f, %f, %f: pitch and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00292 EXPECT_NEAR(v2.x(), 0,epsilon);
00293 EXPECT_NEAR(v2.y(), -1,epsilon);
00294 EXPECT_NEAR(v2.z(), 0,epsilon);
00295 };
00296
00297 TEST(Bullet, EulerConventionsConstructors)
00298 {
00299 double epsilon = 1e-6;
00300 double yaw, pitch, roll;
00301
00315
00316 yaw = M_PI/2;
00317 pitch = 0;
00318 roll = 0;
00319
00320 btQuaternion q(0,0,0);
00321 btVector3 v(1,0,0);
00322 btTransform tr(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00323
00324 btVector3 v2 = tr * v;
00325
00326 printf("%f, %f, %f: yaw by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), yaw, v2.x(), v2.y(), v2.z());
00327 EXPECT_NEAR(v2.x(), 0,epsilon);
00328 EXPECT_NEAR(v2.y(), 1,epsilon);
00329 EXPECT_NEAR(v2.z(), 0,epsilon);
00330
00331
00332 yaw = 0;
00333 pitch = M_PI/2;
00334 roll = 0;
00335
00336 q = btQuaternion(0,0,0);
00337 v = btVector3(1,0,0);
00338 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00339
00340 v2 = tr * v;
00341
00342 printf("%f, %f, %f: pitch by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00343 EXPECT_NEAR(v2.x(), 0,epsilon);
00344 EXPECT_NEAR(v2.y(), 0,epsilon);
00345 EXPECT_NEAR(v2.z(), -1,epsilon);
00346
00347
00348 yaw = 0;
00349 pitch = 0;
00350 roll = M_PI/2;
00351
00352 q = btQuaternion(0,0,0);
00353 v = btVector3(0,1,0);
00354 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00355
00356 v2 = tr * v;
00357
00358 printf("%f, %f, %f: roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), roll, v2.x(), v2.y(), v2.z());
00359 EXPECT_NEAR(v2.x(), 0,epsilon);
00360 EXPECT_NEAR(v2.y(), 0,epsilon);
00361 EXPECT_NEAR(v2.z(), 1,epsilon);
00362
00363
00364 yaw = M_PI/2;
00365 pitch = 0;
00366 roll = M_PI/2;
00367
00368 q = btQuaternion(0,0,0);
00369 v = btVector3(1,0,0);
00370 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00371
00372 v2 = tr * v;
00373
00374 printf("%f, %f, %f: yaw and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), roll, v2.x(), v2.y(), v2.z());
00375 EXPECT_NEAR(v2.x(), 0,epsilon);
00376 EXPECT_NEAR(v2.y(), 1,epsilon);
00377 EXPECT_NEAR(v2.z(), 0,epsilon);
00378
00379 q = btQuaternion(0,0,0);
00380 v = btVector3(0,1,0);
00381 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00382
00383 v2 = tr * v;
00384
00385 printf("%f, %f, %f: yaw and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), roll, v2.x(), v2.y(), v2.z());
00386 EXPECT_NEAR(v2.x(), 0,epsilon);
00387 EXPECT_NEAR(v2.y(), 0,epsilon);
00388 EXPECT_NEAR(v2.z(), 1,epsilon);
00389
00390 q = btQuaternion(0,0,0);
00391 v = btVector3(0,0,1);
00392 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00393
00394 v2 = tr * v;
00395
00396 printf("%f, %f, %f: yaw and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), roll, v2.x(), v2.y(), v2.z());
00397 EXPECT_NEAR(v2.x(), 1,epsilon);
00398 EXPECT_NEAR(v2.y(), 0,epsilon);
00399 EXPECT_NEAR(v2.z(), 0,epsilon);
00400
00401
00402 yaw = M_PI/2;
00403 pitch = M_PI/2;
00404 roll = 0;
00405
00406 q = btQuaternion(0,0,0);
00407 v = btVector3(1,0,0);
00408 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00409
00410 v2 = tr * v;
00411
00412 printf("%f, %f, %f: yaw and pitch by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00413 EXPECT_NEAR(v2.x(), 0,epsilon);
00414 EXPECT_NEAR(v2.y(), 0,epsilon);
00415 EXPECT_NEAR(v2.z(), -1,epsilon);
00416
00417 q = btQuaternion(0,0,0);
00418 v = btVector3(0,1,0);
00419 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00420
00421 v2 = tr * v;
00422
00423 printf("%f, %f, %f: yaw and pitch by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00424 EXPECT_NEAR(v2.x(), -1,epsilon);
00425 EXPECT_NEAR(v2.y(), 0,epsilon);
00426 EXPECT_NEAR(v2.z(), 0,epsilon);
00427
00428 q = btQuaternion(0,0,0);
00429 v = btVector3(0,0,1);
00430 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00431
00432 v2 = tr * v;
00433
00434 printf("%f, %f, %f: yaw and pitch by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00435 EXPECT_NEAR(v2.x(), 0,epsilon);
00436 EXPECT_NEAR(v2.y(), 1,epsilon);
00437 EXPECT_NEAR(v2.z(), 0,epsilon);
00438
00439
00440 yaw = 0;
00441 pitch = M_PI/2;
00442 roll = M_PI/2;
00443
00444 q = btQuaternion(0,0,0);
00445 v = btVector3(1,0,0);
00446 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00447
00448 v2 = tr * v;
00449
00450 printf("%f, %f, %f: pitch and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00451 EXPECT_NEAR(v2.x(), 0,epsilon);
00452 EXPECT_NEAR(v2.y(), 0,epsilon);
00453 EXPECT_NEAR(v2.z(), -1,epsilon);
00454
00455 q = btQuaternion(0,0,0);
00456 v = btVector3(0,1,0);
00457 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00458
00459 v2 = tr * v;
00460
00461 printf("%f, %f, %f: pitch and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00462 EXPECT_NEAR(v2.x(), 1,epsilon);
00463 EXPECT_NEAR(v2.y(), 0,epsilon);
00464 EXPECT_NEAR(v2.z(), 0,epsilon);
00465
00466 q = btQuaternion(0,0,0);
00467 v = btVector3(0,0,1);
00468 tr = btTransform(btQuaternion(yaw, pitch,roll), btVector3(0,0,0));
00469
00470 v2 = tr * v;
00471
00472 printf("%f, %f, %f: pitch and roll by %f -> %f, %f, %f\n", v.x(), v.y(), v.z(), pitch, v2.x(), v2.y(), v2.z());
00473 EXPECT_NEAR(v2.x(), 0,epsilon);
00474 EXPECT_NEAR(v2.y(), -1,epsilon);
00475 EXPECT_NEAR(v2.z(), 0,epsilon);
00476 };
00477
00478 TEST(Bullet, Angle)
00479 {
00480 seed_rand();
00481 unsigned int num_steps = 1000;
00482 double epsilon = 1e-3;
00483 btQuaternion q1(0, 0, 0, 1);
00484 for(unsigned int i = 0; i < num_steps; ++i){
00485 double q1_angle = 1.0 * i / num_steps * 2. * M_PI;
00486 q1.setRPY(1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX, 1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX, q1_angle);
00487 for(unsigned int j = 0; j < num_steps; j++){
00488 btQuaternion q2;
00489 double q2_angle = 1.0 * j / num_steps * 2. * M_PI;
00490 q2.setRPY(1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX, 1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX, q2_angle);
00491
00492
00493 double ratio = (double) rand() / (double) RAND_MAX;
00494 EXPECT_GE(ratio, 0.0);
00495 EXPECT_LE(ratio, 1.0);
00496
00497 btQuaternion q3 = q2.slerp(q1, ratio);
00498 EXPECT_NEAR(angleShortestPath(q3, q2), angleShortestPath(q2, q1) * ratio, epsilon);
00499 EXPECT_NEAR(angleShortestPath(q3, q1), angleShortestPath(q2, q1) * (1 - ratio), epsilon);
00500
00501 btQuaternion q4 = q1.slerp(q2, ratio);
00502 EXPECT_NEAR(angleShortestPath(q4, q1), angleShortestPath(q2, q1) * ratio, epsilon);
00503 EXPECT_NEAR(angleShortestPath(q4, q2), angleShortestPath(q2, q1) * (1 - ratio), epsilon);
00504
00505
00506
00507
00508
00509
00510
00511 q2.setX(-1.0 * q2.x());
00512 q2.setY(-1.0 * q2.y());
00513 q2.setZ(-1.0 * q2.z());
00514 q2.setW(-1.0 * q2.w());
00515
00516
00517 q3 = q2.slerp(q1, ratio);
00518 EXPECT_NEAR(angleShortestPath(q3, q2), angleShortestPath(q2, q1) * ratio, epsilon);
00519 EXPECT_NEAR(angleShortestPath(q3, q1), angleShortestPath(q2, q1) * (1 - ratio), epsilon);
00520
00521 q4 = q1.slerp(q2, ratio);
00522 EXPECT_NEAR(angleShortestPath(q4, q1), angleShortestPath(q2, q1) * ratio, epsilon);
00523 EXPECT_NEAR(angleShortestPath(q4, q2), angleShortestPath(q2, q1) * (1 - ratio), epsilon);
00524
00525 EXPECT_LT(angleShortestPath(q1, q2), M_PI);
00526 }
00527 }
00528
00529 btQuaternion q5(-0.00285953665482, 0.0134168786627, 0.871697390887, -0.489852497327);
00530 btQuaternion q6(0.00256516236927, -0.0136650510447, -0.865612832372, 0.500520839481);
00531
00532 btQuaternion q7 = q6.slerp(q5, 0.5);
00533 EXPECT_NEAR(angleShortestPath(q7, q5), angleShortestPath(q5, q6) / 2, epsilon);
00534 EXPECT_NEAR(angleShortestPath(q7, q6), angleShortestPath(q5, q6) / 2, epsilon);
00535
00536 btQuaternion q8 = q5.slerp(q6, 0.5);
00537 EXPECT_NEAR(angleShortestPath(q8, q5), angleShortestPath(q5, q6) / 2, epsilon);
00538 EXPECT_NEAR(angleShortestPath(q8, q6), angleShortestPath(q5, q6) / 2, epsilon);
00539 }
00540
00541
00542 TEST(Bullet, Slerp)
00543 {
00544
00545 unsigned int runs = 100;
00546 seed_rand();
00547
00548 btQuaternion q1, q2;
00549 q1.setEuler(0,0,0);
00550
00551 for (unsigned int i = 0 ; i < runs ; i++)
00552 {
00553 q2.setEuler(1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX,
00554 1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX,
00555 1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX);
00556
00557
00558 btQuaternion q3 = slerp(q1,q2,0.5);
00559
00560 EXPECT_NEAR(q3.angle(q1), q2.angle(q3), 1e-5);
00561 }
00562
00563 }
00564
00565 TEST(Bullet, QuaternionMultiplication)
00566 {
00567 btQuaternion q1 (btVector3(1,0,0), M_PI/2.0);
00568 btQuaternion q2 (btVector3(0,0,1), M_PI/2.0);
00569
00570 btQuaternion q3 = q1*q2;
00571 printf("(%f,%f,%f,%f)*(%f,%f,%f,%f)=(%f,%f,%f,%f)\n",q1.x(), q1.y(), q1.z(), q1.getAngle(), q2.x(), q2.y(), q2.z(), q2.getAngle(), q3.x(), q3.y(), q3.z(), q3.getAngle());
00572
00573 btMatrix3x3 m3(q3);
00574
00575 btVector3 xout = m3*btVector3(1,0,0);
00576 btVector3 yout = m3*btVector3(0,1,0);
00577 btVector3 zout = m3*btVector3(0,0,1);
00578 printf("(%f, %f, %f), (%f, %f, %f), (%f, %f, %f)\n",
00579 xout.x(), xout.y(), xout.z() ,
00580 yout.x(), yout.y(), yout.z() ,
00581 zout.x(), zout.y(), zout.z());
00582
00583 q3 = q2*q1;
00584 printf("(%f,%f,%f,%f)*(%f,%f,%f,%f)=(%f,%f,%f,%f)\n",q2.x(), q2.y(), q2.z(), q2.getAngle(), q1.x(), q1.y(), q1.z(), q1.getAngle(), q3.x(), q3.y(), q3.z(), q3.getAngle());
00585
00586 m3.setRotation(q3);
00587
00588 xout = m3*btVector3(1,0,0);
00589 yout = m3*btVector3(0,1,0);
00590 zout = m3*btVector3(0,0,1);
00591 printf("(%f, %f, %f), (%f, %f, %f), (%f, %f, %f)\n",
00592 xout.x(), xout.y(), xout.z() ,
00593 yout.x(), yout.y(), yout.z() ,
00594 zout.x(), zout.y(), zout.z());
00595 }
00596 TEST(Bullet, QuaternionTimesEqual)
00597 {
00598 btQuaternion q1 (btVector3(1,0,0), M_PI/2.0);
00599 btQuaternion q2 (btVector3(0,0,1), M_PI/2.0);
00600
00601 btQuaternion q3 (q1);
00602 q3*=q2;
00603 printf("(%f,%f,%f,%f)*(%f,%f,%f,%f)=(%f,%f,%f,%f)\n",q1.x(), q1.y(), q1.z(), q1.getAngle(), q2.x(), q2.y(), q2.z(), q2.getAngle(), q3.x(), q3.y(), q3.z(), q3.getAngle());
00604
00605 btMatrix3x3 m3(q3);
00606
00607 btVector3 xout = m3*btVector3(1,0,0);
00608 btVector3 yout = m3*btVector3(0,1,0);
00609 btVector3 zout = m3*btVector3(0,0,1);
00610 printf("(%f, %f, %f), (%f, %f, %f), (%f, %f, %f)\n",
00611 xout.x(), xout.y(), xout.z() ,
00612 yout.x(), yout.y(), yout.z() ,
00613 zout.x(), zout.y(), zout.z());
00614 q3 = q1;
00615 q3*=q1;
00616 printf("(%f,%f,%f,%f)*(%f,%f,%f,%f)=(%f,%f,%f,%f)\n",q2.x(), q2.y(), q2.z(), q2.getAngle(), q1.x(), q1.y(), q1.z(), q1.getAngle(), q3.x(), q3.y(), q3.z(), q3.getAngle());
00617
00618 m3.setRotation(q3);
00619
00620 xout = m3*btVector3(1,0,0);
00621 yout = m3*btVector3(0,1,0);
00622 zout = m3*btVector3(0,0,1);
00623 printf("(%f, %f, %f), (%f, %f, %f), (%f, %f, %f)\n",
00624 xout.x(), xout.y(), xout.z() ,
00625 yout.x(), yout.y(), yout.z() ,
00626 zout.x(), zout.y(), zout.z());
00627 }
00628
00629 TEST (Bullet, downcast)
00630 {
00631 btVector3 v (1,2,3);
00632 btVector3 v2(v);
00633
00634 }
00635
00636 TEST(Bullet, TransformOrder )
00637 {
00638 btTransform tf(btQuaternion(1,0,0));
00639 btTransform tf2(btQuaternion(0,0,0),btVector3(100,0,0));
00640
00641 btTransform tf3 = tf * tf2;
00642
00643 tf*= tf2;
00644 EXPECT_TRUE(tf3 == tf);
00645
00646 tf = btTransform(btQuaternion(1,0,0));
00647 tf3 = tf;
00648
00649 EXPECT_TRUE(tf.inverse() * tf2 == tf.inverseTimes(tf2));
00650
00651
00652 }
00653
00654
00655 TEST(Bullet, SlerpZeroDistanceOppositeSigns)
00656 {
00657 btQuaternion q1 (M_PI/4,0,0);
00658 btQuaternion q2(-q1.x(), -q1.y(), -q1.z()-.0001, -q1.w()+.0001);
00659 q2.normalize();
00660 btQuaternion q3 = q2.slerp(q1, .5);
00661
00662
00663
00664 EXPECT_NEAR(q1.angleShortestPath(q2), 0, 0.01);
00665 EXPECT_NEAR(q2.angleShortestPath(q2), 0, 0.01);
00666 EXPECT_NEAR(q1.angleShortestPath(q3), 0, 0.01);
00667 }
00668
00669 TEST(Bullet, SetEulerZYX)
00670 {
00671 btMatrix3x3 mat;
00672 mat.setEulerZYX(M_PI/2, 0, 0);
00673 double yaw, pitch, roll;
00674 mat.getEulerZYX(yaw, pitch, roll);
00675 EXPECT_NEAR(yaw, M_PI/2, 0.1);
00676 EXPECT_NEAR(pitch, 0, 0.1);
00677 EXPECT_NEAR(roll, 0, 0.1);
00678
00679 btQuaternion q;
00680 mat.getRotation(q);
00681 EXPECT_NEAR(q.z(), sqrt(2)/2, 0.1);
00682 EXPECT_NEAR(q.y(), 0, 0.1);
00683 EXPECT_NEAR(q.x(), 0, 0.1);
00684 EXPECT_NEAR(q.w(), sqrt(2)/2, 0.1);
00685
00686 }
00687
00688
00689
00690 TEST(Bullet, calculateDiffAxisAngleQuaternion)
00691 {
00692 btVector3 vec;
00693 btScalar ang;
00694 for (unsigned int i = 1 ; i < 1000 ; i++)
00695 {
00696 btQuaternion q1(M_PI*2 *(double) i / 1000, 0, 0);
00697 btQuaternion q2(M_PI/2*0, 0,0);
00698 btTransformUtil::calculateDiffAxisAngleQuaternion(q1, q2, vec, ang);
00699
00700 EXPECT_NEAR(std::min(M_PI*2 *(double) i / 1000, 2 * M_PI - M_PI*2 *(double) i / 1000), ang, 0.001);
00701 btTransformUtil::calculateDiffAxisAngleQuaternion(q2, q1, vec, ang);
00702
00703 if (i <= 500)
00704 EXPECT_NEAR( vec.z(), 1.0, 0.001);
00705 else
00706 EXPECT_NEAR( vec.z(), -1.0, 0.001);
00707
00708 EXPECT_NEAR(std::min(M_PI*2 *(double) i / 1000, 2 * M_PI - M_PI*2 *(double) i / 1000), ang, 0.001);
00709 if (i <= 500)
00710 EXPECT_NEAR( vec.z(), 1.0, 0.001);
00711 else
00712 EXPECT_NEAR( vec.z(), -1.0, 0.001);
00713 }
00714 for (unsigned int i = 1 ; i < 1000 ; i++)
00715 {
00716 btQuaternion q1(0, M_PI*2 *(double) i / 1000,1);
00717 btQuaternion q2(0, 0, 1);
00718 btTransformUtil::calculateDiffAxisAngleQuaternion(q1, q2, vec, ang);
00719
00720 EXPECT_NEAR(std::min(M_PI*2 *(double) i / 1000, 2 * M_PI - M_PI*2 *(double) i / 1000), ang, 0.001);
00721 if (i < 500)
00722 EXPECT_NEAR( vec.y(), -1.0, 0.001);
00723 else if (i > 501)
00724 EXPECT_NEAR( vec.y(), 1.0, 0.001);
00725 else
00726 EXPECT_NEAR( fabs(vec.y()), 1.0, 0.001);
00727 btTransformUtil::calculateDiffAxisAngleQuaternion(q2, q1, vec, ang);
00728
00729 EXPECT_NEAR(std::min(M_PI*2 *(double) i / 1000, 2 * M_PI - M_PI*2 *(double) i / 1000), ang, 0.001);
00730 if (i < 500)
00731 EXPECT_NEAR( vec.y(), 1.0, 0.001);
00732 else if (i > 500)
00733 EXPECT_NEAR( vec.y(), -1.0, 0.001);
00734 else
00735 EXPECT_NEAR( fabs(vec.y()), 1.0, 0.001);
00736 }
00737 for (unsigned int i = 1 ; i < 1000 ; i++)
00738 {
00739 btQuaternion q1(0, 0, M_PI*2 *(double) i / 1000);
00740 btQuaternion q2(0, 0,0);
00741 btTransformUtil::calculateDiffAxisAngleQuaternion(q1, q2, vec, ang);
00742
00743 EXPECT_NEAR(std::min(M_PI*2 *(double) i / 1000, 2 * M_PI - M_PI*2 *(double) i / 1000), ang, 0.001);
00744 if (i <= 500)
00745 EXPECT_NEAR( vec.x(), -1.0, 0.001);
00746 else
00747 EXPECT_NEAR( vec.x(), 1.0, 0.001);
00748 btTransformUtil::calculateDiffAxisAngleQuaternion(q2, q1, vec, ang);
00749
00750 EXPECT_NEAR(std::min(M_PI*2 *(double) i / 1000, 2 * M_PI - M_PI*2 *(double) i / 1000), ang, 0.001);
00751 if (i <= 500)
00752 EXPECT_NEAR( vec.x(), 1.0, 0.001);
00753 else
00754 EXPECT_NEAR( vec.x(), -1.0, 0.001);
00755 }
00756 }
00757
00758
00759 int main(int argc, char **argv){
00760 testing::InitGoogleTest(&argc, argv);
00761 return RUN_ALL_TESTS();
00762 }