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  * <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  */
     47 public 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 }