00001
00034 #include <tut/tut.h>
00035 #include "linden_common.h"
00036 #include "lltut.h"
00037 #include "llquaternion.h"
00038 #include "m3math.h"
00039 #include "v4math.h"
00040 #include "llsd.h"
00041 #include "v3dmath.h"
00042 #include "v3dmath.h"
00043
00044 namespace tut
00045 {
00046 struct v3dmath_data
00047 {
00048 };
00049 typedef test_group<v3dmath_data> v3dmath_test;
00050 typedef v3dmath_test::object v3dmath_object;
00051 tut::v3dmath_test v3dmath_testcase("v3dmath");
00052
00053 template<> template<>
00054 void v3dmath_object::test<1>()
00055 {
00056 LLVector3d vec3D;
00057 ensure("1:LLVector3d:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ])));
00058 F64 x = 2.32f, y = 1.212f, z = -.12f;
00059 LLVector3d vec3Da(x,y,z);
00060 ensure("2:LLVector3d:Fail to initialize ", ((2.32f == vec3Da.mdV[VX]) && (1.212f == vec3Da.mdV[VY]) && (-.12f == vec3Da.mdV[VZ])));
00061 const F64 vec[3] = {1.2f ,3.2f, -4.2f};
00062 LLVector3d vec3Db(vec);
00063 ensure("3:LLVector3d:Fail to initialize ", ((1.2f == vec3Db.mdV[VX]) && (3.2f == vec3Db.mdV[VY]) && (-4.2f == vec3Db.mdV[VZ])));
00064 LLVector3 vec3((F32)x,(F32)y,(F32)z);
00065 LLVector3d vec3Dc(vec3);
00066 ensure_equals("4:LLVector3d Fail to initialize",vec3Da,vec3Dc);
00067 }
00068
00069 template<> template<>
00070 void v3dmath_object::test<2>()
00071 {
00072 S32 a = -235;
00073 LLSD llsd(a);
00074 LLVector3d vec3d(llsd);
00075 LLSD sd = vec3d.getValue();
00076 LLVector3d vec3da(sd);
00077 ensure("1:getValue:Fail ", (vec3d == vec3da));
00078 }
00079
00080 template<> template<>
00081 void v3dmath_object::test<3>()
00082 {
00083 F64 a = 232345521.411132;
00084 LLSD llsd(a);
00085 LLVector3d vec3d;
00086 vec3d.setValue(llsd);
00087 LLSD sd = vec3d.getValue();
00088 LLVector3d vec3da(sd);
00089 ensure("1:setValue:Fail to initialize ", (vec3d == vec3da));
00090 }
00091
00092 template<> template<>
00093 void v3dmath_object::test<4>()
00094 {
00095 F64 a[3] = {222231.43222, 12345.2343, -434343.33222};
00096 LLSD llsd;
00097 llsd[0] = a[0];
00098 llsd[1] = a[1];
00099 llsd[2] = a[2];
00100 LLVector3d vec3D;
00101 vec3D = llsd;
00102 ensure("1:operator=:Fail to initialize ", ((llsd[0].asReal()== vec3D.mdV[VX]) && (llsd[1].asReal() == vec3D.mdV[VY]) && (llsd[2].asReal() == vec3D.mdV[VZ])));
00103 }
00104
00105 template<> template<>
00106 void v3dmath_object::test<5>()
00107 {
00108 F64 x = 2.32f, y = 1.212f, z = -.12f;
00109 LLVector3d vec3D(x,y,z);
00110 vec3D.clearVec();
00111 ensure("1:clearVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ])));
00112 vec3D.setVec(x,y,z);
00113 ensure("2:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ])));
00114 vec3D.zeroVec();
00115 ensure("3:zeroVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ])));
00116 vec3D.clearVec();
00117 LLVector3 vec3((F32)x,(F32)y,(F32)z);
00118 vec3D.setVec(vec3);
00119 ensure("4:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ])));
00120 vec3D.clearVec();
00121 const F64 vec[3] = {x,y,z};
00122 vec3D.setVec(vec);
00123 ensure("5:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ])));
00124 LLVector3d vec3Da;
00125 vec3Da.setVec(vec3D);
00126 ensure_equals("6:setVec: Fail to initialize", vec3D, vec3Da);
00127 }
00128
00129 template<> template<>
00130 void v3dmath_object::test<6>()
00131 {
00132 F64 x = -2.32, y = 1.212, z = -.12;
00133 LLVector3d vec3D(x,y,z);
00134 vec3D.abs();
00135 ensure("1:abs:Fail ", ((-x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (-z == vec3D.mdV[VZ])));
00136 ensure("2:isNull():Fail ", (FALSE == vec3D.isNull()));
00137 vec3D.clearVec();
00138 x =.00000001, y = .000001001, z = .000001001;
00139 vec3D.setVec(x,y,z);
00140 ensure("3:isNull():Fail ", (TRUE == vec3D.isNull()));
00141 ensure("4:isExactlyZero():Fail ", (FALSE == vec3D.isExactlyZero()));
00142 x =.0000000, y = .00000000, z = .00000000;
00143 vec3D.setVec(x,y,z);
00144 ensure("5:isExactlyZero():Fail ", (TRUE == vec3D.isExactlyZero()));
00145 }
00146
00147 template<> template<>
00148 void v3dmath_object::test<7>()
00149 {
00150 F64 x = -2.32, y = 1.212, z = -.12;
00151 LLVector3d vec3D(x,y,z);
00152
00153 ensure("1:operator [] failed",( x == vec3D[0]));
00154 ensure("2:operator [] failed",( y == vec3D[1]));
00155 ensure("3:operator [] failed",( z == vec3D[2]));
00156 vec3D.clearVec();
00157 x = 23.23, y = -.2361, z = 3.25;
00158 vec3D.setVec(x,y,z);
00159 F64 &ref1 = vec3D[0];
00160 ensure("4:operator [] failed",( ref1 == vec3D[0]));
00161 F64 &ref2 = vec3D[1];
00162 ensure("5:operator [] failed",( ref2 == vec3D[1]));
00163 F64 &ref3 = vec3D[2];
00164 ensure("6:operator [] failed",( ref3 == vec3D[2]));
00165 }
00166
00167 template<> template<>
00168 void v3dmath_object::test<8>()
00169 {
00170 F32 x = 1.f, y = 2.f, z = -1.f;
00171 LLVector4 vec4(x,y,z);
00172 LLVector3d vec3D;
00173 vec3D = vec4;
00174 ensure("1:operator=:Fail to initialize ", ((vec4.mV[VX] == vec3D.mdV[VX]) && (vec4.mV[VY] == vec3D.mdV[VY]) && (vec4.mV[VZ] == vec3D.mdV[VZ])));
00175 }
00176
00177 template<> template<>
00178 void v3dmath_object::test<9>()
00179 {
00180 F64 x1 = 1.78787878, y1 = 232322.2121, z1 = -12121.121212;
00181 F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
00182 LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db;
00183 vec3Db = vec3Da+ vec3D;
00184 ensure("1:operator+:Fail to initialize ", ((x1+x2 == vec3Db.mdV[VX]) && (y1+y2 == vec3Db.mdV[VY]) && (z1+z2 == vec3Db.mdV[VZ])));
00185 x1 = -2.45, y1 = 2.1, z1 = 3.0;
00186 vec3D.clearVec();
00187 vec3Da.clearVec();
00188 vec3D.setVec(x1,y1,z1);
00189 vec3Da += vec3D;
00190 ensure_equals("2:operator+=: Fail to initialize", vec3Da,vec3D);
00191 vec3Da += vec3D;
00192 ensure("3:operator+=:Fail to initialize ", ((2*x1 == vec3Da.mdV[VX]) && (2*y1 == vec3Da.mdV[VY]) && (2*z1 == vec3Da.mdV[VZ])));
00193 }
00194
00195 template<> template<>
00196 void v3dmath_object::test<10>()
00197 {
00198 F64 x1 = 1., y1 = 2., z1 = -1.1;
00199 F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
00200 LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db;
00201 vec3Db = vec3Da - vec3D;
00202 ensure("1:operator-:Fail to initialize ", ((x2-x1 == vec3Db.mdV[VX]) && (y2-y1 == vec3Db.mdV[VY]) && (z2-z1 == vec3Db.mdV[VZ])));
00203 x1 = -2.45, y1 = 2.1, z1 = 3.0;
00204 vec3D.clearVec();
00205 vec3Da.clearVec();
00206 vec3D.setVec(x1,y1,z1);
00207 vec3Da -=vec3D;
00208 ensure("2:operator-=:Fail to initialize ", ((2.45 == vec3Da.mdV[VX]) && (-2.1 == vec3Da.mdV[VY]) && (-3.0 == vec3Da.mdV[VZ])));
00209 vec3Da -= vec3D;
00210 ensure("3:operator-=:Fail to initialize ", ((-2*x1 == vec3Da.mdV[VX]) && (-2*y1 == vec3Da.mdV[VY]) && (-2*z1 == vec3Da.mdV[VZ])));
00211 }
00212 template<> template<>
00213 void v3dmath_object::test<11>()
00214 {
00215 F64 x1 = 1., y1 = 2., z1 = -1.1;
00216 F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
00217 LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2);
00218 F64 res = vec3D * vec3Da;
00219 ensure_approximately_equals(
00220 "1:operator* failed",
00221 res,
00222 (x1*x2 + y1*y2 + z1*z2),
00223 8);
00224 vec3Da.clearVec();
00225 F64 mulVal = 4.2;
00226 vec3Da = vec3D * mulVal;
00227 ensure_approximately_equals(
00228 "2a:operator* failed",
00229 vec3Da.mdV[VX],
00230 x1*mulVal,
00231 8);
00232 ensure_approximately_equals(
00233 "2b:operator* failed",
00234 vec3Da.mdV[VY],
00235 y1*mulVal,
00236 8);
00237 ensure_approximately_equals(
00238 "2c:operator* failed",
00239 vec3Da.mdV[VZ],
00240 z1*mulVal,
00241 8);
00242 vec3Da.clearVec();
00243 vec3Da = mulVal * vec3D;
00244 ensure_approximately_equals(
00245 "3a:operator* failed",
00246 vec3Da.mdV[VX],
00247 x1*mulVal,
00248 8);
00249 ensure_approximately_equals(
00250 "3b:operator* failed",
00251 vec3Da.mdV[VY],
00252 y1*mulVal,
00253 8);
00254 ensure_approximately_equals(
00255 "3c:operator* failed",
00256 vec3Da.mdV[VZ],
00257 z1*mulVal,
00258 8);
00259 vec3D *= mulVal;
00260 ensure_approximately_equals(
00261 "4a:operator*= failed",
00262 vec3D.mdV[VX],
00263 x1*mulVal,
00264 8);
00265 ensure_approximately_equals(
00266 "4b:operator*= failed",
00267 vec3D.mdV[VY],
00268 y1*mulVal,
00269 8);
00270 ensure_approximately_equals(
00271 "4c:operator*= failed",
00272 vec3D.mdV[VZ],
00273 z1*mulVal,
00274 8);
00275 }
00276
00277 template<> template<>
00278 void v3dmath_object::test<12>()
00279 {
00280 F64 x1 = 1., y1 = 2., z1 = -1.1;
00281 F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
00282 F64 val1, val2, val3;
00283 LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2), vec3Db;
00284 vec3Db = vec3D % vec3Da;
00285 val1 = y1*z2 - y2*z1;
00286 val2 = z1*x2 -z2*x1;
00287 val3 = x1*y2-x2*y1;
00288 ensure("1:operator% failed",(val1 == vec3Db.mdV[VX]) && (val2 == vec3Db.mdV[VY]) && (val3 == vec3Db.mdV[VZ]));
00289 vec3D %= vec3Da;
00290 ensure("2:operator%= failed",
00291 is_approx_equal(vec3D.mdV[VX],vec3Db.mdV[VX]) &&
00292 is_approx_equal(vec3D.mdV[VY],vec3Db.mdV[VY]) &&
00293 is_approx_equal(vec3D.mdV[VZ],vec3Db.mdV[VZ]) );
00294 }
00295
00296 template<> template<>
00297 void v3dmath_object::test<13>()
00298 {
00299 F64 x1 = 1., y1 = 2., z1 = -1.1,div = 4.2;
00300 F64 t = 1.f / div;
00301 LLVector3d vec3D(x1,y1,z1), vec3Da;
00302 vec3Da = vec3D/div;
00303 ensure_approximately_equals(
00304 "1a:operator/ failed",
00305 vec3Da.mdV[VX],
00306 x1*t,
00307 8);
00308 ensure_approximately_equals(
00309 "1b:operator/ failed",
00310 vec3Da.mdV[VY],
00311 y1*t,
00312 8);
00313 ensure_approximately_equals(
00314 "1c:operator/ failed",
00315 vec3Da.mdV[VZ],
00316 z1*t,
00317 8);
00318 x1 = 1.23, y1 = 4., z1 = -2.32;
00319 vec3D.clearVec();
00320 vec3Da.clearVec();
00321 vec3D.setVec(x1,y1,z1);
00322 vec3Da = vec3D/div;
00323 ensure_approximately_equals(
00324 "2a:operator/ failed",
00325 vec3Da.mdV[VX],
00326 x1*t,
00327 8);
00328 ensure_approximately_equals(
00329 "2b:operator/ failed",
00330 vec3Da.mdV[VY],
00331 y1*t,
00332 8);
00333 ensure_approximately_equals(
00334 "2c:operator/ failed",
00335 vec3Da.mdV[VZ],
00336 z1*t,
00337 8);
00338 vec3D /= div;
00339 ensure_approximately_equals(
00340 "3a:operator/= failed",
00341 vec3D.mdV[VX],
00342 x1*t,
00343 8);
00344 ensure_approximately_equals(
00345 "3b:operator/= failed",
00346 vec3D.mdV[VY],
00347 y1*t,
00348 8);
00349 ensure_approximately_equals(
00350 "3c:operator/= failed",
00351 vec3D.mdV[VZ],
00352 z1*t,
00353 8);
00354 }
00355
00356 template<> template<>
00357 void v3dmath_object::test<14>()
00358 {
00359 F64 x1 = 1., y1 = 2., z1 = -1.1;
00360 LLVector3d vec3D(x1,y1,z1), vec3Da;
00361 ensure("1:operator!= failed",(TRUE == (vec3D !=vec3Da)));
00362 vec3Da = vec3D;
00363 ensure("2:operator== failed",(vec3D ==vec3Da));
00364 vec3D.clearVec();
00365 vec3Da.clearVec();
00366 x1 = .211, y1 = 21.111, z1 = 23.22;
00367 vec3D.setVec(x1,y1,z1);
00368 vec3Da.setVec(x1,y1,z1);
00369 ensure("3:operator== failed",(vec3D ==vec3Da));
00370 ensure("4:operator!= failed",(FALSE == (vec3D !=vec3Da)));
00371 }
00372
00373 template<> template<>
00374 void v3dmath_object::test<15>()
00375 {
00376 F64 x1 = 1., y1 = 2., z1 = -1.1;
00377 LLVector3d vec3D(x1,y1,z1), vec3Da;
00378 std::ostringstream stream1, stream2;
00379 stream1 << vec3D;
00380 vec3Da.setVec(x1,y1,z1);
00381 stream2 << vec3Da;
00382 ensure("1:operator << failed",(stream1.str() == stream2.str()));
00383 }
00384
00385 template<> template<>
00386 void v3dmath_object::test<16>()
00387 {
00388 F64 x1 = 1.23, y1 = 2.0, z1 = 4.;
00389 char buf[] = "1.23 2. 4";
00390 LLVector3d vec3D, vec3Da(x1,y1,z1);
00391 LLVector3d::parseVector3d(buf, &vec3D);
00392 ensure_equals("1:parseVector3d: failed " , vec3D, vec3Da);
00393 }
00394
00395 template<> template<>
00396 void v3dmath_object::test<17>()
00397 {
00398 F64 x1 = 1., y1 = 2., z1 = -1.1;
00399 LLVector3d vec3D(x1,y1,z1), vec3Da;
00400 vec3Da = -vec3D;
00401 ensure("1:operator- failed", (vec3D == - vec3Da));
00402 }
00403
00404 template<> template<>
00405 void v3dmath_object::test<18>()
00406 {
00407 F64 x = 1., y = 2., z = -1.1;
00408 LLVector3d vec3D(x,y,z);
00409 F64 res = (x*x + y*y + z*z) - vec3D.magVecSquared();
00410 ensure("1:magVecSquared:Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO)));
00411 res = fsqrtf(x*x + y*y + z*z) - vec3D.magVec();
00412 ensure("2:magVec: Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO)));
00413 }
00414
00415 template<> template<>
00416 void v3dmath_object::test<19>()
00417 {
00418 F64 x = 1., y = 2., z = -1.1;
00419 LLVector3d vec3D(x,y,z);
00420 F64 mag = vec3D.normVec();
00421 mag = 1.f/ mag;
00422 ensure_approximately_equals(
00423 "1a:normVec: Fail ",
00424 vec3D.mdV[VX],
00425 x * mag,
00426 8);
00427 ensure_approximately_equals(
00428 "1b:normVec: Fail ",
00429 vec3D.mdV[VY],
00430 y * mag,
00431 8);
00432 ensure_approximately_equals(
00433 "1c:normVec: Fail ",
00434 vec3D.mdV[VZ],
00435 z * mag,
00436 8);
00437 x = 0.000000001, y = 0.000000001, z = 0.000000001;
00438 vec3D.clearVec();
00439 vec3D.setVec(x,y,z);
00440 mag = vec3D.normVec();
00441 ensure_approximately_equals(
00442 "2a:normVec: Fail ",
00443 vec3D.mdV[VX],
00444 x * mag,
00445 8);
00446 ensure_approximately_equals(
00447 "2b:normVec: Fail ",
00448 vec3D.mdV[VY],
00449 y * mag,
00450 8);
00451 ensure_approximately_equals(
00452 "2c:normVec: Fail ",
00453 vec3D.mdV[VZ],
00454 z * mag,
00455 8);
00456 }
00457
00458 template<> template<>
00459 void v3dmath_object::test<20>()
00460 {
00461 F64 x1 = 1111.232222;
00462 F64 y1 = 2222222222.22;
00463 F64 z1 = 422222222222.0;
00464 char buf[] = "1111.232222 2222222222.22 422222222222";
00465 LLVector3d vec3Da, vec3Db(x1,y1,z1);
00466 LLVector3d::parseVector3d(buf, &vec3Da);
00467 ensure_equals("1:parseVector3 failed", vec3Da, vec3Db);
00468 }
00469
00470 template<> template<>
00471 void v3dmath_object::test<21>()
00472 {
00473 F64 x1 = 1., y1 = 2., z1 = -1.1;
00474 F64 x2 = 1.2, y2 = 2.5, z2 = 1.;
00475 F64 val = 2.3f,val1,val2,val3;
00476 val1 = x1 + (x2 - x1)* val;
00477 val2 = y1 + (y2 - y1)* val;
00478 val3 = z1 + (z2 - z1)* val;
00479 LLVector3d vec3Da(x1,y1,z1),vec3Db(x2,y2,z2);
00480 LLVector3d vec3d = lerp(vec3Da,vec3Db,val);
00481 ensure("1:lerp failed", ((val1 ==vec3d.mdV[VX])&& (val2 ==vec3d.mdV[VY]) && (val3 ==vec3d.mdV[VZ])));
00482 }
00483
00484 template<> template<>
00485 void v3dmath_object::test<22>()
00486 {
00487 F64 x = 2.32, y = 1.212, z = -.12;
00488 F64 min = 0.0001, max = 3.0;
00489 LLVector3d vec3d(x,y,z);
00490 ensure("1:clamp:Fail ", (TRUE == (vec3d.clamp(min, max))));
00491 x = 0.000001f, z = 5.3f;
00492 vec3d.setVec(x,y,z);
00493 ensure("2:clamp:Fail ", (TRUE == (vec3d.clamp(min, max))));
00494 }
00495
00496 template<> template<>
00497 void v3dmath_object::test<23>()
00498 {
00499 F64 x = 10., y = 20., z = -15.;
00500 F64 epsilon = .23425;
00501 LLVector3d vec3Da(x,y,z), vec3Db(x,y,z);
00502 ensure("1:are_parallel: Fail ", (TRUE == are_parallel(vec3Da,vec3Db,epsilon)));
00503 F64 x1 = -12., y1 = -20., z1 = -100.;
00504 vec3Db.clearVec();
00505 vec3Db.setVec(x1,y1,z1);
00506 ensure("2:are_parallel: Fail ", (FALSE == are_parallel(vec3Da,vec3Db,epsilon)));
00507 }
00508
00509 template<> template<>
00510 void v3dmath_object::test<24>()
00511 {
00512 F64 x = 10., y = 20., z = -15.;
00513 F64 angle1, angle2;
00514 LLVector3d vec3Da(x,y,z), vec3Db(x,y,z);
00515 angle1 = angle_between(vec3Da, vec3Db);
00516 ensure("1:angle_between: Fail ", (0 == angle1));
00517 F64 x1 = -1., y1 = -20., z1 = -1.;
00518 vec3Da.clearVec();
00519 vec3Da.setVec(x1,y1,z1);
00520 angle2 = angle_between(vec3Da, vec3Db);
00521 vec3Db.normVec();
00522 vec3Da.normVec();
00523 F64 angle = vec3Db*vec3Da;
00524 angle = acos(angle);
00525 ensure("2:angle_between: Fail ", (angle == angle2));
00526 }
00527 }