rem..om 11 years ago
parent 1b2b9a6e88
commit 9bf532b95e
  1. 204
      engine/src/core/com/jme3/bounding/BoundingBox.java

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2012 jMonkeyEngine * Copyright (c) 2009-2013 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
@ -47,31 +47,40 @@ import java.nio.FloatBuffer;
//import com.jme.scene.TriMesh; //import com.jme.scene.TriMesh;
/** /**
* <code>BoundingBox</code> defines an axis-aligned cube that defines a * <code>BoundingBox</code> describes a bounding volume as an axis-aligned box.
* container for a group of vertices of a particular piece of geometry. This box
* defines a center and extents from that center along the x, y and z axis. <br>
* <br> * <br>
* A typical usage is to allow the class define the center and radius by calling * Instances may be initialized by invoking the <code>containAABB</code> method.
* either <code>containAABB</code> or <code>averagePoints</code>. A call to
* <code>computeFramePoint</code> in turn calls <code>containAABB</code>.
* *
* @author Joshua Slack * @author Joshua Slack
* @version $Id: BoundingBox.java,v 1.50 2007/09/22 16:46:35 irrisor Exp $ * @version $Id: BoundingBox.java,v 1.50 2007/09/22 16:46:35 irrisor Exp $
*/ */
public class BoundingBox extends BoundingVolume { public class BoundingBox extends BoundingVolume {
/**
float xExtent, yExtent, zExtent; * the X-extent of the box (>=0, may be +Infinity)
*/
float xExtent;
/**
* the Y-extent of the box (>=0, may be +Infinity)
*/
float yExtent;
/**
* the Z-extent of the box (>=0, may be +Infinity)
*/
float zExtent;
/** /**
* Default constructor instantiates a new <code>BoundingBox</code> * Instantiate a <code>BoundingBox</code> without initializing it.
* object.
*/ */
public BoundingBox() { public BoundingBox() {
} }
/** /**
* Contstructor instantiates a new <code>BoundingBox</code> object with * Instantiate a <code>BoundingBox</code> with given center and extents.
* given specs. *
* @param c the coordinates of the center of the box (not null, not altered)
* @param x the X-extent of the box (>=0, may be +Infinity)
* @param y the Y-extent of the box (>=0, may be +Infinity)
* @param z the Z-extent of the box (>=0, may be +Infinity)
*/ */
public BoundingBox(Vector3f c, float x, float y, float z) { public BoundingBox(Vector3f c, float x, float y, float z) {
this.center.set(c); this.center.set(c);
@ -80,6 +89,11 @@ public class BoundingBox extends BoundingVolume {
this.zExtent = z; this.zExtent = z;
} }
/**
* Instantiate a <code>BoundingBox</code> equivalent to an existing box.
*
* @param source the existing box (not null, not altered)
*/
public BoundingBox(BoundingBox source) { public BoundingBox(BoundingBox source) {
this.center.set(source.center); this.center.set(source.center);
this.xExtent = source.xExtent; this.xExtent = source.xExtent;
@ -368,52 +382,28 @@ public class BoundingBox extends BoundingVolume {
} }
/** /**
* <code>merge</code> combines this bounding box with a second bounding box. * <code>merge</code> combines this bounding box locally with a second
* This new box contains both bounding box and is returned. * bounding volume. The result contains both the original box and the second
* volume.
* *
* @param volume * @param volume the bounding volume to combine with this box (or null) (not
* the bounding box to combine with this bounding box. * altered)
* @return the new bounding box * @return this box (with its components modified) or null if the second
* volume is of some type other than AABB or Sphere
*/ */
public BoundingVolume merge(BoundingVolume volume) { public BoundingVolume merge(BoundingVolume volume) {
if (volume == null) { return mergeLocal(volume);
return this;
}
switch (volume.getType()) {
case AABB: {
BoundingBox vBox = (BoundingBox) volume;
return merge(vBox.center, vBox.xExtent, vBox.yExtent,
vBox.zExtent, new BoundingBox(new Vector3f(0, 0, 0), 0,
0, 0));
}
case Sphere: {
BoundingSphere vSphere = (BoundingSphere) volume;
return merge(vSphere.center, vSphere.radius, vSphere.radius,
vSphere.radius, new BoundingBox(new Vector3f(0, 0, 0),
0, 0, 0));
}
// case OBB: {
// OrientedBoundingBox box = (OrientedBoundingBox) volume;
// BoundingBox rVal = (BoundingBox) this.clone(null);
// return rVal.mergeOBB(box);
// }
default:
return null;
}
} }
/** /**
* <code>mergeLocal</code> combines this sphere with a second bounding * <code>mergeLocal</code> combines this bounding box locally with a second
* sphere locally. Altering this sphere to contain both the original and the * bounding volume. The result contains both the original box and the second
* additional sphere volumes; * volume.
* *
* @param volume * @param volume the bounding volume to combine with this box (or null) (not
* the sphere to combine with this sphere. * altered)
* @return this * @return this box (with its components modified) or null if the second
* volume is of some type other than AABB or Sphere
*/ */
public BoundingVolume mergeLocal(BoundingVolume volume) { public BoundingVolume mergeLocal(BoundingVolume volume) {
if (volume == null) { if (volume == null) {
@ -421,17 +411,15 @@ public class BoundingBox extends BoundingVolume {
} }
switch (volume.getType()) { switch (volume.getType()) {
case AABB: { case AABB:
BoundingBox vBox = (BoundingBox) volume; BoundingBox vBox = (BoundingBox) volume;
return merge(vBox.center, vBox.xExtent, vBox.yExtent, return mergeLocal(vBox.center, vBox.xExtent, vBox.yExtent,
vBox.zExtent, this); vBox.zExtent);
}
case Sphere: { case Sphere:
BoundingSphere vSphere = (BoundingSphere) volume; BoundingSphere vSphere = (BoundingSphere) volume;
return merge(vSphere.center, vSphere.radius, vSphere.radius, return mergeLocal(vSphere.center, vSphere.radius,
vSphere.radius, this); vSphere.radius, vSphere.radius);
}
// case OBB: { // case OBB: {
// return mergeOBB((OrientedBoundingBox) volume); // return mergeOBB((OrientedBoundingBox) volume);
@ -486,61 +474,68 @@ public class BoundingBox extends BoundingVolume {
// return this; // return this;
// } // }
/** /**
* <code>merge</code> combines this bounding box with another box which is * <code>mergeLocal</code> combines this bounding box locally with a second
* defined by the center, x, y, z extents. * bounding box described by its center and extents.
* *
* @param boxCenter * @param c the center of the second box (not null, not altered)
* the center of the box to merge with * @param x the X-extent of the second box
* @param boxX * @param y the Y-extent of the second box
* the x extent of the box to merge with. * @param z the Z-extent of the second box
* @param boxY
* the y extent of the box to merge with.
* @param boxZ
* the z extent of the box to merge with.
* @param rVal
* the resulting merged box.
* @return the resulting merged box. * @return the resulting merged box.
*/ */
private BoundingBox merge(Vector3f boxCenter, float boxX, float boxY, private BoundingBox mergeLocal(Vector3f c, float x, float y, float z) {
float boxZ, BoundingBox rVal) { if (xExtent == Float.POSITIVE_INFINITY
|| x == Float.POSITIVE_INFINITY) {
TempVars vars = TempVars.get(); center.x = 0;
xExtent = Float.POSITIVE_INFINITY;
vars.vect1.x = center.x - xExtent; } else {
if (vars.vect1.x > boxCenter.x - boxX) { float low = center.x - xExtent;
vars.vect1.x = boxCenter.x - boxX; if (low > c.x - x) {
low = c.x - x;
} }
vars.vect1.y = center.y - yExtent; float high = center.x + xExtent;
if (vars.vect1.y > boxCenter.y - boxY) { if (high < c.x + x) {
vars.vect1.y = boxCenter.y - boxY; high = c.x + x;
} }
vars.vect1.z = center.z - zExtent; center.x = (low + high) / 2;
if (vars.vect1.z > boxCenter.z - boxZ) { xExtent = high - center.x;
vars.vect1.z = boxCenter.z - boxZ;
} }
vars.vect2.x = center.x + xExtent; if (yExtent == Float.POSITIVE_INFINITY
if (vars.vect2.x < boxCenter.x + boxX) { || y == Float.POSITIVE_INFINITY) {
vars.vect2.x = boxCenter.x + boxX; center.y = 0;
yExtent = Float.POSITIVE_INFINITY;
} else {
float low = center.y - yExtent;
if (low > c.y - y) {
low = c.y - y;
} }
vars.vect2.y = center.y + yExtent; float high = center.y + yExtent;
if (vars.vect2.y < boxCenter.y + boxY) { if (high < c.y + y) {
vars.vect2.y = boxCenter.y + boxY; high = c.y + y;
} }
vars.vect2.z = center.z + zExtent; center.y = (low + high) / 2;
if (vars.vect2.z < boxCenter.z + boxZ) { yExtent = high - center.y;
vars.vect2.z = boxCenter.z + boxZ;
} }
center.set(vars.vect2).addLocal(vars.vect1).multLocal(0.5f); if (zExtent == Float.POSITIVE_INFINITY
|| z == Float.POSITIVE_INFINITY) {
xExtent = vars.vect2.x - center.x; center.z = 0;
yExtent = vars.vect2.y - center.y; zExtent = Float.POSITIVE_INFINITY;
zExtent = vars.vect2.z - center.z; } else {
float low = center.z - zExtent;
vars.release(); if (low > c.z - z) {
low = c.z - z;
}
float high = center.z + zExtent;
if (high < c.z + z) {
high = c.z + z;
}
center.z = (low + high) / 2;
zExtent = high - center.z;
}
return rVal; return this;
} }
/** /**
@ -570,7 +565,8 @@ public class BoundingBox extends BoundingVolume {
/** /**
* <code>toString</code> returns the string representation of this object. * <code>toString</code> returns the string representation of this object.
* The form is: "Radius: RRR.SSSS Center: <Vector>". * The form is: "[Center: <Vector> xExtent: X.XX yExtent: Y.YY zExtent:
* Z.ZZ]".
* *
* @return the string representation of this. * @return the string representation of this.
*/ */

Loading…
Cancel
Save