improve formatting and rm trailing whitespace (16 files in jme3-core)

v3.3
Stephen Gold 5 years ago
parent ce862bc09e
commit e98df18a9c
  1. 116
      jme3-core/src/main/java/com/jme3/bounding/BoundingBox.java
  2. 34
      jme3-core/src/main/java/com/jme3/bounding/BoundingVolume.java
  3. 237
      jme3-core/src/main/java/com/jme3/math/CurveAndSurfaceMath.java
  4. 154
      jme3-core/src/main/java/com/jme3/math/FastMath.java
  5. 173
      jme3-core/src/main/java/com/jme3/math/Matrix3f.java
  6. 242
      jme3-core/src/main/java/com/jme3/math/Matrix4f.java
  7. 49
      jme3-core/src/main/java/com/jme3/math/Plane.java
  8. 119
      jme3-core/src/main/java/com/jme3/math/Quaternion.java
  9. 189
      jme3-core/src/main/java/com/jme3/math/Spline.java
  10. 126
      jme3-core/src/main/java/com/jme3/math/Transform.java
  11. 144
      jme3-core/src/main/java/com/jme3/math/Vector3f.java
  12. 73
      jme3-core/src/main/java/com/jme3/scene/mesh/VirtualIndexBuffer.java
  13. 16
      jme3-core/src/main/java/com/jme3/scene/shape/Curve.java
  14. 273
      jme3-core/src/main/java/com/jme3/texture/FrameBuffer.java
  15. 3
      jme3-core/src/main/java/com/jme3/util/BufferUtils.java
  16. 118
      jme3-core/src/main/java/com/jme3/util/ReflectionAllocator.java

@ -68,7 +68,7 @@ public class BoundingBox extends BoundingVolume {
* the Z-extent of the box (>=0, may be +Infinity) * the Z-extent of the box (>=0, may be +Infinity)
*/ */
float zExtent; float zExtent;
/** /**
* Instantiate a <code>BoundingBox</code> without initializing it. * Instantiate a <code>BoundingBox</code> without initializing it.
*/ */
@ -113,7 +113,7 @@ public class BoundingBox extends BoundingVolume {
/** /**
* <code>computeFromPoints</code> creates a new Bounding Box from a given * <code>computeFromPoints</code> creates a new Bounding Box from a given
* set of points. It uses the <code>containAABB</code> method as default. * set of points. It uses the <code>containAABB</code> method as default.
* *
* @param points * @param points
* the points to contain. * the points to contain.
*/ */
@ -124,7 +124,7 @@ public class BoundingBox extends BoundingVolume {
/** /**
* <code>computeFromTris</code> creates a new Bounding Box from a given * <code>computeFromTris</code> creates a new Bounding Box from a given
* set of triangles. It is used in OBBTree calculations. * set of triangles. It is used in OBBTree calculations.
* *
* @param tris * @param tris
* @param start * @param start
* @param end * @param end
@ -136,8 +136,10 @@ public class BoundingBox extends BoundingVolume {
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY)); Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY,
Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY)); Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY,
Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
Vector3f point; Vector3f point;
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
@ -219,7 +221,7 @@ public class BoundingBox extends BoundingVolume {
* <code>containAABB</code> creates a minimum-volume axis-aligned bounding * <code>containAABB</code> creates a minimum-volume axis-aligned bounding
* box of the points, then selects the smallest enclosing sphere of the box * box of the points, then selects the smallest enclosing sphere of the box
* with the sphere centered at the boxes center. * with the sphere centered at the boxes center.
* *
* @param points * @param points
* the list of points. * the list of points.
*/ */
@ -235,12 +237,16 @@ public class BoundingBox extends BoundingVolume {
} }
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
float[] tmpArray = vars.skinPositions; float[] tmpArray = vars.skinPositions;
float minX = Float.POSITIVE_INFINITY, minY = Float.POSITIVE_INFINITY, minZ = Float.POSITIVE_INFINITY; float minX = Float.POSITIVE_INFINITY,
float maxX = Float.NEGATIVE_INFINITY, maxY = Float.NEGATIVE_INFINITY, maxZ = Float.NEGATIVE_INFINITY; minY = Float.POSITIVE_INFINITY,
minZ = Float.POSITIVE_INFINITY;
float maxX = Float.NEGATIVE_INFINITY,
maxY = Float.NEGATIVE_INFINITY,
maxZ = Float.NEGATIVE_INFINITY;
int iterations = (int) FastMath.ceil(points.limit() / ((float) tmpArray.length)); int iterations = (int) FastMath.ceil(points.limit() / ((float) tmpArray.length));
for (int i = iterations - 1; i >= 0; i--) { for (int i = iterations - 1; i >= 0; i--) {
int bufLength = Math.min(tmpArray.length, points.remaining()); int bufLength = Math.min(tmpArray.length, points.remaining());
@ -248,9 +254,9 @@ public class BoundingBox extends BoundingVolume {
for (int j = 0; j < bufLength; j += 3) { for (int j = 0; j < bufLength; j += 3) {
vars.vect1.x = tmpArray[j]; vars.vect1.x = tmpArray[j];
vars.vect1.y = tmpArray[j+1]; vars.vect1.y = tmpArray[j + 1];
vars.vect1.z = tmpArray[j+2]; vars.vect1.z = tmpArray[j + 2];
if (vars.vect1.x < minX) { if (vars.vect1.x < minX) {
minX = vars.vect1.x; minX = vars.vect1.x;
} }
@ -287,8 +293,8 @@ public class BoundingBox extends BoundingVolume {
/** /**
* <code>transform</code> modifies the center of the box to reflect the * <code>transform</code> modifies the center of the box to reflect the
* change made via a rotation, translation and scale. * change made via a rotation, translation and scale.
* *
* @param trans * @param trans
* the transform to apply * the transform to apply
* @param store * @param store
* box to store result in * box to store result in
@ -314,7 +320,9 @@ public class BoundingBox extends BoundingVolume {
transMatrix.absoluteLocal(); transMatrix.absoluteLocal();
Vector3f scale = trans.getScale(); Vector3f scale = trans.getScale();
vars.vect1.set(xExtent * FastMath.abs(scale.x), yExtent * FastMath.abs(scale.y), zExtent * FastMath.abs(scale.z)); vars.vect1.set(xExtent * FastMath.abs(scale.x),
yExtent * FastMath.abs(scale.y),
zExtent * FastMath.abs(scale.z));
transMatrix.mult(vars.vect1, vars.vect2); transMatrix.mult(vars.vect1, vars.vect2);
// Assign the biggest rotations after scales. // Assign the biggest rotations after scales.
box.xExtent = FastMath.abs(vars.vect2.getX()); box.xExtent = FastMath.abs(vars.vect2.getX());
@ -335,7 +343,6 @@ public class BoundingBox extends BoundingVolume {
} }
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
float w = trans.multProj(center, box.center); float w = trans.multProj(center, box.center);
box.center.divideLocal(w); box.center.divideLocal(w);
@ -361,7 +368,7 @@ public class BoundingBox extends BoundingVolume {
/** /**
* <code>whichSide</code> takes a plane (typically provided by a view * <code>whichSide</code> takes a plane (typically provided by a view
* frustum) to determine which side this bound is on. * frustum) to determine which side this bound is on.
* *
* @param plane * @param plane
* the plane to check against. * the plane to check against.
*/ */
@ -425,15 +432,14 @@ public class BoundingBox extends BoundingVolume {
// case OBB: { // case OBB: {
// return mergeOBB((OrientedBoundingBox) volume); // return mergeOBB((OrientedBoundingBox) volume);
// } // }
default: default:
return null; return null;
} }
} }
/** /*
* Merges this AABB with the given OBB. * Merges this AABB with the given OBB.
* *
* @param volume * @param volume
* the OBB to merge this AABB with. * the OBB to merge this AABB with.
* @return This AABB extended to fit the given OBB. * @return This AABB extended to fit the given OBB.
@ -474,6 +480,7 @@ public class BoundingBox extends BoundingVolume {
// zExtent = max.z - center.z; // zExtent = max.z - center.z;
// return this; // return this;
// } // }
/** /**
* <code>mergeLocal</code> combines this bounding box locally with a second * <code>mergeLocal</code> combines this bounding box locally with a second
* bounding box described by its center and extents. * bounding box described by its center and extents.
@ -542,7 +549,7 @@ public class BoundingBox extends BoundingVolume {
/** /**
* <code>clone</code> creates a new BoundingBox object containing the same * <code>clone</code> creates a new BoundingBox object containing the same
* data as this one. * data as this one.
* *
* @param store * @param store
* where to store the cloned information. if null or wrong class, * where to store the cloned information. if null or wrong class,
* a new store is created. * a new store is created.
@ -581,8 +588,8 @@ public class BoundingBox extends BoundingVolume {
/** /**
* intersects determines if this Bounding Box intersects with another given * intersects determines if this Bounding Box intersects with another given
* bounding volume. If so, true is returned, otherwise, false is returned. * bounding volume. If so, true is returned, otherwise, false is returned.
* *
* @see BoundingVolume#intersects(com.jme3.bounding.BoundingVolume) * @see BoundingVolume#intersects(com.jme3.bounding.BoundingVolume)
*/ */
public boolean intersects(BoundingVolume bv) { public boolean intersects(BoundingVolume bv) {
return bv.intersectsBoundingBox(this); return bv.intersectsBoundingBox(this);
@ -590,7 +597,7 @@ public class BoundingBox extends BoundingVolume {
/** /**
* determines if this bounding box intersects a given bounding sphere. * determines if this bounding box intersects a given bounding sphere.
* *
* @see BoundingVolume#intersectsSphere(com.jme3.bounding.BoundingSphere) * @see BoundingVolume#intersectsSphere(com.jme3.bounding.BoundingSphere)
*/ */
public boolean intersectsSphere(BoundingSphere bs) { public boolean intersectsSphere(BoundingSphere bs) {
@ -601,7 +608,7 @@ public class BoundingBox extends BoundingVolume {
* determines if this bounding box intersects a given bounding box. If the * determines if this bounding box intersects a given bounding box. If the
* two boxes intersect in any way, true is returned. Otherwise, false is * two boxes intersect in any way, true is returned. Otherwise, false is
* returned. * returned.
* *
* @see BoundingVolume#intersectsBoundingBox(com.jme3.bounding.BoundingBox) * @see BoundingVolume#intersectsBoundingBox(com.jme3.bounding.BoundingBox)
*/ */
public boolean intersectsBoundingBox(BoundingBox bb) { public boolean intersectsBoundingBox(BoundingBox bb) {
@ -621,10 +628,10 @@ public class BoundingBox extends BoundingVolume {
} }
} }
/** /*
* determines if this bounding box intersects with a given oriented bounding * determines if this bounding box intersects with a given oriented bounding
* box. * box.
* *
* @see com.jme.bounding.BoundingVolume#intersectsOrientedBoundingBox(com.jme.bounding.OrientedBoundingBox) * @see com.jme.bounding.BoundingVolume#intersectsOrientedBoundingBox(com.jme.bounding.OrientedBoundingBox)
*/ */
// public boolean intersectsOrientedBoundingBox(OrientedBoundingBox obb) { // public boolean intersectsOrientedBoundingBox(OrientedBoundingBox obb) {
@ -633,8 +640,8 @@ public class BoundingBox extends BoundingVolume {
/** /**
* determines if this bounding box intersects with a given ray object. If an * determines if this bounding box intersects with a given ray object. If an
* intersection has occurred, true is returned, otherwise false is returned. * intersection has occurred, true is returned, otherwise false is returned.
* *
* @see BoundingVolume#intersects(com.jme3.math.Ray) * @see BoundingVolume#intersects(com.jme3.math.Ray)
*/ */
public boolean intersects(Ray ray) { public boolean intersects(Ray ray) {
assert Vector3f.isValidVector(center); assert Vector3f.isValidVector(center);
@ -710,14 +717,14 @@ public class BoundingBox extends BoundingVolume {
*/ */
private int collideWithRay(Ray ray, CollisionResults results) { private int collideWithRay(Ray ray, CollisionResults results) {
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
try { try {
Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center); Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center);
Vector3f direction = vars.vect2.set(ray.direction); Vector3f direction = vars.vect2.set(ray.direction);
//float[] t = {0f, Float.POSITIVE_INFINITY}; //float[] t = {0f, Float.POSITIVE_INFINITY};
float[] t = vars.fWdU; // use one of the tempvars arrays float[] t = vars.fWdU; // use one of the tempvars arrays
t[0] = 0; t[0] = 0;
t[1] = Float.POSITIVE_INFINITY; t[1] = Float.POSITIVE_INFINITY;
float saveT0 = t[0], saveT1 = t[1]; float saveT0 = t[0], saveT1 = t[1];
boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t) boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t)
@ -732,14 +739,14 @@ public class BoundingBox extends BoundingVolume {
float[] distances = t; float[] distances = t;
Vector3f point0 = new Vector3f(ray.direction).multLocal(distances[0]).addLocal(ray.origin); Vector3f point0 = new Vector3f(ray.direction).multLocal(distances[0]).addLocal(ray.origin);
Vector3f point1 = new Vector3f(ray.direction).multLocal(distances[1]).addLocal(ray.origin); Vector3f point1 = new Vector3f(ray.direction).multLocal(distances[1]).addLocal(ray.origin);
CollisionResult result = new CollisionResult(point0, distances[0]); CollisionResult result = new CollisionResult(point0, distances[0]);
results.addCollision(result); results.addCollision(result);
result = new CollisionResult(point1, distances[1]); result = new CollisionResult(point1, distances[1]);
results.addCollision(result); results.addCollision(result);
return 2; return 2;
} }
Vector3f point = new Vector3f(ray.direction).multLocal(t[0]).addLocal(ray.origin); Vector3f point = new Vector3f(ray.direction).multLocal(t[0]).addLocal(ray.origin);
CollisionResult result = new CollisionResult(point, t[0]); CollisionResult result = new CollisionResult(point, t[0]);
results.addCollision(result); results.addCollision(result);
@ -753,14 +760,14 @@ public class BoundingBox extends BoundingVolume {
private int collideWithRay(Ray ray) { private int collideWithRay(Ray ray) {
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
try { try {
Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center); Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center);
Vector3f direction = vars.vect2.set(ray.direction); Vector3f direction = vars.vect2.set(ray.direction);
//float[] t = {0f, Float.POSITIVE_INFINITY}; //float[] t = {0f, Float.POSITIVE_INFINITY};
float[] t = vars.fWdU; // use one of the tempvars arrays float[] t = vars.fWdU; // use one of the tempvars arrays
t[0] = 0; t[0] = 0;
t[1] = Float.POSITIVE_INFINITY; t[1] = Float.POSITIVE_INFINITY;
float saveT0 = t[0], saveT1 = t[1]; float saveT0 = t[0], saveT1 = t[1];
boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t) boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t)
@ -771,15 +778,18 @@ public class BoundingBox extends BoundingVolume {
&& clip(-direction.z, +diff.z - zExtent, t); && clip(-direction.z, +diff.z - zExtent, t);
if (notEntirelyClipped && (t[0] != saveT0 || t[1] != saveT1)) { if (notEntirelyClipped && (t[0] != saveT0 || t[1] != saveT1)) {
if (t[1] > t[0]) return 2; if (t[1] > t[0]) {
else return 1; return 2;
} else {
return 1;
}
} }
return 0; return 0;
} finally { } finally {
vars.release(); vars.release();
} }
} }
@Override @Override
public int collideWith(Collidable other, CollisionResults results) { public int collideWith(Collidable other, CollisionResults results) {
if (other instanceof Ray) { if (other instanceof Ray) {
@ -806,7 +816,7 @@ public class BoundingBox extends BoundingVolume {
throw new UnsupportedCollisionException("With: " + other.getClass().getSimpleName()); throw new UnsupportedCollisionException("With: " + other.getClass().getSimpleName());
} }
} }
@Override @Override
public int collideWith(Collidable other) { public int collideWith(Collidable other) {
if (other instanceof Ray) { if (other instanceof Ray) {
@ -855,10 +865,10 @@ public class BoundingBox extends BoundingVolume {
public float distanceToEdge(Vector3f point) { public float distanceToEdge(Vector3f point) {
// compute coordinates of point in box coordinate system // compute coordinates of point in box coordinate system
TempVars vars= TempVars.get(); TempVars vars = TempVars.get();
Vector3f closest = vars.vect1; Vector3f closest = vars.vect1;
point.subtract(center,closest); point.subtract(center, closest);
// project test point onto box // project test point onto box
float sqrDistance = 0.0f; float sqrDistance = 0.0f;
@ -893,7 +903,7 @@ public class BoundingBox extends BoundingVolume {
sqrDistance += delta * delta; sqrDistance += delta * delta;
closest.z = zExtent; closest.z = zExtent;
} }
vars.release(); vars.release();
return FastMath.sqrt(sqrDistance); return FastMath.sqrt(sqrDistance);
} }
@ -901,7 +911,7 @@ public class BoundingBox extends BoundingVolume {
/** /**
* <code>clip</code> determines if a line segment intersects the current * <code>clip</code> determines if a line segment intersects the current
* test plane. * test plane.
* *
* @param denom * @param denom
* the denominator of the line segment. * the denominator of the line segment.
* @param numer * @param numer
@ -923,26 +933,26 @@ public class BoundingBox extends BoundingVolume {
// work out the same but in floating point there can // work out the same but in floating point there can
// be subtle math errors. The multiply will exaggerate // be subtle math errors. The multiply will exaggerate
// errors that may have been introduced when the value // errors that may have been introduced when the value
// was originally divided. // was originally divided.
// //
// This is especially true when the bounding box has zero // This is especially true when the bounding box has zero
// extents in some plane because the error rate is critical. // extents in some plane because the error rate is critical.
// comparing a to b * c is not the same as comparing a/b to c // comparing a to b * c is not the same as comparing a/b to c
// in this case. In fact, I tried converting this method to // in this case. In fact, I tried converting this method to
// double and the and the error was in the last decimal place. // double and the and the error was in the last decimal place.
// //
// So, instead, we now compare the divided version to the divided // So, instead, we now compare the divided version to the divided
// version. We lose some slight performance here as divide // version. We lose some slight performance here as divide
// will be more expensive than the divide. Some microbenchmarks // will be more expensive than the divide. Some microbenchmarks
// show divide to be 3x slower than multiple on Java 1.6. // show divide to be 3x slower than multiple on Java 1.6.
// BUT... we also saved a multiply in the non-clipped case because // BUT... we also saved a multiply in the non-clipped case because
// we can reuse the divided version in both if checks. // we can reuse the divided version in both if checks.
// I think it's better to be right in this case. // I think it's better to be right in this case.
// //
// Bug that I'm fixing: rays going right through quads at certain // Bug that I'm fixing: rays going right through quads at certain
// angles and distances because they fail the bounding box test. // angles and distances because they fail the bounding box test.
// Many Bothans died bring you this fix. // Many Bothans died bring you this fix.
// -pspeed // -pspeed
float newT = numer / denom; float newT = numer / denom;
if (newT > t[1]) { if (newT > t[1]) {
return false; return false;
@ -959,7 +969,7 @@ public class BoundingBox extends BoundingVolume {
// When we move it over to the other side we have to flip // When we move it over to the other side we have to flip
// the comparison. Algebra for the win. // the comparison. Algebra for the win.
float newT = numer / denom; float newT = numer / denom;
if (newT < t[0]) { if (newT < t[0]) {
return false; return false;
} }
if (newT < t[1]) { if (newT < t[1]) {
@ -973,7 +983,7 @@ public class BoundingBox extends BoundingVolume {
/** /**
* Query extent. * Query extent.
* *
* @param store * @param store
* where extent gets stored - null to return a new vector * where extent gets stored - null to return a new vector
* @return store / new vector * @return store / new vector

@ -44,12 +44,11 @@ import java.nio.FloatBuffer;
/** /**
* <code>BoundingVolume</code> defines an interface for dealing with * <code>BoundingVolume</code> defines an interface for dealing with
* containment of a collection of points. * containment of a collection of points.
* *
* @author Mark Powell * @author Mark Powell
* @version $Id: BoundingVolume.java,v 1.24 2007/09/21 15:45:32 nca Exp $ * @version $Id: BoundingVolume.java,v 1.24 2007/09/21 15:45:32 nca Exp $
*/ */
public abstract class BoundingVolume implements Savable, Cloneable, Collidable { public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/** /**
* The type of bounding volume being used. * The type of bounding volume being used.
*/ */
@ -57,13 +56,11 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/** /**
* {@link BoundingSphere} * {@link BoundingSphere}
*/ */
Sphere, Sphere,
/** /**
* {@link BoundingBox}. * {@link BoundingBox}.
*/ */
AABB, AABB,
/** /**
* Currently unsupported by jME3. * Currently unsupported by jME3.
*/ */
@ -82,7 +79,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/** /**
* Grabs the checkplane we should check first. * Grabs the checkplane we should check first.
*
*/ */
public int getCheckPlane() { public int getCheckPlane() {
return checkPlane; return checkPlane;
@ -103,7 +99,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
public abstract Type getType(); public abstract Type getType();
/** /**
*
* <code>transform</code> alters the location of the bounding volume by a * <code>transform</code> alters the location of the bounding volume by a
* rotation, translation and a scalar. * rotation, translation and a scalar.
* *
@ -116,7 +111,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
} }
/** /**
*
* <code>transform</code> alters the location of the bounding volume by a * <code>transform</code> alters the location of the bounding volume by a
* rotation, translation and a scalar. * rotation, translation and a scalar.
* *
@ -131,7 +125,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
public abstract BoundingVolume transform(Matrix4f trans, BoundingVolume store); public abstract BoundingVolume transform(Matrix4f trans, BoundingVolume store);
/** /**
*
* <code>whichSide</code> returns the side on which the bounding volume * <code>whichSide</code> returns the side on which the bounding volume
* lies on a plane. Possible values are POSITIVE_SIDE, NEGATIVE_SIDE, and * lies on a plane. Possible values are POSITIVE_SIDE, NEGATIVE_SIDE, and
* NO_SIDE. * NO_SIDE.
@ -143,7 +136,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
public abstract Plane.Side whichSide(Plane plane); public abstract Plane.Side whichSide(Plane plane);
/** /**
*
* <code>computeFromPoints</code> generates a bounding volume that * <code>computeFromPoints</code> generates a bounding volume that
* encompasses a collection of points. * encompasses a collection of points.
* *
@ -204,7 +196,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/** /**
* Find the distance from the center of this Bounding Volume to the given * Find the distance from the center of this Bounding Volume to the given
* point. * point.
* *
* @param point * @param point
* The point to get the distance to * The point to get the distance to
* @return distance * @return distance
@ -216,7 +208,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/** /**
* Find the squared distance from the center of this Bounding Volume to the * Find the squared distance from the center of this Bounding Volume to the
* given point. * given point.
* *
* @param point * @param point
* The point to get the distance to * The point to get the distance to
* @return distance * @return distance
@ -228,7 +220,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/** /**
* Find the distance from the nearest edge of this Bounding Volume to the given * Find the distance from the nearest edge of this Bounding Volume to the given
* point. * point.
* *
* @param point * @param point
* The point to get the distance to * The point to get the distance to
* @return distance * @return distance
@ -255,7 +247,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
*/ */
public abstract boolean intersects(Ray ray); public abstract boolean intersects(Ray ray);
/** /**
* determines if this bounding volume and a given bounding sphere are * determines if this bounding volume and a given bounding sphere are
* intersecting. * intersecting.
@ -276,7 +267,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
*/ */
public abstract boolean intersectsBoundingBox(BoundingBox bb); public abstract boolean intersectsBoundingBox(BoundingBox bb);
/** /*
* determines if this bounding volume and a given bounding box are * determines if this bounding volume and a given bounding box are
* intersecting. * intersecting.
* *
@ -286,11 +277,10 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
*/ */
// public abstract boolean intersectsOrientedBoundingBox(OrientedBoundingBox bb); // public abstract boolean intersectsOrientedBoundingBox(OrientedBoundingBox bb);
/** /**
*
* determines if a given point is contained within this bounding volume. * determines if a given point is contained within this bounding volume.
* If the point is on the edge of the bounding volume, this method will * If the point is on the edge of the bounding volume, this method will
* return false. Use intersects(Vector3f) to check for edge intersection. * return false. Use intersects(Vector3f) to check for edge intersection.
* *
* @param point * @param point
* the point to check * the point to check
* @return true if the point lies within this bounding volume. * @return true if the point lies within this bounding volume.
@ -299,6 +289,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/** /**
* Determines if a given point intersects (touches or is inside) this bounding volume. * Determines if a given point intersects (touches or is inside) this bounding volume.
*
* @param point the point to check * @param point the point to check
* @return true if the point lies within this bounding volume. * @return true if the point lies within this bounding volume.
*/ */
@ -308,11 +299,11 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
@Override @Override
public BoundingVolume clone() { public BoundingVolume clone() {
try{ try {
BoundingVolume clone = (BoundingVolume) super.clone(); BoundingVolume clone = (BoundingVolume) super.clone();
clone.center = center.clone(); clone.center = center.clone();
return clone; return clone;
}catch (CloneNotSupportedException ex){ } catch (CloneNotSupportedException ex) {
throw new AssertionError(); throw new AssertionError();
} }
} }
@ -324,7 +315,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
public void read(JmeImporter e) throws IOException { public void read(JmeImporter e) throws IOException {
center = (Vector3f) e.getCapsule(this).readSavable("center", Vector3f.ZERO.clone()); center = (Vector3f) e.getCapsule(this).readSavable("center", Vector3f.ZERO.clone());
} }
public int collideWith(Collidable other) { public int collideWith(Collidable other) {
TempVars tempVars = TempVars.get(); TempVars tempVars = TempVars.get();
try { try {
@ -336,4 +327,3 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
} }
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2012 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,130 +36,129 @@ import java.util.List;
/** /**
* This class offers methods to help with curves and surfaces calculations. * This class offers methods to help with curves and surfaces calculations.
*
* @author Marcin Roguski (Kealthas) * @author Marcin Roguski (Kealthas)
*/ */
public class CurveAndSurfaceMath { public class CurveAndSurfaceMath {
private static final float KNOTS_MINIMUM_DELTA = 0.0001f; private static final float KNOTS_MINIMUM_DELTA = 0.0001f;
/**
* A private constructor is defined to avoid instantiation of this class.
*/
private CurveAndSurfaceMath() {
}
/** /**
* A private constructor is defined to avoid instantiation of this * This method interpolates the data for the nurbs curve.
* class. *
*/ * @param u the u value
private CurveAndSurfaceMath() {} * @param nurbSpline
* the nurbs spline definition
/** * @param store
* This method interpolates the data for the nurbs curve. * the resulting point in 3D space
* @param u */
* the u value public static void interpolateNurbs(float u, Spline nurbSpline, Vector3f store) {
* @param nurbSpline if (nurbSpline.getType() != SplineType.Nurb) {
* the nurbs spline definition throw new IllegalArgumentException("Given spline is not of a NURB type!");
* @param store }
* the resulting point in 3D space List<Vector3f> controlPoints = nurbSpline.getControlPoints();
*/ float[] weights = nurbSpline.getWeights();
public static void interpolateNurbs(float u, Spline nurbSpline, Vector3f store) { List<Float> knots = nurbSpline.getKnots();
if (nurbSpline.getType() != SplineType.Nurb) { int controlPointAmount = controlPoints.size();
throw new IllegalArgumentException("Given spline is not of a NURB type!"); store.set(Vector3f.ZERO);
} float delimeter = 0;
List<Vector3f> controlPoints = nurbSpline.getControlPoints(); for (int i = 0; i < controlPointAmount; ++i) {
float[] weights = nurbSpline.getWeights(); float val = weights[i] * CurveAndSurfaceMath.computeBaseFunctionValue(i, nurbSpline.getBasisFunctionDegree(), u, knots);
List<Float> knots = nurbSpline.getKnots(); store.addLocal(nurbSpline.getControlPoints().get(i)
int controlPointAmount = controlPoints.size(); .mult(val));
delimeter += val;
}
store.divideLocal(delimeter);
}
store.set(Vector3f.ZERO); /**
float delimeter = 0; * This method interpolates the data for the nurbs surface.
for (int i = 0; i < controlPointAmount; ++i) { *
float val = weights[i] * CurveAndSurfaceMath.computeBaseFunctionValue(i, nurbSpline.getBasisFunctionDegree(), u, knots); * @param u the u value
store.addLocal(nurbSpline.getControlPoints().get(i) * @param v the v value
.mult(val)); * @param controlPoints
delimeter += val; * the nurbs' control points
} * @param knots
store.divideLocal(delimeter); * the nurbs' knots
} * @param basisUFunctionDegree
* the degree of basis U function
* @param basisVFunctionDegree
* the degree of basis V function
* @param store
* the resulting point in 3D space
*/
public static void interpolate(float u, float v, List<List<Vector4f>> controlPoints, List<Float>[] knots,
int basisUFunctionDegree, int basisVFunctionDegree, Vector3f store) {
store.set(Vector3f.ZERO);
float delimeter = 0;
int vControlPointsAmount = controlPoints.size();
int uControlPointsAmount = controlPoints.get(0).size();
for (int i = 0; i < vControlPointsAmount; ++i) {
for (int j = 0; j < uControlPointsAmount; ++j) {
Vector4f controlPoint = controlPoints.get(i).get(j);
float val = controlPoint.w
* CurveAndSurfaceMath.computeBaseFunctionValue(i, basisVFunctionDegree, v, knots[1])
* CurveAndSurfaceMath.computeBaseFunctionValue(j, basisUFunctionDegree, u, knots[0]);
store.addLocal(controlPoint.x * val, controlPoint.y * val, controlPoint.z * val);
delimeter += val;
}
}
store.divideLocal(delimeter);
}
/** /**
* This method interpolates the data for the nurbs surface. * This method prepares the knots to be used. If the knots represent
* * non-uniform B-splines (first and last knot values are being repeated) it
* @param u * leads to NaN results during calculations. This method adds a small number
* the u value * to each of such knots to avoid NaN's.
* @param v *
* the v value * @param knots
* @param controlPoints * the knots to be prepared to use
* the nurbs' control points * @param basisFunctionDegree
* @param knots * the degree of basis function
* the nurbs' knots */
* @param basisUFunctionDegree // TODO: improve this; constant delta may lead to errors if the difference between tha last repeated
* the degree of basis U function // point and the following one is lower than it
* @param basisVFunctionDegree public static void prepareNurbsKnots(List<Float> knots, int basisFunctionDegree) {
* the degree of basis V function float delta = KNOTS_MINIMUM_DELTA;
* @param store float prevValue = knots.get(0).floatValue();
* the resulting point in 3D space for (int i = 1; i < knots.size(); ++i) {
*/ float value = knots.get(i).floatValue();
public static void interpolate(float u, float v, List<List<Vector4f>> controlPoints, List<Float>[] knots, if (value <= prevValue) {
int basisUFunctionDegree, int basisVFunctionDegree, Vector3f store) { value += delta;
store.set(Vector3f.ZERO); knots.set(i, Float.valueOf(value));
float delimeter = 0; delta += KNOTS_MINIMUM_DELTA;
int vControlPointsAmount = controlPoints.size(); } else {
int uControlPointsAmount = controlPoints.get(0).size(); delta = KNOTS_MINIMUM_DELTA;//reset the delta's value
for (int i = 0; i < vControlPointsAmount; ++i) { }
for (int j = 0; j < uControlPointsAmount; ++j) {
Vector4f controlPoint = controlPoints.get(i).get(j);
float val = controlPoint.w
* CurveAndSurfaceMath.computeBaseFunctionValue(i, basisVFunctionDegree, v, knots[1])
* CurveAndSurfaceMath.computeBaseFunctionValue(j, basisUFunctionDegree, u, knots[0]);
store.addLocal(controlPoint.x * val, controlPoint.y * val, controlPoint.z * val);
delimeter += val;
}
}
store.divideLocal(delimeter);
}
/** prevValue = value;
* This method prepares the knots to be used. If the knots represent non-uniform B-splines (first and last knot values are being }
* repeated) it leads to NaN results during calculations. This method adds a small number to each of such knots to avoid NaN's. }
* @param knots
* the knots to be prepared to use
* @param basisFunctionDegree
* the degree of basis function
*/
// TODO: improve this; constant delta may lead to errors if the difference between tha last repeated
// point and the following one is lower than it
public static void prepareNurbsKnots(List<Float> knots, int basisFunctionDegree) {
float delta = KNOTS_MINIMUM_DELTA;
float prevValue = knots.get(0).floatValue();
for(int i=1;i<knots.size();++i) {
float value = knots.get(i).floatValue();
if(value<=prevValue) {
value += delta;
knots.set(i, Float.valueOf(value));
delta += KNOTS_MINIMUM_DELTA;
} else {
delta = KNOTS_MINIMUM_DELTA;//reset the delta's value
}
prevValue = value;
}
}
/** /**
* This method computes the base function value for the NURB curve. * This method computes the base function value for the NURB curve.
* @param i *
* the knot index * @param i the knot index
* @param k * @param k the base function degree
* the base function degree * @param t the knot value
* @param t * @param knots
* the knot value * the knots' values
* @param knots * @return the base function value
* the knots' values */
* @return the base function value private static float computeBaseFunctionValue(int i, int k, float t, List<Float> knots) {
*/ if (k == 1) {
private static float computeBaseFunctionValue(int i, int k, float t, List<Float> knots) { return knots.get(i) <= t && t < knots.get(i + 1) ? 1.0f : 0.0f;
if (k == 1) { } else {
return knots.get(i) <= t && t < knots.get(i + 1) ? 1.0f : 0.0f; return (t - knots.get(i)) / (knots.get(i + k - 1) - knots.get(i))
} else { * CurveAndSurfaceMath.computeBaseFunctionValue(i, k - 1, t, knots)
return (t - knots.get(i)) / (knots.get(i + k - 1) - knots.get(i)) * + (knots.get(i + k) - t) / (knots.get(i + k) - knots.get(i + 1))
CurveAndSurfaceMath.computeBaseFunctionValue(i, k - 1, t, knots) * CurveAndSurfaceMath.computeBaseFunctionValue(i + 1, k - 1, t, knots);
+ (knots.get(i + k) - t) / (knots.get(i + k) - knots.get(i + 1)) * }
CurveAndSurfaceMath.computeBaseFunctionValue(i + 1, k - 1, t, knots); }
}
}
} }

@ -41,44 +41,67 @@ import java.util.Random;
* @version $Id: FastMath.java,v 1.45 2007/08/26 08:44:20 irrisor Exp $ * @version $Id: FastMath.java,v 1.45 2007/08/26 08:44:20 irrisor Exp $
*/ */
final public class FastMath { final public class FastMath {
private FastMath() { private FastMath() {
} }
/** A "close to zero" double epsilon value for use*/ /**
* A "close to zero" double epsilon value for use
*/
public static final double DBL_EPSILON = 2.220446049250313E-16d; public static final double DBL_EPSILON = 2.220446049250313E-16d;
/** A "close to zero" float epsilon value for use*/ /**
* A "close to zero" float epsilon value for use
*/
public static final float FLT_EPSILON = 1.1920928955078125E-7f; public static final float FLT_EPSILON = 1.1920928955078125E-7f;
/** A "close to zero" float epsilon value for use*/ /**
* A "close to zero" float epsilon value for use
*/
public static final float ZERO_TOLERANCE = 0.0001f; public static final float ZERO_TOLERANCE = 0.0001f;
public static final float ONE_THIRD = 1f / 3f; public static final float ONE_THIRD = 1f / 3f;
/** The value PI as a float. (180 degrees) */ /**
* The value PI as a float. (180 degrees)
*/
public static final float PI = (float) Math.PI; public static final float PI = (float) Math.PI;
/** The value 2PI as a float. (360 degrees) */ /**
* The value 2PI as a float. (360 degrees)
*/
public static final float TWO_PI = 2.0f * PI; public static final float TWO_PI = 2.0f * PI;
/** The value PI/2 as a float. (90 degrees) */ /**
* The value PI/2 as a float. (90 degrees)
*/
public static final float HALF_PI = 0.5f * PI; public static final float HALF_PI = 0.5f * PI;
/** The value PI/4 as a float. (45 degrees) */ /**
* The value PI/4 as a float. (45 degrees)
*/
public static final float QUARTER_PI = 0.25f * PI; public static final float QUARTER_PI = 0.25f * PI;
/** The value 1/PI as a float. */ /**
* The value 1/PI as a float.
*/
public static final float INV_PI = 1.0f / PI; public static final float INV_PI = 1.0f / PI;
/** The value 1/(2PI) as a float. */ /**
* The value 1/(2PI) as a float.
*/
public static final float INV_TWO_PI = 1.0f / TWO_PI; public static final float INV_TWO_PI = 1.0f / TWO_PI;
/** A value to multiply a degree value by, to convert it to radians. */ /**
* A value to multiply a degree value by, to convert it to radians.
*/
public static final float DEG_TO_RAD = PI / 180.0f; public static final float DEG_TO_RAD = PI / 180.0f;
/** A value to multiply a radian value by, to convert it to degrees. */ /**
* A value to multiply a radian value by, to convert it to degrees.
*/
public static final float RAD_TO_DEG = 180.0f / PI; public static final float RAD_TO_DEG = 180.0f / PI;
/** A precreated random object for random numbers. */ /**
* A precreated random object for random numbers.
*/
public static final Random rand = new Random(System.currentTimeMillis()); public static final Random rand = new Random(System.currentTimeMillis());
/** /**
* Returns true if the number is a power of 2 (2,4,8,16...) * Returns true if the number is a power of 2 (2,4,8,16...)
* *
* A good implementation found on the Java boards. note: a number is a power * A good implementation found on the Java boards. note: a number is a power
* of two if and only if it is the smallest number with that number of * of two if and only if it is the smallest number with that number of
* significant bits. Therefore, if you subtract 1, you know that the new * significant bits. Therefore, if you subtract 1, you know that the new
* number will have fewer bits, so ANDing the original number with anything * number will have fewer bits, so ANDing the original number with anything
* less than it will give 0. * less than it will give 0.
* *
* @param number * @param number
* The number to test. * The number to test.
* @return True if it is a power of two. * @return True if it is a power of two.
@ -89,10 +112,10 @@ final public class FastMath {
/** /**
* Get the next power of two of the given number. * Get the next power of two of the given number.
* *
* E.g. for an input 100, this returns 128. * E.g. for an input 100, this returns 128.
* Returns 1 for all numbers less than or equal to 1. * Returns 1 for all numbers less than or equal to 1.
* *
* @param number The number to obtain the POT for. * @param number The number to obtain the POT for.
* @return The next power of two. * @return The next power of two.
*/ */
@ -111,7 +134,7 @@ final public class FastMath {
/** /**
* Linear interpolation from startValue to endValue by the given percent. * Linear interpolation from startValue to endValue by the given percent.
* Basically: ((1 - percent) * startValue) + (percent * endValue) * Basically: ((1 - percent) * startValue) + (percent * endValue)
* *
* @param scale * @param scale
* scale value to use. if 1, use endValue, if 0, use startValue. * scale value to use. if 1, use endValue, if 0, use startValue.
* @param startValue * @param startValue
@ -146,7 +169,8 @@ final public class FastMath {
* @param store a vector3f to store the result * @param store a vector3f to store the result
* @return The interpolated value between startValue and endValue. * @return The interpolated value between startValue and endValue.
*/ */
public static Vector3f interpolateLinear(float scale, Vector3f startValue, Vector3f endValue, Vector3f store) { public static Vector3f interpolateLinear(float scale, Vector3f startValue,
Vector3f endValue, Vector3f store) {
if (store == null) { if (store == null) {
store = new Vector3f(); store = new Vector3f();
} }
@ -177,6 +201,7 @@ final public class FastMath {
* if scale is between 0 and 1 this method returns the same result as interpolateLinear * if scale is between 0 and 1 this method returns the same result as interpolateLinear
* if the scale is over 1 the value is linearly extrapolated. * if the scale is over 1 the value is linearly extrapolated.
* Note that the end value is the value for a scale of 1. * Note that the end value is the value for a scale of 1.
*
* @param scale the scale for extrapolation * @param scale the scale for extrapolation
* @param startValue the starting value (scale = 0) * @param startValue the starting value (scale = 0)
* @param endValue the end value (scale = 1) * @param endValue the end value (scale = 1)
@ -193,14 +218,16 @@ final public class FastMath {
* Linear extrapolation from startValue to endValue by the given scale. * Linear extrapolation from startValue to endValue by the given scale.
* if scale is between 0 and 1 this method returns the same result as interpolateLinear * if scale is between 0 and 1 this method returns the same result as interpolateLinear
* if the scale is over 1 the value is linearly extrapolated. * if the scale is over 1 the value is linearly extrapolated.
* Note that the end value is the value for a scale of 1. * Note that the end value is the value for a scale of 1.
*
* @param scale the scale for extrapolation * @param scale the scale for extrapolation
* @param startValue the starting value (scale = 0) * @param startValue the starting value (scale = 0)
* @param endValue the end value (scale = 1) * @param endValue the end value (scale = 1)
* @param store an initialized vector to store the return value * @param store an initialized vector to store the return value
* @return an extrapolation for the given parameters * @return an extrapolation for the given parameters
*/ */
public static Vector3f extrapolateLinear(float scale, Vector3f startValue, Vector3f endValue, Vector3f store) { public static Vector3f extrapolateLinear(float scale, Vector3f startValue,
Vector3f endValue, Vector3f store) {
if (store == null) { if (store == null) {
store = new Vector3f(); store = new Vector3f();
} }
@ -218,6 +245,7 @@ final public class FastMath {
* if scale is between 0 and 1 this method returns the same result as interpolateLinear * if scale is between 0 and 1 this method returns the same result as interpolateLinear
* if the scale is over 1 the value is linearly extrapolated. * if the scale is over 1 the value is linearly extrapolated.
* Note that the end value is the value for a scale of 1. * Note that the end value is the value for a scale of 1.
*
* @param scale the scale for extrapolation * @param scale the scale for extrapolation
* @param startValue the starting value (scale = 0) * @param startValue the starting value (scale = 0)
* @param endValue the end value (scale = 1) * @param endValue the end value (scale = 1)
@ -227,7 +255,8 @@ final public class FastMath {
return extrapolateLinear(scale, startValue, endValue, null); return extrapolateLinear(scale, startValue, endValue, null);
} }
/**Interpolate a spline between at least 4 control points following the Catmull-Rom equation. /**
* Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
* here is the interpolation matrix * here is the interpolation matrix
* m = [ 0.0 1.0 0.0 0.0 ] * m = [ 0.0 1.0 0.0 0.0 ]
* [-T 0.0 T 0.0 ] * [-T 0.0 T 0.0 ]
@ -253,7 +282,8 @@ final public class FastMath {
return ((c4 * u + c3) * u + c2) * u + c1; return ((c4 * u + c3) * u + c2) * u + c1;
} }
/**Interpolate a spline between at least 4 control points following the Catmull-Rom equation. /**
* Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
* here is the interpolation matrix * here is the interpolation matrix
* m = [ 0.0 1.0 0.0 0.0 ] * m = [ 0.0 1.0 0.0 0.0 ]
* [-T 0.0 T 0.0 ] * [-T 0.0 T 0.0 ]
@ -270,7 +300,8 @@ final public class FastMath {
* @param store a Vector3f to store the result * @param store a Vector3f to store the result
* @return CatmullRom interpolation * @return CatmullRom interpolation
*/ */
public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3, Vector3f store) { public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0,
Vector3f p1, Vector3f p2, Vector3f p3, Vector3f store) {
if (store == null) { if (store == null) {
store = new Vector3f(); store = new Vector3f();
} }
@ -282,7 +313,7 @@ final public class FastMath {
/** /**
* Interpolate a spline between at least 4 control points using the * Interpolate a spline between at least 4 control points using the
* Catmull-Rom equation. Here is the interpolation matrix: * Catmull-Rom equation. Here is the interpolation matrix:
* m = [ 0.0 1.0 0.0 0.0 ] * m = [ 0.0 1.0 0.0 0.0 ]
* [-T 0.0 T 0.0 ] * [-T 0.0 T 0.0 ]
* [ 2T T-3 3-2T -T ] * [ 2T T-3 3-2T -T ]
@ -297,7 +328,8 @@ final public class FastMath {
* @param p3 control point 3 * @param p3 control point 3
* @return CatmullRom interpolation * @return CatmullRom interpolation
*/ */
public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3) { public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0,
Vector3f p1, Vector3f p2, Vector3f p3) {
return interpolateCatmullRom(u, T, p0, p1, p2, p3, null); return interpolateCatmullRom(u, T, p0, p1, p2, p3, null);
} }
@ -326,7 +358,8 @@ final public class FastMath {
+ p3 * u2 * u; + p3 * u2 * u;
} }
/**Interpolate a spline between at least 4 control points following the Bezier equation. /**
* Interpolate a spline between at least 4 control points following the Bezier equation.
* here is the interpolation matrix * here is the interpolation matrix
* m = [ -1.0 3.0 -3.0 1.0 ] * m = [ -1.0 3.0 -3.0 1.0 ]
* [ 3.0 -6.0 3.0 0.0 ] * [ 3.0 -6.0 3.0 0.0 ]
@ -342,7 +375,8 @@ final public class FastMath {
* @param store a Vector3f to store the result * @param store a Vector3f to store the result
* @return Bezier interpolation * @return Bezier interpolation
*/ */
public static Vector3f interpolateBezier(float u, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3, Vector3f store) { public static Vector3f interpolateBezier(float u, Vector3f p0, Vector3f p1,
Vector3f p2, Vector3f p3, Vector3f store) {
if (store == null) { if (store == null) {
store = new Vector3f(); store = new Vector3f();
} }
@ -352,7 +386,8 @@ final public class FastMath {
return store; return store;
} }
/**Interpolate a spline between at least 4 control points following the Bezier equation. /**
* Interpolate a spline between at least 4 control points following the Bezier equation.
* here is the interpolation matrix * here is the interpolation matrix
* m = [ -1.0 3.0 -3.0 1.0 ] * m = [ -1.0 3.0 -3.0 1.0 ]
* [ 3.0 -6.0 3.0 0.0 ] * [ 3.0 -6.0 3.0 0.0 ]
@ -373,6 +408,7 @@ final public class FastMath {
/** /**
* Compute the length of a CatmullRom spline between control points 1 and 2 * Compute the length of a CatmullRom spline between control points 1 and 2
*
* @param p0 control point 0 * @param p0 control point 0
* @param p1 control point 1 * @param p1 control point 1
* @param p2 control point 2 * @param p2 control point 2
@ -382,7 +418,8 @@ final public class FastMath {
* @param curveTension the curve tension * @param curveTension the curve tension
* @return the length of the segment * @return the length of the segment
*/ */
public static float getCatmullRomP1toP2Length(Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3, float startRange, float endRange, float curveTension) { public static float getCatmullRomP1toP2Length(Vector3f p0, Vector3f p1,
Vector3f p2, Vector3f p3, float startRange, float endRange, float curveTension) {
float epsilon = 0.001f; float epsilon = 0.001f;
float middleValue = (startRange + endRange) * 0.5f; float middleValue = (startRange + endRange) * 0.5f;
@ -409,6 +446,7 @@ final public class FastMath {
/** /**
* Compute the length on a Bezier spline between control points 1 and 2. * Compute the length on a Bezier spline between control points 1 and 2.
*
* @param p0 control point 0 * @param p0 control point 0
* @param p1 control point 1 * @param p1 control point 1
* @param p2 control point 2 * @param p2 control point 2
@ -432,6 +470,7 @@ final public class FastMath {
* Special cases: * Special cases:
* <ul><li>If fValue is smaller than -1, then the result is PI. * <ul><li>If fValue is smaller than -1, then the result is PI.
* <li>If the argument is greater than 1, then the result is 0.</ul> * <li>If the argument is greater than 1, then the result is 0.</ul>
*
* @param fValue The value to arc cosine. * @param fValue The value to arc cosine.
* @return The angle, in radians. * @return The angle, in radians.
* @see java.lang.Math#acos(double) * @see java.lang.Math#acos(double)
@ -453,6 +492,7 @@ final public class FastMath {
* Special cases: * Special cases:
* <ul><li>If fValue is smaller than -1, then the result is -HALF_PI. * <ul><li>If fValue is smaller than -1, then the result is -HALF_PI.
* <li>If the argument is greater than 1, then the result is HALF_PI.</ul> * <li>If the argument is greater than 1, then the result is HALF_PI.</ul>
*
* @param fValue The value to arc sine. * @param fValue The value to arc sine.
* @return the angle in radians. * @return the angle in radians.
* @see java.lang.Math#asin(double) * @see java.lang.Math#asin(double)
@ -471,6 +511,7 @@ final public class FastMath {
/** /**
* Returns the arc tangent of an angle given in radians.<br> * Returns the arc tangent of an angle given in radians.<br>
*
* @param fValue The angle, in radians. * @param fValue The angle, in radians.
* @return fValue's atan * @return fValue's atan
* @see java.lang.Math#atan(double) * @see java.lang.Math#atan(double)
@ -481,6 +522,7 @@ final public class FastMath {
/** /**
* A direct call to Math.atan2. * A direct call to Math.atan2.
*
* @param fY * @param fY
* @param fX * @param fX
* @return Math.atan2(fY,fX) * @return Math.atan2(fY,fX)
@ -491,7 +533,8 @@ final public class FastMath {
} }
/** /**
* Rounds a fValue up. A call to Math.ceil * Rounds a fValue up. A call to Math.ceil
*
* @param fValue The value. * @param fValue The value.
* @return The fValue rounded up * @return The fValue rounded up
* @see java.lang.Math#ceil(double) * @see java.lang.Math#ceil(double)
@ -502,9 +545,10 @@ final public class FastMath {
/** /**
* Returns cosine of an angle. Direct call to java.lang.Math * Returns cosine of an angle. Direct call to java.lang.Math
* @see Math#cos(double) *
* @see Math#cos(double)
* @param v The angle to cosine. * @param v The angle to cosine.
* @return the cosine of the angle. * @return the cosine of the angle.
*/ */
public static float cos(float v) { public static float cos(float v) {
return (float) Math.cos(v); return (float) Math.cos(v);
@ -512,7 +556,8 @@ final public class FastMath {
/** /**
* Returns the sine of an angle. Direct call to java.lang.Math * Returns the sine of an angle. Direct call to java.lang.Math
* @see Math#sin(double) *
* @see Math#sin(double)
* @param v The angle to sine. * @param v The angle to sine.
* @return the sine of the angle. * @return the sine of the angle.
*/ */
@ -522,6 +567,7 @@ final public class FastMath {
/** /**
* Returns E^fValue * Returns E^fValue
*
* @param fValue Value to raise to a power. * @param fValue Value to raise to a power.
* @return The value E^fValue * @return The value E^fValue
* @see java.lang.Math#exp(double) * @see java.lang.Math#exp(double)
@ -532,6 +578,7 @@ final public class FastMath {
/** /**
* Returns Absolute value of a float. * Returns Absolute value of a float.
*
* @param fValue The value to abs. * @param fValue The value to abs.
* @return The abs of the value. * @return The abs of the value.
* @see java.lang.Math#abs(float) * @see java.lang.Math#abs(float)
@ -545,6 +592,7 @@ final public class FastMath {
/** /**
* Returns a number rounded down. * Returns a number rounded down.
*
* @param fValue The value to round * @param fValue The value to round
* @return The given number rounded down * @return The given number rounded down
* @see java.lang.Math#floor(double) * @see java.lang.Math#floor(double)
@ -555,6 +603,7 @@ final public class FastMath {
/** /**
* Returns 1/sqrt(fValue) * Returns 1/sqrt(fValue)
*
* @param fValue The value to process. * @param fValue The value to process.
* @return 1/sqrt(fValue) * @return 1/sqrt(fValue)
* @see java.lang.Math#sqrt(double) * @see java.lang.Math#sqrt(double)
@ -574,6 +623,7 @@ final public class FastMath {
/** /**
* Returns the log base E of a value. * Returns the log base E of a value.
*
* @param fValue The value to log. * @param fValue The value to log.
* @return The log of fValue base E * @return The log of fValue base E
* @see java.lang.Math#log(double) * @see java.lang.Math#log(double)
@ -583,8 +633,9 @@ final public class FastMath {
} }
/** /**
* Returns the logarithm of value with given base, calculated as log(value)/log(base), * Returns the logarithm of value with given base, calculated as log(value)/log(base),
* so that pow(base, return)==value (contributed by vear) * so that pow(base, return)==value (contributed by vear)
*
* @param value The value to log. * @param value The value to log.
* @param base Base of logarithm. * @param base Base of logarithm.
* @return The logarithm of value with given base * @return The logarithm of value with given base
@ -594,7 +645,8 @@ final public class FastMath {
} }
/** /**
* Returns a number raised to an exponent power. fBase^fExponent * Returns a number raised to an exponent power. fBase^fExponent
*
* @param fBase The base value (IE 2) * @param fBase The base value (IE 2)
* @param fExponent The exponent value (IE 3) * @param fExponent The exponent value (IE 3)
* @return base raised to exponent (IE 8) * @return base raised to exponent (IE 8)
@ -605,7 +657,8 @@ final public class FastMath {
} }
/** /**
* Returns the value squared. fValue ^ 2 * Returns the value squared. fValue ^ 2
*
* @param fValue The value to square. * @param fValue The value to square.
* @return The square of the given value. * @return The square of the given value.
*/ */
@ -615,6 +668,7 @@ final public class FastMath {
/** /**
* Returns the square root of a given value. * Returns the square root of a given value.
*
* @param fValue The value to sqrt. * @param fValue The value to sqrt.
* @return The square root of the given value. * @return The square root of the given value.
* @see java.lang.Math#sqrt(double) * @see java.lang.Math#sqrt(double)
@ -626,6 +680,7 @@ final public class FastMath {
/** /**
* Returns the tangent of a value. If USE_FAST_TRIG is enabled, an approximate value * Returns the tangent of a value. If USE_FAST_TRIG is enabled, an approximate value
* is returned. Otherwise, a direct value is used. * is returned. Otherwise, a direct value is used.
*
* @param fValue The value to tangent, in radians. * @param fValue The value to tangent, in radians.
* @return The tangent of fValue. * @return The tangent of fValue.
* @see java.lang.Math#tan(double) * @see java.lang.Math#tan(double)
@ -636,6 +691,7 @@ final public class FastMath {
/** /**
* Returns 1 if the number is positive, -1 if the number is negative, and 0 otherwise * Returns 1 if the number is positive, -1 if the number is negative, and 0 otherwise
*
* @param iValue The integer to examine. * @param iValue The integer to examine.
* @return The integer's sign. * @return The integer's sign.
*/ */
@ -651,6 +707,7 @@ final public class FastMath {
/** /**
* Returns 1 if the number is positive, -1 if the number is negative, and 0 otherwise * Returns 1 if the number is positive, -1 if the number is negative, and 0 otherwise
*
* @param fValue The float to examine. * @param fValue The float to examine.
* @return The float's sign. * @return The float's sign.
*/ */
@ -661,6 +718,7 @@ final public class FastMath {
/** /**
* Given 3 points in a 2d plane, this function computes if the points going from A-B-C * Given 3 points in a 2d plane, this function computes if the points going from A-B-C
* are moving counter clock wise. * are moving counter clock wise.
*
* @param p0 Point 0. * @param p0 Point 0.
* @param p1 Point 1. * @param p1 Point 1.
* @param p2 Point 2. * @param p2 Point 2.
@ -690,6 +748,7 @@ final public class FastMath {
/** /**
* Test if a point is inside a triangle. 1 if the point is on the ccw side, * Test if a point is inside a triangle. 1 if the point is on the ccw side,
* -1 if the point is on the cw side, and 0 if it is on neither. * -1 if the point is on the cw side, and 0 if it is on neither.
*
* @param t0 First point of the triangle. * @param t0 First point of the triangle.
* @param t1 Second point of the triangle. * @param t1 Second point of the triangle.
* @param t2 Third point of the triangle. * @param t2 Third point of the triangle.
@ -720,6 +779,7 @@ final public class FastMath {
/** /**
* A method that computes normal for a triangle defined by three vertices. * A method that computes normal for a triangle defined by three vertices.
*
* @param v1 first vertex * @param v1 first vertex
* @param v2 second vertex * @param v2 second vertex
* @param v3 third vertex * @param v3 third vertex
@ -753,9 +813,9 @@ final public class FastMath {
/** /**
* Returns a random float between 0 and 1. * Returns a random float between 0 and 1.
* *
* @return A random float between <tt>0.0f</tt> (inclusive) to * @return A random float between <tt>0.0f</tt> (inclusive) to
* <tt>1.0f</tt> (exclusive). * <tt>1.0f</tt> (exclusive).
*/ */
public static float nextRandomFloat() { public static float nextRandomFloat() {
return rand.nextFloat(); return rand.nextFloat();
@ -763,9 +823,9 @@ final public class FastMath {
/** /**
* Returns a random integer between min and max. * Returns a random integer between min and max.
* *
* @return A random int between <tt>min</tt> (inclusive) to * @return A random int between <tt>min</tt> (inclusive) to
* <tt>max</tt> (inclusive). * <tt>max</tt> (inclusive).
*/ */
public static int nextRandomInt(int min, int max) { public static int nextRandomInt(int min, int max) {
return (int) (nextRandomFloat() * (max - min + 1)) + min; return (int) (nextRandomFloat() * (max - min + 1)) + min;
@ -861,7 +921,7 @@ final public class FastMath {
/** /**
* Takes a value and expresses it in terms of min to max. * Takes a value and expresses it in terms of min to max.
* *
* @param val - * @param val -
* the angle to normalize (in radians) * the angle to normalize (in radians)
* @return the normalized angle (also in radians) * @return the normalized angle (also in radians)
@ -899,7 +959,7 @@ final public class FastMath {
/** /**
* Take a float input and clamp it between min and max. * Take a float input and clamp it between min and max.
* *
* @param input * @param input
* @param min * @param min
* @param max * @param max
@ -923,9 +983,9 @@ final public class FastMath {
* Determine if two floats are approximately equal. * Determine if two floats are approximately equal.
* This takes into account the magnitude of the floats, since * This takes into account the magnitude of the floats, since
* large numbers will have larger differences be close to each other. * large numbers will have larger differences be close to each other.
* *
* Should return true for a=100000, b=100001, but false for a=10000, b=10001. * Should return true for a=100000, b=100001, but false for a=10000, b=10001.
* *
* @param a The first float to compare * @param a The first float to compare
* @param b The second float to compare * @param b The second float to compare
* @return True if a and b are approximately equal, false otherwise. * @return True if a and b are approximately equal, false otherwise.
@ -937,7 +997,7 @@ final public class FastMath {
return (abs(a - b) / Math.max(abs(a), abs(b))) <= 0.00001f; return (abs(a - b) / Math.max(abs(a), abs(b))) <= 0.00001f;
} }
} }
/** /**
* Converts a single precision (32 bit) floating point value * Converts a single precision (32 bit) floating point value
* into half precision (16 bit). * into half precision (16 bit).
@ -996,6 +1056,7 @@ final public class FastMath {
/** /**
* Converts a range of min/max to a 0-1 range. * Converts a range of min/max to a 0-1 range.
*
* @param value the value between min-max (inclusive). * @param value the value between min-max (inclusive).
* @param min the minimum of the range. * @param min the minimum of the range.
* @param max the maximum of the range. * @param max the maximum of the range.
@ -1004,5 +1065,4 @@ final public class FastMath {
public static float unInterpolateLinear(float value, float min, float max) { public static float unInterpolateLinear(float value, float min, float max) {
return (value - min) / (max - min); return (value - min) / (max - min);
} }
} }

@ -43,7 +43,7 @@ import java.util.logging.Logger;
* internally and is accessible via the get and set methods. Convenience methods * internally and is accessible via the get and set methods. Convenience methods
* are used for matrix operations as well as generating a matrix from a given * are used for matrix operations as well as generating a matrix from a given
* set of values. * set of values.
* *
* @author Mark Powell * @author Mark Powell
* @author Joshua Slack * @author Joshua Slack
*/ */
@ -61,7 +61,6 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Constructor instantiates a new <code>Matrix3f</code> object. The * Constructor instantiates a new <code>Matrix3f</code> object. The
* initial values for the matrix is that of the identity matrix. * initial values for the matrix is that of the identity matrix.
*
*/ */
public Matrix3f() { public Matrix3f() {
loadIdentity(); loadIdentity();
@ -69,25 +68,16 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* constructs a matrix with the given values. * constructs a matrix with the given values.
* *
* @param m00 * @param m00 0x0 in the matrix.
* 0x0 in the matrix. * @param m01 0x1 in the matrix.
* @param m01 * @param m02 0x2 in the matrix.
* 0x1 in the matrix. * @param m10 1x0 in the matrix.
* @param m02 * @param m11 1x1 in the matrix.
* 0x2 in the matrix. * @param m12 1x2 in the matrix.
* @param m10 * @param m20 2x0 in the matrix.
* 1x0 in the matrix. * @param m21 2x1 in the matrix.
* @param m11 * @param m22 2x2 in the matrix.
* 1x1 in the matrix.
* @param m12
* 1x2 in the matrix.
* @param m20
* 2x0 in the matrix.
* @param m21
* 2x1 in the matrix.
* @param m22
* 2x2 in the matrix.
*/ */
public Matrix3f(float m00, float m01, float m02, float m10, float m11, public Matrix3f(float m00, float m01, float m02, float m10, float m11,
float m12, float m20, float m21, float m22) { float m12, float m20, float m21, float m22) {
@ -106,7 +96,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Copy constructor that creates a new <code>Matrix3f</code> object that * Copy constructor that creates a new <code>Matrix3f</code> object that
* is the same as the provided matrix. * is the same as the provided matrix.
* *
* @param mat * @param mat
* the matrix to copy. * the matrix to copy.
*/ */
@ -133,7 +123,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>copy</code> transfers the contents of a given matrix to this * <code>copy</code> transfers the contents of a given matrix to this
* matrix. If a null matrix is supplied, this matrix is set to the identity * matrix. If a null matrix is supplied, this matrix is set to the identity
* matrix. * matrix.
* *
* @param matrix * @param matrix
* the matrix to copy. * the matrix to copy.
* @return this * @return this
@ -159,11 +149,9 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>get</code> retrieves a value from the matrix at the given * <code>get</code> retrieves a value from the matrix at the given
* position. If the position is invalid a <code>JmeException</code> is * position. If the position is invalid a <code>JmeException</code> is
* thrown. * thrown.
* *
* @param i * @param i the row index.
* the row index. * @param j the colum index.
* @param j
* the colum index.
* @return the value at (i, j). * @return the value at (i, j).
*/ */
@SuppressWarnings("fallthrough") @SuppressWarnings("fallthrough")
@ -261,11 +249,11 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
throw new IndexOutOfBoundsException("Array size must be 9 or 16 in Matrix3f.get()."); throw new IndexOutOfBoundsException("Array size must be 9 or 16 in Matrix3f.get().");
} }
} }
/** /**
* Normalize this matrix and store the result in the store parameter that is * Normalize this matrix and store the result in the store parameter that is
* returned. * returned.
* *
* Note that the original matrix is not altered. * Note that the original matrix is not altered.
* *
* @param store the matrix to store the result of the normalization. If this * @param store the matrix to store the result of the normalization. If this
@ -303,6 +291,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Normalize this matrix * Normalize this matrix
*
* @return this matrix once normalized. * @return this matrix once normalized.
*/ */
public Matrix3f normalizeLocal() { public Matrix3f normalizeLocal() {
@ -312,7 +301,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>getColumn</code> returns one of three columns specified by the * <code>getColumn</code> returns one of three columns specified by the
* parameter. This column is returned as a <code>Vector3f</code> object. * parameter. This column is returned as a <code>Vector3f</code> object.
* *
* @param i * @param i
* the column to retrieve. Must be between 0 and 2. * the column to retrieve. Must be between 0 and 2.
* @return the column specified by the index. * @return the column specified by the index.
@ -324,7 +313,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>getColumn</code> returns one of three columns specified by the * <code>getColumn</code> returns one of three columns specified by the
* parameter. This column is returned as a <code>Vector3f</code> object. * parameter. This column is returned as a <code>Vector3f</code> object.
* *
* @param i * @param i
* the column to retrieve. Must be between 0 and 2. * the column to retrieve. Must be between 0 and 2.
* @param store * @param store
@ -362,7 +351,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>getColumn</code> returns one of three rows as specified by the * <code>getColumn</code> returns one of three rows as specified by the
* parameter. This row is returned as a <code>Vector3f</code> object. * parameter. This row is returned as a <code>Vector3f</code> object.
* *
* @param i * @param i
* the row to retrieve. Must be between 0 and 2. * the row to retrieve. Must be between 0 and 2.
* @return the row specified by the index. * @return the row specified by the index.
@ -374,7 +363,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>getRow</code> returns one of three rows as specified by the * <code>getRow</code> returns one of three rows as specified by the
* parameter. This row is returned as a <code>Vector3f</code> object. * parameter. This row is returned as a <code>Vector3f</code> object.
* *
* @param i * @param i
* the row to retrieve. Must be between 0 and 2. * the row to retrieve. Must be between 0 and 2.
* @param store * @param store
@ -412,7 +401,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains * <code>toFloatBuffer</code> returns a FloatBuffer object that contains
* the matrix data. * the matrix data.
* *
* @return matrix data as a FloatBuffer. * @return matrix data as a FloatBuffer.
*/ */
public FloatBuffer toFloatBuffer() { public FloatBuffer toFloatBuffer() {
@ -428,7 +417,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>fillFloatBuffer</code> fills a FloatBuffer object with the matrix * <code>fillFloatBuffer</code> fills a FloatBuffer object with the matrix
* data. * data.
* *
* @param fb * @param fb
* the buffer to fill, starting at current position. Must have * the buffer to fill, starting at current position. Must have
* room for 9 more floats. * room for 9 more floats.
@ -448,7 +437,6 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
fillFloatArray(vars.matrixWrite, columnMajor); fillFloatArray(vars.matrixWrite, columnMajor);
fb.put(vars.matrixWrite, 0, 9); fb.put(vars.matrixWrite, 0, 9);
@ -459,33 +447,32 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
public void fillFloatArray(float[] f, boolean columnMajor) { public void fillFloatArray(float[] f, boolean columnMajor) {
if (columnMajor) { if (columnMajor) {
f[ 0] = m00; f[0] = m00;
f[ 1] = m10; f[1] = m10;
f[ 2] = m20; f[2] = m20;
f[ 3] = m01; f[3] = m01;
f[ 4] = m11; f[4] = m11;
f[ 5] = m21; f[5] = m21;
f[ 6] = m02; f[6] = m02;
f[ 7] = m12; f[7] = m12;
f[ 8] = m22; f[8] = m22;
} else { } else {
f[ 0] = m00; f[0] = m00;
f[ 1] = m01; f[1] = m01;
f[ 2] = m02; f[2] = m02;
f[ 3] = m10; f[3] = m10;
f[ 4] = m11; f[4] = m11;
f[ 5] = m12; f[5] = m12;
f[ 6] = m20; f[6] = m20;
f[ 7] = m21; f[7] = m21;
f[ 8] = m22; f[8] = m22;
} }
} }
/** /**
*
* <code>setColumn</code> sets a particular column of this matrix to that * <code>setColumn</code> sets a particular column of this matrix to that
* represented by the provided vector. * represented by the provided vector.
* *
* @param i * @param i
* the column to set. * the column to set.
* @param column * @param column
@ -522,10 +509,9 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>setRow</code> sets a particular row of this matrix to that * <code>setRow</code> sets a particular row of this matrix to that
* represented by the provided vector. * represented by the provided vector.
* *
* @param i * @param i
* the row to set. * the row to set.
* @param row * @param row
@ -565,7 +551,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>set</code> places a given value into the matrix at the given * <code>set</code> places a given value into the matrix at the given
* position. If the position is invalid a <code>JmeException</code> is * position. If the position is invalid a <code>JmeException</code> is
* thrown. * thrown.
* *
* @param i * @param i
* the row index. * the row index.
* @param j * @param j
@ -620,10 +606,9 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>set</code> sets the values of the matrix to those supplied by the * <code>set</code> sets the values of the matrix to those supplied by the
* 3x3 two dimenion array. * 3x3 two dimenion array.
* *
* @param matrix * @param matrix
* the new values of the matrix. * the new values of the matrix.
* @throws JmeException * @throws JmeException
@ -651,13 +636,10 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Recreate Matrix using the provided axis. * Recreate Matrix using the provided axis.
* *
* @param uAxis * @param uAxis Vector3f
* Vector3f * @param vAxis Vector3f
* @param vAxis * @param wAxis Vector3f
* Vector3f
* @param wAxis
* Vector3f
*/ */
public void fromAxes(Vector3f uAxis, Vector3f vAxis, Vector3f wAxis) { public void fromAxes(Vector3f uAxis, Vector3f vAxis, Vector3f wAxis) {
m00 = uAxis.x; m00 = uAxis.x;
@ -676,7 +658,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>set</code> sets the values of this matrix from an array of * <code>set</code> sets the values of this matrix from an array of
* values assuming that the data is rowMajor order; * values assuming that the data is rowMajor order;
* *
* @param matrix * @param matrix
* the matrix to set the value to. * the matrix to set the value to.
* @return this * @return this
@ -688,7 +670,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>set</code> sets the values of this matrix from an array of * <code>set</code> sets the values of this matrix from an array of
* values; * values;
* *
* @param matrix * @param matrix
* the matrix to set the value to. * the matrix to set the value to.
* @param rowMajor * @param rowMajor
@ -726,11 +708,10 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>set</code> defines the values of the matrix based on a supplied * <code>set</code> defines the values of the matrix based on a supplied
* <code>Quaternion</code>. It should be noted that all previous values * <code>Quaternion</code>. It should be noted that all previous values
* will be overridden. * will be overridden.
* *
* @param quaternion * @param quaternion
* the quaternion to create a rotational matrix from. * the quaternion to create a rotational matrix from.
* @return this * @return this
@ -742,7 +723,6 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>loadIdentity</code> sets this matrix to the identity matrix. * <code>loadIdentity</code> sets this matrix to the identity matrix.
* Where all values are zero except those along the diagonal which are one. * Where all values are zero except those along the diagonal which are one.
*
*/ */
public void loadIdentity() { public void loadIdentity() {
m01 = m02 = m10 = m12 = m20 = m21 = 0; m01 = m02 = m10 = m12 = m20 = m21 = 0;
@ -762,7 +742,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>fromAngleAxis</code> sets this matrix4f to the values specified * <code>fromAngleAxis</code> sets this matrix4f to the values specified
* by an angle and an axis of rotation. This method creates an object, so * by an angle and an axis of rotation. This method creates an object, so
* use fromAngleNormalAxis if your axis is already normalized. * use fromAngleNormalAxis if your axis is already normalized.
* *
* @param angle * @param angle
* the angle to rotate (in radians). * the angle to rotate (in radians).
* @param axis * @param axis
@ -776,7 +756,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>fromAngleNormalAxis</code> sets this matrix4f to the values * <code>fromAngleNormalAxis</code> sets this matrix4f to the values
* specified by an angle and a normalized axis of rotation. * specified by an angle and a normalized axis of rotation.
* *
* @param angle * @param angle
* the angle to rotate (in radians). * the angle to rotate (in radians).
* @param axis * @param axis
@ -811,7 +791,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies this matrix by a given matrix. The result * <code>mult</code> multiplies this matrix by a given matrix. The result
* matrix is returned as a new object. If the given matrix is null, a null * matrix is returned as a new object. If the given matrix is null, a null
* matrix is returned. * matrix is returned.
* *
* @param mat * @param mat
* the matrix to multiply this matrix by. * the matrix to multiply this matrix by.
* @return the result matrix. * @return the result matrix.
@ -823,7 +803,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>mult</code> multiplies this matrix by a given matrix. The result * <code>mult</code> multiplies this matrix by a given matrix. The result
* matrix is returned as a new object. * matrix is returned as a new object.
* *
* @param mat * @param mat
* the matrix to multiply this matrix by. * the matrix to multiply this matrix by.
* @param product * @param product
@ -867,7 +847,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies this matrix by a given * <code>mult</code> multiplies this matrix by a given
* <code>Vector3f</code> object. The result vector is returned. If the * <code>Vector3f</code> object. The result vector is returned. If the
* given vector is null, null will be returned. * given vector is null, null will be returned.
* *
* @param vec * @param vec
* the vector to multiply this matrix by. * the vector to multiply this matrix by.
* @return the result vector. * @return the result vector.
@ -879,7 +859,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Multiplies this 3x3 matrix by the 1x3 Vector vec and stores the result in * Multiplies this 3x3 matrix by the 1x3 Vector vec and stores the result in
* product. * product.
* *
* @param vec * @param vec
* The Vector3f to multiply. * The Vector3f to multiply.
* @param product * @param product
@ -904,9 +884,9 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
* <code>multLocal</code> multiplies this matrix internally by * <code>multLocal</code> multiplies this matrix internally by
* a given float scale factor. * a given float scale factor.
* *
* @param scale * @param scale
* the value to scale by. * the value to scale by.
* @return this Matrix3f * @return this Matrix3f
@ -929,7 +909,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>Vector3f</code> object. The result vector is stored inside the * <code>Vector3f</code> object. The result vector is stored inside the
* passed vector, then returned . If the given vector is null, null will be * passed vector, then returned . If the given vector is null, null will be
* returned. * returned.
* *
* @param vec * @param vec
* the vector to multiply this matrix by. * the vector to multiply this matrix by.
* @return The passed vector after multiplication * @return The passed vector after multiplication
@ -951,7 +931,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* matrix is saved in the current matrix. If the given matrix is null, * matrix is saved in the current matrix. If the given matrix is null,
* nothing happens. The current matrix is returned. This is equivalent to * nothing happens. The current matrix is returned. This is equivalent to
* this*=mat * this*=mat
* *
* @param mat * @param mat
* the matrix to multiply this matrix by. * the matrix to multiply this matrix by.
* @return This matrix, after the multiplication * @return This matrix, after the multiplication
@ -962,7 +942,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Transposes this matrix in place. Returns this matrix for chaining * Transposes this matrix in place. Returns this matrix for chaining
* *
* @return This matrix after transpose * @return This matrix after transpose
*/ */
public Matrix3f transposeLocal() { public Matrix3f transposeLocal() {
@ -987,7 +967,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Inverts this matrix as a new Matrix3f. * Inverts this matrix as a new Matrix3f.
* *
* @return The new inverse matrix * @return The new inverse matrix
*/ */
public Matrix3f invert() { public Matrix3f invert() {
@ -996,7 +976,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Inverts this matrix and stores it in the given store. * Inverts this matrix and stores it in the given store.
* *
* @return The store * @return The store
*/ */
public Matrix3f invert(Matrix3f store) { public Matrix3f invert(Matrix3f store) {
@ -1025,7 +1005,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Inverts this matrix locally. * Inverts this matrix locally.
* *
* @return this * @return this
*/ */
public Matrix3f invertLocal() { public Matrix3f invertLocal() {
@ -1060,7 +1040,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Returns a new matrix representing the adjoint of this matrix. * Returns a new matrix representing the adjoint of this matrix.
* *
* @return The adjoint matrix * @return The adjoint matrix
*/ */
public Matrix3f adjoint() { public Matrix3f adjoint() {
@ -1069,7 +1049,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Places the adjoint of this matrix in store (creates store if null.) * Places the adjoint of this matrix in store (creates store if null.)
* *
* @param store * @param store
* The matrix to store the result in. If null, a new matrix is created. * The matrix to store the result in. If null, a new matrix is created.
* @return store * @return store
@ -1094,7 +1074,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>determinant</code> generates the determinant of this matrix. * <code>determinant</code> generates the determinant of this matrix.
* *
* @return the determinant * @return the determinant
*/ */
public float determinant() { public float determinant() {
@ -1107,7 +1087,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Sets all of the values in this matrix to zero. * Sets all of the values in this matrix to zero.
* *
* @return this matrix * @return this matrix
*/ */
public Matrix3f zero() { public Matrix3f zero() {
@ -1120,7 +1100,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* This is inconsistent with general value vs local semantics, but is * This is inconsistent with general value vs local semantics, but is
* preserved for backwards compatibility. Use transposeNew() to transpose * preserved for backwards compatibility. Use transposeNew() to transpose
* to a new object (value). * to a new object (value).
* *
* @return this object for chaining. * @return this object for chaining.
*/ */
public Matrix3f transpose() { public Matrix3f transpose() {
@ -1144,7 +1124,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* 1.0 0.0 0.0 <br> * 1.0 0.0 0.0 <br>
* 0.0 1.0 0.0 <br> * 0.0 1.0 0.0 <br>
* 0.0 0.0 1.0 <br>]<br> * 0.0 0.0 1.0 <br>]<br>
* *
* @return the string representation of this object. * @return the string representation of this object.
*/ */
@Override @Override
@ -1175,11 +1155,10 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>hashCode</code> returns the hash code value as an integer and is * <code>hashCode</code> returns the hash code value as an integer and is
* supported for the benefit of hashing based collection classes such as * supported for the benefit of hashing based collection classes such as
* Hashtable, HashMap, HashSet etc. * Hashtable, HashMap, HashSet etc.
* *
* @return the hashcode for this instance of Matrix4f. * @return the hashcode for this instance of Matrix4f.
* @see java.lang.Object#hashCode() * @see java.lang.Object#hashCode()
*/ */
@ -1281,7 +1260,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/** /**
* A function for creating a rotation matrix that rotates a vector called * A function for creating a rotation matrix that rotates a vector called
* "start" into another vector called "end". * "start" into another vector called "end".
* *
* @param start * @param start
* normalized non-zero starting vector * normalized non-zero starting vector
* @param end * @param end

@ -41,10 +41,10 @@ import java.util.logging.Logger;
/** /**
* <code>Matrix4f</code> defines and maintains a 4x4 matrix in row major order. * <code>Matrix4f</code> defines and maintains a 4x4 matrix in row major order.
* This matrix is intended for use in a translation and rotational capacity. * This matrix is intended for use in a translation and rotational capacity.
* It provides convenience methods for creating the matrix from a multitude * It provides convenience methods for creating the matrix from a multitude
* of sources. * of sources.
* *
* Matrices are stored assuming column vectors on the right, with the translation * Matrices are stored assuming column vectors on the right, with the translation
* in the rightmost column. Element numbering is row,column, so m03 is the zeroth * in the rightmost column. Element numbering is row,column, so m03 is the zeroth
* row, third column, which is the "x" translation part. This means that the implicit * row, third column, which is the "x" translation part. This means that the implicit
@ -69,7 +69,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* Constructor instantiates a new <code>Matrix</code> that is set to the * Constructor instantiates a new <code>Matrix</code> that is set to the
* identity matrix. * identity matrix.
*
*/ */
public Matrix4f() { public Matrix4f() {
loadIdentity(); loadIdentity();
@ -105,7 +104,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* Create a new Matrix4f, given data in column-major format. * Create a new Matrix4f, given data in column-major format.
* *
* @param array * @param array
* An array of 16 floats in column-major format (translation in elements 12, 13 and 14). * An array of 16 floats in column-major format (translation in elements 12, 13 and 14).
*/ */
public Matrix4f(float[] array) { public Matrix4f(float[] array) {
set(array, false); set(array, false);
@ -115,7 +114,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* Constructor instantiates a new <code>Matrix</code> that is set to the * Constructor instantiates a new <code>Matrix</code> that is set to the
* provided matrix. This constructor copies a given Matrix. If the provided * provided matrix. This constructor copies a given Matrix. If the provided
* matrix is null, the constructor sets the matrix to the identity. * matrix is null, the constructor sets the matrix to the identity.
* *
* @param mat * @param mat
* the matrix to copy. * the matrix to copy.
*/ */
@ -127,7 +126,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>copy</code> transfers the contents of a given matrix to this * <code>copy</code> transfers the contents of a given matrix to this
* matrix. If a null matrix is supplied, this matrix is set to the identity * matrix. If a null matrix is supplied, this matrix is set to the identity
* matrix. * matrix.
* *
* @param matrix * @param matrix
* the matrix to copy. * the matrix to copy.
*/ */
@ -188,7 +187,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>get</code> retrieves the values of this object into * <code>get</code> retrieves the values of this object into
* a float array in row-major order. * a float array in row-major order.
* *
* @param matrix * @param matrix
* the matrix to set the values into. * the matrix to set the values into.
*/ */
@ -199,7 +198,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>set</code> retrieves the values of this object into * <code>set</code> retrieves the values of this object into
* a float array. * a float array.
* *
* @param matrix * @param matrix
* the matrix to set the values into. * the matrix to set the values into.
* @param rowMajor * @param rowMajor
@ -252,11 +251,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>get</code> retrieves a value from the matrix at the given * <code>get</code> retrieves a value from the matrix at the given
* position. If the position is invalid a <code>JmeException</code> is * position. If the position is invalid a <code>JmeException</code> is
* thrown. * thrown.
* *
* @param i * @param i the row index.
* the row index. * @param j the colum index.
* @param j
* the colum index.
* @return the value at (i, j). * @return the value at (i, j).
*/ */
@SuppressWarnings("fallthrough") @SuppressWarnings("fallthrough")
@ -315,9 +312,8 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>getColumn</code> returns one of three columns specified by the * <code>getColumn</code> returns one of three columns specified by the
* parameter. This column is returned as a float array of length 4. * parameter. This column is returned as a float array of length 4.
* *
* @param i * @param i the column to retrieve. Must be between 0 and 3.
* the column to retrieve. Must be between 0 and 3.
* @return the column specified by the index. * @return the column specified by the index.
*/ */
public float[] getColumn(int i) { public float[] getColumn(int i) {
@ -327,9 +323,8 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>getColumn</code> returns one of three columns specified by the * <code>getColumn</code> returns one of three columns specified by the
* parameter. This column is returned as a float[4]. * parameter. This column is returned as a float[4].
* *
* @param i * @param i the column to retrieve. Must be between 0 and 3.
* the column to retrieve. Must be between 0 and 3.
* @param store * @param store
* the float array to store the result in. if null, a new one * the float array to store the result in. if null, a new one
* is created. * is created.
@ -372,12 +367,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>setColumn</code> sets a particular column of this matrix to that * <code>setColumn</code> sets a particular column of this matrix to that
* represented by the provided vector. * represented by the provided vector.
* *
* @param i * @param i the column to set.
* the column to set.
* @param column * @param column
* the data to set. * the data to set.
*/ */
@ -422,11 +415,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>set</code> places a given value into the matrix at the given * <code>set</code> places a given value into the matrix at the given
* position. If the position is invalid a <code>JmeException</code> is * position. If the position is invalid a <code>JmeException</code> is
* thrown. * thrown.
* *
* @param i * @param i the row index.
* the row index. * @param j the colum index.
* @param j
* the colum index.
* @param value * @param value
* the value for (i, j). * the value for (i, j).
*/ */
@ -502,7 +493,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>set</code> sets the values of this matrix from an array of * <code>set</code> sets the values of this matrix from an array of
* values. * values.
* *
* @param matrix * @param matrix
* the matrix to set the value to. * the matrix to set the value to.
* @throws JmeException * @throws JmeException
@ -531,8 +522,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
m32 = matrix[3][2]; m32 = matrix[3][2];
m33 = matrix[3][3]; m33 = matrix[3][3];
} }
/** /**
* Sets the values of this matrix * Sets the values of this matrix
*/ */
@ -588,7 +578,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>set</code> sets the values of this matrix from an array of * <code>set</code> sets the values of this matrix from an array of
* values assuming that the data is rowMajor order; * values assuming that the data is rowMajor order;
* *
* @param matrix * @param matrix
* the matrix to set the value to. * the matrix to set the value to.
*/ */
@ -599,7 +589,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>set</code> sets the values of this matrix from an array of * <code>set</code> sets the values of this matrix from an array of
* values; * values;
* *
* @param matrix * @param matrix
* the matrix to set the value to. * the matrix to set the value to.
* @param rowMajor * @param rowMajor
@ -657,7 +647,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>transpose</code> locally transposes this Matrix. * <code>transpose</code> locally transposes this Matrix.
* *
* @return this object for chaining. * @return this object for chaining.
*/ */
public Matrix4f transposeLocal() { public Matrix4f transposeLocal() {
@ -691,7 +681,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains * <code>toFloatBuffer</code> returns a FloatBuffer object that contains
* the matrix data. * the matrix data.
* *
* @return matrix data as a FloatBuffer. * @return matrix data as a FloatBuffer.
*/ */
public FloatBuffer toFloatBuffer() { public FloatBuffer toFloatBuffer() {
@ -701,7 +691,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains the * <code>toFloatBuffer</code> returns a FloatBuffer object that contains the
* matrix data. * matrix data.
* *
* @param columnMajor * @param columnMajor
* if true, this buffer should be filled with column major data, * if true, this buffer should be filled with column major data,
* otherwise it will be filled row major. * otherwise it will be filled row major.
@ -718,6 +708,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>fillFloatBuffer</code> fills a FloatBuffer object with * <code>fillFloatBuffer</code> fills a FloatBuffer object with
* the matrix data. * the matrix data.
*
* @param fb the buffer to fill, must be correct size * @param fb the buffer to fill, must be correct size
* @return matrix data as a FloatBuffer. * @return matrix data as a FloatBuffer.
*/ */
@ -728,7 +719,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>fillFloatBuffer</code> fills a FloatBuffer object with the matrix * <code>fillFloatBuffer</code> fills a FloatBuffer object with the matrix
* data. * data.
* *
* @param fb * @param fb
* the buffer to fill, starting at current position. Must have * the buffer to fill, starting at current position. Must have
* room for 16 more floats. * room for 16 more floats.
@ -753,7 +744,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
fillFloatArray(vars.matrixWrite, columnMajor); fillFloatArray(vars.matrixWrite, columnMajor);
fb.put(vars.matrixWrite, 0, 16); fb.put(vars.matrixWrite, 0, 16);
@ -764,16 +754,16 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
public void fillFloatArray(float[] f, boolean columnMajor) { public void fillFloatArray(float[] f, boolean columnMajor) {
if (columnMajor) { if (columnMajor) {
f[ 0] = m00; f[0] = m00;
f[ 1] = m10; f[1] = m10;
f[ 2] = m20; f[2] = m20;
f[ 3] = m30; f[3] = m30;
f[ 4] = m01; f[4] = m01;
f[ 5] = m11; f[5] = m11;
f[ 6] = m21; f[6] = m21;
f[ 7] = m31; f[7] = m31;
f[ 8] = m02; f[8] = m02;
f[ 9] = m12; f[9] = m12;
f[10] = m22; f[10] = m22;
f[11] = m32; f[11] = m32;
f[12] = m03; f[12] = m03;
@ -781,16 +771,16 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
f[14] = m23; f[14] = m23;
f[15] = m33; f[15] = m33;
} else { } else {
f[ 0] = m00; f[0] = m00;
f[ 1] = m01; f[1] = m01;
f[ 2] = m02; f[2] = m02;
f[ 3] = m03; f[3] = m03;
f[ 4] = m10; f[4] = m10;
f[ 5] = m11; f[5] = m11;
f[ 6] = m12; f[6] = m12;
f[ 7] = m13; f[7] = m13;
f[ 8] = m20; f[8] = m20;
f[ 9] = m21; f[9] = m21;
f[10] = m22; f[10] = m22;
f[11] = m23; f[11] = m23;
f[12] = m30; f[12] = m30;
@ -802,6 +792,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>readFloatBuffer</code> reads value for this matrix from a FloatBuffer. * <code>readFloatBuffer</code> reads value for this matrix from a FloatBuffer.
*
* @param fb the buffer to read from, must be correct size * @param fb the buffer to read from, must be correct size
* @return this data as a FloatBuffer. * @return this data as a FloatBuffer.
*/ */
@ -811,9 +802,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>readFloatBuffer</code> reads value for this matrix from a FloatBuffer. * <code>readFloatBuffer</code> reads value for this matrix from a FloatBuffer.
*
* @param fb the buffer to read from, must be correct size * @param fb the buffer to read from, must be correct size
* @param columnMajor if true, this buffer should be filled with column * @param columnMajor if true, this buffer should be filled with column
* major data, otherwise it will be filled row major. * major data, otherwise it will be filled row major.
* @return this data as a FloatBuffer. * @return this data as a FloatBuffer.
*/ */
public Matrix4f readFloatBuffer(FloatBuffer fb, boolean columnMajor) { public Matrix4f readFloatBuffer(FloatBuffer fb, boolean columnMajor) {
@ -859,7 +851,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>loadIdentity</code> sets this matrix to the identity matrix, * <code>loadIdentity</code> sets this matrix to the identity matrix,
* namely all zeros with ones along the diagonal. * namely all zeros with ones along the diagonal.
*
*/ */
public void loadIdentity() { public void loadIdentity() {
m01 = m02 = m03 = 0.0f; m01 = m02 = m03 = 0.0f;
@ -869,7 +860,8 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
m00 = m11 = m22 = m33 = 1.0f; m00 = m11 = m22 = m33 = 1.0f;
} }
public void fromFrustum(float near, float far, float left, float right, float top, float bottom, boolean parallel) { public void fromFrustum(float near, float far, float left, float right,
float top, float bottom, boolean parallel) {
loadIdentity(); loadIdentity();
if (parallel) { if (parallel) {
// scale // scale
@ -893,7 +885,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
// A // A
m02 = (right + left) / (right - left); m02 = (right + left) / (right - left);
// B // B
m12 = (top + bottom) / (top - bottom); m12 = (top + bottom) / (top - bottom);
// C // C
@ -908,7 +900,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>fromAngleAxis</code> sets this matrix4f to the values specified * <code>fromAngleAxis</code> sets this matrix4f to the values specified
* by an angle and an axis of rotation. This method creates an object, so * by an angle and an axis of rotation. This method creates an object, so
* use fromAngleNormalAxis if your axis is already normalized. * use fromAngleNormalAxis if your axis is already normalized.
* *
* @param angle * @param angle
* the angle to rotate (in radians). * the angle to rotate (in radians).
* @param axis * @param axis
@ -922,7 +914,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>fromAngleNormalAxis</code> sets this matrix4f to the values * <code>fromAngleNormalAxis</code> sets this matrix4f to the values
* specified by an angle and a normalized axis of rotation. * specified by an angle and a normalized axis of rotation.
* *
* @param angle * @param angle
* the angle to rotate (in radians). * the angle to rotate (in radians).
* @param axis * @param axis
@ -958,7 +950,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>mult</code> multiplies this matrix by a scalar. * <code>mult</code> multiplies this matrix by a scalar.
* *
* @param scalar * @param scalar
* the scalar to multiply this matrix by. * the scalar to multiply this matrix by.
*/ */
@ -998,7 +990,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies this matrix with another matrix. The * <code>mult</code> multiplies this matrix with another matrix. The
* result matrix will then be returned. This matrix will be on the left hand * result matrix will then be returned. This matrix will be on the left hand
* side, while the parameter matrix will be on the right. * side, while the parameter matrix will be on the right.
* *
* @param in2 * @param in2
* the matrix to multiply this matrix by. * the matrix to multiply this matrix by.
* @return the resultant matrix * @return the resultant matrix
@ -1011,7 +1003,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies this matrix with another matrix. The * <code>mult</code> multiplies this matrix with another matrix. The
* result matrix will then be returned. This matrix will be on the left hand * result matrix will then be returned. This matrix will be on the left hand
* side, while the parameter matrix will be on the right. * side, while the parameter matrix will be on the right.
* *
* @param in2 * @param in2
* the matrix to multiply this matrix by. * the matrix to multiply this matrix by.
* @param store * @param store
@ -1095,7 +1087,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
+ m32 * in2.m23 + m32 * in2.m23
+ m33 * in2.m33; + m33 * in2.m33;
store.m00 = m[0]; store.m00 = m[0];
store.m01 = m[1]; store.m01 = m[1];
store.m02 = m[2]; store.m02 = m[2];
@ -1118,10 +1109,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>mult</code> multiplies this matrix with another matrix. The * <code>mult</code> multiplies this matrix with another matrix. The
* results are stored internally and a handle to this matrix will * results are stored internally and a handle to this matrix will
* then be returned. This matrix will be on the left hand * then be returned. This matrix will be on the left hand
* side, while the parameter matrix will be on the right. * side, while the parameter matrix will be on the right.
* *
* @param in2 * @param in2
* the matrix to multiply this matrix by. * the matrix to multiply this matrix by.
* @return the resultant matrix * @return the resultant matrix
@ -1133,7 +1124,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>mult</code> multiplies a vector about a rotation matrix. The * <code>mult</code> multiplies a vector about a rotation matrix. The
* resulting vector is returned as a new Vector3f. * resulting vector is returned as a new Vector3f.
* *
* @param vec * @param vec
* vec to multiply against. * vec to multiply against.
* @return the rotated vector. * @return the rotated vector.
@ -1145,7 +1136,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>mult</code> multiplies a vector about a rotation matrix and adds * <code>mult</code> multiplies a vector about a rotation matrix and adds
* translation. The resulting vector is returned. * translation. The resulting vector is returned.
* *
* @param vec * @param vec
* vec to multiply against. * vec to multiply against.
* @param store * @param store
@ -1211,7 +1202,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* *
* @param vec * @param vec
* vec to multiply against. * vec to multiply against.
*
* @return the rotated vector. * @return the rotated vector.
*/ */
public Vector4f multAcross(Vector4f vec) { public Vector4f multAcross(Vector4f vec) {
@ -1296,11 +1286,11 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies a vector about a rotation matrix and adds * <code>mult</code> multiplies a vector about a rotation matrix and adds
* translation. The w value is returned as a result of * translation. The w value is returned as a result of
* multiplying the last column of the matrix by 1.0 * multiplying the last column of the matrix by 1.0
* *
* @param vec * @param vec
* vec to multiply against. * vec to multiply against.
* @param store * @param store
* a vector to store the result in. * a vector to store the result in.
* @return the W value * @return the W value
*/ */
public float multProj(Vector3f vec, Vector3f store) { public float multProj(Vector3f vec, Vector3f store) {
@ -1314,7 +1304,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>mult</code> multiplies a vector about a rotation matrix. The * <code>mult</code> multiplies a vector about a rotation matrix. The
* resulting vector is returned. * resulting vector is returned.
* *
* @param vec * @param vec
* vec to multiply against. * vec to multiply against.
* @param store * @param store
@ -1371,9 +1361,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
* <code>mult</code> multiplies an array of 4 floats against this rotation * <code>mult</code> multiplies an array of 4 floats against this rotation
* matrix. The results are stored directly in the array. (vec4f x mat4f) * matrix. The results are stored directly in the array. (vec4f x mat4f)
* *
* @param vec4f * @param vec4f
* float array (size 4) to multiply against the matrix. * float array (size 4) to multiply against the matrix.
* @return the vec4f for chaining. * @return the vec4f for chaining.
@ -1395,9 +1385,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
* <code>mult</code> multiplies an array of 4 floats against this rotation * <code>mult</code> multiplies an array of 4 floats against this rotation
* matrix. The results are stored directly in the array. (vec4f x mat4f) * matrix. The results are stored directly in the array. (vec4f x mat4f)
* *
* @param vec4f * @param vec4f
* float array (size 4) to multiply against the matrix. * float array (size 4) to multiply against the matrix.
* @return the vec4f for chaining. * @return the vec4f for chaining.
@ -1420,7 +1410,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* Inverts this matrix as a new Matrix4f. * Inverts this matrix as a new Matrix4f.
* *
* @return The new inverse matrix * @return The new inverse matrix
*/ */
public Matrix4f invert() { public Matrix4f invert() {
@ -1429,7 +1419,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* Inverts this matrix and stores it in the given store. * Inverts this matrix and stores it in the given store.
* *
* @return The store * @return The store
*/ */
public Matrix4f invert(Matrix4f store) { public Matrix4f invert(Matrix4f store) {
@ -1480,7 +1470,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* Inverts this matrix locally. * Inverts this matrix locally.
* *
* @return this * @return this
*/ */
public Matrix4f invertLocal() { public Matrix4f invertLocal() {
@ -1545,7 +1535,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* Returns a new matrix representing the adjoint of this matrix. * Returns a new matrix representing the adjoint of this matrix.
* *
* @return The adjoint matrix * @return The adjoint matrix
*/ */
public Matrix4f adjoint() { public Matrix4f adjoint() {
@ -1581,7 +1571,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* Places the adjoint of this matrix in store (creates store if null.) * Places the adjoint of this matrix in store (creates store if null.)
* *
* @param store * @param store
* The matrix to store the result in. If null, a new matrix is created. * The matrix to store the result in. If null, a new matrix is created.
* @return store * @return store
@ -1626,7 +1616,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>determinant</code> generates the determinate of this matrix. * <code>determinant</code> generates the determinate of this matrix.
* *
* @return the determinate * @return the determinate
*/ */
public float determinant() { public float determinant() {
@ -1648,7 +1638,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* Sets all of the values in this matrix to zero. * Sets all of the values in this matrix to zero.
* *
* @return this matrix * @return this matrix
*/ */
public Matrix4f zero() { public Matrix4f zero() {
@ -1682,7 +1672,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>add</code> adds the values of a parameter matrix to this matrix. * <code>add</code> adds the values of a parameter matrix to this matrix.
* *
* @param mat * @param mat
* the matrix to add to this. * the matrix to add to this.
*/ */
@ -1738,18 +1728,18 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
mat.m20 = m20; mat.m20 = m20;
mat.m21 = m21; mat.m21 = m21;
mat.m22 = m22; mat.m22 = m22;
} }
/** /**
* Retrieves the scale vector from the matrix. * Retrieves the scale vector from the matrix.
* *
* @return the scale vector * @return the scale vector
*/ */
public Vector3f toScaleVector() { public Vector3f toScaleVector() {
Vector3f result = new Vector3f(); Vector3f result = new Vector3f();
this.toScaleVector(result); this.toScaleVector(result);
return result; return result;
} }
/** /**
* Retrieves the scale vector from the matrix and stores it into a given * Retrieves the scale vector from the matrix and stores it into a given
@ -1759,16 +1749,16 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* @return the store vector * @return the store vector
*/ */
public Vector3f toScaleVector(Vector3f store) { public Vector3f toScaleVector(Vector3f store) {
float scaleX = (float) Math.sqrt(m00 * m00 + m10 * m10 + m20 * m20); float scaleX = (float) Math.sqrt(m00 * m00 + m10 * m10 + m20 * m20);
float scaleY = (float) Math.sqrt(m01 * m01 + m11 * m11 + m21 * m21); float scaleY = (float) Math.sqrt(m01 * m01 + m11 * m11 + m21 * m21);
float scaleZ = (float) Math.sqrt(m02 * m02 + m12 * m12 + m22 * m22); float scaleZ = (float) Math.sqrt(m02 * m02 + m12 * m12 + m22 * m22);
store.set(scaleX, scaleY, scaleZ); store.set(scaleX, scaleY, scaleZ);
return store; return store;
} }
/** /**
* Sets the scale. * Sets the scale.
* *
* @param x * @param x
* the X scale * the X scale
* @param y * @param y
@ -1805,7 +1795,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* Sets the scale. * Sets the scale.
* *
* @param scale * @param scale
* the scale vector to set * the scale vector to set
*/ */
@ -1815,7 +1805,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>setTranslation</code> will set the matrix's translation values. * <code>setTranslation</code> will set the matrix's translation values.
* *
* @param translation * @param translation
* the new values for the translation. * the new values for the translation.
* @throws JmeException * @throws JmeException
@ -1833,13 +1823,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>setTranslation</code> will set the matrix's translation values. * <code>setTranslation</code> will set the matrix's translation values.
* *
* @param x * @param x value of the translation on the x axis
* value of the translation on the x axis * @param y value of the translation on the y axis
* @param y * @param z value of the translation on the z axis
* value of the translation on the y axis
* @param z
* value of the translation on the z axis
*/ */
public void setTranslation(float x, float y, float z) { public void setTranslation(float x, float y, float z) {
m03 = x; m03 = x;
@ -1862,7 +1849,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>setInverseTranslation</code> will set the matrix's inverse * <code>setInverseTranslation</code> will set the matrix's inverse
* translation values. * translation values.
* *
* @param translation * @param translation
* the new values for the inverse translation. * the new values for the inverse translation.
* @throws JmeException * @throws JmeException
@ -1883,7 +1870,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* three axes (x, y, z). Where each axis has a specified rotation in * three axes (x, y, z). Where each axis has a specified rotation in
* degrees. These rotations are expressed in a single <code>Vector3f</code> * degrees. These rotations are expressed in a single <code>Vector3f</code>
* object. * object.
* *
* @param angles * @param angles
* the angles to rotate. * the angles to rotate.
*/ */
@ -1919,7 +1906,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>setRotationQuaternion</code> builds a rotation from a * <code>setRotationQuaternion</code> builds a rotation from a
* <code>Quaternion</code>. * <code>Quaternion</code>.
* *
* @param quat * @param quat
* the quaternion to build the rotation from. * the quaternion to build the rotation from.
* @throws NullPointerException * @throws NullPointerException
@ -1932,7 +1919,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>setInverseRotationRadians</code> builds an inverted rotation from * <code>setInverseRotationRadians</code> builds an inverted rotation from
* Euler angles that are in radians. * Euler angles that are in radians.
* *
* @param angles * @param angles
* the Euler angles in radians. * the Euler angles in radians.
* @throws JmeException * @throws JmeException
@ -1969,7 +1956,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>setInverseRotationDegrees</code> builds an inverted rotation from * <code>setInverseRotationDegrees</code> builds an inverted rotation from
* Euler angles that are in degrees. * Euler angles that are in degrees.
* *
* @param angles * @param angles
* the Euler angles in degrees. * the Euler angles in degrees.
* @throws JmeException * @throws JmeException
@ -1988,10 +1975,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>inverseTranslateVect</code> translates a given Vector3f by the * <code>inverseTranslateVect</code> translates a given Vector3f by the
* translation part of this matrix. * translation part of this matrix.
* *
* @param vec * @param vec
* the Vector3f data to be translated. * the Vector3f data to be translated.
* @throws JmeException * @throws JmeException
@ -2009,10 +1995,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>inverseTranslateVect</code> translates a given Vector3f by the * <code>inverseTranslateVect</code> translates a given Vector3f by the
* translation part of this matrix. * translation part of this matrix.
* *
* @param data * @param data
* the Vector3f to be translated. * the Vector3f to be translated.
* @throws JmeException * @throws JmeException
@ -2025,10 +2010,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>inverseTranslateVect</code> translates a given Vector3f by the * <code>inverseTranslateVect</code> translates a given Vector3f by the
* translation part of this matrix. * translation part of this matrix.
* *
* @param data * @param data
* the Vector3f to be translated. * the Vector3f to be translated.
* @throws JmeException * @throws JmeException
@ -2041,10 +2025,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>inverseRotateVect</code> rotates a given Vector3f by the rotation * <code>inverseRotateVect</code> rotates a given Vector3f by the rotation
* part of this matrix. * part of this matrix.
* *
* @param vec * @param vec
* the Vector3f to be rotated. * the Vector3f to be rotated.
*/ */
@ -2072,7 +2055,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* 0.0 1.0 0.0 0.0 <br> * 0.0 1.0 0.0 0.0 <br>
* 0.0 0.0 1.0 0.0 <br> * 0.0 0.0 1.0 0.0 <br>
* 0.0 0.0 0.0 1.0 <br>]<br> * 0.0 0.0 0.0 1.0 <br>]<br>
* *
* @return the string representation of this object. * @return the string representation of this object.
*/ */
@Override @Override
@ -2118,11 +2101,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>hashCode</code> returns the hash code value as an integer and is * <code>hashCode</code> returns the hash code value as an integer and is
* supported for the benefit of hashing based collection classes such as * supported for the benefit of hashing based collection classes such as
* Hashtable, HashMap, HashSet etc. * Hashtable, HashMap, HashSet etc.
* *
* @return the hashcode for this instance of Matrix4f. * @return the hashcode for this instance of Matrix4f.
* @see java.lang.Object#hashCode() * @see java.lang.Object#hashCode()
*/ */
@ -2277,7 +2259,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/** /**
* Apply a scale to this matrix. * Apply a scale to this matrix.
* *
* @param scale * @param scale
* the scale to apply * the scale to apply
*/ */

@ -40,7 +40,7 @@ import java.util.logging.Logger;
* This provides methods for calculating a "distance" of a point from this * This provides methods for calculating a "distance" of a point from this
* plane. The distance is pseudo due to the fact that it can be negative if the * plane. The distance is pseudo due to the fact that it can be negative if the
* point is on the non-normal side of the plane. * point is on the non-normal side of the plane.
* *
* @author Mark Powell * @author Mark Powell
* @author Joshua Slack * @author Joshua Slack
* @author Ian McClean * @author Ian McClean
@ -58,12 +58,12 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
Negative Negative
} }
/** /**
* Vector normal to the plane. * Vector normal to the plane.
*/ */
protected Vector3f normal = new Vector3f(); protected Vector3f normal = new Vector3f();
/** /**
* Constant of the plane. See formula in class definition. * Constant of the plane. See formula in class definition.
*/ */
protected float constant; protected float constant;
@ -78,7 +78,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
/** /**
* Constructor instantiates a new <code>Plane</code> object. The normal * Constructor instantiates a new <code>Plane</code> object. The normal
* and constant values are set at creation. * and constant values are set at creation.
* *
* @param normal * @param normal
* the normal of the plane. * the normal of the plane.
* @param constant * @param constant
@ -105,7 +105,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
/** /**
* <code>setNormal</code> sets the normal of the plane. * <code>setNormal</code> sets the normal of the plane.
* *
* @param normal * @param normal
* the new normal of the plane. * the new normal of the plane.
*/ */
@ -121,12 +121,12 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
* *
*/ */
public void setNormal(float x, float y, float z) { public void setNormal(float x, float y, float z) {
this.normal.set(x,y,z); this.normal.set(x, y, z);
} }
/** /**
* <code>getNormal</code> retrieves the normal of the plane. * <code>getNormal</code> retrieves the normal of the plane.
* *
* @return the normal of the plane. * @return the normal of the plane.
*/ */
public Vector3f getNormal() { public Vector3f getNormal() {
@ -136,7 +136,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
/** /**
* <code>setConstant</code> sets the constant value that helps define the * <code>setConstant</code> sets the constant value that helps define the
* plane. * plane.
* *
* @param constant * @param constant
* the new constant value. * the new constant value.
*/ */
@ -146,27 +146,28 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
/** /**
* <code>getConstant</code> returns the constant of the plane. * <code>getConstant</code> returns the constant of the plane.
* *
* @return the constant of the plane. * @return the constant of the plane.
*/ */
public float getConstant() { public float getConstant() {
return constant; return constant;
} }
public Vector3f getClosestPoint(Vector3f point, Vector3f store){ public Vector3f getClosestPoint(Vector3f point, Vector3f store) {
// float t = constant - normal.dot(point); // float t = constant - normal.dot(point);
// return store.set(normal).multLocal(t).addLocal(point); // return store.set(normal).multLocal(t).addLocal(point);
float t = (constant - normal.dot(point)) / normal.dot(normal); float t = (constant - normal.dot(point)) / normal.dot(normal);
return store.set(normal).multLocal(t).addLocal(point); return store.set(normal).multLocal(t).addLocal(point);
} }
public Vector3f getClosestPoint(Vector3f point){ public Vector3f getClosestPoint(Vector3f point) {
return getClosestPoint(point, new Vector3f()); return getClosestPoint(point, new Vector3f());
} }
public Vector3f reflect(Vector3f point, Vector3f store){ public Vector3f reflect(Vector3f point, Vector3f store) {
if (store == null) if (store == null) {
store = new Vector3f(); store = new Vector3f();
}
float d = pseudoDistance(point); float d = pseudoDistance(point);
store.set(normal).negateLocal().multLocal(d * 2f); store.set(normal).negateLocal().multLocal(d * 2f);
@ -179,7 +180,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
* a provided point. If the point is on the negative side of the plane the * a provided point. If the point is on the negative side of the plane the
* distance returned is negative, otherwise it is positive. If the point is * distance returned is negative, otherwise it is positive. If the point is
* on the plane, it is zero. * on the plane, it is zero.
* *
* @param point * @param point
* the point to check. * the point to check.
* @return the signed distance from the plane to a point. * @return the signed distance from the plane to a point.
@ -192,7 +193,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
* <code>whichSide</code> returns the side at which a point lies on the * <code>whichSide</code> returns the side at which a point lies on the
* plane. The positive values returned are: NEGATIVE_SIDE, POSITIVE_SIDE and * plane. The positive values returned are: NEGATIVE_SIDE, POSITIVE_SIDE and
* NO_SIDE. * NO_SIDE.
* *
* @param point * @param point
* the point to check. * the point to check.
* @return the side at which the point lies. * @return the side at which the point lies.
@ -208,19 +209,19 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
} }
} }
public boolean isOnPlane(Vector3f point){ public boolean isOnPlane(Vector3f point) {
float dist = pseudoDistance(point); float dist = pseudoDistance(point);
if (dist < FastMath.FLT_EPSILON && dist > -FastMath.FLT_EPSILON) if (dist < FastMath.FLT_EPSILON && dist > -FastMath.FLT_EPSILON) {
return true; return true;
else } else {
return false; return false;
}
} }
/** /**
* Initialize this plane using the three points of the given triangle. * Initialize this plane using the three points of the given triangle.
* *
* @param t * @param t the triangle
* the triangle
*/ */
public void setPlanePoints(AbstractTriangle t) { public void setPlanePoints(AbstractTriangle t) {
setPlanePoints(t.get1(), t.get2(), t.get3()); setPlanePoints(t.get1(), t.get2(), t.get3());
@ -232,14 +233,14 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
* @param origin * @param origin
* @param normal * @param normal
*/ */
public void setOriginNormal(Vector3f origin, Vector3f normal){ public void setOriginNormal(Vector3f origin, Vector3f normal) {
this.normal.set(normal); this.normal.set(normal);
this.constant = normal.x * origin.x + normal.y * origin.y + normal.z * origin.z; this.constant = normal.x * origin.x + normal.y * origin.y + normal.z * origin.z;
} }
/** /**
* Initialize the Plane using the given 3 points as coplanar. * Initialize the Plane using the given 3 points as coplanar.
* *
* @param v1 * @param v1
* the first point * the first point
* @param v2 * @param v2
@ -260,7 +261,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
* <code>Vector3f</code> object, so the format is the following: * <code>Vector3f</code> object, so the format is the following:
* com.jme.math.Plane [Normal: org.jme.math.Vector3f [X=XX.XXXX, Y=YY.YYYY, * com.jme.math.Plane [Normal: org.jme.math.Vector3f [X=XX.XXXX, Y=YY.YYYY,
* Z=ZZ.ZZZZ] - Constant: CC.CCCCC] * Z=ZZ.ZZZZ] - Constant: CC.CCCCC]
* *
* @return the string representation of this plane. * @return the string representation of this plane.
*/ */
@Override @Override

@ -42,10 +42,9 @@ import java.util.logging.Logger;
* hypercomplex numbers. Quaternions extends a rotation in three dimensions to a * hypercomplex numbers. Quaternions extends a rotation in three dimensions to a
* rotation in four dimensions. This avoids "gimbal lock" and allows for smooth * rotation in four dimensions. This avoids "gimbal lock" and allows for smooth
* continuous rotation. * continuous rotation.
* *
* <code>Quaternion</code> is defined by four floating point numbers: {x y z * <code>Quaternion</code> is defined by four floating point numbers: {x y z w}.
* w}. *
*
* @author Mark Powell * @author Mark Powell
* @author Joshua Slack * @author Joshua Slack
*/ */
@ -60,7 +59,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
public static final Quaternion IDENTITY = new Quaternion(); public static final Quaternion IDENTITY = new Quaternion();
public static final Quaternion DIRECTION_Z = new Quaternion(); public static final Quaternion DIRECTION_Z = new Quaternion();
public static final Quaternion ZERO = new Quaternion(0, 0, 0, 0); public static final Quaternion ZERO = new Quaternion(0, 0, 0, 0);
static { static {
DIRECTION_Z.fromAxes(Vector3f.UNIT_X, Vector3f.UNIT_Y, Vector3f.UNIT_Z); DIRECTION_Z.fromAxes(Vector3f.UNIT_X, Vector3f.UNIT_Y, Vector3f.UNIT_Z);
} }
@ -82,14 +81,10 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* Constructor instantiates a new <code>Quaternion</code> object from the * Constructor instantiates a new <code>Quaternion</code> object from the
* given list of parameters. * given list of parameters.
* *
* @param x * @param x the x value of the quaternion.
* the x value of the quaternion. * @param y the y value of the quaternion.
* @param y * @param z the z value of the quaternion.
* the y value of the quaternion. * @param w the w value of the quaternion.
* @param z
* the z value of the quaternion.
* @param w
* the w value of the quaternion.
*/ */
public Quaternion(float x, float y, float z, float w) { public Quaternion(float x, float y, float z, float w) {
this.x = x; this.x = x;
@ -115,17 +110,13 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
} }
/** /**
* sets the data in a <code>Quaternion</code> object from the given list * sets the data in a <code>Quaternion</code> object from the given list of
* of parameters. * parameters.
* *
* @param x * @param x the x value of the quaternion.
* the x value of the quaternion. * @param y the y value of the quaternion.
* @param y * @param z the z value of the quaternion.
* the y value of the quaternion. * @param w the w value of the quaternion.
* @param z
* the z value of the quaternion.
* @param w
* the w value of the quaternion.
* @return this * @return this
*/ */
public Quaternion set(float x, float y, float z, float w) { public Quaternion set(float x, float y, float z, float w) {
@ -141,8 +132,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* passed <code>Quaternion</code> object. The values are copied producing * passed <code>Quaternion</code> object. The values are copied producing
* a new object. * a new object.
* *
* @param q * @param q The Quaternion to copy values from.
* The Quaternion to copy values from.
* @return this * @return this
*/ */
public Quaternion set(Quaternion q) { public Quaternion set(Quaternion q) {
@ -184,8 +174,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* Constructor instantiates a new <code>Quaternion</code> object from an * Constructor instantiates a new <code>Quaternion</code> object from an
* existing quaternion, creating a copy. * existing quaternion, creating a copy.
* *
* @param q * @param q the quaternion to copy.
* the quaternion to copy.
*/ */
public Quaternion(Quaternion q) { public Quaternion(Quaternion q) {
this.x = q.x; this.x = q.x;
@ -195,7 +184,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
} }
/** /**
* Sets this Quaternion to {0, 0, 0, 1}. Same as calling set(0,0,0,1). * Sets this Quaternion to {0, 0, 0, 1}. Same as calling set(0,0,0,1).
*/ */
public void loadIdentity() { public void loadIdentity() {
x = y = z = 0; x = y = z = 0;
@ -231,10 +220,12 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/** /**
* <code>fromAngles</code> builds a Quaternion from the Euler rotation * <code>fromAngles</code> builds a Quaternion from the Euler rotation
* angles (x,y,z) aka (pitch, yaw, roll)). Note that we are applying in order: (y, z, x) aka (yaw, roll, pitch) but * angles (x,y,z) aka (pitch, yaw, roll)).
* we've ordered them in x, y, and z for convenience. * Note that we are applying in order: (y, z, x) aka (yaw, roll, pitch)
* but we've ordered them in x, y, and z for convenience.
*
* @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm</a> * @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm</a>
* *
* @param xAngle * @param xAngle
* the Euler pitch of rotation (in radians). (aka Attitude, often rot * the Euler pitch of rotation (in radians). (aka Attitude, often rot
* around x) * around x)
@ -275,10 +266,10 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/** /**
* <code>toAngles</code> returns this quaternion converted to Euler rotation * <code>toAngles</code> returns this quaternion converted to Euler rotation
* angles (x,y,z) aka (pitch, yaw, roll).<br/> * angles (x,y,z) aka (pitch, yaw, roll).<br/>
* Note that the result is not always 100% accurate due to the implications of euler angles. * Note that the result is not always 100% accurate due to the implications of euler angles.
* @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm</a> * @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm</a>
* *
* @param angles * @param angles
* the float[] in which the angles should be stored, or null if * the float[] in which the angles should be stored, or null if
* you want a new float[] to be created * you want a new float[] to be created
@ -307,7 +298,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
angles[2] = -FastMath.HALF_PI; angles[2] = -FastMath.HALF_PI;
angles[0] = 0; angles[0] = 0;
} else { } else {
angles[1] = FastMath.atan2(2 * y * w - 2 * x * z, sqx - sqy - sqz + sqw); // yaw or heading angles[1] = FastMath.atan2(2 * y * w - 2 * x * z, sqx - sqy - sqz + sqw); // yaw or heading
angles[2] = FastMath.asin(2 * test / unit); // roll or bank angles[2] = FastMath.asin(2 * test / unit); // roll or bank
angles[0] = FastMath.atan2(2 * x * w - 2 * y * z, -sqx + sqy - sqz + sqw); // pitch or attitude angles[0] = FastMath.atan2(2 * x * w - 2 * y * z, -sqx + sqy - sqz + sqw); // pitch or attitude
} }
@ -315,10 +306,9 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
} }
/** /**
*
* <code>fromRotationMatrix</code> generates a quaternion from a supplied * <code>fromRotationMatrix</code> generates a quaternion from a supplied
* matrix. This matrix is assumed to be a rotational matrix. * matrix. This matrix is assumed to be a rotational matrix.
* *
* @param matrix * @param matrix
* the matrix that defines the rotation. * the matrix that defines the rotation.
*/ */
@ -353,7 +343,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
m22 *= lengthSquared; m22 *= lengthSquared;
} }
// Use the Graphics Gems code, from // Use the Graphics Gems code, from
// ftp://ftp.cis.upenn.edu/pub/graphics/shoemake/quatut.ps.Z // ftp://ftp.cis.upenn.edu/pub/graphics/shoemake/quatut.ps.Z
// *NOT* the "Matrix and Quaternions FAQ", which has errors! // *NOT* the "Matrix and Quaternions FAQ", which has errors!
@ -398,7 +388,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/** /**
* <code>toRotationMatrix</code> converts this quaternion to a rotational * <code>toRotationMatrix</code> converts this quaternion to a rotational
* matrix. Note: the result is created from a normalized version of this quat. * matrix. Note: the result is created from a normalized version of this quat.
* *
* @return the rotation matrix representation of this quaternion. * @return the rotation matrix representation of this quaternion.
*/ */
public Matrix3f toRotationMatrix() { public Matrix3f toRotationMatrix() {
@ -409,7 +399,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/** /**
* <code>toRotationMatrix</code> converts this quaternion to a rotational * <code>toRotationMatrix</code> converts this quaternion to a rotational
* matrix. The result is stored in result. * matrix. The result is stored in result.
* *
* @param result * @param result
* The Matrix3f to store the result in. * The Matrix3f to store the result in.
* @return the rotation matrix representation of this quaternion. * @return the rotation matrix representation of this quaternion.
@ -805,6 +795,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/** /**
* Sets the values of this quaternion to the nlerp from itself to q2 by blend. * Sets the values of this quaternion to the nlerp from itself to q2 by blend.
*
* @param q2 * @param q2
* @param blend * @param blend
*/ */
@ -829,8 +820,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>add</code> adds the values of this quaternion to those of the * <code>add</code> adds the values of this quaternion to those of the
* parameter quaternion. The result is returned as a new quaternion. * parameter quaternion. The result is returned as a new quaternion.
* *
* @param q * @param q the quaternion to add to this.
* the quaternion to add to this.
* @return the new quaternion. * @return the new quaternion.
*/ */
public Quaternion add(Quaternion q) { public Quaternion add(Quaternion q) {
@ -841,8 +831,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>add</code> adds the values of this quaternion to those of the * <code>add</code> adds the values of this quaternion to those of the
* parameter quaternion. The result is stored in this Quaternion. * parameter quaternion. The result is stored in this Quaternion.
* *
* @param q * @param q the quaternion to add to this.
* the quaternion to add to this.
* @return This Quaternion after addition. * @return This Quaternion after addition.
*/ */
public Quaternion addLocal(Quaternion q) { public Quaternion addLocal(Quaternion q) {
@ -858,8 +847,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* from those of this quaternion. The result is returned as a new * from those of this quaternion. The result is returned as a new
* quaternion. * quaternion.
* *
* @param q * @param q the quaternion to subtract from this.
* the quaternion to subtract from this.
* @return the new quaternion. * @return the new quaternion.
*/ */
public Quaternion subtract(Quaternion q) { public Quaternion subtract(Quaternion q) {
@ -870,8 +858,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>subtract</code> subtracts the values of the parameter quaternion * <code>subtract</code> subtracts the values of the parameter quaternion
* from those of this quaternion. The result is stored in this Quaternion. * from those of this quaternion. The result is stored in this Quaternion.
* *
* @param q * @param q the quaternion to subtract from this.
* the quaternion to subtract from this.
* @return This Quaternion after subtraction. * @return This Quaternion after subtraction.
*/ */
public Quaternion subtractLocal(Quaternion q) { public Quaternion subtractLocal(Quaternion q) {
@ -903,8 +890,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* It IS safe for q and res to be the same object. * 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. * It IS NOT safe for this and res to be the same object.
* *
* @param q * @param q the quaternion to multiply this quaternion by.
* the quaternion to multiply this quaternion by.
* @param res * @param res
* the quaternion to store the result in. * the quaternion to store the result in.
* @return the new quaternion. * @return the new quaternion.
@ -982,8 +968,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* corresponds to an axis of the coordinate system defined by the quaternion * corresponds to an axis of the coordinate system defined by the quaternion
* rotation. * rotation.
* *
* @param axis * @param axis the array of vectors to be filled.
* the array of vectors to be filled.
*/ */
public void toAxes(Vector3f axis[]) { public void toAxes(Vector3f axis[]) {
Matrix3f tempMat = toRotationMatrix(); Matrix3f tempMat = toRotationMatrix();
@ -996,8 +981,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>mult</code> multiplies this quaternion by a parameter vector. The * <code>mult</code> multiplies this quaternion by a parameter vector. The
* result is returned as a new vector. * result is returned as a new vector.
* *
* @param v * @param v the vector to multiply this quaternion by.
* the vector to multiply this quaternion by.
* @return the new vector. * @return the new vector.
*/ */
public Vector3f mult(Vector3f v) { public Vector3f mult(Vector3f v) {
@ -1008,8 +992,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>mult</code> multiplies this quaternion by a parameter vector. The * <code>mult</code> multiplies this quaternion by a parameter vector. The
* result is stored in the supplied vector * result is stored in the supplied vector
* *
* @param v * @param v the vector to multiply this quaternion by.
* the vector to multiply this quaternion by.
* @return v * @return v
*/ */
public Vector3f multLocal(Vector3f v) { public Vector3f multLocal(Vector3f v) {
@ -1031,8 +1014,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* stored in this Quaternion, which is also returned for chaining. Similar * stored in this Quaternion, which is also returned for chaining. Similar
* to this *= q. * to this *= q.
* *
* @param q * @param q The Quaternion to multiply this one by.
* The Quaternion to multiply this one by.
* @return This Quaternion, after multiplication. * @return This Quaternion, after multiplication.
*/ */
public Quaternion multLocal(Quaternion q) { public Quaternion multLocal(Quaternion q) {
@ -1051,14 +1033,10 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* stored in this Quaternion, which is also returned for chaining. Similar * stored in this Quaternion, which is also returned for chaining. Similar
* to this *= q. * to this *= q.
* *
* @param qx - * @param qx quat x value
* quat x value * @param qy quat y value
* @param qy - * @param qz quat z value
* quat y value * @param qw quat w value
* @param qz -
* quat z value
* @param qw -
* quat w value
* *
* @return This Quaternion, after multiplication. * @return This Quaternion, after multiplication.
*/ */
@ -1076,7 +1054,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/** /**
* <code>mult</code> multiplies this quaternion by a parameter vector. The * <code>mult</code> multiplies this quaternion by a parameter vector. The
* result is returned as a new vector. * result is returned as a new vector.
* *
* @param v * @param v
* the vector to multiply this quaternion by. * the vector to multiply this quaternion by.
* @param store * @param store
@ -1279,7 +1257,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
} }
return true; return true;
} }
/** /**
* Returns true if this quaternion is similar to the specified quaternion * Returns true if this quaternion is similar to the specified quaternion
* within some value of epsilon. * within some value of epsilon.
@ -1304,11 +1282,10 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
} }
/** /**
*
* <code>hashCode</code> returns the hash code value as an integer and is * <code>hashCode</code> returns the hash code value as an integer and is
* supported for the benefit of hashing based collection classes such as * supported for the benefit of hashing based collection classes such as
* Hashtable, HashMap, HashSet etc. * Hashtable, HashMap, HashSet etc.
* *
* @return the hashcode for this instance of Quaternion. * @return the hashcode for this instance of Quaternion.
* @see java.lang.Object#hashCode() * @see java.lang.Object#hashCode()
*/ */
@ -1327,7 +1304,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>readExternal</code> builds a quaternion from an * <code>readExternal</code> builds a quaternion from an
* <code>ObjectInput</code> object. <br> * <code>ObjectInput</code> object. <br>
* NOTE: Used with serialization. Not to be called manually. * NOTE: Used with serialization. Not to be called manually.
* *
* @param in * @param in
* the ObjectInput value to read from. * the ObjectInput value to read from.
* @throws IOException * @throws IOException
@ -1345,7 +1322,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>writeExternal</code> writes this quaternion out to a * <code>writeExternal</code> writes this quaternion out to a
* <code>ObjectOutput</code> object. NOTE: Used with serialization. Not to * <code>ObjectOutput</code> object. NOTE: Used with serialization. Not to
* be called manually. * be called manually.
* *
* @param out * @param out
* the object to write to. * the object to write to.
* @throws IOException * @throws IOException

@ -49,11 +49,11 @@ public class Spline implements Savable {
Bezier, Bezier,
Nurb Nurb
} }
private List<Vector3f> controlPoints = new ArrayList<Vector3f>(); private List<Vector3f> controlPoints = new ArrayList<Vector3f>();
private List<Float> knots; //knots of NURBS spline private List<Float> knots; //knots of NURBS spline
private float[] weights; //weights of NURBS spline private float[] weights; //weights of NURBS spline
private int basisFunctionDegree; //degree of NURBS spline basis function (computed automatically) private int basisFunctionDegree; //degree of NURBS spline basis function (computed automatically)
private boolean cycle; private boolean cycle;
private List<Float> segmentsLength; private List<Float> segmentsLength;
private float totalLength; private float totalLength;
@ -66,6 +66,7 @@ public class Spline implements Savable {
/** /**
* Create a spline * Create a spline
*
* @param splineType the type of the spline @see {SplineType} * @param splineType the type of the spline @see {SplineType}
* @param controlPoints an array of vector to use as control points of the spline * @param controlPoints an array of vector to use as control points of the spline
* If the type of the curve is Bezier curve the control points should be provided * If the type of the curve is Bezier curve the control points should be provided
@ -74,15 +75,15 @@ public class Spline implements Savable {
* for the border points of the curve, who should have only one handle point. * for the border points of the curve, who should have only one handle point.
* The pattern should be as follows: * The pattern should be as follows:
* P0 - H0 : H1 - P1 - H1 : ... : Hn - Pn * P0 - H0 : H1 - P1 - H1 : ... : Hn - Pn
* *
* n is the amount of 'P' - points. * n is the amount of 'P' - points.
* @param curveTension the tension of the spline * @param curveTension the tension of the spline
* @param cycle true if the spline cycle. * @param cycle true if the spline cycle.
*/ */
public Spline(SplineType splineType, Vector3f[] controlPoints, float curveTension, boolean cycle) { public Spline(SplineType splineType, Vector3f[] controlPoints, float curveTension, boolean cycle) {
if(splineType==SplineType.Nurb) { if (splineType == SplineType.Nurb) {
throw new IllegalArgumentException("To create NURBS spline use: 'public Spline(Vector3f[] controlPoints, float[] weights, float[] nurbKnots)' constructor!"); throw new IllegalArgumentException("To create NURBS spline use: 'public Spline(Vector3f[] controlPoints, float[] weights, float[] nurbKnots)' constructor!");
} }
for (int i = 0; i < controlPoints.length; i++) { for (int i = 0; i < controlPoints.length; i++) {
Vector3f vector3f = controlPoints[i]; Vector3f vector3f = controlPoints[i];
this.controlPoints.add(vector3f); this.controlPoints.add(vector3f);
@ -95,6 +96,7 @@ public class Spline implements Savable {
/** /**
* Create a spline * Create a spline
*
* @param splineType the type of the spline @see {SplineType} * @param splineType the type of the spline @see {SplineType}
* @param controlPoints a list of vector to use as control points of the spline * @param controlPoints a list of vector to use as control points of the spline
* If the type of the curve is Bezier curve the control points should be provided * If the type of the curve is Bezier curve the control points should be provided
@ -103,45 +105,46 @@ public class Spline implements Savable {
* for the border points of the curve, who should have only one handle point. * for the border points of the curve, who should have only one handle point.
* The pattern should be as follows: * The pattern should be as follows:
* P0 - H0 : H1 - P1 - H1 : ... : Hn - Pn * P0 - H0 : H1 - P1 - H1 : ... : Hn - Pn
* *
* n is the amount of 'P' - points. * n is the amount of 'P' - points.
* @param curveTension the tension of the spline * @param curveTension the tension of the spline
* @param cycle true if the spline cycle. * @param cycle true if the spline cycle.
*/ */
public Spline(SplineType splineType, List<Vector3f> controlPoints, float curveTension, boolean cycle) { public Spline(SplineType splineType, List<Vector3f> controlPoints, float curveTension, boolean cycle) {
if(splineType==SplineType.Nurb) { if (splineType == SplineType.Nurb) {
throw new IllegalArgumentException("To create NURBS spline use: 'public Spline(Vector3f[] controlPoints, float[] weights, float[] nurbKnots)' constructor!"); throw new IllegalArgumentException("To create NURBS spline use: 'public Spline(Vector3f[] controlPoints, float[] weights, float[] nurbKnots)' constructor!");
} }
type = splineType; type = splineType;
this.controlPoints.addAll(controlPoints); this.controlPoints.addAll(controlPoints);
this.curveTension = curveTension; this.curveTension = curveTension;
this.cycle = cycle; this.cycle = cycle;
this.computeTotalLength(); this.computeTotalLength();
} }
/** /**
* Create a NURBS spline. A spline type is automatically set to SplineType.Nurb. * Create a NURBS spline. A spline type is automatically set to SplineType.Nurb.
* The cycle is set to <b>false</b> by default. * The cycle is set to <b>false</b> by default.
*
* @param controlPoints a list of vector to use as control points of the spline * @param controlPoints a list of vector to use as control points of the spline
* @param nurbKnots the nurb's spline knots * @param nurbKnots the nurb's spline knots
*/ */
public Spline(List<Vector4f> controlPoints, List<Float> nurbKnots) { public Spline(List<Vector4f> controlPoints, List<Float> nurbKnots) {
//input data control //input data control
for(int i=0;i<nurbKnots.size()-1;++i) { for (int i = 0; i < nurbKnots.size() - 1; ++i) {
if(nurbKnots.get(i)>nurbKnots.get(i+1)) { if (nurbKnots.get(i) > nurbKnots.get(i + 1)) {
throw new IllegalArgumentException("The knots values cannot decrease!"); throw new IllegalArgumentException("The knots values cannot decrease!");
} }
} }
//storing the data //storing the data
type = SplineType.Nurb; type = SplineType.Nurb;
this.weights = new float[controlPoints.size()]; this.weights = new float[controlPoints.size()];
this.knots = nurbKnots; this.knots = nurbKnots;
this.basisFunctionDegree = nurbKnots.size() - weights.length; this.basisFunctionDegree = nurbKnots.size() - weights.length;
for(int i=0;i<controlPoints.size();++i) { for (int i = 0; i < controlPoints.size(); ++i) {
Vector4f controlPoint = controlPoints.get(i); Vector4f controlPoint = controlPoints.get(i);
this.controlPoints.add(new Vector3f(controlPoint.x, controlPoint.y, controlPoint.z)); this.controlPoints.add(new Vector3f(controlPoint.x, controlPoint.y, controlPoint.z));
this.weights[i] = controlPoint.w; this.weights[i] = controlPoint.w;
} }
CurveAndSurfaceMath.prepareNurbsKnots(knots, basisFunctionDegree); CurveAndSurfaceMath.prepareNurbsKnots(knots, basisFunctionDegree);
this.computeTotalLength(); this.computeTotalLength();
@ -175,6 +178,7 @@ public class Spline implements Savable {
/** /**
* Adds a controlPoint to the spline * Adds a controlPoint to the spline
*
* @param controlPoint a position in world space * @param controlPoint a position in world space
*/ */
public void addControlPoint(Vector3f controlPoint) { public void addControlPoint(Vector3f controlPoint) {
@ -192,6 +196,7 @@ public class Spline implements Savable {
/** /**
* remove the controlPoint from the spline * remove the controlPoint from the spline
*
* @param controlPoint the controlPoint to remove * @param controlPoint the controlPoint to remove
*/ */
public void removeControlPoint(Vector3f controlPoint) { public void removeControlPoint(Vector3f controlPoint) {
@ -200,8 +205,8 @@ public class Spline implements Savable {
this.computeTotalLength(); this.computeTotalLength();
} }
} }
public void clearControlPoints(){ public void clearControlPoints() {
controlPoints.clear(); controlPoints.clear();
totalLength = 0; totalLength = 0;
} }
@ -225,10 +230,10 @@ public class Spline implements Savable {
totalLength += l; totalLength += l;
} }
} }
} else if(type == SplineType.Bezier) { } else if (type == SplineType.Bezier) {
this.computeBezierLength(); this.computeBezierLength();
} else if(type == SplineType.Nurb) { } else if (type == SplineType.Nurb) {
this.computeNurbLength(); this.computeNurbLength();
} else { } else {
this.initCatmullRomWayPoints(controlPoints); this.initCatmullRomWayPoints(controlPoints);
this.computeCatmulLength(); this.computeCatmulLength();
@ -249,34 +254,37 @@ public class Spline implements Savable {
} }
} }
} }
/** /**
* This method calculates the Bezier curve length. * This method calculates the Bezier curve length.
*/ */
private void computeBezierLength() { private void computeBezierLength() {
float l = 0; float l = 0;
if (controlPoints.size() > 1) { if (controlPoints.size() > 1) {
for (int i = 0; i < controlPoints.size() - 1; i+=3) { for (int i = 0; i < controlPoints.size() - 1; i += 3) {
l = FastMath.getBezierP1toP2Length(controlPoints.get(i), l = FastMath.getBezierP1toP2Length(controlPoints.get(i),
controlPoints.get(i + 1), controlPoints.get(i + 2), controlPoints.get(i + 3)); controlPoints.get(i + 1), controlPoints.get(i + 2), controlPoints.get(i + 3));
segmentsLength.add(l); segmentsLength.add(l);
totalLength += l; totalLength += l;
} }
} }
} }
/** /**
* This method calculates the NURB curve length. * This method calculates the NURB curve length.
*/ */
private void computeNurbLength() { private void computeNurbLength() {
//TODO: implement //TODO: implement
} }
/** /**
* Interpolate a position on the spline * Interpolate a position on the spline
* @param value a value from 0 to 1 that represent the position between the current control point and the next one *
* @param value a value from 0 to 1 that represent the position between the
* current control point and the next one
* @param currentControlPoint the current control point * @param currentControlPoint the current control point
* @param store a vector to store the result (use null to create a new one that will be returned by the method) * @param store a vector to store the result (use null to create a new one
* that will be returned by the method)
* @return the position * @return the position
*/ */
public Vector3f interpolate(float value, int currentControlPoint, Vector3f store) { public Vector3f interpolate(float value, int currentControlPoint, Vector3f store) {
@ -291,11 +299,11 @@ public class Spline implements Savable {
FastMath.interpolateLinear(value, controlPoints.get(currentControlPoint), controlPoints.get(currentControlPoint + 1), store); FastMath.interpolateLinear(value, controlPoints.get(currentControlPoint), controlPoints.get(currentControlPoint + 1), store);
break; break;
case Bezier: case Bezier:
FastMath.interpolateBezier(value, controlPoints.get(currentControlPoint), controlPoints.get(currentControlPoint + 1), controlPoints.get(currentControlPoint + 2), controlPoints.get(currentControlPoint + 3), store); FastMath.interpolateBezier(value, controlPoints.get(currentControlPoint), controlPoints.get(currentControlPoint + 1), controlPoints.get(currentControlPoint + 2), controlPoints.get(currentControlPoint + 3), store);
break; break;
case Nurb: case Nurb:
CurveAndSurfaceMath.interpolateNurbs(value, this, store); CurveAndSurfaceMath.interpolateNurbs(value, this, store);
break; break;
default: default:
break; break;
} }
@ -316,8 +324,8 @@ public class Spline implements Savable {
*/ */
public void setCurveTension(float curveTension) { public void setCurveTension(float curveTension) {
this.curveTension = curveTension; this.curveTension = curveTension;
if(type==SplineType.CatmullRom && !getControlPoints().isEmpty()) { if (type == SplineType.CatmullRom && !getControlPoints().isEmpty()) {
this.computeTotalLength(); this.computeTotalLength();
} }
} }
@ -330,23 +338,24 @@ public class Spline implements Savable {
/** /**
* set to true to make the spline cycle * set to true to make the spline cycle
*
* @param cycle * @param cycle
*/ */
public void setCycle(boolean cycle) { public void setCycle(boolean cycle) {
if(type!=SplineType.Nurb) { if (type != SplineType.Nurb) {
if (controlPoints.size() >= 2) { if (controlPoints.size() >= 2) {
if (this.cycle && !cycle) { if (this.cycle && !cycle) {
controlPoints.remove(controlPoints.size() - 1); controlPoints.remove(controlPoints.size() - 1);
} }
if (!this.cycle && cycle) { if (!this.cycle && cycle) {
controlPoints.add(controlPoints.get(0)); controlPoints.add(controlPoints.get(0));
} }
this.cycle = cycle; this.cycle = cycle;
this.computeTotalLength(); this.computeTotalLength();
} else { } else {
this.cycle = cycle; this.cycle = cycle;
} }
} }
} }
/** /**
@ -365,6 +374,7 @@ public class Spline implements Savable {
/** /**
* Sets the type of the spline * Sets the type of the spline
*
* @param type * @param type
*/ */
public void setType(SplineType type) { public void setType(SplineType type) {
@ -385,57 +395,63 @@ public class Spline implements Savable {
public List<Float> getSegmentsLength() { public List<Float> getSegmentsLength() {
return segmentsLength; return segmentsLength;
} }
//////////// NURBS getters ///////////////////// //////////// NURBS getters /////////////////////
/**
/** * This method returns the minimum nurb curve knot value. Check the nurb
* This method returns the minimum nurb curve knot value. Check the nurb type before calling this method. It the curve is not of a Nurb * type before calling this method. It the curve is not of a Nurb type - NPE
* type - NPE will be thrown. * will be thrown.
* @return the minimum nurb curve knot value *
*/ * @return the minimum nurb curve knot value
*/
public float getMinNurbKnot() { public float getMinNurbKnot() {
return knots.get(basisFunctionDegree - 1); return knots.get(basisFunctionDegree - 1);
} }
/** /**
* This method returns the maximum nurb curve knot value. Check the nurb type before calling this method. It the curve is not of a Nurb * This method returns the maximum nurb curve knot value. Check the nurb
* type - NPE will be thrown. * type before calling this method. It the curve is not of a Nurb type - NPE
* @return the maximum nurb curve knot value * will be thrown.
*/ *
* @return the maximum nurb curve knot value
*/
public float getMaxNurbKnot() { public float getMaxNurbKnot() {
return knots.get(weights.length); return knots.get(weights.length);
} }
/** /**
* This method returns NURBS' spline knots. * This method returns NURBS' spline knots.
*
* @return NURBS' spline knots * @return NURBS' spline knots
*/ */
public List<Float> getKnots() { public List<Float> getKnots() {
return knots; return knots;
} }
/** /**
* This method returns NURBS' spline weights. * This method returns NURBS' spline weights.
*
* @return NURBS' spline weights * @return NURBS' spline weights
*/ */
public float[] getWeights() { public float[] getWeights() {
return weights; return weights;
} }
/** /**
* This method returns NURBS' spline basis function degree. * This method returns NURBS' spline basis function degree.
*
* @return NURBS' spline basis function degree * @return NURBS' spline basis function degree
*/ */
public int getBasisFunctionDegree() { public int getBasisFunctionDegree() {
return basisFunctionDegree; return basisFunctionDegree;
} }
@Override @Override
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = ex.getCapsule(this); OutputCapsule oc = ex.getCapsule(this);
oc.writeSavableArrayList((ArrayList) controlPoints, "controlPoints", null); oc.writeSavableArrayList((ArrayList) controlPoints, "controlPoints", null);
oc.write(type, "type", SplineType.CatmullRom); oc.write(type, "type", SplineType.CatmullRom);
float list[] = null; float list[] = null;
if (segmentsLength != null) { if (segmentsLength != null) {
list = new float[segmentsLength.size()]; list = new float[segmentsLength.size()];
@ -449,7 +465,7 @@ public class Spline implements Savable {
oc.writeSavableArrayList((ArrayList) CRcontrolPoints, "CRControlPoints", null); oc.writeSavableArrayList((ArrayList) CRcontrolPoints, "CRControlPoints", null);
oc.write(curveTension, "curveTension", 0.5f); oc.write(curveTension, "curveTension", 0.5f);
oc.write(cycle, "cycle", false); oc.write(cycle, "cycle", false);
oc.writeSavableArrayList((ArrayList<Float>)knots, "knots", null); oc.writeSavableArrayList((ArrayList<Float>) knots, "knots", null);
oc.write(weights, "weights", null); oc.write(weights, "weights", null);
oc.write(basisFunctionDegree, "basisFunctionDegree", 0); oc.write(basisFunctionDegree, "basisFunctionDegree", 0);
} }
@ -458,7 +474,8 @@ public class Spline implements Savable {
public void read(JmeImporter im) throws IOException { public void read(JmeImporter im) throws IOException {
InputCapsule in = im.getCapsule(this); InputCapsule in = im.getCapsule(this);
controlPoints = in.readSavableArrayList("controlPoints", new ArrayList<>()); /* Empty List as default, prevents null pointers */ controlPoints = in.readSavableArrayList("controlPoints", new ArrayList<>());
/* Empty List as default, prevents null pointers */
float list[] = in.readFloatArray("segmentsLength", null); float list[] = in.readFloatArray("segmentsLength", null);
if (list != null) { if (list != null) {
segmentsLength = new ArrayList<Float>(); segmentsLength = new ArrayList<Float>();

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2018 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -39,7 +39,7 @@ import java.io.IOException;
/** /**
* Started Date: Jul 16, 2004<br><br> * Started Date: Jul 16, 2004<br><br>
* Represents a translation, rotation and scale in one object. * Represents a translation, rotation and scale in one object.
* *
* @author Jack Lindamood * @author Jack Lindamood
* @author Joshua Slack * @author Joshua Slack
*/ */
@ -53,30 +53,31 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
private Vector3f translation = new Vector3f(); private Vector3f translation = new Vector3f();
private Vector3f scale = new Vector3f(1, 1, 1); private Vector3f scale = new Vector3f(1, 1, 1);
public Transform(Vector3f translation, Quaternion rot){ public Transform(Vector3f translation, Quaternion rot) {
this.translation.set(translation); this.translation.set(translation);
this.rot.set(rot); this.rot.set(rot);
} }
public Transform(Vector3f translation, Quaternion rot, Vector3f scale){ public Transform(Vector3f translation, Quaternion rot, Vector3f scale) {
this(translation, rot); this(translation, rot);
this.scale.set(scale); this.scale.set(scale);
} }
public Transform(Vector3f translation){ public Transform(Vector3f translation) {
this(translation, Quaternion.IDENTITY); this(translation, Quaternion.IDENTITY);
} }
public Transform(Quaternion rot){ public Transform(Quaternion rot) {
this(Vector3f.ZERO, rot); this(Vector3f.ZERO, rot);
} }
public Transform(){ public Transform() {
this(Vector3f.ZERO, Quaternion.IDENTITY); this(Vector3f.ZERO, Quaternion.IDENTITY);
} }
/** /**
* Sets this rotation to the given Quaternion value. * Sets this rotation to the given Quaternion value.
*
* @param rot The new rotation for this matrix. * @param rot The new rotation for this matrix.
* @return this * @return this
*/ */
@ -87,6 +88,7 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
/** /**
* Sets this translation to the given value. * Sets this translation to the given value.
*
* @param trans The new translation for this matrix. * @param trans The new translation for this matrix.
* @return this * @return this
*/ */
@ -97,6 +99,7 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
/** /**
* Return the translation vector in this matrix. * Return the translation vector in this matrix.
*
* @return translation vector. * @return translation vector.
*/ */
public Vector3f getTranslation() { public Vector3f getTranslation() {
@ -105,6 +108,7 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
/** /**
* Sets this scale to the given value. * Sets this scale to the given value.
*
* @param scale The new scale for this matrix. * @param scale The new scale for this matrix.
* @return this * @return this
*/ */
@ -115,6 +119,7 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
/** /**
* Sets this scale to the given value. * Sets this scale to the given value.
*
* @param scale The new scale for this matrix. * @param scale The new scale for this matrix.
* @return this * @return this
*/ */
@ -125,6 +130,7 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
/** /**
* Return the scale vector in this matrix. * Return the scale vector in this matrix.
*
* @return scale vector. * @return scale vector.
*/ */
public Vector3f getScale() { public Vector3f getScale() {
@ -132,64 +138,82 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
} }
/** /**
* Stores this translation value into the given vector3f. If trans is null, a new vector3f is created to * Stores this translation value into the given vector3f. If trans is null,
* hold the value. The value, once stored, is returned. * a new vector3f is created to hold the value. The value, once stored, is
* returned.
*
* @param trans The store location for this matrix's translation. * @param trans The store location for this matrix's translation.
* @return The value of this matrix's translation. * @return The value of this matrix's translation.
*/ */
public Vector3f getTranslation(Vector3f trans) { public Vector3f getTranslation(Vector3f trans) {
if (trans==null) trans=new Vector3f(); if (trans == null) {
trans = new Vector3f();
}
trans.set(this.translation); trans.set(this.translation);
return trans; return trans;
} }
/** /**
* Stores this rotation value into the given Quaternion. If quat is null, a new Quaternion is created to * Stores this rotation value into the given Quaternion. If quat is null, a
* hold the value. The value, once stored, is returned. * new Quaternion is created to hold the value. The value, once stored, is
* returned.
*
* @param quat The store location for this matrix's rotation. * @param quat The store location for this matrix's rotation.
* @return The value of this matrix's rotation. * @return The value of this matrix's rotation.
*/ */
public Quaternion getRotation(Quaternion quat) { public Quaternion getRotation(Quaternion quat) {
if (quat==null) quat=new Quaternion(); if (quat == null) {
quat = new Quaternion();
}
quat.set(rot); quat.set(rot);
return quat; return quat;
} }
/** /**
* Return the rotation quaternion in this matrix. * Return the rotation quaternion in this matrix.
*
* @return rotation quaternion. * @return rotation quaternion.
*/ */
public Quaternion getRotation() { public Quaternion getRotation() {
return rot; return rot;
} }
/** /**
* Stores this scale value into the given vector3f. If scale is null, a new vector3f is created to * Stores this scale value into the given vector3f. If scale is null, a new
* hold the value. The value, once stored, is returned. * vector3f is created to hold the value. The value, once stored, is
* returned.
*
* @param scale The store location for this matrix's scale. * @param scale The store location for this matrix's scale.
* @return The value of this matrix's scale. * @return The value of this matrix's scale.
*/ */
public Vector3f getScale(Vector3f scale) { public Vector3f getScale(Vector3f scale) {
if (scale==null) scale=new Vector3f(); if (scale == null) {
scale = new Vector3f();
}
scale.set(this.scale); scale.set(this.scale);
return scale; return scale;
} }
/** /**
* Sets this transform to the interpolation between the first transform and the second by delta amount. * Sets this transform to the interpolation between the first transform and
* the second by delta amount.
*
* @param t1 The beginning transform. * @param t1 The beginning transform.
* @param t2 The ending transform. * @param t2 The ending transform.
* @param delta An amount between 0 and 1 representing how far to interpolate from t1 to t2. * @param delta An amount between 0 and 1 representing how far to
* interpolate from t1 to t2.
*/ */
public void interpolateTransforms(Transform t1, Transform t2, float delta) { public void interpolateTransforms(Transform t1, Transform t2, float delta) {
t1.rot.nlerp(t2.rot, delta); t1.rot.nlerp(t2.rot, delta);
this.rot.set(t1.rot); this.rot.set(t1.rot);
this.translation.interpolateLocal(t1.translation,t2.translation,delta); this.translation.interpolateLocal(t1.translation, t2.translation, delta);
this.scale.interpolateLocal(t1.scale,t2.scale,delta); this.scale.interpolateLocal(t1.scale, t2.scale, delta);
} }
/** /**
* Changes the values of this matrix according to its parent. Very similar to the concept of Node/Spatial transforms. * Changes the values of this matrix according to its parent. Very similar
* to the concept of Node/Spatial transforms.
*
* @param parent The parent matrix. * @param parent The parent matrix.
* @return This matrix, after combining. * @return This matrix, after combining.
*/ */
@ -202,56 +226,58 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
translation.multLocal(parent.scale); translation.multLocal(parent.scale);
//applying parent rotation to local translation, then applying parent translation to local translation. //applying parent rotation to local translation, then applying parent translation to local translation.
//Note that parent.rot.multLocal(translation) doesn't modify "parent.rot" but "translation" //Note that parent.rot.multLocal(translation) doesn't modify "parent.rot" but "translation"
parent parent.rot
.rot .multLocal(translation)
.multLocal(translation) .addLocal(parent.translation);
.addLocal(parent.translation);
return this; return this;
} }
/** /**
* Sets this matrix's translation to the given x,y,z values. * Sets this matrix's translation to the given x,y,z values.
*
* @param x This matrix's new x translation. * @param x This matrix's new x translation.
* @param y This matrix's new y translation. * @param y This matrix's new y translation.
* @param z This matrix's new z translation. * @param z This matrix's new z translation.
* @return this * @return this
*/ */
public Transform setTranslation(float x,float y, float z) { public Transform setTranslation(float x, float y, float z) {
translation.set(x,y,z); translation.set(x, y, z);
return this; return this;
} }
/** /**
* Sets this matrix's scale to the given x,y,z values. * Sets this matrix's scale to the given x,y,z values.
*
* @param x This matrix's new x scale. * @param x This matrix's new x scale.
* @param y This matrix's new y scale. * @param y This matrix's new y scale.
* @param z This matrix's new z scale. * @param z This matrix's new z scale.
* @return this * @return this
*/ */
public Transform setScale(float x, float y, float z) { public Transform setScale(float x, float y, float z) {
scale.set(x,y,z); scale.set(x, y, z);
return this; return this;
} }
public Vector3f transformVector(final Vector3f in, Vector3f store){ public Vector3f transformVector(final Vector3f in, Vector3f store) {
if (store == null) if (store == null) {
store = new Vector3f(); store = new Vector3f();
}
// multiply with scale first, then rotate, finally translate (cf. // multiply with scale first, then rotate, finally translate (cf.
// Eberly) // Eberly)
return rot.mult(store.set(in).multLocal(scale), store).addLocal(translation); return rot.mult(store.set(in).multLocal(scale), store).addLocal(translation);
} }
public Vector3f transformInverseVector(final Vector3f in, Vector3f store){ public Vector3f transformInverseVector(final Vector3f in, Vector3f store) {
if (store == null) if (store == null) {
store = new Vector3f(); store = new Vector3f();
}
// The author of this code should look above and take the inverse of that // The author of this code should look above and take the inverse of that
// But for some reason, they didn't .. // But for some reason, they didn't ..
// in.subtract(translation, store).divideLocal(scale); // in.subtract(translation, store).divideLocal(scale);
// rot.inverse().mult(store, store); // rot.inverse().mult(store, store);
in.subtract(translation, store); in.subtract(translation, store);
rot.inverse().mult(store, store); rot.inverse().mult(store, store);
store.divideLocal(scale); store.divideLocal(scale);
@ -272,7 +298,7 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
store.setScale(scale); store.setScale(scale);
return store; return store;
} }
public void fromTransformMatrix(Matrix4f mat) { public void fromTransformMatrix(Matrix4f mat) {
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
translation.set(mat.toTranslationVector(vars.vect1)); translation.set(mat.toTranslationVector(vars.vect1));
@ -280,13 +306,13 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
scale.set(mat.toScaleVector(vars.vect2)); scale.set(mat.toScaleVector(vars.vect2));
vars.release(); vars.release();
} }
public Transform invert() { public Transform invert() {
Transform t = new Transform(); Transform t = new Transform();
t.fromTransformMatrix(toTransformMatrix().invertLocal()); t.fromTransformMatrix(toTransformMatrix().invertLocal());
return t; return t;
} }
/** /**
* Loads the identity. Equal to translation=0,0,0 scale=1,1,1 rot=0,0,0,1. * Loads the identity. Equal to translation=0,0,0 scale=1,1,1 rot=0,0,0,1.
*/ */
@ -331,14 +357,16 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
} }
@Override @Override
public String toString(){ public String toString() {
return getClass().getSimpleName() + "[ " + translation.x + ", " + translation.y + ", " + translation.z + "]\n" return getClass().getSimpleName()
+ "[ " + rot.x + ", " + rot.y + ", " + rot.z + ", " + rot.w + "]\n" + "[ " + translation.x + ", " + translation.y + ", " + translation.z + "]\n"
+ "[ " + scale.x + " , " + scale.y + ", " + scale.z + "]"; + "[ " + rot.x + ", " + rot.y + ", " + rot.z + ", " + rot.w + "]\n"
+ "[ " + scale.x + " , " + scale.y + ", " + scale.z + "]";
} }
/** /**
* Sets this matrix to be equal to the given matrix. * Sets this matrix to be equal to the given matrix.
*
* @param matrixQuat The matrix to be equal to. * @param matrixQuat The matrix to be equal to.
* @return this * @return this
*/ */
@ -360,12 +388,12 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
@Override @Override
public void read(JmeImporter e) throws IOException { public void read(JmeImporter e) throws IOException {
InputCapsule capsule = e.getCapsule(this); InputCapsule capsule = e.getCapsule(this);
rot.set((Quaternion)capsule.readSavable("rot", Quaternion.IDENTITY)); rot.set((Quaternion) capsule.readSavable("rot", Quaternion.IDENTITY));
translation.set((Vector3f)capsule.readSavable("translation", Vector3f.ZERO)); translation.set((Vector3f) capsule.readSavable("translation", Vector3f.ZERO));
scale.set((Vector3f)capsule.readSavable("scale", Vector3f.UNIT_XYZ)); scale.set((Vector3f) capsule.readSavable("scale", Vector3f.UNIT_XYZ));
} }
@Override @Override
public Transform clone() { public Transform clone() {
try { try {

@ -29,7 +29,6 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package com.jme3.math; package com.jme3.math;
import com.jme3.export.*; import com.jme3.export.*;
@ -52,7 +51,6 @@ import java.util.logging.Logger;
public final class Vector3f implements Savable, Cloneable, java.io.Serializable { public final class Vector3f implements Savable, Cloneable, java.io.Serializable {
static final long serialVersionUID = 1; static final long serialVersionUID = 1;
private static final Logger logger = Logger.getLogger(Vector3f.class.getName()); private static final Logger logger = Logger.getLogger(Vector3f.class.getName());
public final static Vector3f ZERO = new Vector3f(0, 0, 0); public final static Vector3f ZERO = new Vector3f(0, 0, 0);
@ -69,18 +67,14 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY,
Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY,
Float.NEGATIVE_INFINITY); Float.NEGATIVE_INFINITY);
/** /**
* the x value of the vector. * the x value of the vector.
*/ */
public float x; public float x;
/** /**
* the y value of the vector. * the y value of the vector.
*/ */
public float y; public float y;
/** /**
* the z value of the vector. * the z value of the vector.
*/ */
@ -156,7 +150,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>add</code> adds a provided vector to this vector creating a * <code>add</code> adds a provided vector to this vector creating a
* resultant vector which is returned. If the provided vector is null, null * resultant vector which is returned. If the provided vector is null, null
* is returned. * is returned.
@ -174,7 +167,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>add</code> adds the values of a provided vector storing the * <code>add</code> adds the values of a provided vector storing the
* values in the supplied vector. * values in the supplied vector.
* *
@ -212,7 +204,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>add</code> adds the provided values to this vector, creating a * <code>add</code> adds the provided values to this vector, creating a
* new vector that is then returned. * new vector that is then returned.
* *
@ -249,7 +240,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>scaleAdd</code> multiplies this vector by a scalar then adds the * <code>scaleAdd</code> multiplies this vector by a scalar then adds the
* given Vector3f. * given Vector3f.
* *
@ -266,7 +256,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>scaleAdd</code> multiplies the given vector by a scalar then adds * <code>scaleAdd</code> multiplies the given vector by a scalar then adds
* the given vector. * the given vector.
* *
@ -285,7 +274,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>dot</code> calculates the dot product of this vector with a * <code>dot</code> calculates the dot product of this vector with a
* provided vector. If the provided vector is null, 0 is returned. * provided vector. If the provided vector is null, 0 is returned.
* *
@ -323,7 +311,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* the vector to store the cross product result. * the vector to store the cross product result.
* @return result, after receiving the cross product vector. * @return result, after receiving the cross product vector.
*/ */
public Vector3f cross(Vector3f v,Vector3f result) { public Vector3f cross(Vector3f v, Vector3f result) {
return cross(v.x, v.y, v.z, result); return cross(v.x, v.y, v.z, result);
} }
@ -342,8 +330,10 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return result, after receiving the cross product vector. * @return result, after receiving the cross product vector.
*/ */
public Vector3f cross(float otherX, float otherY, float otherZ, Vector3f result) { public Vector3f cross(float otherX, float otherY, float otherZ, Vector3f result) {
if (result == null) result = new Vector3f(); if (result == null) {
float resX = ((y * otherZ) - (z * otherY)); result = new Vector3f();
}
float resX = ((y * otherZ) - (z * otherY));
float resY = ((z * otherX) - (x * otherZ)); float resY = ((z * otherX) - (x * otherZ));
float resZ = ((x * otherY) - (y * otherX)); float resZ = ((x * otherY) - (y * otherX));
result.set(resX, resY, resZ); result.set(resX, resY, resZ);
@ -375,8 +365,8 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return this. * @return this.
*/ */
public Vector3f crossLocal(float otherX, float otherY, float otherZ) { public Vector3f crossLocal(float otherX, float otherY, float otherZ) {
float tempx = ( y * otherZ ) - ( z * otherY ); float tempx = (y * otherZ) - (z * otherY);
float tempy = ( z * otherX ) - ( x * otherZ ); float tempy = (z * otherX) - (x * otherZ);
z = (x * otherY) - (y * otherX); z = (x * otherY) - (y * otherX);
x = tempx; x = tempx;
y = tempy; y = tempy;
@ -389,10 +379,10 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @param other The vector to project this vector onto * @param other The vector to project this vector onto
* @return A new vector with the projection result * @return A new vector with the projection result
*/ */
public Vector3f project(Vector3f other){ public Vector3f project(Vector3f other) {
float n = this.dot(other); // A . B float n = this.dot(other); // A . B
float d = other.lengthSquared(); // |B|^2 float d = other.lengthSquared(); // |B|^2
return new Vector3f(other).multLocal(n/d); return new Vector3f(other).multLocal(n / d);
} }
/** /**
@ -402,20 +392,20 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @param other The vector to project this vector onto * @param other The vector to project this vector onto
* @return This Vector3f, set to the projection result * @return This Vector3f, set to the projection result
*/ */
public Vector3f projectLocal(Vector3f other){ public Vector3f projectLocal(Vector3f other) {
float n = this.dot(other); // A . B float n = this.dot(other); // A . B
float d = other.lengthSquared(); // |B|^2 float d = other.lengthSquared(); // |B|^2
return set(other).multLocal(n/d); return set(other).multLocal(n / d);
} }
/** /**
* Returns true if this vector is a unit vector (length() ~= 1), * Returns true if this vector is a unit vector (length() ~= 1),
* returns false otherwise. * returns false otherwise.
* *
* @return true if this vector is a unit vector (length() ~= 1), * @return true if this vector is a unit vector (length() ~= 1),
* or false otherwise. * or false otherwise.
*/ */
public boolean isUnitVector(){ public boolean isUnitVector() {
float len = length(); float len = length();
return 0.99f < len && len < 1.01f; return 0.99f < len && len < 1.01f;
} }
@ -465,7 +455,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>mult</code> multiplies this vector by a scalar. The resultant * <code>mult</code> multiplies this vector by a scalar. The resultant
* vector is returned. * vector is returned.
* *
@ -478,7 +467,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>mult</code> multiplies this vector by a scalar. The resultant * <code>mult</code> multiplies this vector by a scalar. The resultant
* vector is supplied as the second parameter and returned. * vector is supplied as the second parameter and returned.
* *
@ -581,11 +569,12 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
logger.warning("Provided vector is null, null returned."); logger.warning("Provided vector is null, null returned.");
return null; return null;
} }
if (store == null) store = new Vector3f(); if (store == null) {
store = new Vector3f();
}
return store.set(x * vec.x, y * vec.y, z * vec.z); 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 * <code>divide</code> divides the values of this vector by a scalar and
* returns the result. The values of this vector remain untouched. * returns the result. The values of this vector remain untouched.
@ -595,7 +584,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return the result <code>Vector</code>. * @return the result <code>Vector</code>.
*/ */
public Vector3f divide(float scalar) { public Vector3f divide(float scalar) {
scalar = 1f/scalar; scalar = 1f / scalar;
return new Vector3f(x * scalar, y * scalar, z * scalar); return new Vector3f(x * scalar, y * scalar, z * scalar);
} }
@ -609,14 +598,13 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return this * @return this
*/ */
public Vector3f divideLocal(float scalar) { public Vector3f divideLocal(float scalar) {
scalar = 1f/scalar; scalar = 1f / scalar;
x *= scalar; x *= scalar;
y *= scalar; y *= scalar;
z *= scalar; z *= scalar;
return this; return this;
} }
/** /**
* <code>divide</code> divides the values of this vector by a scalar and * <code>divide</code> divides the values of this vector by a scalar and
* returns the result. The values of this vector remain untouched. * returns the result. The values of this vector remain untouched.
@ -646,7 +634,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>negate</code> returns the negative of this vector. All values are * <code>negate</code> returns the negative of this vector. All values are
* negated and set to a new vector. * negated and set to a new vector.
* *
@ -657,7 +644,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>negateLocal</code> negates the internal values of this vector. * <code>negateLocal</code> negates the internal values of this vector.
* *
* @return this. * @return this.
@ -670,7 +656,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>subtract</code> subtracts the values of a given vector from those * <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 * of this vector creating a new vector object. If the provided vector is
* null, null is returned. * null, null is returned.
@ -704,7 +689,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>subtract</code> * <code>subtract</code>
* *
* @param vec * @param vec
@ -714,7 +698,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return result * @return result
*/ */
public Vector3f subtract(Vector3f vec, Vector3f result) { public Vector3f subtract(Vector3f vec, Vector3f result) {
if(result == null) { if (result == null) {
result = new Vector3f(); result = new Vector3f();
} }
result.x = x - vec.x; result.x = x - vec.x;
@ -724,7 +708,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
*
* <code>subtract</code> subtracts the provided values from this vector, * <code>subtract</code> subtracts the provided values from this vector,
* creating a new vector that is then returned. * creating a new vector that is then returned.
* *
@ -773,7 +756,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
// //
// return divide(1); // return divide(1);
float length = x * x + y * y + z * z; float length = x * x + y * y + z * z;
if (length != 1f && length != 0f){ if (length != 1f && length != 0f) {
length = 1.0f / FastMath.sqrt(length); length = 1.0f / FastMath.sqrt(length);
return new Vector3f(x * length, y * length, z * length); return new Vector3f(x * length, y * length, z * length);
} }
@ -791,7 +774,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
// than the old jme normalize as this method // than the old jme normalize as this method
// is commonly used. // is commonly used.
float length = x * x + y * y + z * z; float length = x * x + y * y + z * z;
if (length != 1f && length != 0f){ if (length != 1f && length != 0f) {
length = 1.0f / FastMath.sqrt(length); length = 1.0f / FastMath.sqrt(length);
x *= length; x *= length;
y *= length; y *= length;
@ -801,12 +784,13 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
/** /**
* <code>maxLocal</code> computes the maximum value for each * <code>maxLocal</code> computes the maximum value for each
* component in this and <code>other</code> vector. The result is stored * component in this and <code>other</code> vector. The result is stored
* in this vector. * in this vector.
* @param other *
* @param other
*/ */
public Vector3f maxLocal(Vector3f other){ public Vector3f maxLocal(Vector3f other) {
x = other.x > x ? other.x : x; x = other.x > x ? other.x : x;
y = other.y > y ? other.y : y; y = other.y > y ? other.y : y;
z = other.z > z ? other.z : z; z = other.z > z ? other.z : z;
@ -817,9 +801,10 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* <code>minLocal</code> computes the minimum value for each * <code>minLocal</code> computes the minimum value for each
* component in this and <code>other</code> vector. The result is stored * component in this and <code>other</code> vector. The result is stored
* in this vector. * in this vector.
*
* @param other * @param other
*/ */
public Vector3f minLocal(Vector3f other){ public Vector3f minLocal(Vector3f other) {
x = other.x < x ? other.x : x; x = other.x < x ? other.x : x;
y = other.y < y ? other.y : y; y = other.y < y ? other.y : y;
z = other.z < z ? other.z : z; z = other.z < z ? other.z : z;
@ -837,7 +822,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
/** /**
* <code>angleBetween</code> returns (in radians) the angle between two vectors. * <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). * 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 * @param otherVector a unit vector to find the angle against
* @return the angle in radians. * @return the angle in radians.
*/ */
@ -846,51 +831,60 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
float angle = FastMath.acos(dotProduct); float angle = FastMath.acos(dotProduct);
return angle; return angle;
} }
/** /**
* Sets this vector to the interpolation by changeAmnt from this to the finalVec * Sets this vector to the interpolation by changeAmnt from this to the finalVec
* this=(1-changeAmnt)*this + changeAmnt * finalVec * this=(1-changeAmnt)*this + changeAmnt * finalVec
*
* @param finalVec The final vector to interpolate towards * @param finalVec The final vector to interpolate towards
* @param changeAmnt An amount between 0.0 - 1.0 representing a percentage * @param changeAmnt An amount between 0.0 - 1.0 representing a percentage
* change from this towards finalVec * change from this towards finalVec
*/ */
public Vector3f interpolateLocal(Vector3f finalVec, float changeAmnt) { public Vector3f interpolateLocal(Vector3f finalVec, float changeAmnt) {
this.x=(1-changeAmnt)*this.x + changeAmnt*finalVec.x; this.x = (1 - changeAmnt) * this.x + changeAmnt * finalVec.x;
this.y=(1-changeAmnt)*this.y + changeAmnt*finalVec.y; this.y = (1 - changeAmnt) * this.y + changeAmnt * finalVec.y;
this.z=(1-changeAmnt)*this.z + changeAmnt*finalVec.z; this.z = (1 - changeAmnt) * this.z + changeAmnt * finalVec.z;
return this; return this;
} }
/** /**
* Sets this vector to the interpolation by changeAmnt from beginVec to finalVec * Sets this vector to the interpolation by changeAmnt from beginVec to finalVec
* this=(1-changeAmnt)*beginVec + changeAmnt * finalVec * this=(1-changeAmnt)*beginVec + changeAmnt * finalVec
*
* @param beginVec the beginning vector (changeAmnt=0) * @param beginVec the beginning vector (changeAmnt=0)
* @param finalVec The final vector to interpolate towards * @param finalVec The final vector to interpolate towards
* @param changeAmnt An amount between 0.0 - 1.0 representing a percentage * @param changeAmnt An amount between 0.0 - 1.0 representing a percentage
* change from beginVec towards finalVec * change from beginVec towards finalVec
*/ */
public Vector3f interpolateLocal(Vector3f beginVec,Vector3f finalVec, float changeAmnt) { public Vector3f interpolateLocal(Vector3f beginVec, Vector3f finalVec, float changeAmnt) {
this.x=(1-changeAmnt)*beginVec.x + changeAmnt*finalVec.x; this.x = (1 - changeAmnt) * beginVec.x + changeAmnt * finalVec.x;
this.y=(1-changeAmnt)*beginVec.y + changeAmnt*finalVec.y; this.y = (1 - changeAmnt) * beginVec.y + changeAmnt * finalVec.y;
this.z=(1-changeAmnt)*beginVec.z + changeAmnt*finalVec.z; this.z = (1 - changeAmnt) * beginVec.z + changeAmnt * finalVec.z;
return this; return this;
} }
/** /**
* Check a vector... if it is null or its floats are NaN or infinite, * Check a vector... if it is null or its floats are NaN or infinite,
* return false. Else return true. * return false. Else return true.
*
* @param vector the vector to check * @param vector the vector to check
* @return true or false as stated above. * @return true or false as stated above.
*/ */
public static boolean isValidVector(Vector3f vector) { public static boolean isValidVector(Vector3f vector) {
if (vector == null) return false; if (vector == null) {
if (Float.isNaN(vector.x) || return false;
Float.isNaN(vector.y) || }
Float.isNaN(vector.z)) return false; if (Float.isNaN(vector.x)
if (Float.isInfinite(vector.x) || || Float.isNaN(vector.y)
Float.isInfinite(vector.y) || || Float.isNaN(vector.z)) {
Float.isInfinite(vector.z)) return false; return false;
return true; }
if (Float.isInfinite(vector.x)
|| Float.isInfinite(vector.y)
|| Float.isInfinite(vector.z)) {
return false;
}
return true;
} }
public static void generateOrthonormalBasis(Vector3f u, Vector3f v, Vector3f w) { public static void generateOrthonormalBasis(Vector3f u, Vector3f v, Vector3f w) {
@ -934,7 +928,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
/** /**
* Saves this Vector3f into the given float[] object. * Saves this Vector3f into the given float[] object.
* *
* @param floats * @param floats
* The float[] to take this Vector3f. If null, a new float[3] is * The float[] to take this Vector3f. If null, a new float[3] is
* created. * created.
@ -959,17 +953,27 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return true if they are equal * @return true if they are equal
*/ */
public boolean equals(Object o) { public boolean equals(Object o) {
if (!(o instanceof Vector3f)) { return false; } if (!(o instanceof Vector3f)) {
return false;
}
if (this == o) { return true; } if (this == o) {
return true;
}
Vector3f comp = (Vector3f) o; Vector3f comp = (Vector3f) o;
if (Float.compare(x,comp.x) != 0) return false; if (Float.compare(x, comp.x) != 0) {
if (Float.compare(y,comp.y) != 0) return false; return false;
if (Float.compare(z,comp.z) != 0) return false; }
if (Float.compare(y, comp.y) != 0) {
return false;
}
if (Float.compare(z, comp.z) != 0) {
return false;
}
return true; return true;
} }
/** /**
* Returns true if this vector is similar to the specified vector within * Returns true if this vector is similar to the specified vector within
* some value of epsilon. * some value of epsilon.
@ -994,6 +998,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* <code>hashCode</code> returns a unique code for this vector object based * <code>hashCode</code> returns a unique code for this vector object based
* on its values. If two vectors are logically equivalent, they will return * on its values. If two vectors are logically equivalent, they will return
* the same hash code value. * the same hash code value.
*
* @return the hash code value of this vector. * @return the hash code value of this vector.
*/ */
public int hashCode() { public int hashCode() {
@ -1056,7 +1061,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
this.z = z; this.z = z;
return this; return this;
} }
/** /**
* @param index * @param index
* @return x value if index == 0, y value if index == 1 or z value if index == * @return x value if index == 0, y value if index == 1 or z value if index ==
@ -1075,7 +1080,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
throw new IllegalArgumentException("index must be either 0, 1 or 2"); throw new IllegalArgumentException("index must be either 0, 1 or 2");
} }
/** /**
* @param index * @param index
* which field index in this vector to set. * which field index in this vector to set.
@ -1098,5 +1103,4 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
} }
throw new IllegalArgumentException("index must be either 0, 1 or 2"); throw new IllegalArgumentException("index must be either 0, 1 or 2");
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2012 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -49,7 +49,7 @@ import java.nio.Buffer;
* <li>{@link Mode#TriangleStrip}: 0, 1, 2 | 2, 1, 3 | 2, 3, 4 | ...</li> * <li>{@link Mode#TriangleStrip}: 0, 1, 2 | 2, 1, 3 | 2, 3, 4 | ...</li>
* <li>{@link Mode#TriangleFan}: 0, 1, 2 | 0, 2, 3 | 0, 3, 4 | ...</li> * <li>{@link Mode#TriangleFan}: 0, 1, 2 | 0, 2, 3 | 0, 3, 4 | ...</li>
* </ul> * </ul>
* *
* @author Kirill Vainer * @author Kirill Vainer
*/ */
public class VirtualIndexBuffer extends IndexBuffer { public class VirtualIndexBuffer extends IndexBuffer {
@ -58,8 +58,8 @@ public class VirtualIndexBuffer extends IndexBuffer {
protected int numIndices = 0; protected int numIndices = 0;
protected Mode meshMode; protected Mode meshMode;
protected int position = 0; protected int position = 0;
public VirtualIndexBuffer(int numVerts, Mode meshMode){ public VirtualIndexBuffer(int numVerts, Mode meshMode) {
this.numVerts = numVerts; this.numVerts = numVerts;
this.meshMode = meshMode; this.meshMode = meshMode;
switch (meshMode) { switch (meshMode) {
@ -108,33 +108,38 @@ public class VirtualIndexBuffer extends IndexBuffer {
@Override @Override
public int get(int i) { public int get(int i) {
if (meshMode == Mode.Triangles || meshMode == Mode.Lines || meshMode == Mode.Points){ if (meshMode == Mode.Triangles || meshMode == Mode.Lines || meshMode == Mode.Points) {
return i; return i;
}else if (meshMode == Mode.LineStrip){ } else if (meshMode == Mode.LineStrip) {
return (i + 1) / 2; return (i + 1) / 2;
}else if (meshMode == Mode.LineLoop){ } else if (meshMode == Mode.LineLoop) {
return (i == (numVerts-1)) ? 0 : ((i + 1) / 2); return (i == (numVerts - 1)) ? 0 : ((i + 1) / 2);
}else if (meshMode == Mode.TriangleStrip){ } else if (meshMode == Mode.TriangleStrip) {
int triIndex = i/3; int triIndex = i / 3;
int vertIndex = i%3; int vertIndex = i % 3;
boolean isBack = (i/3)%2==1; boolean isBack = (i / 3) % 2 == 1;
if (!isBack){ if (!isBack) {
return triIndex + vertIndex; return triIndex + vertIndex;
}else{ } else {
switch (vertIndex){ switch (vertIndex) {
case 0: return triIndex + 1; case 0:
case 1: return triIndex; return triIndex + 1;
case 2: return triIndex + 2; case 1:
default: throw new AssertionError(); return triIndex;
} case 2:
return triIndex + 2;
default:
throw new AssertionError();
}
} }
}else if (meshMode == Mode.TriangleFan){ } else if (meshMode == Mode.TriangleFan) {
int vertIndex = i%3; int vertIndex = i % 3;
if (vertIndex == 0) if (vertIndex == 0) {
return 0; return 0;
else } else {
return (i / 3) + vertIndex; return (i / 3) + vertIndex;
}else{ }
} else {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }
@ -154,15 +159,15 @@ public class VirtualIndexBuffer extends IndexBuffer {
return null; return null;
} }
@Override @Override
public IndexBuffer put (int value) { public IndexBuffer put(int value) {
throw new UnsupportedOperationException("Does not represent index buffer"); throw new UnsupportedOperationException("Does not represent index buffer");
} }
@Override @Override
public Format getFormat () { public Format getFormat() {
// return largest size // return largest size
return Format.UnsignedInt; return Format.UnsignedInt;
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2019 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -198,12 +198,12 @@ public class Curve extends Mesh {
* points * points
*/ */
private void createNurbMesh(int nbSubSegments) { private void createNurbMesh(int nbSubSegments) {
if(spline.getControlPoints() != null && spline.getControlPoints().size() > 0) { if (spline.getControlPoints() != null && spline.getControlPoints().size() > 0) {
if(nbSubSegments == 0) { if (nbSubSegments == 0) {
nbSubSegments = spline.getControlPoints().size() + 1; nbSubSegments = spline.getControlPoints().size() + 1;
} else { } else {
nbSubSegments = spline.getControlPoints().size() * nbSubSegments + 1; nbSubSegments = spline.getControlPoints().size() * nbSubSegments + 1;
} }
float minKnot = spline.getMinNurbKnot(); float minKnot = spline.getMinNurbKnot();
float maxKnot = spline.getMaxNurbKnot(); float maxKnot = spline.getMaxNurbKnot();
float deltaU = (maxKnot - minKnot) / nbSubSegments; float deltaU = (maxKnot - minKnot) / nbSubSegments;
@ -233,7 +233,7 @@ public class Curve extends Mesh {
this.setBuffer(VertexBuffer.Type.Index, 2, indices); this.setBuffer(VertexBuffer.Type.Index, 2, indices);
this.updateBound(); this.updateBound();
this.updateCounts(); this.updateCounts();
} }
} }
private void createLinearMesh() { private void createLinearMesh() {

@ -41,38 +41,38 @@ import java.util.ArrayList;
* <p> * <p>
* <code>FrameBuffer</code>s are rendering surfaces allowing * <code>FrameBuffer</code>s are rendering surfaces allowing
* off-screen rendering and render-to-texture functionality. * off-screen rendering and render-to-texture functionality.
* Instead of the scene rendering to the screen, it is rendered into the * Instead of the scene rendering to the screen, it is rendered into the
* FrameBuffer, the result can be either a texture or a buffer. * FrameBuffer, the result can be either a texture or a buffer.
* <p> * <p>
* A <code>FrameBuffer</code> supports two methods of rendering, * A <code>FrameBuffer</code> supports two methods of rendering,
* using a {@link Texture} or using a buffer. * using a {@link Texture} or using a buffer.
* When using a texture, the result of the rendering will be rendered * When using a texture, the result of the rendering will be rendered
* onto the texture, after which the texture can be placed on an object * onto the texture, after which the texture can be placed on an object
* and rendered as if the texture was uploaded from disk. * and rendered as if the texture was uploaded from disk.
* When using a buffer, the result is rendered onto * When using a buffer, the result is rendered onto
* a buffer located on the GPU, the data of this buffer is not accessible * a buffer located on the GPU, the data of this buffer is not accessible
* to the user. buffers are useful if one * to the user. buffers are useful if one
* wishes to retrieve only the color content of the scene, but still desires * wishes to retrieve only the color content of the scene, but still desires
* depth testing (which requires a depth buffer). * depth testing (which requires a depth buffer).
* Buffers can be copied to other framebuffers * Buffers can be copied to other framebuffers
* including the main screen, by using * including the main screen, by using
* {@link Renderer#copyFrameBuffer(com.jme3.texture.FrameBuffer, com.jme3.texture.FrameBuffer, boolean)}. * {@link Renderer#copyFrameBuffer(com.jme3.texture.FrameBuffer, com.jme3.texture.FrameBuffer, boolean)}.
* The content of a {@link RenderBuffer} can be retrieved by using * The content of a {@link RenderBuffer} can be retrieved by using
* {@link Renderer#readFrameBuffer(com.jme3.texture.FrameBuffer, java.nio.ByteBuffer) }. * {@link Renderer#readFrameBuffer(com.jme3.texture.FrameBuffer, java.nio.ByteBuffer) }.
* <p> * <p>
* <code>FrameBuffer</code>s have several attachment points, there are * <code>FrameBuffer</code>s have several attachment points, there are
* several <em>color</em> attachment points and a single <em>depth</em> * several <em>color</em> attachment points and a single <em>depth</em>
* attachment point. * attachment point.
* The color attachment points support image formats such as * The color attachment points support image formats such as
* {@link Format#RGBA8}, allowing rendering the color content of the scene. * {@link Format#RGBA8}, allowing rendering the color content of the scene.
* The depth attachment point requires a depth image format. * The depth attachment point requires a depth image format.
* *
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer) * @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
* *
* @author Kirill Vainer * @author Kirill Vainer
*/ */
public class FrameBuffer extends NativeObject { public class FrameBuffer extends NativeObject {
public static final int SLOT_UNDEF = -1; public static final int SLOT_UNDEF = -1;
public static final int SLOT_DEPTH = -100; public static final int SLOT_DEPTH = -100;
public static final int SLOT_DEPTH_STENCIL = -101; public static final int SLOT_DEPTH_STENCIL = -101;
@ -86,7 +86,7 @@ public class FrameBuffer extends NativeObject {
private boolean srgb; private boolean srgb;
/** /**
* <code>RenderBuffer</code> represents either a texture or a * <code>RenderBuffer</code> represents either a texture or a
* buffer that will be rendered to. <code>RenderBuffer</code>s * buffer that will be rendered to. <code>RenderBuffer</code>s
* are attached to an attachment slot on a <code>FrameBuffer</code>. * are attached to an attachment slot on a <code>FrameBuffer</code>.
*/ */
@ -98,7 +98,7 @@ public class FrameBuffer extends NativeObject {
int slot = SLOT_UNDEF; int slot = SLOT_UNDEF;
int face = -1; int face = -1;
int layer = -1; int layer = -1;
/** /**
* @return The image format of the render buffer. * @return The image format of the render buffer.
*/ */
@ -110,7 +110,7 @@ public class FrameBuffer extends NativeObject {
* @return The texture to render to for this <code>RenderBuffer</code> * @return The texture to render to for this <code>RenderBuffer</code>
* or null if content should be rendered into a buffer. * or null if content should be rendered into a buffer.
*/ */
public Texture getTexture(){ public Texture getTexture() {
return tex; return tex;
} }
@ -124,7 +124,7 @@ public class FrameBuffer extends NativeObject {
/** /**
* Do not use. * Do not use.
*/ */
public void setId(int id){ public void setId(int id) {
this.id = id; this.id = id;
} }
@ -134,30 +134,30 @@ public class FrameBuffer extends NativeObject {
public int getSlot() { public int getSlot() {
return slot; return slot;
} }
public int getFace() { public int getFace() {
return face; return face;
} }
public void resetObject(){ public void resetObject() {
id = -1; id = -1;
} }
public RenderBuffer createDestructableClone(){ public RenderBuffer createDestructableClone() {
if (tex != null){ if (tex != null) {
return null; return null;
}else{ } else {
RenderBuffer destructClone = new RenderBuffer(); RenderBuffer destructClone = new RenderBuffer();
destructClone.id = id; destructClone.id = id;
return destructClone; return destructClone;
} }
} }
@Override @Override
public String toString(){ public String toString() {
if (tex != null){ if (tex != null) {
return "TextureTarget[format=" + format + "]"; return "TextureTarget[format=" + format + "]";
}else{ } else {
return "BufferTarget[format=" + format + "]"; return "BufferTarget[format=" + format + "]";
} }
} }
@ -173,28 +173,29 @@ public class FrameBuffer extends NativeObject {
* of samples. If any textures are attached to this FrameBuffer, then * of samples. If any textures are attached to this FrameBuffer, then
* they must have the same number of samples as given in this constructor. * they must have the same number of samples as given in this constructor.
* <p> * <p>
* Note that if the {@link Renderer} does not expose the * Note that if the {@link Renderer} does not expose the
* {@link Caps#NonPowerOfTwoTextures}, then an exception will be thrown * {@link Caps#NonPowerOfTwoTextures}, then an exception will be thrown
* if the width and height arguments are not power of two. * if the width and height arguments are not power of two.
* *
* @param width The width to use * @param width The width to use
* @param height The height to use * @param height The height to use
* @param samples The number of samples to use for a multisampled * @param samples The number of samples to use for a multisampled
* framebuffer, or 1 if the framebuffer should be singlesampled. * framebuffer, or 1 if the framebuffer should be singlesampled.
* *
* @throws IllegalArgumentException If width or height are not positive. * @throws IllegalArgumentException If width or height are not positive.
*/ */
public FrameBuffer(int width, int height, int samples){ public FrameBuffer(int width, int height, int samples) {
super(); super();
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("FrameBuffer must have valid size."); throw new IllegalArgumentException("FrameBuffer must have valid size.");
}
this.width = width; this.width = width;
this.height = height; this.height = height;
this.samples = samples == 0 ? 1 : samples; this.samples = samples == 0 ? 1 : samples;
} }
protected FrameBuffer(FrameBuffer src){ protected FrameBuffer(FrameBuffer src) {
super(src.id); super(src.id);
/* /*
for (RenderBuffer renderBuf : src.colorBufs){ for (RenderBuffer renderBuf : src.colorBufs){
@ -209,60 +210,68 @@ public class FrameBuffer extends NativeObject {
/** /**
* Enables the use of a depth buffer for this <code>FrameBuffer</code>. * Enables the use of a depth buffer for this <code>FrameBuffer</code>.
* *
* @param format The format to use for the depth buffer. * @param format The format to use for the depth buffer.
* @throws IllegalArgumentException If <code>format</code> is not a depth format. * @throws IllegalArgumentException If <code>format</code> is not a depth format.
*/ */
public void setDepthBuffer(Image.Format format){ public void setDepthBuffer(Image.Format format) {
if (id != -1) if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized."); throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
if (!format.isDepthFormat()) if (!format.isDepthFormat()) {
throw new IllegalArgumentException("Depth buffer format must be depth."); throw new IllegalArgumentException("Depth buffer format must be depth.");
}
depthBuf = new RenderBuffer(); depthBuf = new RenderBuffer();
depthBuf.slot = format.isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH; depthBuf.slot = format.isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH;
depthBuf.format = format; depthBuf.format = format;
} }
/** /**
* Enables the use of a color buffer for this <code>FrameBuffer</code>. * Enables the use of a color buffer for this <code>FrameBuffer</code>.
* *
* @param format The format to use for the color buffer. * @param format The format to use for the color buffer.
* @throws IllegalArgumentException If <code>format</code> is not a color format. * @throws IllegalArgumentException If <code>format</code> is not a color format.
*/ */
public void setColorBuffer(Image.Format format){ public void setColorBuffer(Image.Format format) {
if (id != -1) if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized."); throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
if (format.isDepthFormat()) if (format.isDepthFormat()) {
throw new IllegalArgumentException("Color buffer format must be color/luminance."); throw new IllegalArgumentException("Color buffer format must be color/luminance.");
}
RenderBuffer colorBuf = new RenderBuffer(); RenderBuffer colorBuf = new RenderBuffer();
colorBuf.slot = 0; colorBuf.slot = 0;
colorBuf.format = format; colorBuf.format = format;
colorBufs.clear(); colorBufs.clear();
colorBufs.add(colorBuf); colorBufs.add(colorBuf);
} }
private void checkSetTexture(Texture tex, boolean depth){ private void checkSetTexture(Texture tex, boolean depth) {
Image img = tex.getImage(); Image img = tex.getImage();
if (img == null) if (img == null) {
throw new IllegalArgumentException("Texture not initialized with RTT."); throw new IllegalArgumentException("Texture not initialized with RTT.");
}
if (depth && !img.getFormat().isDepthFormat()) if (depth && !img.getFormat().isDepthFormat()) {
throw new IllegalArgumentException("Texture image format must be depth."); throw new IllegalArgumentException("Texture image format must be depth.");
else if (!depth && img.getFormat().isDepthFormat()) } else if (!depth && img.getFormat().isDepthFormat()) {
throw new IllegalArgumentException("Texture image format must be color/luminance."); throw new IllegalArgumentException("Texture image format must be color/luminance.");
}
// check that resolution matches texture resolution // check that resolution matches texture resolution
if (width != img.getWidth() || height != img.getHeight()) if (width != img.getWidth() || height != img.getHeight()) {
throw new IllegalArgumentException("Texture image resolution " + throw new IllegalArgumentException("Texture image resolution "
"must match FB resolution"); + "must match FB resolution");
}
if (samples != tex.getImage().getMultiSamples()) if (samples != tex.getImage().getMultiSamples()) {
throw new IllegalStateException("Texture samples must match framebuffer samples"); throw new IllegalStateException("Texture samples must match framebuffer samples");
}
} }
/** /**
@ -270,38 +279,43 @@ public class FrameBuffer extends NativeObject {
* will be able to write several results into the renderbuffers * will be able to write several results into the renderbuffers
* by using the <code>gl_FragData</code> array. Every slot in that * by using the <code>gl_FragData</code> array. Every slot in that
* array maps into a color buffer attached to this framebuffer. * array maps into a color buffer attached to this framebuffer.
* *
* @param enabled True to enable MRT (multiple rendering targets). * @param enabled True to enable MRT (multiple rendering targets).
*/ */
public void setMultiTarget(boolean enabled){ public void setMultiTarget(boolean enabled) {
if (enabled) colorBufIndex = -1; if (enabled) {
else colorBufIndex = 0; colorBufIndex = -1;
} else {
colorBufIndex = 0;
}
} }
/** /**
* @return True if MRT (multiple rendering targets) is enabled. * @return True if MRT (multiple rendering targets) is enabled.
* @see FrameBuffer#setMultiTarget(boolean) * @see FrameBuffer#setMultiTarget(boolean)
*/ */
public boolean isMultiTarget(){ public boolean isMultiTarget() {
return colorBufIndex == -1; return colorBufIndex == -1;
} }
/** /**
* If MRT is not enabled ({@link FrameBuffer#setMultiTarget(boolean) } is false) * If MRT is not enabled ({@link FrameBuffer#setMultiTarget(boolean) } is false)
* then this specifies the color target to which the scene should be rendered. * then this specifies the color target to which the scene should be rendered.
* <p> * <p>
* By default the value is 0. * By default the value is 0.
* *
* @param index The color attachment index. * @param index The color attachment index.
* @throws IllegalArgumentException If index is negative or doesn't map * @throws IllegalArgumentException If index is negative or doesn't map
* to any attachment on this framebuffer. * to any attachment on this framebuffer.
*/ */
public void setTargetIndex(int index){ public void setTargetIndex(int index) {
if (index < 0 || index >= 16) if (index < 0 || index >= 16) {
throw new IllegalArgumentException("Target index must be between 0 and 16"); throw new IllegalArgumentException("Target index must be between 0 and 16");
}
if (colorBufs.size() < index) if (colorBufs.size() < index) {
throw new IllegalArgumentException("The target at " + index + " is not set!"); throw new IllegalArgumentException("The target at " + index + " is not set!");
}
colorBufIndex = index; colorBufIndex = index;
setUpdateNeeded(); setUpdateNeeded();
@ -309,10 +323,10 @@ public class FrameBuffer extends NativeObject {
/** /**
* @return The color target to which the scene should be rendered. * @return The color target to which the scene should be rendered.
* *
* @see FrameBuffer#setTargetIndex(int) * @see FrameBuffer#setTargetIndex(int)
*/ */
public int getTargetIndex(){ public int getTargetIndex() {
return colorBufIndex; return colorBufIndex;
} }
@ -321,27 +335,27 @@ public class FrameBuffer extends NativeObject {
* This automatically clears all existing textures added previously * This automatically clears all existing textures added previously
* with {@link FrameBuffer#addColorTexture } and adds this texture as the * with {@link FrameBuffer#addColorTexture } and adds this texture as the
* only target. * only target.
* *
* @param tex The color texture to set. * @param tex The color texture to set.
*/ */
public void setColorTexture(Texture2D tex){ public void setColorTexture(Texture2D tex) {
clearColorTargets(); clearColorTargets();
addColorTexture(tex); addColorTexture(tex);
} }
/** /**
* Set the color texture array to use for this framebuffer. * Set the color texture array to use for this framebuffer.
* This automatically clears all existing textures added previously * This automatically clears all existing textures added previously
* with {@link FrameBuffer#addColorTexture } and adds this texture as the * with {@link FrameBuffer#addColorTexture } and adds this texture as the
* only target. * only target.
* *
* @param tex The color texture array to set. * @param tex The color texture array to set.
*/ */
public void setColorTexture(TextureArray tex, int layer){ public void setColorTexture(TextureArray tex, int layer) {
clearColorTargets(); clearColorTargets();
addColorTexture(tex, layer); addColorTexture(tex, layer);
} }
/** /**
* Set the color texture to use for this framebuffer. * Set the color texture to use for this framebuffer.
* This automatically clears all existing textures added previously * This automatically clears all existing textures added previously
@ -359,47 +373,50 @@ public class FrameBuffer extends NativeObject {
/** /**
* Clears all color targets that were set or added previously. * Clears all color targets that were set or added previously.
*/ */
public void clearColorTargets(){ public void clearColorTargets() {
colorBufs.clear(); colorBufs.clear();
} }
/** /**
* Add a color buffer without a texture bound to it. * Add a color buffer without a texture bound to it.
* If MRT is enabled, then each subsequently added texture or buffer can be * If MRT is enabled, then each subsequently added texture or buffer can be
* rendered to through a shader that writes to the array <code>gl_FragData</code>. * rendered to through a shader that writes to the array <code>gl_FragData</code>.
* If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) } * If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) }
* is rendered to by the shader. * is rendered to by the shader.
* *
* @param format the format of the color buffer * @param format the format of the color buffer
* @see #addColorTexture(com.jme3.texture.Texture2D) * @see #addColorTexture(com.jme3.texture.Texture2D)
*/ */
public void addColorBuffer(Image.Format format){ public void addColorBuffer(Image.Format format) {
if (id != -1) if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized."); throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
if (format.isDepthFormat()) if (format.isDepthFormat()) {
throw new IllegalArgumentException("Color buffer format must be color/luminance."); throw new IllegalArgumentException("Color buffer format must be color/luminance.");
}
RenderBuffer colorBuf = new RenderBuffer(); RenderBuffer colorBuf = new RenderBuffer();
colorBuf.slot = colorBufs.size(); colorBuf.slot = colorBufs.size();
colorBuf.format = format; colorBuf.format = format;
colorBufs.add(colorBuf); colorBufs.add(colorBuf);
} }
/** /**
* Add a color texture to use for this framebuffer. * Add a color texture to use for this framebuffer.
* If MRT is enabled, then each subsequently added texture can be * If MRT is enabled, then each subsequently added texture can be
* rendered to through a shader that writes to the array <code>gl_FragData</code>. * rendered to through a shader that writes to the array <code>gl_FragData</code>.
* If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) } * If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) }
* is rendered to by the shader. * is rendered to by the shader.
* *
* @param tex The texture to add. * @param tex The texture to add.
* @see #addColorBuffer(com.jme3.texture.Image.Format) * @see #addColorBuffer(com.jme3.texture.Image.Format)
*/ */
public void addColorTexture(Texture2D tex) { public void addColorTexture(Texture2D tex) {
if (id != -1) if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized."); throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage(); Image img = tex.getImage();
checkSetTexture(tex, false); checkSetTexture(tex, false);
@ -411,19 +428,20 @@ public class FrameBuffer extends NativeObject {
colorBufs.add(colorBuf); colorBufs.add(colorBuf);
} }
/** /**
* Add a color texture array to use for this framebuffer. * Add a color texture array to use for this framebuffer.
* If MRT is enabled, then each subsequently added texture can be * If MRT is enabled, then each subsequently added texture can be
* rendered to through a shader that writes to the array <code>gl_FragData</code>. * rendered to through a shader that writes to the array <code>gl_FragData</code>.
* If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) } * If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) }
* is rendered to by the shader. * is rendered to by the shader.
* *
* @param tex The texture array to add. * @param tex The texture array to add.
*/ */
public void addColorTexture(TextureArray tex, int layer) { public void addColorTexture(TextureArray tex, int layer) {
if (id != -1) if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized."); throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage(); Image img = tex.getImage();
checkSetTexture(tex, false); checkSetTexture(tex, false);
@ -436,8 +454,8 @@ public class FrameBuffer extends NativeObject {
colorBufs.add(colorBuf); colorBufs.add(colorBuf);
} }
/** /**
* Add a color texture to use for this framebuffer. * Add a color texture to use for this framebuffer.
* If MRT is enabled, then each subsequently added texture can be * If MRT is enabled, then each subsequently added texture can be
* rendered to through a shader that writes to the array <code>gl_FragData</code>. * rendered to through a shader that writes to the array <code>gl_FragData</code>.
@ -448,8 +466,9 @@ public class FrameBuffer extends NativeObject {
* @param face The face of the cube-map to render to. * @param face The face of the cube-map to render to.
*/ */
public void addColorTexture(TextureCubeMap tex, TextureCubeMap.Face face) { public void addColorTexture(TextureCubeMap tex, TextureCubeMap.Face face) {
if (id != -1) if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized."); throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage(); Image img = tex.getImage();
checkSetTexture(tex, false); checkSetTexture(tex, false);
@ -465,39 +484,42 @@ public class FrameBuffer extends NativeObject {
/** /**
* Set the depth texture to use for this framebuffer. * Set the depth texture to use for this framebuffer.
* *
* @param tex The color texture to set. * @param tex The color texture to set.
*/ */
public void setDepthTexture(Texture2D tex){ public void setDepthTexture(Texture2D tex) {
if (id != -1) if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized."); throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage(); Image img = tex.getImage();
checkSetTexture(tex, true); checkSetTexture(tex, true);
depthBuf = new RenderBuffer(); depthBuf = new RenderBuffer();
depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH; depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH;
depthBuf.tex = tex; depthBuf.tex = tex;
depthBuf.format = img.getFormat(); depthBuf.format = img.getFormat();
} }
public void setDepthTexture(TextureArray tex, int layer){
if (id != -1) public void setDepthTexture(TextureArray tex, int layer) {
if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized."); throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage(); Image img = tex.getImage();
checkSetTexture(tex, true); checkSetTexture(tex, true);
depthBuf = new RenderBuffer(); depthBuf = new RenderBuffer();
depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH; depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH;
depthBuf.tex = tex; depthBuf.tex = tex;
depthBuf.format = img.getFormat(); depthBuf.format = img.getFormat();
depthBuf.layer = layer; depthBuf.layer = layer;
} }
/** /**
* @return The number of color buffers attached to this texture. * @return The number of color buffers attached to this texture.
*/ */
public int getNumColorBuffers(){ public int getNumColorBuffers() {
return colorBufs.size(); return colorBufs.size();
} }
@ -505,21 +527,22 @@ public class FrameBuffer extends NativeObject {
* @param index * @param index
* @return The color buffer at the given index. * @return The color buffer at the given index.
*/ */
public RenderBuffer getColorBuffer(int index){ public RenderBuffer getColorBuffer(int index) {
return colorBufs.get(index); return colorBufs.get(index);
} }
/** /**
* @return The color buffer with the index set by {@link #setTargetIndex(int)}, or null * @return The color buffer with the index set by {@link #setTargetIndex(int)}, or null
* if no color buffers are attached. * if no color buffers are attached.
* If MRT is disabled, the first color buffer is returned. * If MRT is disabled, the first color buffer is returned.
*/ */
public RenderBuffer getColorBuffer() { public RenderBuffer getColorBuffer() {
if (colorBufs.isEmpty()) if (colorBufs.isEmpty()) {
return null; return null;
if (colorBufIndex<0 || colorBufIndex>=colorBufs.size()) { }
return colorBufs.get(0); if (colorBufIndex < 0 || colorBufIndex >= colorBufs.size()) {
} return colorBufs.get(0);
}
return colorBufs.get(colorBufIndex); return colorBufs.get(colorBufIndex);
} }
@ -554,16 +577,17 @@ public class FrameBuffer extends NativeObject {
} }
@Override @Override
public String toString(){ public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String mrtStr = colorBufIndex >= 0 ? "" + colorBufIndex : "mrt"; String mrtStr = colorBufIndex >= 0 ? "" + colorBufIndex : "mrt";
sb.append("FrameBuffer[format=").append(width).append("x").append(height) sb.append("FrameBuffer[format=").append(width).append("x").append(height)
.append("x").append(samples).append(", drawBuf=").append(mrtStr).append("]\n"); .append("x").append(samples).append(", drawBuf=").append(mrtStr).append("]\n");
if (depthBuf != null) if (depthBuf != null) {
sb.append("Depth => ").append(depthBuf).append("\n"); sb.append("Depth => ").append(depthBuf).append("\n");
for (RenderBuffer colorBuf : colorBufs){ }
for (RenderBuffer colorBuf : colorBufs) {
sb.append("Color(").append(colorBuf.slot) sb.append("Color(").append(colorBuf.slot)
.append(") => ").append(colorBuf).append("\n"); .append(") => ").append(colorBuf).append("\n");
} }
return sb.toString(); return sb.toString();
} }
@ -571,31 +595,33 @@ public class FrameBuffer extends NativeObject {
@Override @Override
public void resetObject() { public void resetObject() {
this.id = -1; this.id = -1;
for (int i = 0; i < colorBufs.size(); i++) { for (int i = 0; i < colorBufs.size(); i++) {
colorBufs.get(i).resetObject(); colorBufs.get(i).resetObject();
} }
if (depthBuf != null) if (depthBuf != null) {
depthBuf.resetObject(); depthBuf.resetObject();
}
setUpdateNeeded(); setUpdateNeeded();
} }
@Override @Override
public void deleteObject(Object rendererObject) { public void deleteObject(Object rendererObject) {
((Renderer)rendererObject).deleteFrameBuffer(this); ((Renderer) rendererObject).deleteFrameBuffer(this);
} }
public NativeObject createDestructableClone(){ @Override
public NativeObject createDestructableClone() {
return new FrameBuffer(this); return new FrameBuffer(this);
} }
@Override @Override
public long getUniqueId() { public long getUniqueId() {
return ((long)OBJTYPE_FRAMEBUFFER << 32) | ((long)id); return ((long) OBJTYPE_FRAMEBUFFER << 32) | ((long) id);
} }
/** /**
* Specifies that the color values stored in this framebuffer are in SRGB * Specifies that the color values stored in this framebuffer are in SRGB
* format. * format.
@ -631,5 +657,4 @@ public class FrameBuffer extends NativeObject {
public boolean isSrgb() { public boolean isSrgb() {
return srgb; return srgb;
} }
} }

@ -1269,7 +1269,7 @@ public final class BufferUtils {
* and cleans the direct buffers. However, as this doesn't happen * and cleans the direct buffers. However, as this doesn't happen
* immediately after discarding all references to a direct buffer, it's easy * immediately after discarding all references to a direct buffer, it's easy
* to OutOfMemoryError yourself using direct buffers. * to OutOfMemoryError yourself using direct buffers.
**/ */
public static void destroyDirectBuffer(Buffer toBeDestroyed) { public static void destroyDirectBuffer(Buffer toBeDestroyed) {
if (!isDirect(toBeDestroyed)) { if (!isDirect(toBeDestroyed)) {
return; return;
@ -1318,5 +1318,4 @@ public final class BufferUtils {
} }
} }
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2012 jMonkeyEngine * Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -81,74 +81,74 @@ public final class ReflectionAllocator implements BufferAllocator {
} catch (ClassNotFoundException ex) { } catch (ClassNotFoundException ex) {
return null; // the direct buffer implementation was not found return null; // the direct buffer implementation was not found
} catch (Throwable t) { } catch (Throwable t) {
if (t.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) { if (t.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) {
return null;// the class is in an unexported module return null;// the class is in an unexported module
} else { } else {
throw t; throw t;
} }
} }
} }
@Override @Override
/** /**
* This function explicitly calls the Cleaner method of a direct buffer. * This function explicitly calls the Cleaner method of a direct buffer.
* *
* @param toBeDestroyed * @param toBeDestroyed
* The direct buffer that will be "cleaned". Utilizes reflection. * The direct buffer that will be "cleaned". Utilizes reflection.
* *
*/ */
public void destroyDirectBuffer(Buffer toBeDestroyed) { public void destroyDirectBuffer(Buffer toBeDestroyed) {
try { try {
if (freeMethod != null) { if (freeMethod != null) {
freeMethod.invoke(toBeDestroyed); freeMethod.invoke(toBeDestroyed);
} else { } else {
//TODO load the methods only once, store them into a cache (only for Java >= 9) //TODO load the methods only once, store them into a cache (only for Java >= 9)
Method localCleanerMethod; Method localCleanerMethod;
if (cleanerMethod == null) { if (cleanerMethod == null) {
localCleanerMethod = loadMethod(toBeDestroyed.getClass().getName(), "cleaner"); localCleanerMethod = loadMethod(toBeDestroyed.getClass().getName(), "cleaner");
} else { } else {
localCleanerMethod = cleanerMethod; localCleanerMethod = cleanerMethod;
} }
if (localCleanerMethod == null) { if (localCleanerMethod == null) {
Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE,
"Buffer cannot be destroyed: {0}", toBeDestroyed); "Buffer cannot be destroyed: {0}", toBeDestroyed);
} else { } else {
Object cleaner = localCleanerMethod.invoke(toBeDestroyed); Object cleaner = localCleanerMethod.invoke(toBeDestroyed);
if (cleaner != null) { if (cleaner != null) {
Method localCleanMethod; Method localCleanMethod;
if (cleanMethod == null) { if (cleanMethod == null) {
if (cleaner instanceof Runnable) { if (cleaner instanceof Runnable) {
// jdk.internal.ref.Cleaner implements Runnable in Java 9 // jdk.internal.ref.Cleaner implements Runnable in Java 9
localCleanMethod = loadMethod(Runnable.class.getName(), "run"); localCleanMethod = loadMethod(Runnable.class.getName(), "run");
} else { } else {
// sun.misc.Cleaner does not implement Runnable in Java < 9 // sun.misc.Cleaner does not implement Runnable in Java < 9
localCleanMethod = loadMethod(cleaner.getClass().getName(), "clean"); localCleanMethod = loadMethod(cleaner.getClass().getName(), "clean");
} }
} else { } else {
localCleanMethod = cleanMethod; localCleanMethod = cleanMethod;
} }
if (localCleanMethod == null) { if (localCleanMethod == null) {
Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE,
"Buffer cannot be destroyed: {0}", toBeDestroyed); "Buffer cannot be destroyed: {0}", toBeDestroyed);
} else { } else {
localCleanMethod.invoke(cleaner); localCleanMethod.invoke(cleaner);
} }
} else { } else {
Method localViewedBufferMethod; Method localViewedBufferMethod;
if (viewedBufferMethod == null) { if (viewedBufferMethod == null) {
localViewedBufferMethod = loadMethod(toBeDestroyed.getClass().getName(), "viewedBuffer"); localViewedBufferMethod = loadMethod(toBeDestroyed.getClass().getName(), "viewedBuffer");
} else { } else {
localViewedBufferMethod = viewedBufferMethod; localViewedBufferMethod = viewedBufferMethod;
} }
if (localViewedBufferMethod == null) { if (localViewedBufferMethod == null) {
Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE,
"Buffer cannot be destroyed: {0}", toBeDestroyed); "Buffer cannot be destroyed: {0}", toBeDestroyed);
} else { } else {
// Try the alternate approach of getting the viewed // Try the alternate approach of getting the viewed
// buffer // buffer
// first // first
Object viewedBuffer = localViewedBufferMethod.invoke(toBeDestroyed); Object viewedBuffer = localViewedBufferMethod.invoke(toBeDestroyed);
if (viewedBuffer != null) { if (viewedBuffer != null) {
if (viewedBuffer instanceof Buffer) { if (viewedBuffer instanceof Buffer) {
destroyDirectBuffer((Buffer) viewedBuffer); destroyDirectBuffer((Buffer) viewedBuffer);
} }
@ -157,10 +157,10 @@ public final class ReflectionAllocator implements BufferAllocator {
} else { } else {
Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE,
"Buffer cannot be destroyed: {0}", toBeDestroyed); "Buffer cannot be destroyed: {0}", toBeDestroyed);
} }
} }
} }
} }
} }
} catch (IllegalAccessException ex) { } catch (IllegalAccessException ex) {
Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex); Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);

Loading…
Cancel
Save