• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
Vector4f()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      */
Vector4f(float x, float y, float z, float w)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      */
Vector4f(Vector4f copy)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      */
set(float x, float y, float z, float w)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      */
set(Vector4f vect)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      */
add(Vector4f vec)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      */
add(Vector4f vec, Vector4f result)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      */
addLocal(Vector4f vec)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      */
add(float addX, float addY, float addZ, float addW)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      */
addLocal(float addX, float addY, float addZ, float addW)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      */
scaleAdd(float scalar, Vector4f add)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      */
scaleAdd(float scalar, Vector4f mult, Vector4f add)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      */
dot(Vector4f vec)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 
project(Vector4f other)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      */
isUnitVector()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      */
length()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      */
lengthSquared()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      */
distanceSquared(Vector4f v)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      */
distance(Vector4f v)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      */
mult(float scalar)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      */
mult(float scalar, Vector4f product)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      */
multLocal(float scalar)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      */
multLocal(Vector4f vec)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      */
multLocal(float x, float y, float z, float w)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      */
mult(Vector4f vec)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      */
mult(Vector4f vec, Vector4f store)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      */
divide(float scalar)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      */
divideLocal(float scalar)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      */
divide(Vector4f scalar)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      */
divideLocal(Vector4f scalar)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      */
negate()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      */
negateLocal()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      */
subtract(Vector4f vec)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      */
subtractLocal(Vector4f vec)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      */
subtract(Vector4f vec, Vector4f result)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      */
subtract(float subtractX, float subtractY, float subtractZ, float subtractW)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      */
subtractLocal(float subtractX, float subtractY, float subtractZ, float subtractW)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      */
normalize()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      */
normalizeLocal()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      */
maxLocal(Vector4f other)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      */
minLocal(Vector4f other)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 }