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