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