computing constraints. The fix also improved the constraints computation speed at least several times :)experimental
parent
9eca2251a9
commit
c9eadcc762
@ -0,0 +1,453 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.scene.plugins.blender.math; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
import com.jme3.export.InputCapsule; |
||||||
|
import com.jme3.export.JmeExporter; |
||||||
|
import com.jme3.export.JmeImporter; |
||||||
|
import com.jme3.export.OutputCapsule; |
||||||
|
import com.jme3.export.Savable; |
||||||
|
import com.jme3.math.Quaternion; |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>DQuaternion</code> defines a single example of a more general class of |
||||||
|
* hypercomplex numbers. DQuaternions extends a rotation in three dimensions to a |
||||||
|
* rotation in four dimensions. This avoids "gimbal lock" and allows for smooth |
||||||
|
* continuous rotation. |
||||||
|
* |
||||||
|
* <code>DQuaternion</code> is defined by four double point numbers: {x y z w}. |
||||||
|
* |
||||||
|
* This class's only purpose is to give better accuracy in floating point operations during computations. |
||||||
|
* This is made by copying the original Quaternion class from jme3 core and leaving only required methods and basic computation methods, so that |
||||||
|
* the class is smaller and easier to maintain. |
||||||
|
* Should any other methods be needed, they will be added. |
||||||
|
* |
||||||
|
* @author Mark Powell |
||||||
|
* @author Joshua Slack |
||||||
|
* @author Marcin Roguski (Kaelthas) |
||||||
|
*/ |
||||||
|
public final class DQuaternion implements Savable, Cloneable, java.io.Serializable { |
||||||
|
private static final long serialVersionUID = 5009180713885017539L; |
||||||
|
|
||||||
|
/** |
||||||
|
* Represents the identity quaternion rotation (0, 0, 0, 1). |
||||||
|
*/ |
||||||
|
public static final DQuaternion IDENTITY = new DQuaternion(); |
||||||
|
public static final DQuaternion DIRECTION_Z = new DQuaternion(); |
||||||
|
public static final DQuaternion ZERO = new DQuaternion(0, 0, 0, 0); |
||||||
|
protected double x, y, z, w = 1; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor instantiates a new <code>DQuaternion</code> object |
||||||
|
* initializing all values to zero, except w which is initialized to 1. |
||||||
|
* |
||||||
|
*/ |
||||||
|
public DQuaternion() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor instantiates a new <code>DQuaternion</code> object from the |
||||||
|
* given list of parameters. |
||||||
|
* |
||||||
|
* @param x |
||||||
|
* the x value of the quaternion. |
||||||
|
* @param y |
||||||
|
* the y value of the quaternion. |
||||||
|
* @param z |
||||||
|
* the z value of the quaternion. |
||||||
|
* @param w |
||||||
|
* the w value of the quaternion. |
||||||
|
*/ |
||||||
|
public DQuaternion(double x, double y, double z, double w) { |
||||||
|
this.set(x, y, z, w); |
||||||
|
} |
||||||
|
|
||||||
|
public DQuaternion(Quaternion q) { |
||||||
|
this(q.getX(), q.getY(), q.getZ(), q.getW()); |
||||||
|
} |
||||||
|
|
||||||
|
public Quaternion toQuaternion() { |
||||||
|
return new Quaternion((float) x, (float) y, (float) z, (float) w); |
||||||
|
} |
||||||
|
|
||||||
|
public double getX() { |
||||||
|
return x; |
||||||
|
} |
||||||
|
|
||||||
|
public double getY() { |
||||||
|
return y; |
||||||
|
} |
||||||
|
|
||||||
|
public double getZ() { |
||||||
|
return z; |
||||||
|
} |
||||||
|
|
||||||
|
public double getW() { |
||||||
|
return w; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* sets the data in a <code>DQuaternion</code> object from the given list |
||||||
|
* of parameters. |
||||||
|
* |
||||||
|
* @param x |
||||||
|
* the x value of the quaternion. |
||||||
|
* @param y |
||||||
|
* the y value of the quaternion. |
||||||
|
* @param z |
||||||
|
* the z value of the quaternion. |
||||||
|
* @param w |
||||||
|
* the w value of the quaternion. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public DQuaternion set(double x, double y, double z, double w) { |
||||||
|
this.x = x; |
||||||
|
this.y = y; |
||||||
|
this.z = z; |
||||||
|
this.w = w; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the data in this <code>DQuaternion</code> object to be equal to the |
||||||
|
* passed <code>DQuaternion</code> object. The values are copied producing |
||||||
|
* a new object. |
||||||
|
* |
||||||
|
* @param q |
||||||
|
* The DQuaternion to copy values from. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public DQuaternion set(DQuaternion q) { |
||||||
|
x = q.x; |
||||||
|
y = q.y; |
||||||
|
z = q.z; |
||||||
|
w = q.w; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets this DQuaternion to {0, 0, 0, 1}. Same as calling set(0,0,0,1). |
||||||
|
*/ |
||||||
|
public void loadIdentity() { |
||||||
|
x = y = z = 0; |
||||||
|
w = 1; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>fromAngleAxis</code> sets this quaternion to the values specified |
||||||
|
* by an angle and an axis of rotation. This method creates an object, so |
||||||
|
* use fromAngleNormalAxis if your axis is already normalized. |
||||||
|
* |
||||||
|
* @param angle |
||||||
|
* the angle to rotate (in radians). |
||||||
|
* @param axis |
||||||
|
* the axis of rotation. |
||||||
|
* @return this quaternion |
||||||
|
*/ |
||||||
|
public DQuaternion fromAngleAxis(double angle, Vector3d axis) { |
||||||
|
Vector3d normAxis = axis.normalize(); |
||||||
|
this.fromAngleNormalAxis(angle, normAxis); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>fromAngleNormalAxis</code> sets this quaternion to the values |
||||||
|
* specified by an angle and a normalized axis of rotation. |
||||||
|
* |
||||||
|
* @param angle |
||||||
|
* the angle to rotate (in radians). |
||||||
|
* @param axis |
||||||
|
* the axis of rotation (already normalized). |
||||||
|
*/ |
||||||
|
public DQuaternion fromAngleNormalAxis(double angle, Vector3d axis) { |
||||||
|
if (axis.x == 0 && axis.y == 0 && axis.z == 0) { |
||||||
|
this.loadIdentity(); |
||||||
|
} else { |
||||||
|
double halfAngle = 0.5f * angle; |
||||||
|
double sin = Math.sin(halfAngle); |
||||||
|
w = Math.cos(halfAngle); |
||||||
|
x = sin * axis.x; |
||||||
|
y = sin * axis.y; |
||||||
|
z = sin * axis.z; |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>add</code> adds the values of this quaternion to those of the |
||||||
|
* parameter quaternion. The result is returned as a new quaternion. |
||||||
|
* |
||||||
|
* @param q |
||||||
|
* the quaternion to add to this. |
||||||
|
* @return the new quaternion. |
||||||
|
*/ |
||||||
|
public DQuaternion add(DQuaternion q) { |
||||||
|
return new DQuaternion(x + q.x, y + q.y, z + q.z, w + q.w); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>add</code> adds the values of this quaternion to those of the |
||||||
|
* parameter quaternion. The result is stored in this DQuaternion. |
||||||
|
* |
||||||
|
* @param q |
||||||
|
* the quaternion to add to this. |
||||||
|
* @return This DQuaternion after addition. |
||||||
|
*/ |
||||||
|
public DQuaternion addLocal(DQuaternion q) { |
||||||
|
x += q.x; |
||||||
|
y += q.y; |
||||||
|
z += q.z; |
||||||
|
w += q.w; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>subtract</code> subtracts the values of the parameter quaternion |
||||||
|
* from those of this quaternion. The result is returned as a new |
||||||
|
* quaternion. |
||||||
|
* |
||||||
|
* @param q |
||||||
|
* the quaternion to subtract from this. |
||||||
|
* @return the new quaternion. |
||||||
|
*/ |
||||||
|
public DQuaternion subtract(DQuaternion q) { |
||||||
|
return new DQuaternion(x - q.x, y - q.y, z - q.z, w - q.w); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>subtract</code> subtracts the values of the parameter quaternion |
||||||
|
* from those of this quaternion. The result is stored in this DQuaternion. |
||||||
|
* |
||||||
|
* @param q |
||||||
|
* the quaternion to subtract from this. |
||||||
|
* @return This DQuaternion after subtraction. |
||||||
|
*/ |
||||||
|
public DQuaternion subtractLocal(DQuaternion q) { |
||||||
|
x -= q.x; |
||||||
|
y -= q.y; |
||||||
|
z -= q.z; |
||||||
|
w -= q.w; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>mult</code> multiplies this quaternion by a parameter quaternion. |
||||||
|
* The result is returned as a new quaternion. It should be noted that |
||||||
|
* quaternion multiplication is not commutative so q * p != p * q. |
||||||
|
* |
||||||
|
* @param q |
||||||
|
* the quaternion to multiply this quaternion by. |
||||||
|
* @return the new quaternion. |
||||||
|
*/ |
||||||
|
public DQuaternion mult(DQuaternion q) { |
||||||
|
return this.mult(q, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>mult</code> multiplies this quaternion by a parameter quaternion. |
||||||
|
* The result is returned as a new quaternion. It should be noted that |
||||||
|
* quaternion multiplication is not commutative so q * p != p * q. |
||||||
|
* |
||||||
|
* It IS safe for q and res to be the same object. |
||||||
|
* It IS NOT safe for this and res to be the same object. |
||||||
|
* |
||||||
|
* @param q |
||||||
|
* the quaternion to multiply this quaternion by. |
||||||
|
* @param res |
||||||
|
* the quaternion to store the result in. |
||||||
|
* @return the new quaternion. |
||||||
|
*/ |
||||||
|
public DQuaternion mult(DQuaternion q, DQuaternion res) { |
||||||
|
if (res == null) { |
||||||
|
res = new DQuaternion(); |
||||||
|
} |
||||||
|
double qw = q.w, qx = q.x, qy = q.y, qz = q.z; |
||||||
|
res.x = x * qw + y * qz - z * qy + w * qx; |
||||||
|
res.y = -x * qz + y * qw + z * qx + w * qy; |
||||||
|
res.z = x * qy - y * qx + z * qw + w * qz; |
||||||
|
res.w = -x * qx - y * qy - z * qz + w * qw; |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>mult</code> multiplies this quaternion by a parameter vector. The |
||||||
|
* result is returned as a new vector. |
||||||
|
* |
||||||
|
* @param v |
||||||
|
* the vector to multiply this quaternion by. |
||||||
|
* @return the new vector. |
||||||
|
*/ |
||||||
|
public Vector3d mult(Vector3d v) { |
||||||
|
return this.mult(v, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Multiplies this DQuaternion by the supplied quaternion. The result is |
||||||
|
* stored in this DQuaternion, which is also returned for chaining. Similar |
||||||
|
* to this *= q. |
||||||
|
* |
||||||
|
* @param q |
||||||
|
* The DQuaternion to multiply this one by. |
||||||
|
* @return This DQuaternion, after multiplication. |
||||||
|
*/ |
||||||
|
public DQuaternion multLocal(DQuaternion q) { |
||||||
|
double x1 = x * q.w + y * q.z - z * q.y + w * q.x; |
||||||
|
double y1 = -x * q.z + y * q.w + z * q.x + w * q.y; |
||||||
|
double z1 = x * q.y - y * q.x + z * q.w + w * q.z; |
||||||
|
w = -x * q.x - y * q.y - z * q.z + w * q.w; |
||||||
|
x = x1; |
||||||
|
y = y1; |
||||||
|
z = z1; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>mult</code> multiplies this quaternion by a parameter vector. The |
||||||
|
* result is returned as a new vector. |
||||||
|
* |
||||||
|
* @param v |
||||||
|
* the vector to multiply this quaternion by. |
||||||
|
* @param store |
||||||
|
* the vector to store the result in. It IS safe for v and store |
||||||
|
* to be the same object. |
||||||
|
* @return the result vector. |
||||||
|
*/ |
||||||
|
public Vector3d mult(Vector3d v, Vector3d store) { |
||||||
|
if (store == null) { |
||||||
|
store = new Vector3d(); |
||||||
|
} |
||||||
|
if (v.x == 0 && v.y == 0 && v.z == 0) { |
||||||
|
store.set(0, 0, 0); |
||||||
|
} else { |
||||||
|
double vx = v.x, vy = v.y, vz = v.z; |
||||||
|
store.x = w * w * vx + 2 * y * w * vz - 2 * z * w * vy + x * x * vx + 2 * y * x * vy + 2 * z * x * vz - z * z * vx - y * y * vx; |
||||||
|
store.y = 2 * x * y * vx + y * y * vy + 2 * z * y * vz + 2 * w * z * vx - z * z * vy + w * w * vy - 2 * x * w * vz - x * x * vy; |
||||||
|
store.z = 2 * x * z * vx + 2 * y * z * vy + z * z * vz - 2 * w * y * vx - y * y * vz + 2 * w * x * vy - x * x * vz + w * w * vz; |
||||||
|
} |
||||||
|
return store; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>toString</code> creates the string representation of this <code>DQuaternion</code>. The values of the quaternion are displaced (x, |
||||||
|
* y, z, w), in the following manner: <br> |
||||||
|
* (x, y, z, w) |
||||||
|
* |
||||||
|
* @return the string representation of this object. |
||||||
|
* @see java.lang.Object#toString() |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "(" + x + ", " + y + ", " + z + ", " + w + ")"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>equals</code> determines if two quaternions are logically equal, |
||||||
|
* that is, if the values of (x, y, z, w) are the same for both quaternions. |
||||||
|
* |
||||||
|
* @param o |
||||||
|
* the object to compare for equality |
||||||
|
* @return true if they are equal, false otherwise. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public boolean equals(Object o) { |
||||||
|
if (!(o instanceof DQuaternion)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (this == o) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
DQuaternion comp = (DQuaternion) o; |
||||||
|
if (Double.compare(x, comp.x) != 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (Double.compare(y, comp.y) != 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (Double.compare(z, comp.z) != 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (Double.compare(w, comp.w) != 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>hashCode</code> returns the hash code value as an integer and is |
||||||
|
* supported for the benefit of hashing based collection classes such as |
||||||
|
* Hashtable, HashMap, HashSet etc. |
||||||
|
* |
||||||
|
* @return the hashcode for this instance of DQuaternion. |
||||||
|
* @see java.lang.Object#hashCode() |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
long hash = 37; |
||||||
|
hash = 37 * hash + Double.doubleToLongBits(x); |
||||||
|
hash = 37 * hash + Double.doubleToLongBits(y); |
||||||
|
hash = 37 * hash + Double.doubleToLongBits(z); |
||||||
|
hash = 37 * hash + Double.doubleToLongBits(w); |
||||||
|
return (int) hash; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void write(JmeExporter e) throws IOException { |
||||||
|
OutputCapsule cap = e.getCapsule(this); |
||||||
|
cap.write(x, "x", 0); |
||||||
|
cap.write(y, "y", 0); |
||||||
|
cap.write(z, "z", 0); |
||||||
|
cap.write(w, "w", 1); |
||||||
|
} |
||||||
|
|
||||||
|
public void read(JmeImporter e) throws IOException { |
||||||
|
InputCapsule cap = e.getCapsule(this); |
||||||
|
x = cap.readFloat("x", 0); |
||||||
|
y = cap.readFloat("y", 0); |
||||||
|
z = cap.readFloat("z", 0); |
||||||
|
w = cap.readFloat("w", 1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DQuaternion clone() { |
||||||
|
try { |
||||||
|
return (DQuaternion) super.clone(); |
||||||
|
} catch (CloneNotSupportedException e) { |
||||||
|
throw new AssertionError(); // can not happen
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,170 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.scene.plugins.blender.math; |
||||||
|
|
||||||
|
import com.jme3.export.*; |
||||||
|
import com.jme3.math.Transform; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Started Date: Jul 16, 2004<br> |
||||||
|
* <br> |
||||||
|
* Represents a translation, rotation and scale in one object. |
||||||
|
* |
||||||
|
* This class's only purpose is to give better accuracy in floating point operations during computations. |
||||||
|
* This is made by copying the original Transfrom class from jme3 core and removing unnecessary methods so that |
||||||
|
* the class is smaller and easier to maintain. |
||||||
|
* Should any other methods be needed, they will be added. |
||||||
|
* |
||||||
|
* @author Jack Lindamood |
||||||
|
* @author Joshua Slack |
||||||
|
* @author Marcin Roguski (Kaelthas) |
||||||
|
*/ |
||||||
|
public final class DTransform implements Savable, Cloneable, java.io.Serializable { |
||||||
|
private static final long serialVersionUID = 7812915425940606722L; |
||||||
|
|
||||||
|
private DQuaternion rotation; |
||||||
|
private Vector3d translation; |
||||||
|
private Vector3d scale; |
||||||
|
|
||||||
|
public DTransform(Transform transform) { |
||||||
|
translation = new Vector3d(transform.getTranslation()); |
||||||
|
rotation = new DQuaternion(transform.getRotation()); |
||||||
|
scale = new Vector3d(transform.getScale()); |
||||||
|
} |
||||||
|
|
||||||
|
public Transform toTransform() { |
||||||
|
return new Transform(translation.toVector3f(), rotation.toQuaternion(), scale.toVector3f()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets this translation to the given value. |
||||||
|
* @param trans |
||||||
|
* The new translation for this matrix. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public DTransform setTranslation(Vector3d trans) { |
||||||
|
translation.set(trans); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets this rotation to the given DQuaternion value. |
||||||
|
* @param rot |
||||||
|
* The new rotation for this matrix. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public DTransform setRotation(DQuaternion rot) { |
||||||
|
rotation.set(rot); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets this scale to the given value. |
||||||
|
* @param scale |
||||||
|
* The new scale for this matrix. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public DTransform setScale(Vector3d scale) { |
||||||
|
this.scale.set(scale); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets this scale to the given value. |
||||||
|
* @param scale |
||||||
|
* The new scale for this matrix. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public DTransform setScale(float scale) { |
||||||
|
this.scale.set(scale, scale, scale); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Return the translation vector in this matrix. |
||||||
|
* @return translation vector. |
||||||
|
*/ |
||||||
|
public Vector3d getTranslation() { |
||||||
|
return translation; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Return the rotation quaternion in this matrix. |
||||||
|
* @return rotation quaternion. |
||||||
|
*/ |
||||||
|
public DQuaternion getRotation() { |
||||||
|
return rotation; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Return the scale vector in this matrix. |
||||||
|
* @return scale vector. |
||||||
|
*/ |
||||||
|
public Vector3d getScale() { |
||||||
|
return scale; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return this.getClass().getSimpleName() + "[ " + translation.x + ", " + translation.y + ", " + translation.z + "]\n" + "[ " + rotation.x + ", " + rotation.y + ", " + rotation.z + ", " + rotation.w + "]\n" + "[ " + scale.x + " , " + scale.y + ", " + scale.z + "]"; |
||||||
|
} |
||||||
|
|
||||||
|
public void write(JmeExporter e) throws IOException { |
||||||
|
OutputCapsule capsule = e.getCapsule(this); |
||||||
|
capsule.write(rotation, "rot", new DQuaternion()); |
||||||
|
capsule.write(translation, "translation", Vector3d.ZERO); |
||||||
|
capsule.write(scale, "scale", Vector3d.UNIT_XYZ); |
||||||
|
} |
||||||
|
|
||||||
|
public void read(JmeImporter e) throws IOException { |
||||||
|
InputCapsule capsule = e.getCapsule(this); |
||||||
|
|
||||||
|
rotation = (DQuaternion) capsule.readSavable("rot", new DQuaternion()); |
||||||
|
translation = (Vector3d) capsule.readSavable("translation", Vector3d.ZERO); |
||||||
|
scale = (Vector3d) capsule.readSavable("scale", Vector3d.UNIT_XYZ); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DTransform clone() { |
||||||
|
try { |
||||||
|
DTransform tq = (DTransform) super.clone(); |
||||||
|
tq.rotation = rotation.clone(); |
||||||
|
tq.scale = scale.clone(); |
||||||
|
tq.translation = translation.clone(); |
||||||
|
return tq; |
||||||
|
} catch (CloneNotSupportedException e) { |
||||||
|
throw new AssertionError(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,867 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.jme3.scene.plugins.blender.math; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
import com.jme3.export.InputCapsule; |
||||||
|
import com.jme3.export.JmeExporter; |
||||||
|
import com.jme3.export.JmeImporter; |
||||||
|
import com.jme3.export.OutputCapsule; |
||||||
|
import com.jme3.export.Savable; |
||||||
|
import com.jme3.math.FastMath; |
||||||
|
import com.jme3.math.Vector3f; |
||||||
|
|
||||||
|
/* |
||||||
|
* -- Added *Local methods to cut down on object creation - JS |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>Vector3d</code> defines a Vector for a three float value tuple. <code>Vector3d</code> can represent any three dimensional value, such as a |
||||||
|
* vertex, a normal, etc. Utility methods are also included to aid in |
||||||
|
* mathematical calculations. |
||||||
|
* |
||||||
|
* This class's only purpose is to give better accuracy in floating point operations during computations. |
||||||
|
* This is made by copying the original Vector3f class from jme3 core and leaving only required methods and basic computation methods, so that |
||||||
|
* the class is smaller and easier to maintain. |
||||||
|
* Should any other methods be needed, they will be added. |
||||||
|
* |
||||||
|
* @author Mark Powell |
||||||
|
* @author Joshua Slack |
||||||
|
* @author Marcin Roguski (Kaelthas) |
||||||
|
*/ |
||||||
|
public final class Vector3d implements Savable, Cloneable, Serializable { |
||||||
|
private static final long serialVersionUID = 3090477054277293078L; |
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(Vector3d.class.getName()); |
||||||
|
|
||||||
|
public final static Vector3d ZERO = new Vector3d(); |
||||||
|
public final static Vector3d UNIT_XYZ = new Vector3d(1, 1, 1); |
||||||
|
public final static Vector3d UNIT_X = new Vector3d(1, 0, 0); |
||||||
|
public final static Vector3d UNIT_Y = new Vector3d(0, 1, 0); |
||||||
|
public final static Vector3d UNIT_Z = new Vector3d(0, 0, 1); |
||||||
|
|
||||||
|
/** |
||||||
|
* the x value of the vector. |
||||||
|
*/ |
||||||
|
public double x; |
||||||
|
|
||||||
|
/** |
||||||
|
* the y value of the vector. |
||||||
|
*/ |
||||||
|
public double y; |
||||||
|
|
||||||
|
/** |
||||||
|
* the z value of the vector. |
||||||
|
*/ |
||||||
|
public double z; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor instantiates a new <code>Vector3d</code> with default |
||||||
|
* values of (0,0,0). |
||||||
|
* |
||||||
|
*/ |
||||||
|
public Vector3d() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor instantiates a new <code>Vector3d</code> with provides |
||||||
|
* values. |
||||||
|
* |
||||||
|
* @param x |
||||||
|
* the x value of the vector. |
||||||
|
* @param y |
||||||
|
* the y value of the vector. |
||||||
|
* @param z |
||||||
|
* the z value of the vector. |
||||||
|
*/ |
||||||
|
public Vector3d(double x, double y, double z) { |
||||||
|
this.x = x; |
||||||
|
this.y = y; |
||||||
|
this.z = z; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor instantiates a new <code>Vector3d</code> that is a copy |
||||||
|
* of the provided vector |
||||||
|
* @param copy |
||||||
|
* The Vector3d to copy |
||||||
|
*/ |
||||||
|
public Vector3d(Vector3f vector3f) { |
||||||
|
this(vector3f.x, vector3f.y, vector3f.z); |
||||||
|
} |
||||||
|
|
||||||
|
public Vector3f toVector3f() { |
||||||
|
return new Vector3f((float) x, (float) y, (float) z); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>set</code> sets the x,y,z values of the vector based on passed |
||||||
|
* parameters. |
||||||
|
* |
||||||
|
* @param x |
||||||
|
* the x value of the vector. |
||||||
|
* @param y |
||||||
|
* the y value of the vector. |
||||||
|
* @param z |
||||||
|
* the z value of the vector. |
||||||
|
* @return this vector |
||||||
|
*/ |
||||||
|
public Vector3d set(double x, double y, double z) { |
||||||
|
this.x = x; |
||||||
|
this.y = y; |
||||||
|
this.z = z; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>set</code> sets the x,y,z values of the vector by copying the |
||||||
|
* supplied vector. |
||||||
|
* |
||||||
|
* @param vect |
||||||
|
* the vector to copy. |
||||||
|
* @return this vector |
||||||
|
*/ |
||||||
|
public Vector3d set(Vector3d vect) { |
||||||
|
return this.set(vect.x, vect.y, vect.z); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>add</code> adds a provided vector to this vector creating a |
||||||
|
* resultant vector which is returned. If the provided vector is null, null |
||||||
|
* is returned. |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to add to this. |
||||||
|
* @return the resultant vector. |
||||||
|
*/ |
||||||
|
public Vector3d add(Vector3d vec) { |
||||||
|
if (null == vec) { |
||||||
|
LOGGER.warning("Provided vector is null, null returned."); |
||||||
|
return null; |
||||||
|
} |
||||||
|
return new Vector3d(x + vec.x, y + vec.y, z + vec.z); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>add</code> adds the values of a provided vector storing the |
||||||
|
* values in the supplied vector. |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to add to this |
||||||
|
* @param result |
||||||
|
* the vector to store the result in |
||||||
|
* @return result returns the supplied result vector. |
||||||
|
*/ |
||||||
|
public Vector3d add(Vector3d vec, Vector3d result) { |
||||||
|
result.x = x + vec.x; |
||||||
|
result.y = y + vec.y; |
||||||
|
result.z = z + vec.z; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>addLocal</code> adds a provided vector to this vector internally, |
||||||
|
* and returns a handle to this vector for easy chaining of calls. If the |
||||||
|
* provided vector is null, null is returned. |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to add to this vector. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d addLocal(Vector3d vec) { |
||||||
|
if (null == vec) { |
||||||
|
LOGGER.warning("Provided vector is null, null returned."); |
||||||
|
return null; |
||||||
|
} |
||||||
|
x += vec.x; |
||||||
|
y += vec.y; |
||||||
|
z += vec.z; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>add</code> adds the provided values to this vector, creating a |
||||||
|
* new vector that is then returned. |
||||||
|
* |
||||||
|
* @param addX |
||||||
|
* the x value to add. |
||||||
|
* @param addY |
||||||
|
* the y value to add. |
||||||
|
* @param addZ |
||||||
|
* the z value to add. |
||||||
|
* @return the result vector. |
||||||
|
*/ |
||||||
|
public Vector3d add(double addX, double addY, double addZ) { |
||||||
|
return new Vector3d(x + addX, y + addY, z + addZ); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>addLocal</code> adds the provided values to this vector |
||||||
|
* internally, and returns a handle to this vector for easy chaining of |
||||||
|
* calls. |
||||||
|
* |
||||||
|
* @param addX |
||||||
|
* value to add to x |
||||||
|
* @param addY |
||||||
|
* value to add to y |
||||||
|
* @param addZ |
||||||
|
* value to add to z |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d addLocal(double addX, double addY, double addZ) { |
||||||
|
x += addX; |
||||||
|
y += addY; |
||||||
|
z += addZ; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>scaleAdd</code> multiplies this vector by a scalar then adds the |
||||||
|
* given Vector3d. |
||||||
|
* |
||||||
|
* @param scalar |
||||||
|
* the value to multiply this vector by. |
||||||
|
* @param add |
||||||
|
* the value to add |
||||||
|
*/ |
||||||
|
public Vector3d scaleAdd(double scalar, Vector3d add) { |
||||||
|
x = x * scalar + add.x; |
||||||
|
y = y * scalar + add.y; |
||||||
|
z = z * scalar + add.z; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>scaleAdd</code> multiplies the given vector by a scalar then adds |
||||||
|
* the given vector. |
||||||
|
* |
||||||
|
* @param scalar |
||||||
|
* the value to multiply this vector by. |
||||||
|
* @param mult |
||||||
|
* the value to multiply the scalar by |
||||||
|
* @param add |
||||||
|
* the value to add |
||||||
|
*/ |
||||||
|
public Vector3d scaleAdd(double scalar, Vector3d mult, Vector3d add) { |
||||||
|
x = mult.x * scalar + add.x; |
||||||
|
y = mult.y * scalar + add.y; |
||||||
|
z = mult.z * scalar + add.z; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>dot</code> calculates the dot product of this vector with a |
||||||
|
* provided vector. If the provided vector is null, 0 is returned. |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to dot with this vector. |
||||||
|
* @return the resultant dot product of this vector and a given vector. |
||||||
|
*/ |
||||||
|
public double dot(Vector3d vec) { |
||||||
|
if (null == vec) { |
||||||
|
LOGGER.warning("Provided vector is null, 0 returned."); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
return x * vec.x + y * vec.y + z * vec.z; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>cross</code> calculates the cross product of this vector with a |
||||||
|
* parameter vector v. |
||||||
|
* |
||||||
|
* @param v |
||||||
|
* the vector to take the cross product of with this. |
||||||
|
* @return the cross product vector. |
||||||
|
*/ |
||||||
|
public Vector3d cross(Vector3d v) { |
||||||
|
return this.cross(v, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>cross</code> calculates the cross product of this vector with a |
||||||
|
* parameter vector v. The result is stored in <code>result</code> |
||||||
|
* |
||||||
|
* @param v |
||||||
|
* the vector to take the cross product of with this. |
||||||
|
* @param result |
||||||
|
* the vector to store the cross product result. |
||||||
|
* @return result, after recieving the cross product vector. |
||||||
|
*/ |
||||||
|
public Vector3d cross(Vector3d v, Vector3d result) { |
||||||
|
return this.cross(v.x, v.y, v.z, result); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>cross</code> calculates the cross product of this vector with a |
||||||
|
* parameter vector v. The result is stored in <code>result</code> |
||||||
|
* |
||||||
|
* @param otherX |
||||||
|
* x component of the vector to take the cross product of with this. |
||||||
|
* @param otherY |
||||||
|
* y component of the vector to take the cross product of with this. |
||||||
|
* @param otherZ |
||||||
|
* z component of the vector to take the cross product of with this. |
||||||
|
* @param result |
||||||
|
* the vector to store the cross product result. |
||||||
|
* @return result, after recieving the cross product vector. |
||||||
|
*/ |
||||||
|
public Vector3d cross(double otherX, double otherY, double otherZ, Vector3d result) { |
||||||
|
if (result == null) { |
||||||
|
result = new Vector3d(); |
||||||
|
} |
||||||
|
double resX = y * otherZ - z * otherY; |
||||||
|
double resY = z * otherX - x * otherZ; |
||||||
|
double resZ = x * otherY - y * otherX; |
||||||
|
result.set(resX, resY, resZ); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>crossLocal</code> calculates the cross product of this vector |
||||||
|
* with a parameter vector v. |
||||||
|
* |
||||||
|
* @param v |
||||||
|
* the vector to take the cross product of with this. |
||||||
|
* @return this. |
||||||
|
*/ |
||||||
|
public Vector3d crossLocal(Vector3d v) { |
||||||
|
return this.crossLocal(v.x, v.y, v.z); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>crossLocal</code> calculates the cross product of this vector |
||||||
|
* with a parameter vector v. |
||||||
|
* |
||||||
|
* @param otherX |
||||||
|
* x component of the vector to take the cross product of with this. |
||||||
|
* @param otherY |
||||||
|
* y component of the vector to take the cross product of with this. |
||||||
|
* @param otherZ |
||||||
|
* z component of the vector to take the cross product of with this. |
||||||
|
* @return this. |
||||||
|
*/ |
||||||
|
public Vector3d crossLocal(double otherX, double otherY, double otherZ) { |
||||||
|
double tempx = y * otherZ - z * otherY; |
||||||
|
double tempy = z * otherX - x * otherZ; |
||||||
|
z = x * otherY - y * otherX; |
||||||
|
x = tempx; |
||||||
|
y = tempy; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>length</code> calculates the magnitude of this vector. |
||||||
|
* |
||||||
|
* @return the length or magnitude of the vector. |
||||||
|
*/ |
||||||
|
public double length() { |
||||||
|
return Math.sqrt(this.lengthSquared()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>lengthSquared</code> calculates the squared value of the |
||||||
|
* magnitude of the vector. |
||||||
|
* |
||||||
|
* @return the magnitude squared of the vector. |
||||||
|
*/ |
||||||
|
public double lengthSquared() { |
||||||
|
return x * x + y * y + z * z; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>distanceSquared</code> calculates the distance squared between |
||||||
|
* this vector and vector v. |
||||||
|
* |
||||||
|
* @param v |
||||||
|
* the second vector to determine the distance squared. |
||||||
|
* @return the distance squared between the two vectors. |
||||||
|
*/ |
||||||
|
public double distanceSquared(Vector3d v) { |
||||||
|
double dx = x - v.x; |
||||||
|
double dy = y - v.y; |
||||||
|
double dz = z - v.z; |
||||||
|
return dx * dx + dy * dy + dz * dz; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>distance</code> calculates the distance between this vector and |
||||||
|
* vector v. |
||||||
|
* |
||||||
|
* @param v |
||||||
|
* the second vector to determine the distance. |
||||||
|
* @return the distance between the two vectors. |
||||||
|
*/ |
||||||
|
public double distance(Vector3d v) { |
||||||
|
return Math.sqrt(this.distanceSquared(v)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>mult</code> multiplies this vector by a scalar. The resultant |
||||||
|
* vector is returned. |
||||||
|
* |
||||||
|
* @param scalar |
||||||
|
* the value to multiply this vector by. |
||||||
|
* @return the new vector. |
||||||
|
*/ |
||||||
|
public Vector3d mult(double scalar) { |
||||||
|
return new Vector3d(x * scalar, y * scalar, z * scalar); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>mult</code> multiplies this vector by a scalar. The resultant |
||||||
|
* vector is supplied as the second parameter and returned. |
||||||
|
* |
||||||
|
* @param scalar |
||||||
|
* the scalar to multiply this vector by. |
||||||
|
* @param product |
||||||
|
* the product to store the result in. |
||||||
|
* @return product |
||||||
|
*/ |
||||||
|
public Vector3d mult(double scalar, Vector3d product) { |
||||||
|
if (null == product) { |
||||||
|
product = new Vector3d(); |
||||||
|
} |
||||||
|
|
||||||
|
product.x = x * scalar; |
||||||
|
product.y = y * scalar; |
||||||
|
product.z = z * scalar; |
||||||
|
return product; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>multLocal</code> multiplies this vector by a scalar internally, |
||||||
|
* and returns a handle to this vector for easy chaining of calls. |
||||||
|
* |
||||||
|
* @param scalar |
||||||
|
* the value to multiply this vector by. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d multLocal(double scalar) { |
||||||
|
x *= scalar; |
||||||
|
y *= scalar; |
||||||
|
z *= scalar; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>multLocal</code> multiplies a provided vector to this vector |
||||||
|
* internally, and returns a handle to this vector for easy chaining of |
||||||
|
* calls. If the provided vector is null, null is returned. |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to mult to this vector. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d multLocal(Vector3d vec) { |
||||||
|
if (null == vec) { |
||||||
|
LOGGER.warning("Provided vector is null, null returned."); |
||||||
|
return null; |
||||||
|
} |
||||||
|
x *= vec.x; |
||||||
|
y *= vec.y; |
||||||
|
z *= vec.z; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>multLocal</code> multiplies this vector by 3 scalars |
||||||
|
* internally, and returns a handle to this vector for easy chaining of |
||||||
|
* calls. |
||||||
|
* |
||||||
|
* @param x |
||||||
|
* @param y |
||||||
|
* @param z |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d multLocal(double x, double y, double z) { |
||||||
|
this.x *= x; |
||||||
|
this.y *= y; |
||||||
|
this.z *= z; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>multLocal</code> multiplies a provided vector to this vector |
||||||
|
* internally, and returns a handle to this vector for easy chaining of |
||||||
|
* calls. If the provided vector is null, null is returned. |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to mult to this vector. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d mult(Vector3d vec) { |
||||||
|
if (null == vec) { |
||||||
|
LOGGER.warning("Provided vector is null, null returned."); |
||||||
|
return null; |
||||||
|
} |
||||||
|
return this.mult(vec, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>multLocal</code> multiplies a provided vector to this vector |
||||||
|
* internally, and returns a handle to this vector for easy chaining of |
||||||
|
* calls. If the provided vector is null, null is returned. |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to mult to this vector. |
||||||
|
* @param store |
||||||
|
* result vector (null to create a new vector) |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d mult(Vector3d vec, Vector3d store) { |
||||||
|
if (null == vec) { |
||||||
|
LOGGER.warning("Provided vector is null, null returned."); |
||||||
|
return null; |
||||||
|
} |
||||||
|
if (store == null) { |
||||||
|
store = new Vector3d(); |
||||||
|
} |
||||||
|
return store.set(x * vec.x, y * vec.y, z * vec.z); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>divide</code> divides the values of this vector by a scalar and |
||||||
|
* returns the result. The values of this vector remain untouched. |
||||||
|
* |
||||||
|
* @param scalar |
||||||
|
* the value to divide this vectors attributes by. |
||||||
|
* @return the result <code>Vector</code>. |
||||||
|
*/ |
||||||
|
public Vector3d divide(double scalar) { |
||||||
|
scalar = 1f / scalar; |
||||||
|
return new Vector3d(x * scalar, y * scalar, z * scalar); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>divideLocal</code> divides this vector by a scalar internally, |
||||||
|
* and returns a handle to this vector for easy chaining of calls. Dividing |
||||||
|
* by zero will result in an exception. |
||||||
|
* |
||||||
|
* @param scalar |
||||||
|
* the value to divides this vector by. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d divideLocal(double scalar) { |
||||||
|
scalar = 1f / scalar; |
||||||
|
x *= scalar; |
||||||
|
y *= scalar; |
||||||
|
z *= scalar; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>divide</code> divides the values of this vector by a scalar and |
||||||
|
* returns the result. The values of this vector remain untouched. |
||||||
|
* |
||||||
|
* @param scalar |
||||||
|
* the value to divide this vectors attributes by. |
||||||
|
* @return the result <code>Vector</code>. |
||||||
|
*/ |
||||||
|
public Vector3d divide(Vector3d scalar) { |
||||||
|
return new Vector3d(x / scalar.x, y / scalar.y, z / scalar.z); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>divideLocal</code> divides this vector by a scalar internally, |
||||||
|
* and returns a handle to this vector for easy chaining of calls. Dividing |
||||||
|
* by zero will result in an exception. |
||||||
|
* |
||||||
|
* @param scalar |
||||||
|
* the value to divides this vector by. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d divideLocal(Vector3d scalar) { |
||||||
|
x /= scalar.x; |
||||||
|
y /= scalar.y; |
||||||
|
z /= scalar.z; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>negate</code> returns the negative of this vector. All values are |
||||||
|
* negated and set to a new vector. |
||||||
|
* |
||||||
|
* @return the negated vector. |
||||||
|
*/ |
||||||
|
public Vector3d negate() { |
||||||
|
return new Vector3d(-x, -y, -z); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>negateLocal</code> negates the internal values of this vector. |
||||||
|
* |
||||||
|
* @return this. |
||||||
|
*/ |
||||||
|
public Vector3d negateLocal() { |
||||||
|
x = -x; |
||||||
|
y = -y; |
||||||
|
z = -z; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>subtract</code> subtracts the values of a given vector from those |
||||||
|
* of this vector creating a new vector object. If the provided vector is |
||||||
|
* null, null is returned. |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to subtract from this vector. |
||||||
|
* @return the result vector. |
||||||
|
*/ |
||||||
|
public Vector3d subtract(Vector3d vec) { |
||||||
|
return new Vector3d(x - vec.x, y - vec.y, z - vec.z); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>subtractLocal</code> subtracts a provided vector to this vector |
||||||
|
* internally, and returns a handle to this vector for easy chaining of |
||||||
|
* calls. If the provided vector is null, null is returned. |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to subtract |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d subtractLocal(Vector3d vec) { |
||||||
|
if (null == vec) { |
||||||
|
LOGGER.warning("Provided vector is null, null returned."); |
||||||
|
return null; |
||||||
|
} |
||||||
|
x -= vec.x; |
||||||
|
y -= vec.y; |
||||||
|
z -= vec.z; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>subtract</code> |
||||||
|
* |
||||||
|
* @param vec |
||||||
|
* the vector to subtract from this |
||||||
|
* @param result |
||||||
|
* the vector to store the result in |
||||||
|
* @return result |
||||||
|
*/ |
||||||
|
public Vector3d subtract(Vector3d vec, Vector3d result) { |
||||||
|
if (result == null) { |
||||||
|
result = new Vector3d(); |
||||||
|
} |
||||||
|
result.x = x - vec.x; |
||||||
|
result.y = y - vec.y; |
||||||
|
result.z = z - vec.z; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* <code>subtract</code> subtracts the provided values from this vector, |
||||||
|
* creating a new vector that is then returned. |
||||||
|
* |
||||||
|
* @param subtractX |
||||||
|
* the x value to subtract. |
||||||
|
* @param subtractY |
||||||
|
* the y value to subtract. |
||||||
|
* @param subtractZ |
||||||
|
* the z value to subtract. |
||||||
|
* @return the result vector. |
||||||
|
*/ |
||||||
|
public Vector3d subtract(double subtractX, double subtractY, double subtractZ) { |
||||||
|
return new Vector3d(x - subtractX, y - subtractY, z - subtractZ); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>subtractLocal</code> subtracts the provided values from this vector |
||||||
|
* internally, and returns a handle to this vector for easy chaining of |
||||||
|
* calls. |
||||||
|
* |
||||||
|
* @param subtractX |
||||||
|
* the x value to subtract. |
||||||
|
* @param subtractY |
||||||
|
* the y value to subtract. |
||||||
|
* @param subtractZ |
||||||
|
* the z value to subtract. |
||||||
|
* @return this |
||||||
|
*/ |
||||||
|
public Vector3d subtractLocal(double subtractX, double subtractY, double subtractZ) { |
||||||
|
x -= subtractX; |
||||||
|
y -= subtractY; |
||||||
|
z -= subtractZ; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>normalize</code> returns the unit vector of this vector. |
||||||
|
* |
||||||
|
* @return unit vector of this vector. |
||||||
|
*/ |
||||||
|
public Vector3d normalize() { |
||||||
|
double length = x * x + y * y + z * z; |
||||||
|
if (length != 1f && length != 0f) { |
||||||
|
length = 1.0f / Math.sqrt(length); |
||||||
|
return new Vector3d(x * length, y * length, z * length); |
||||||
|
} |
||||||
|
return this.clone(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>normalizeLocal</code> makes this vector into a unit vector of |
||||||
|
* itself. |
||||||
|
* |
||||||
|
* @return this. |
||||||
|
*/ |
||||||
|
public Vector3d normalizeLocal() { |
||||||
|
// NOTE: this implementation is more optimized
|
||||||
|
// than the old jme normalize as this method
|
||||||
|
// is commonly used.
|
||||||
|
double length = x * x + y * y + z * z; |
||||||
|
if (length != 1f && length != 0f) { |
||||||
|
length = 1.0f / Math.sqrt(length); |
||||||
|
x *= length; |
||||||
|
y *= length; |
||||||
|
z *= length; |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>angleBetween</code> returns (in radians) the angle between two vectors. |
||||||
|
* It is assumed that both this vector and the given vector are unit vectors (iow, normalized). |
||||||
|
* |
||||||
|
* @param otherVector |
||||||
|
* a unit vector to find the angle against |
||||||
|
* @return the angle in radians. |
||||||
|
*/ |
||||||
|
public double angleBetween(Vector3d otherVector) { |
||||||
|
double dot = this.dot(otherVector); |
||||||
|
// the vectors are normalized, but if they are parallel then the dot product migh get a value like: 1.000000000000000002
|
||||||
|
// which is caused by floating point operations; in such case, the acos function will return NaN so we need to clamp this value
|
||||||
|
dot = FastMath.clamp((float) dot, -1, 1); |
||||||
|
return Math.acos(dot); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Vector3d clone() { |
||||||
|
try { |
||||||
|
return (Vector3d) super.clone(); |
||||||
|
} catch (CloneNotSupportedException e) { |
||||||
|
throw new AssertionError(); // can not happen
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* are these two vectors the same? they are is they both have the same x,y, |
||||||
|
* and z values. |
||||||
|
* |
||||||
|
* @param o |
||||||
|
* the object to compare for equality |
||||||
|
* @return true if they are equal |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public boolean equals(Object o) { |
||||||
|
if (!(o instanceof Vector3d)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (this == o) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
Vector3d comp = (Vector3d) o; |
||||||
|
if (Double.compare(x, comp.x) != 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (Double.compare(y, comp.y) != 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (Double.compare(z, comp.z) != 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>hashCode</code> returns a unique code for this vector object based |
||||||
|
* on it's values. If two vectors are logically equivalent, they will return |
||||||
|
* the same hash code value. |
||||||
|
* @return the hash code value of this vector. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
long hash = 37; |
||||||
|
hash += 37 * hash + Double.doubleToLongBits(x); |
||||||
|
hash += 37 * hash + Double.doubleToLongBits(y); |
||||||
|
hash += 37 * hash + Double.doubleToLongBits(z); |
||||||
|
return (int) hash; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>toString</code> returns the string representation of this vector. |
||||||
|
* The format is: |
||||||
|
* |
||||||
|
* org.jme.math.Vector3d [X=XX.XXXX, Y=YY.YYYY, Z=ZZ.ZZZZ] |
||||||
|
* |
||||||
|
* @return the string representation of this vector. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "(" + x + ", " + y + ", " + z + ")"; |
||||||
|
} |
||||||
|
|
||||||
|
public void write(JmeExporter e) throws IOException { |
||||||
|
OutputCapsule capsule = e.getCapsule(this); |
||||||
|
capsule.write(x, "x", 0); |
||||||
|
capsule.write(y, "y", 0); |
||||||
|
capsule.write(z, "z", 0); |
||||||
|
} |
||||||
|
|
||||||
|
public void read(JmeImporter e) throws IOException { |
||||||
|
InputCapsule capsule = e.getCapsule(this); |
||||||
|
x = capsule.readDouble("x", 0); |
||||||
|
y = capsule.readDouble("y", 0); |
||||||
|
z = capsule.readDouble("z", 0); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue