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 }