Home | History | Annotate | Download | only in math
      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      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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 
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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