1 // 2 // Copyright (c) 2010-2011 Linaro Limited 3 // 4 // All rights reserved. This program and the accompanying materials 5 // are made available under the terms of the MIT License which accompanies 6 // this distribution, and is available at 7 // http://www.opensource.org/licenses/mit-license.php 8 // 9 // Contributors: 10 // Jesse Barker - original implementation. 11 // 12 #ifndef VEC_H_ 13 #define VEC_H_ 14 15 #include <iostream> // only needed for print() functions... 16 #include <math.h> 17 18 namespace LibMatrix 19 { 20 // A template class for creating, managing and operating on a 2-element vector 21 // of any type you like (intended for built-in types, but as long as it 22 // supports the basic arithmetic and assignment operators, any type should 23 // work). 24 template<typename T> 25 class tvec2 26 { 27 public: tvec2()28 tvec2() : 29 x_(0), 30 y_(0) {} tvec2(const T t)31 tvec2(const T t) : 32 x_(t), 33 y_(t) {} tvec2(const T x,const T y)34 tvec2(const T x, const T y) : 35 x_(x), 36 y_(y) {} tvec2(const tvec2 & v)37 tvec2(const tvec2& v) : 38 x_(v.x_), 39 y_(v.y_) {} ~tvec2()40 ~tvec2() {} 41 42 // Print the elements of the vector to standard out. 43 // Really only useful for debug and test. print()44 void print() const 45 { 46 std::cout << "| " << x_ << " " << y_ << " |" << std::endl; 47 } 48 49 // Allow raw data access for API calls and the like. 50 // For example, it is valid to pass a tvec2<float> into a call to 51 // the OpenGL command "glUniform2fv()". 52 operator const T*() const { return &x_;} 53 54 // Get and set access members for the individual elements. x()55 const T x() const { return x_; } y()56 const T y() const { return y_; } 57 x(const T & val)58 void x(const T& val) { x_ = val; } y(const T & val)59 void y(const T& val) { y_ = val; } 60 61 // A direct assignment of 'rhs' to this. Return a reference to this. 62 tvec2& operator=(const tvec2& rhs) 63 { 64 if (this != &rhs) 65 { 66 x_ = rhs.x_; 67 y_ = rhs.y_; 68 } 69 return *this; 70 } 71 72 // Divide this by a scalar. Return a reference to this. 73 tvec2& operator/=(const T& rhs) 74 { 75 x_ /= rhs; 76 y_ /= rhs; 77 return *this; 78 } 79 80 // Divide a copy of this by a scalar. Return the copy. 81 const tvec2 operator/(const T& rhs) const 82 { 83 return tvec2(*this) /= rhs; 84 } 85 86 // Component-wise divide of this by another vector. 87 // Return a reference to this. 88 tvec2& operator/=(const tvec2& rhs) 89 { 90 x_ /= rhs.x_; 91 y_ /= rhs.y_; 92 return *this; 93 } 94 95 // Component-wise divide of a copy of this by another vector. 96 // Return the copy. 97 const tvec2 operator/(const tvec2& rhs) const 98 { 99 return tvec2(*this) /= rhs; 100 } 101 102 // Multiply this by a scalar. Return a reference to this. 103 tvec2& operator*=(const T& rhs) 104 { 105 x_ *= rhs; 106 y_ *= rhs; 107 return *this; 108 } 109 110 // Multiply a copy of this by a scalar. Return the copy. 111 const tvec2 operator*(const T& rhs) const 112 { 113 return tvec2(*this) *= rhs; 114 } 115 116 // Component-wise multiply of this by another vector. 117 // Return a reference to this. 118 tvec2& operator*=(const tvec2& rhs) 119 { 120 x_ *= rhs.x_; 121 y_ *= rhs.y_; 122 return *this; 123 } 124 125 // Component-wise multiply of a copy of this by another vector. 126 // Return the copy. 127 const tvec2 operator*(const tvec2& rhs) const 128 { 129 return tvec2(*this) *= rhs; 130 } 131 132 // Add a scalar to this. Return a reference to this. 133 tvec2& operator+=(const T& rhs) 134 { 135 x_ += rhs; 136 y_ += rhs; 137 return *this; 138 } 139 140 // Add a scalar to a copy of this. Return the copy. 141 const tvec2 operator+(const T& rhs) const 142 { 143 return tvec2(*this) += rhs; 144 } 145 146 // Component-wise addition of another vector to this. 147 // Return a reference to this. 148 tvec2& operator+=(const tvec2& rhs) 149 { 150 x_ += rhs.x_; 151 y_ += rhs.y_; 152 return *this; 153 } 154 155 // Component-wise addition of another vector to a copy of this. 156 // Return the copy. 157 const tvec2 operator+(const tvec2& rhs) const 158 { 159 return tvec2(*this) += rhs; 160 } 161 162 // Subtract a scalar from this. Return a reference to this. 163 tvec2& operator-=(const T& rhs) 164 { 165 x_ -= rhs; 166 y_ -= rhs; 167 return *this; 168 } 169 170 // Subtract a scalar from a copy of this. Return the copy. 171 const tvec2 operator-(const T& rhs) const 172 { 173 return tvec2(*this) -= rhs; 174 } 175 176 // Component-wise subtraction of another vector from this. 177 // Return a reference to this. 178 tvec2& operator-=(const tvec2& rhs) 179 { 180 x_ -= rhs.x_; 181 y_ -= rhs.y_; 182 return *this; 183 } 184 185 // Component-wise subtraction of another vector from a copy of this. 186 // Return the copy. 187 const tvec2 operator-(const tvec2& rhs) const 188 { 189 return tvec2(*this) -= rhs; 190 } 191 192 // Compute the length of this and return it. length()193 float length() const 194 { 195 return sqrt(dot(*this, *this)); 196 } 197 198 // Make this a unit vector. normalize()199 void normalize() 200 { 201 float l = length(); 202 x_ /= l; 203 y_ /= l; 204 } 205 206 // Compute the dot product of two vectors. dot(const tvec2 & v1,const tvec2 & v2)207 static T dot(const tvec2& v1, const tvec2& v2) 208 { 209 return (v1.x_ * v2.x_) + (v1.y_ * v2.y_); 210 } 211 212 private: 213 T x_; 214 T y_; 215 }; 216 217 // A template class for creating, managing and operating on a 3-element vector 218 // of any type you like (intended for built-in types, but as long as it 219 // supports the basic arithmetic and assignment operators, any type should 220 // work). 221 template<typename T> 222 class tvec3 223 { 224 public: tvec3()225 tvec3() : 226 x_(0), 227 y_(0), 228 z_(0) {} tvec3(const T t)229 tvec3(const T t) : 230 x_(t), 231 y_(t), 232 z_(t) {} tvec3(const T x,const T y,const T z)233 tvec3(const T x, const T y, const T z) : 234 x_(x), 235 y_(y), 236 z_(z) {} tvec3(const tvec3 & v)237 tvec3(const tvec3& v) : 238 x_(v.x_), 239 y_(v.y_), 240 z_(v.z_) {} ~tvec3()241 ~tvec3() {} 242 243 // Print the elements of the vector to standard out. 244 // Really only useful for debug and test. print()245 void print() const 246 { 247 std::cout << "| " << x_ << " " << y_ << " " << z_ << " |" << std::endl; 248 } 249 250 // Allow raw data access for API calls and the like. 251 // For example, it is valid to pass a tvec3<float> into a call to 252 // the OpenGL command "glUniform3fv()". 253 operator const T*() const { return &x_;} 254 255 // Get and set access members for the individual elements. x()256 const T x() const { return x_; } y()257 const T y() const { return y_; } z()258 const T z() const { return z_; } 259 x(const T & val)260 void x(const T& val) { x_ = val; } y(const T & val)261 void y(const T& val) { y_ = val; } z(const T & val)262 void z(const T& val) { z_ = val; } 263 264 // A direct assignment of 'rhs' to this. Return a reference to this. 265 tvec3& operator=(const tvec3& rhs) 266 { 267 if (this != &rhs) 268 { 269 x_ = rhs.x_; 270 y_ = rhs.y_; 271 z_ = rhs.z_; 272 } 273 return *this; 274 } 275 276 // Divide this by a scalar. Return a reference to this. 277 tvec3& operator/=(const T& rhs) 278 { 279 x_ /= rhs; 280 y_ /= rhs; 281 z_ /= rhs; 282 return *this; 283 } 284 285 // Divide a copy of this by a scalar. Return the copy. 286 const tvec3 operator/(const T& rhs) const 287 { 288 return tvec3(*this) /= rhs; 289 } 290 291 // Component-wise divide of this by another vector. 292 // Return a reference to this. 293 tvec3& operator/=(const tvec3& rhs) 294 { 295 x_ /= rhs.x_; 296 y_ /= rhs.y_; 297 z_ /= rhs.z_; 298 return *this; 299 } 300 301 // Component-wise divide of a copy of this by another vector. 302 // Return the copy. 303 const tvec3 operator/(const tvec3& rhs) const 304 { 305 return tvec3(*this) /= rhs; 306 } 307 308 // Multiply this by a scalar. Return a reference to this. 309 tvec3& operator*=(const T& rhs) 310 { 311 x_ *= rhs; 312 y_ *= rhs; 313 z_ *= rhs; 314 return *this; 315 } 316 317 // Multiply a copy of this by a scalar. Return the copy. 318 const tvec3 operator*(const T& rhs) const 319 { 320 return tvec3(*this) *= rhs; 321 } 322 323 // Component-wise multiply of this by another vector. 324 // Return a reference to this. 325 tvec3& operator*=(const tvec3& rhs) 326 { 327 x_ *= rhs.x_; 328 y_ *= rhs.y_; 329 z_ *= rhs.z_; 330 return *this; 331 } 332 333 // Component-wise multiply of a copy of this by another vector. 334 // Return the copy. 335 const tvec3 operator*(const tvec3& rhs) const 336 { 337 return tvec3(*this) *= rhs; 338 } 339 340 // Add a scalar to this. Return a reference to this. 341 tvec3& operator+=(const T& rhs) 342 { 343 x_ += rhs; 344 y_ += rhs; 345 z_ += rhs; 346 return *this; 347 } 348 349 // Add a scalar to a copy of this. Return the copy. 350 const tvec3 operator+(const T& rhs) const 351 { 352 return tvec3(*this) += rhs; 353 } 354 355 // Component-wise addition of another vector to this. 356 // Return a reference to this. 357 tvec3& operator+=(const tvec3& rhs) 358 { 359 x_ += rhs.x_; 360 y_ += rhs.y_; 361 z_ += rhs.z_; 362 return *this; 363 } 364 365 // Component-wise addition of another vector to a copy of this. 366 // Return the copy. 367 const tvec3 operator+(const tvec3& rhs) const 368 { 369 return tvec3(*this) += rhs; 370 } 371 372 // Subtract a scalar from this. Return a reference to this. 373 tvec3& operator-=(const T& rhs) 374 { 375 x_ -= rhs; 376 y_ -= rhs; 377 z_ -= rhs; 378 return *this; 379 } 380 381 // Subtract a scalar from a copy of this. Return the copy. 382 const tvec3 operator-(const T& rhs) const 383 { 384 return tvec3(*this) -= rhs; 385 } 386 387 // Component-wise subtraction of another vector from this. 388 // Return a reference to this. 389 tvec3& operator-=(const tvec3& rhs) 390 { 391 x_ -= rhs.x_; 392 y_ -= rhs.y_; 393 z_ -= rhs.z_; 394 return *this; 395 } 396 397 // Component-wise subtraction of another vector from a copy of this. 398 // Return the copy. 399 const tvec3 operator-(const tvec3& rhs) const 400 { 401 return tvec3(*this) -= rhs; 402 } 403 404 // Compute the length of this and return it. length()405 float length() const 406 { 407 return sqrt(dot(*this, *this)); 408 } 409 410 // Make this a unit vector. normalize()411 void normalize() 412 { 413 float l = length(); 414 x_ /= l; 415 y_ /= l; 416 z_ /= l; 417 } 418 419 // Compute the dot product of two vectors. dot(const tvec3 & v1,const tvec3 & v2)420 static T dot(const tvec3& v1, const tvec3& v2) 421 { 422 return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_); 423 } 424 425 // Compute the cross product of two vectors. cross(const tvec3 & u,const tvec3 & v)426 static tvec3 cross(const tvec3& u, const tvec3& v) 427 { 428 return tvec3((u.y_ * v.z_) - (u.z_ * v.y_), 429 (u.z_ * v.x_) - (u.x_ * v.z_), 430 (u.x_ * v.y_) - (u.y_ * v.x_)); 431 } 432 433 private: 434 T x_; 435 T y_; 436 T z_; 437 }; 438 439 // A template class for creating, managing and operating on a 4-element vector 440 // of any type you like (intended for built-in types, but as long as it 441 // supports the basic arithmetic and assignment operators, any type should 442 // work). 443 template<typename T> 444 class tvec4 445 { 446 public: tvec4()447 tvec4() : 448 x_(0), 449 y_(0), 450 z_(0), 451 w_(0) {} tvec4(const T t)452 tvec4(const T t) : 453 x_(t), 454 y_(t), 455 z_(t), 456 w_(t) {} tvec4(const T x,const T y,const T z,const T w)457 tvec4(const T x, const T y, const T z, const T w) : 458 x_(x), 459 y_(y), 460 z_(z), 461 w_(w) {} tvec4(const tvec4 & v)462 tvec4(const tvec4& v) : 463 x_(v.x_), 464 y_(v.y_), 465 z_(v.z_), 466 w_(v.w_) {} ~tvec4()467 ~tvec4() {} 468 469 // Print the elements of the vector to standard out. 470 // Really only useful for debug and test. print()471 void print() const 472 { 473 std::cout << "| " << x_ << " " << y_ << " " << z_ << " " << w_ << " |" << std::endl; 474 } 475 476 // Allow raw data access for API calls and the like. 477 // For example, it is valid to pass a tvec4<float> into a call to 478 // the OpenGL command "glUniform4fv()". 479 operator const T*() const { return &x_;} 480 481 // Get and set access members for the individual elements. x()482 const T x() const { return x_; } y()483 const T y() const { return y_; } z()484 const T z() const { return z_; } w()485 const T w() const { return w_; } 486 x(const T & val)487 void x(const T& val) { x_ = val; } y(const T & val)488 void y(const T& val) { y_ = val; } z(const T & val)489 void z(const T& val) { z_ = val; } w(const T & val)490 void w(const T& val) { w_ = val; } 491 492 // A direct assignment of 'rhs' to this. Return a reference to this. 493 tvec4& operator=(const tvec4& rhs) 494 { 495 if (this != &rhs) 496 { 497 x_ = rhs.x_; 498 y_ = rhs.y_; 499 z_ = rhs.z_; 500 w_ = rhs.w_; 501 } 502 return *this; 503 } 504 505 // Divide this by a scalar. Return a reference to this. 506 tvec4& operator/=(const T& rhs) 507 { 508 x_ /= rhs; 509 y_ /= rhs; 510 z_ /= rhs; 511 w_ /= rhs; 512 return *this; 513 } 514 515 // Divide a copy of this by a scalar. Return the copy. 516 const tvec4 operator/(const T& rhs) const 517 { 518 return tvec4(*this) /= rhs; 519 } 520 521 // Component-wise divide of this by another vector. 522 // Return a reference to this. 523 tvec4& operator/=(const tvec4& rhs) 524 { 525 x_ /= rhs.x_; 526 y_ /= rhs.y_; 527 z_ /= rhs.z_; 528 w_ /= rhs.w_; 529 return *this; 530 } 531 532 // Component-wise divide of a copy of this by another vector. 533 // Return the copy. 534 const tvec4 operator/(const tvec4& rhs) const 535 { 536 return tvec4(*this) /= rhs; 537 } 538 539 // Multiply this by a scalar. Return a reference to this. 540 tvec4& operator*=(const T& rhs) 541 { 542 x_ *= rhs; 543 y_ *= rhs; 544 z_ *= rhs; 545 w_ *= rhs; 546 return *this; 547 } 548 549 // Multiply a copy of this by a scalar. Return the copy. 550 const tvec4 operator*(const T& rhs) const 551 { 552 return tvec4(*this) *= rhs; 553 } 554 555 // Component-wise multiply of this by another vector. 556 // Return a reference to this. 557 tvec4& operator*=(const tvec4& rhs) 558 { 559 x_ *= rhs.x_; 560 y_ *= rhs.y_; 561 z_ *= rhs.z_; 562 w_ *= rhs.w_; 563 return *this; 564 } 565 566 // Component-wise multiply of a copy of this by another vector. 567 // Return the copy. 568 const tvec4 operator*(const tvec4& rhs) const 569 { 570 return tvec4(*this) *= rhs; 571 } 572 573 // Add a scalar to this. Return a reference to this. 574 tvec4& operator+=(const T& rhs) 575 { 576 x_ += rhs; 577 y_ += rhs; 578 z_ += rhs; 579 w_ += rhs; 580 return *this; 581 } 582 583 // Add a scalar to a copy of this. Return the copy. 584 const tvec4 operator+(const T& rhs) const 585 { 586 return tvec4(*this) += rhs; 587 } 588 589 // Component-wise addition of another vector to this. 590 // Return a reference to this. 591 tvec4& operator+=(const tvec4& rhs) 592 { 593 x_ += rhs.x_; 594 y_ += rhs.y_; 595 z_ += rhs.z_; 596 w_ += rhs.w_; 597 return *this; 598 } 599 600 // Component-wise addition of another vector to a copy of this. 601 // Return the copy. 602 const tvec4 operator+(const tvec4& rhs) const 603 { 604 return tvec4(*this) += rhs; 605 } 606 607 // Subtract a scalar from this. Return a reference to this. 608 tvec4& operator-=(const T& rhs) 609 { 610 x_ -= rhs; 611 y_ -= rhs; 612 z_ -= rhs; 613 w_ -= rhs; 614 return *this; 615 } 616 617 // Subtract a scalar from a copy of this. Return the copy. 618 const tvec4 operator-(const T& rhs) const 619 { 620 return tvec4(*this) -= rhs; 621 } 622 623 // Component-wise subtraction of another vector from this. 624 // Return a reference to this. 625 tvec4& operator-=(const tvec4& rhs) 626 { 627 x_ -= rhs.x_; 628 y_ -= rhs.y_; 629 z_ -= rhs.z_; 630 w_ -= rhs.w_; 631 return *this; 632 } 633 634 // Component-wise subtraction of another vector from a copy of this. 635 // Return the copy. 636 const tvec4 operator-(const tvec4& rhs) const 637 { 638 return tvec4(*this) -= rhs; 639 } 640 641 // Compute the length of this and return it. length()642 float length() const 643 { 644 return sqrt(dot(*this, *this)); 645 } 646 647 // Make this a unit vector. normalize()648 void normalize() 649 { 650 float l = length(); 651 x_ /= l; 652 y_ /= l; 653 z_ /= l; 654 w_ /= l; 655 } 656 657 // Compute the dot product of two vectors. dot(const tvec4 & v1,const tvec4 & v2)658 static T dot(const tvec4& v1, const tvec4& v2) 659 { 660 return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_) + (v1.w_ * v2.w_); 661 } 662 663 private: 664 T x_; 665 T y_; 666 T z_; 667 T w_; 668 }; 669 670 // 671 // Convenience typedefs. These are here to present a homogeneous view of these 672 // objects with respect to shader source. 673 // 674 typedef tvec2<float> vec2; 675 typedef tvec3<float> vec3; 676 typedef tvec4<float> vec4; 677 678 typedef tvec2<double> dvec2; 679 typedef tvec3<double> dvec3; 680 typedef tvec4<double> dvec4; 681 682 typedef tvec2<int> ivec2; 683 typedef tvec3<int> ivec3; 684 typedef tvec4<int> ivec4; 685 686 typedef tvec2<unsigned int> uvec2; 687 typedef tvec3<unsigned int> uvec3; 688 typedef tvec4<unsigned int> uvec4; 689 690 typedef tvec2<bool> bvec2; 691 typedef tvec3<bool> bvec3; 692 typedef tvec4<bool> bvec4; 693 694 } // namespace LibMatrix 695 696 // Global operators to allow for things like defining a new vector in terms of 697 // a product of a scalar and a vector 698 template<typename T> 699 const LibMatrix::tvec2<T> operator*(const T t, const LibMatrix::tvec2<T>& v) 700 { 701 return v * t; 702 } 703 704 template<typename T> 705 const LibMatrix::tvec3<T> operator*(const T t, const LibMatrix::tvec3<T>& v) 706 { 707 return v * t; 708 } 709 710 template<typename T> 711 const LibMatrix::tvec4<T> operator*(const T t, const LibMatrix::tvec4<T>& v) 712 { 713 return v * t; 714 } 715 716 #endif // VEC_H_ 717