1/* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33package com.jme3.math; 34 35import com.jme3.export.*; 36import java.io.IOException; 37import java.util.logging.Logger; 38 39/** 40 * <code>Vector4f</code> defines a Vector for a four float value tuple. 41 * <code>Vector4f</code> can represent any four dimensional value, such as a 42 * vertex, a normal, etc. Utility methods are also included to aid in 43 * mathematical calculations. 44 * 45 * @author Maarten Steur 46 */ 47public final class Vector4f implements Savable, Cloneable, java.io.Serializable { 48 49 static final long serialVersionUID = 1; 50 51 private static final Logger logger = Logger.getLogger(Vector4f.class.getName()); 52 53 public final static Vector4f ZERO = new Vector4f(0, 0, 0, 0); 54 public final static Vector4f NAN = new Vector4f(Float.NaN, Float.NaN, Float.NaN, Float.NaN); 55 public final static Vector4f UNIT_X = new Vector4f(1, 0, 0, 0); 56 public final static Vector4f UNIT_Y = new Vector4f(0, 1, 0, 0); 57 public final static Vector4f UNIT_Z = new Vector4f(0, 0, 1, 0); 58 public final static Vector4f UNIT_W = new Vector4f(0, 0, 0, 1); 59 public final static Vector4f UNIT_XYZW = new Vector4f(1, 1, 1, 1); 60 public final static Vector4f POSITIVE_INFINITY = new Vector4f( 61 Float.POSITIVE_INFINITY, 62 Float.POSITIVE_INFINITY, 63 Float.POSITIVE_INFINITY, 64 Float.POSITIVE_INFINITY); 65 public final static Vector4f NEGATIVE_INFINITY = new Vector4f( 66 Float.NEGATIVE_INFINITY, 67 Float.NEGATIVE_INFINITY, 68 Float.NEGATIVE_INFINITY, 69 Float.NEGATIVE_INFINITY); 70 71 /** 72 * the x value of the vector. 73 */ 74 public float x; 75 76 /** 77 * the y value of the vector. 78 */ 79 public float y; 80 81 /** 82 * the z value of the vector. 83 */ 84 public float z; 85 86 /** 87 * the w value of the vector. 88 */ 89 public float w; 90 91 /** 92 * Constructor instantiates a new <code>Vector3f</code> with default 93 * values of (0,0,0). 94 * 95 */ 96 public Vector4f() { 97 x = y = z = w = 0; 98 } 99 100 /** 101 * Constructor instantiates a new <code>Vector4f</code> with provides 102 * values. 103 * 104 * @param x 105 * the x value of the vector. 106 * @param y 107 * the y value of the vector. 108 * @param z 109 * the z value of the vector. 110 * @param w 111 * the w value of the vector. 112 */ 113 public Vector4f(float x, float y, float z, float w) { 114 this.x = x; 115 this.y = y; 116 this.z = z; 117 this.w = w; 118 } 119 120 /** 121 * Constructor instantiates a new <code>Vector3f</code> that is a copy 122 * of the provided vector 123 * @param copy The Vector3f to copy 124 */ 125 public Vector4f(Vector4f copy) { 126 this.set(copy); 127 } 128 129 /** 130 * <code>set</code> sets the x,y,z,w values of the vector based on passed 131 * parameters. 132 * 133 * @param x 134 * the x value of the vector. 135 * @param y 136 * the y value of the vector. 137 * @param z 138 * the z value of the vector. 139 * @param w 140 * the w value of the vector. 141 * @return this vector 142 */ 143 public Vector4f set(float x, float y, float z, float w) { 144 this.x = x; 145 this.y = y; 146 this.z = z; 147 this.w = w; 148 return this; 149 } 150 151 /** 152 * <code>set</code> sets the x,y,z values of the vector by copying the 153 * supplied vector. 154 * 155 * @param vect 156 * the vector to copy. 157 * @return this vector 158 */ 159 public Vector4f set(Vector4f vect) { 160 this.x = vect.x; 161 this.y = vect.y; 162 this.z = vect.z; 163 this.w = vect.w; 164 return this; 165 } 166 167 /** 168 * 169 * <code>add</code> adds a provided vector to this vector creating a 170 * resultant vector which is returned. If the provided vector is null, null 171 * is returned. 172 * 173 * @param vec 174 * the vector to add to this. 175 * @return the resultant vector. 176 */ 177 public Vector4f add(Vector4f vec) { 178 if (null == vec) { 179 logger.warning("Provided vector is null, null returned."); 180 return null; 181 } 182 return new Vector4f(x + vec.x, y + vec.y, z + vec.z, w + vec.w); 183 } 184 185 /** 186 * 187 * <code>add</code> adds the values of a provided vector storing the 188 * values in the supplied vector. 189 * 190 * @param vec 191 * the vector to add to this 192 * @param result 193 * the vector to store the result in 194 * @return result returns the supplied result vector. 195 */ 196 public Vector4f add(Vector4f vec, Vector4f result) { 197 result.x = x + vec.x; 198 result.y = y + vec.y; 199 result.z = z + vec.z; 200 result.w = w + vec.w; 201 return result; 202 } 203 204 /** 205 * <code>addLocal</code> adds a provided vector to this vector internally, 206 * and returns a handle to this vector for easy chaining of calls. If the 207 * provided vector is null, null is returned. 208 * 209 * @param vec 210 * the vector to add to this vector. 211 * @return this 212 */ 213 public Vector4f addLocal(Vector4f vec) { 214 if (null == vec) { 215 logger.warning("Provided vector is null, null returned."); 216 return null; 217 } 218 x += vec.x; 219 y += vec.y; 220 z += vec.z; 221 w += vec.w; 222 return this; 223 } 224 225 /** 226 * 227 * <code>add</code> adds the provided values to this vector, creating a 228 * new vector that is then returned. 229 * 230 * @param addX 231 * the x value to add. 232 * @param addY 233 * the y value to add. 234 * @param addZ 235 * the z value to add. 236 * @return the result vector. 237 */ 238 public Vector4f add(float addX, float addY, float addZ, float addW) { 239 return new Vector4f(x + addX, y + addY, z + addZ, w + addW); 240 } 241 242 /** 243 * <code>addLocal</code> adds the provided values to this vector 244 * internally, and returns a handle to this vector for easy chaining of 245 * calls. 246 * 247 * @param addX 248 * value to add to x 249 * @param addY 250 * value to add to y 251 * @param addZ 252 * value to add to z 253 * @return this 254 */ 255 public Vector4f addLocal(float addX, float addY, float addZ, float addW) { 256 x += addX; 257 y += addY; 258 z += addZ; 259 w += addW; 260 return this; 261 } 262 263 /** 264 * 265 * <code>scaleAdd</code> multiplies this vector by a scalar then adds the 266 * given Vector3f. 267 * 268 * @param scalar 269 * the value to multiply this vector by. 270 * @param add 271 * the value to add 272 */ 273 public Vector4f scaleAdd(float scalar, Vector4f add) { 274 x = x * scalar + add.x; 275 y = y * scalar + add.y; 276 z = z * scalar + add.z; 277 w = w * scalar + add.w; 278 return this; 279 } 280 281 /** 282 * 283 * <code>scaleAdd</code> multiplies the given vector by a scalar then adds 284 * the given vector. 285 * 286 * @param scalar 287 * the value to multiply this vector by. 288 * @param mult 289 * the value to multiply the scalar by 290 * @param add 291 * the value to add 292 */ 293 public Vector4f scaleAdd(float scalar, Vector4f mult, Vector4f add) { 294 this.x = mult.x * scalar + add.x; 295 this.y = mult.y * scalar + add.y; 296 this.z = mult.z * scalar + add.z; 297 this.w = mult.w * scalar + add.w; 298 return this; 299 } 300 301 /** 302 * 303 * <code>dot</code> calculates the dot product of this vector with a 304 * provided vector. If the provided vector is null, 0 is returned. 305 * 306 * @param vec 307 * the vector to dot with this vector. 308 * @return the resultant dot product of this vector and a given vector. 309 */ 310 public float dot(Vector4f vec) { 311 if (null == vec) { 312 logger.warning("Provided vector is null, 0 returned."); 313 return 0; 314 } 315 return x * vec.x + y * vec.y + z * vec.z + w * vec.w; 316 } 317 318 public Vector4f project(Vector4f other){ 319 float n = this.dot(other); // A . B 320 float d = other.lengthSquared(); // |B|^2 321 return new Vector4f(other).normalizeLocal().multLocal(n/d); 322 } 323 324 /** 325 * Returns true if this vector is a unit vector (length() ~= 1), 326 * returns false otherwise. 327 * 328 * @return true if this vector is a unit vector (length() ~= 1), 329 * or false otherwise. 330 */ 331 public boolean isUnitVector(){ 332 float len = length(); 333 return 0.99f < len && len < 1.01f; 334 } 335 336 /** 337 * <code>length</code> calculates the magnitude of this vector. 338 * 339 * @return the length or magnitude of the vector. 340 */ 341 public float length() { 342 return FastMath.sqrt(lengthSquared()); 343 } 344 345 /** 346 * <code>lengthSquared</code> calculates the squared value of the 347 * magnitude of the vector. 348 * 349 * @return the magnitude squared of the vector. 350 */ 351 public float lengthSquared() { 352 return x * x + y * y + z * z + w * w; 353 } 354 355 /** 356 * <code>distanceSquared</code> calculates the distance squared between 357 * this vector and vector v. 358 * 359 * @param v the second vector to determine the distance squared. 360 * @return the distance squared between the two vectors. 361 */ 362 public float distanceSquared(Vector4f v) { 363 double dx = x - v.x; 364 double dy = y - v.y; 365 double dz = z - v.z; 366 double dw = w - v.w; 367 return (float) (dx * dx + dy * dy + dz * dz + dw * dw); 368 } 369 370 /** 371 * <code>distance</code> calculates the distance between this vector and 372 * vector v. 373 * 374 * @param v the second vector to determine the distance. 375 * @return the distance between the two vectors. 376 */ 377 public float distance(Vector4f v) { 378 return FastMath.sqrt(distanceSquared(v)); 379 } 380 381 /** 382 * 383 * <code>mult</code> multiplies this vector by a scalar. The resultant 384 * vector is returned. 385 * 386 * @param scalar 387 * the value to multiply this vector by. 388 * @return the new vector. 389 */ 390 public Vector4f mult(float scalar) { 391 return new Vector4f(x * scalar, y * scalar, z * scalar, w * scalar); 392 } 393 394 /** 395 * 396 * <code>mult</code> multiplies this vector by a scalar. The resultant 397 * vector is supplied as the second parameter and returned. 398 * 399 * @param scalar the scalar to multiply this vector by. 400 * @param product the product to store the result in. 401 * @return product 402 */ 403 public Vector4f mult(float scalar, Vector4f product) { 404 if (null == product) { 405 product = new Vector4f(); 406 } 407 408 product.x = x * scalar; 409 product.y = y * scalar; 410 product.z = z * scalar; 411 product.w = w * scalar; 412 return product; 413 } 414 415 /** 416 * <code>multLocal</code> multiplies this vector by a scalar internally, 417 * and returns a handle to this vector for easy chaining of calls. 418 * 419 * @param scalar 420 * the value to multiply this vector by. 421 * @return this 422 */ 423 public Vector4f multLocal(float scalar) { 424 x *= scalar; 425 y *= scalar; 426 z *= scalar; 427 w *= scalar; 428 return this; 429 } 430 431 /** 432 * <code>multLocal</code> multiplies a provided vector to this vector 433 * internally, and returns a handle to this vector for easy chaining of 434 * calls. If the provided vector is null, null is returned. 435 * 436 * @param vec 437 * the vector to mult to this vector. 438 * @return this 439 */ 440 public Vector4f multLocal(Vector4f vec) { 441 if (null == vec) { 442 logger.warning("Provided vector is null, null returned."); 443 return null; 444 } 445 x *= vec.x; 446 y *= vec.y; 447 z *= vec.z; 448 w *= vec.w; 449 return this; 450 } 451 452 /** 453 * <code>multLocal</code> multiplies this vector by 3 scalars 454 * internally, and returns a handle to this vector for easy chaining of 455 * calls. 456 * 457 * @param x 458 * @param y 459 * @param z 460 * @param w 461 * @return this 462 */ 463 public Vector4f multLocal(float x, float y, float z, float w) { 464 this.x *= x; 465 this.y *= y; 466 this.z *= z; 467 this.w *= w; 468 return this; 469 } 470 471 /** 472 * <code>multLocal</code> multiplies a provided vector to this vector 473 * internally, and returns a handle to this vector for easy chaining of 474 * calls. If the provided vector is null, null is returned. 475 * 476 * @param vec 477 * the vector to mult to this vector. 478 * @return this 479 */ 480 public Vector4f mult(Vector4f vec) { 481 if (null == vec) { 482 logger.warning("Provided vector is null, null returned."); 483 return null; 484 } 485 return mult(vec, null); 486 } 487 488 /** 489 * <code>multLocal</code> multiplies a provided vector to this vector 490 * internally, and returns a handle to this vector for easy chaining of 491 * calls. If the provided vector is null, null is returned. 492 * 493 * @param vec 494 * the vector to mult to this vector. 495 * @param store result vector (null to create a new vector) 496 * @return this 497 */ 498 public Vector4f mult(Vector4f vec, Vector4f store) { 499 if (null == vec) { 500 logger.warning("Provided vector is null, null returned."); 501 return null; 502 } 503 if (store == null) store = new Vector4f(); 504 return store.set(x * vec.x, y * vec.y, z * vec.z, w * vec.w); 505 } 506 507 /** 508 * <code>divide</code> divides the values of this vector by a scalar and 509 * returns the result. The values of this vector remain untouched. 510 * 511 * @param scalar 512 * the value to divide this vectors attributes by. 513 * @return the result <code>Vector</code>. 514 */ 515 public Vector4f divide(float scalar) { 516 scalar = 1f/scalar; 517 return new Vector4f(x * scalar, y * scalar, z * scalar, w * scalar); 518 } 519 520 /** 521 * <code>divideLocal</code> divides this vector by a scalar internally, 522 * and returns a handle to this vector for easy chaining of calls. Dividing 523 * by zero will result in an exception. 524 * 525 * @param scalar 526 * the value to divides this vector by. 527 * @return this 528 */ 529 public Vector4f divideLocal(float scalar) { 530 scalar = 1f/scalar; 531 x *= scalar; 532 y *= scalar; 533 z *= scalar; 534 w *= scalar; 535 return this; 536 } 537 538 /** 539 * <code>divide</code> divides the values of this vector by a scalar and 540 * returns the result. The values of this vector remain untouched. 541 * 542 * @param scalar 543 * the value to divide this vectors attributes by. 544 * @return the result <code>Vector</code>. 545 */ 546 public Vector4f divide(Vector4f scalar) { 547 return new Vector4f(x / scalar.x, y / scalar.y, z / scalar.z, w / scalar.w); 548 } 549 550 /** 551 * <code>divideLocal</code> divides this vector by a scalar internally, 552 * and returns a handle to this vector for easy chaining of calls. Dividing 553 * by zero will result in an exception. 554 * 555 * @param scalar 556 * the value to divides this vector by. 557 * @return this 558 */ 559 public Vector4f divideLocal(Vector4f scalar) { 560 x /= scalar.x; 561 y /= scalar.y; 562 z /= scalar.z; 563 w /= scalar.w; 564 return this; 565 } 566 567 /** 568 * 569 * <code>negate</code> returns the negative of this vector. All values are 570 * negated and set to a new vector. 571 * 572 * @return the negated vector. 573 */ 574 public Vector4f negate() { 575 return new Vector4f(-x, -y, -z, -w); 576 } 577 578 /** 579 * 580 * <code>negateLocal</code> negates the internal values of this vector. 581 * 582 * @return this. 583 */ 584 public Vector4f negateLocal() { 585 x = -x; 586 y = -y; 587 z = -z; 588 w = -w; 589 return this; 590 } 591 592 /** 593 * 594 * <code>subtract</code> subtracts the values of a given vector from those 595 * of this vector creating a new vector object. If the provided vector is 596 * null, null is returned. 597 * 598 * @param vec 599 * the vector to subtract from this vector. 600 * @return the result vector. 601 */ 602 public Vector4f subtract(Vector4f vec) { 603 return new Vector4f(x - vec.x, y - vec.y, z - vec.z, w - vec.w); 604 } 605 606 /** 607 * <code>subtractLocal</code> subtracts a provided vector to this vector 608 * internally, and returns a handle to this vector for easy chaining of 609 * calls. If the provided vector is null, null is returned. 610 * 611 * @param vec 612 * the vector to subtract 613 * @return this 614 */ 615 public Vector4f subtractLocal(Vector4f vec) { 616 if (null == vec) { 617 logger.warning("Provided vector is null, null returned."); 618 return null; 619 } 620 x -= vec.x; 621 y -= vec.y; 622 z -= vec.z; 623 w -= vec.w; 624 return this; 625 } 626 627 /** 628 * 629 * <code>subtract</code> 630 * 631 * @param vec 632 * the vector to subtract from this 633 * @param result 634 * the vector to store the result in 635 * @return result 636 */ 637 public Vector4f subtract(Vector4f vec, Vector4f result) { 638 if(result == null) { 639 result = new Vector4f(); 640 } 641 result.x = x - vec.x; 642 result.y = y - vec.y; 643 result.z = z - vec.z; 644 result.w = w - vec.w; 645 return result; 646 } 647 648 /** 649 * 650 * <code>subtract</code> subtracts the provided values from this vector, 651 * creating a new vector that is then returned. 652 * 653 * @param subtractX 654 * the x value to subtract. 655 * @param subtractY 656 * the y value to subtract. 657 * @param subtractZ 658 * the z value to subtract. 659 * @param subtractW 660 * the w value to subtract. 661 * @return the result vector. 662 */ 663 public Vector4f subtract(float subtractX, float subtractY, float subtractZ, float subtractW) { 664 return new Vector4f(x - subtractX, y - subtractY, z - subtractZ, w - subtractW); 665 } 666 667 /** 668 * <code>subtractLocal</code> subtracts the provided values from this vector 669 * internally, and returns a handle to this vector for easy chaining of 670 * calls. 671 * 672 * @param subtractX 673 * the x value to subtract. 674 * @param subtractY 675 * the y value to subtract. 676 * @param subtractZ 677 * the z value to subtract. 678 * @param subtractW 679 * the w value to subtract. 680 * @return this 681 */ 682 public Vector4f subtractLocal(float subtractX, float subtractY, float subtractZ, float subtractW) { 683 x -= subtractX; 684 y -= subtractY; 685 z -= subtractZ; 686 w -= subtractW; 687 return this; 688 } 689 690 /** 691 * <code>normalize</code> returns the unit vector of this vector. 692 * 693 * @return unit vector of this vector. 694 */ 695 public Vector4f normalize() { 696// float length = length(); 697// if (length != 0) { 698// return divide(length); 699// } 700// 701// return divide(1); 702 float length = x * x + y * y + z * z + w * w; 703 if (length != 1f && length != 0f){ 704 length = 1.0f / FastMath.sqrt(length); 705 return new Vector4f(x * length, y * length, z * length, w * length); 706 } 707 return clone(); 708 } 709 710 /** 711 * <code>normalizeLocal</code> makes this vector into a unit vector of 712 * itself. 713 * 714 * @return this. 715 */ 716 public Vector4f normalizeLocal() { 717 // NOTE: this implementation is more optimized 718 // than the old jme normalize as this method 719 // is commonly used. 720 float length = x * x + y * y + z * z + w * w; 721 if (length != 1f && length != 0f){ 722 length = 1.0f / FastMath.sqrt(length); 723 x *= length; 724 y *= length; 725 z *= length; 726 w *= length; 727 } 728 return this; 729 } 730 731 /** 732 * <code>maxLocal</code> computes the maximum value for each 733 * component in this and <code>other</code> vector. The result is stored 734 * in this vector. 735 * @param other 736 */ 737 public void maxLocal(Vector4f other){ 738 x = other.x > x ? other.x : x; 739 y = other.y > y ? other.y : y; 740 z = other.z > z ? other.z : z; 741 w = other.w > w ? other.w : w; 742 } 743 744 /** 745 * <code>minLocal</code> computes the minimum value for each 746 * component in this and <code>other</code> vector. The result is stored 747 * in this vector. 748 * @param other 749 */ 750 public void minLocal(Vector4f other){ 751 x = other.x < x ? other.x : x; 752 y = other.y < y ? other.y : y; 753 z = other.z < z ? other.z : z; 754 w = other.w < w ? other.w : w; 755 } 756 757 /** 758 * <code>zero</code> resets this vector's data to zero internally. 759 */ 760 public Vector4f zero() { 761 x = y = z = w = 0; 762 return this; 763 } 764 765 /** 766 * <code>angleBetween</code> returns (in radians) the angle between two vectors. 767 * It is assumed that both this vector and the given vector are unit vectors (iow, normalized). 768 * 769 * @param otherVector a unit vector to find the angle against 770 * @return the angle in radians. 771 */ 772 public float angleBetween(Vector4f otherVector) { 773 float dotProduct = dot(otherVector); 774 float angle = FastMath.acos(dotProduct); 775 return angle; 776 } 777 778 /** 779 * Sets this vector to the interpolation by changeAmnt from this to the finalVec 780 * this=(1-changeAmnt)*this + changeAmnt * finalVec 781 * @param finalVec The final vector to interpolate towards 782 * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage 783 * change from this towards finalVec 784 */ 785 public Vector4f interpolate(Vector4f finalVec, float changeAmnt) { 786 this.x=(1-changeAmnt)*this.x + changeAmnt*finalVec.x; 787 this.y=(1-changeAmnt)*this.y + changeAmnt*finalVec.y; 788 this.z=(1-changeAmnt)*this.z + changeAmnt*finalVec.z; 789 this.w=(1-changeAmnt)*this.w + changeAmnt*finalVec.w; 790 return this; 791 } 792 793 /** 794 * Sets this vector to the interpolation by changeAmnt from beginVec to finalVec 795 * this=(1-changeAmnt)*beginVec + changeAmnt * finalVec 796 * @param beginVec the beging vector (changeAmnt=0) 797 * @param finalVec The final vector to interpolate towards 798 * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage 799 * change from beginVec towards finalVec 800 */ 801 public Vector4f interpolate(Vector4f beginVec,Vector4f finalVec, float changeAmnt) { 802 this.x=(1-changeAmnt)*beginVec.x + changeAmnt*finalVec.x; 803 this.y=(1-changeAmnt)*beginVec.y + changeAmnt*finalVec.y; 804 this.z=(1-changeAmnt)*beginVec.z + changeAmnt*finalVec.z; 805 this.w=(1-changeAmnt)*beginVec.w + changeAmnt*finalVec.w; 806 return this; 807 } 808 809 /** 810 * Check a vector... if it is null or its floats are NaN or infinite, 811 * return false. Else return true. 812 * @param vector the vector to check 813 * @return true or false as stated above. 814 */ 815 public static boolean isValidVector(Vector4f vector) { 816 if (vector == null) return false; 817 if (Float.isNaN(vector.x) || 818 Float.isNaN(vector.y) || 819 Float.isNaN(vector.z)|| 820 Float.isNaN(vector.w)) return false; 821 if (Float.isInfinite(vector.x) || 822 Float.isInfinite(vector.y) || 823 Float.isInfinite(vector.z) || 824 Float.isInfinite(vector.w)) return false; 825 return true; 826 } 827 828 @Override 829 public Vector4f clone() { 830 try { 831 return (Vector4f) super.clone(); 832 } catch (CloneNotSupportedException e) { 833 throw new AssertionError(); // can not happen 834 } 835 } 836 837 /** 838 * Saves this Vector3f into the given float[] object. 839 * 840 * @param floats 841 * The float[] to take this Vector3f. If null, a new float[3] is 842 * created. 843 * @return The array, with X, Y, Z float values in that order 844 */ 845 public float[] toArray(float[] floats) { 846 if (floats == null) { 847 floats = new float[4]; 848 } 849 floats[0] = x; 850 floats[1] = y; 851 floats[2] = z; 852 floats[3] = w; 853 return floats; 854 } 855 856 /** 857 * are these two vectors the same? they are is they both have the same x,y, 858 * and z values. 859 * 860 * @param o 861 * the object to compare for equality 862 * @return true if they are equal 863 */ 864 public boolean equals(Object o) { 865 if (!(o instanceof Vector4f)) { return false; } 866 867 if (this == o) { return true; } 868 869 Vector4f comp = (Vector4f) o; 870 if (Float.compare(x,comp.x) != 0) return false; 871 if (Float.compare(y,comp.y) != 0) return false; 872 if (Float.compare(z,comp.z) != 0) return false; 873 if (Float.compare(w,comp.w) != 0) return false; 874 return true; 875 } 876 877 /** 878 * <code>hashCode</code> returns a unique code for this vector object based 879 * on it's values. If two vectors are logically equivalent, they will return 880 * the same hash code value. 881 * @return the hash code value of this vector. 882 */ 883 public int hashCode() { 884 int hash = 37; 885 hash += 37 * hash + Float.floatToIntBits(x); 886 hash += 37 * hash + Float.floatToIntBits(y); 887 hash += 37 * hash + Float.floatToIntBits(z); 888 hash += 37 * hash + Float.floatToIntBits(w); 889 return hash; 890 } 891 892 /** 893 * <code>toString</code> returns the string representation of this vector. 894 * The format is: 895 * 896 * org.jme.math.Vector3f [X=XX.XXXX, Y=YY.YYYY, Z=ZZ.ZZZZ, W=WW.WWWW] 897 * 898 * @return the string representation of this vector. 899 */ 900 public String toString() { 901 return "(" + x + ", " + y + ", " + z + ", " + w + ")"; 902 } 903 904 public void write(JmeExporter e) throws IOException { 905 OutputCapsule capsule = e.getCapsule(this); 906 capsule.write(x, "x", 0); 907 capsule.write(y, "y", 0); 908 capsule.write(z, "z", 0); 909 capsule.write(w, "w", 0); 910 } 911 912 public void read(JmeImporter e) throws IOException { 913 InputCapsule capsule = e.getCapsule(this); 914 x = capsule.readFloat("x", 0); 915 y = capsule.readFloat("y", 0); 916 z = capsule.readFloat("z", 0); 917 w = capsule.readFloat("w", 0); 918 } 919 920 public float getX() { 921 return x; 922 } 923 924 public Vector4f setX(float x) { 925 this.x = x; 926 return this; 927 } 928 929 public float getY() { 930 return y; 931 } 932 933 public Vector4f setY(float y) { 934 this.y = y; 935 return this; 936 } 937 938 public float getZ() { 939 return z; 940 } 941 942 public Vector4f setZ(float z) { 943 this.z = z; 944 return this; 945 } 946 947 public float getW() { 948 return w; 949 } 950 951 public Vector4f setW(float w) { 952 this.w = w; 953 return this; 954 } 955 956 /** 957 * @param index 958 * @return x value if index == 0, y value if index == 1 or z value if index == 959 * 2 960 * @throws IllegalArgumentException 961 * if index is not one of 0, 1, 2. 962 */ 963 public float get(int index) { 964 switch (index) { 965 case 0: 966 return x; 967 case 1: 968 return y; 969 case 2: 970 return z; 971 case 3: 972 return w; 973 } 974 throw new IllegalArgumentException("index must be either 0, 1, 2 or 3"); 975 } 976 977 /** 978 * @param index 979 * which field index in this vector to set. 980 * @param value 981 * to set to one of x, y, z or w. 982 * @throws IllegalArgumentException 983 * if index is not one of 0, 1, 2, 3. 984 */ 985 public void set(int index, float value) { 986 switch (index) { 987 case 0: 988 x = value; 989 return; 990 case 1: 991 y = value; 992 return; 993 case 2: 994 z = value; 995 return; 996 case 3: 997 w = value; 998 return; 999 } 1000 throw new IllegalArgumentException("index must be either 0, 1, 2 or 3"); 1001 } 1002 1003}