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