Hi folks,
I somehow have a working version of portals. Still, it is not meant to be some sort of final implementation since there are still a lot of things missing. Things which are not yet complete are:
- Checking the visibility of a portal is done by checking its bounding volume which currently is a BoundingSphere. This will cause the portal drawn even if it is not really possible. Perfect solution would check the planar polygon of the portal against the frustum. Since this only causes a bit more overhead, I am not currently investigating this.
- Finding the region the cam is currently in is done by checking bounding volumes. This will cause erroneus behaviour if two regions are convex, but their bounding volumes overlap and the cam is in the overlapping region. The solution for this is to use BSPs, which I am waiting for.
- You have to create everything manually currently. As I wrote in another post, I would like to implement this whole thing in the context of a map node.
Therefore I publish this code as some sort of technology demo. If you like, you can try it out by using the test class I have written.
Here is the code used in Camera and AbstractCamera for the handling of additional check planes.
Index: AbstractCamera.java
===================================================================
RCS file: /cvs/jme/src/com/jme/renderer/AbstractCamera.java,v
retrieving revision 1.26
diff -u -r1.26 AbstractCamera.java
--- AbstractCamera.java 18 Sep 2004 19:22:51 -0000 1.26
+++ AbstractCamera.java 14 Dec 2004 22:43:42 -0000
@@ -210,7 +210,7 @@
viewPortTop = 1.0f;
viewPortBottom = 0.0f;
- planeQuantity = 6;
+ planeQuantity = FRUSTUM_PLANES;
worldPlane = new Plane[MAX_WORLD_PLANES];
for (int i = 0; i < MAX_WORLD_PLANES; i++) {
@@ -727,7 +727,7 @@
public int contains(BoundingVolume bound) {
if (bound == null) { return INSIDE_FRUSTUM; }
- int planeCounter = FRUSTUM_PLANES - 1;
+ int planeCounter = planeQuantity - 1;
int mask = 0;
int rVal = INSIDE_FRUSTUM;
@@ -739,9 +739,9 @@
if (side == Plane.NEGATIVE_SIDE) {
//object is outside of frustum
- if (planeCounter != FRUSTUM_PLANES - 1) {
- int i = bound.getCheckPlane(FRUSTUM_PLANES - 1);
- bound.setCheckPlane(FRUSTUM_PLANES - 1, bound
+ if (planeCounter != planeQuantity - 1) {
+ int i = bound.getCheckPlane(planeQuantity - 1);
+ bound.setCheckPlane(planeQuantity - 1, bound
.getCheckPlane(planeCounter));
bound.setCheckPlane(planeCounter, i);
}
@@ -757,6 +757,33 @@
}
return rVal;
+ }
+
+ /**
+ * <code>pushPlane</code> is used to add another check plane to the camera
+ * frustum. Up to MAX_WORLD_PLANES - FRUSTUM_PLANES can be added. This is
+ * used eg. by portals to limit the view through them.
+ * @param newPlane The new plane which further limits the view frustum.
+ * @return true if the plane could be pushed, false if the maximum number
+ * of planes already has been reached and the plane could not be added.
+ */
+ public boolean pushPlane(Plane newPlane) {
+ boolean success = false;
+ if (planeQuantity < MAX_WORLD_PLANES) {
+ worldPlane[planeQuantity++] = newPlane;
+ success = true;
+ }
+ return success;
+ }
+
+ /**
+ * <code>popPlane</code> pops the last plane added. The standard view planes
+ * cannot be popped.
+ */
+ public void popPlane() {
+ if (planeQuantity > FRUSTUM_PLANES) {
+ planeQuantity--;
+ }
}
/**
Index: Camera.java
===================================================================
RCS file: /cvs/jme/src/com/jme/renderer/Camera.java,v
retrieving revision 1.14
diff -u -r1.14 Camera.java
--- Camera.java 14 Sep 2004 03:05:35 -0000 1.14
+++ Camera.java 14 Dec 2004 22:43:42 -0000
@@ -39,6 +39,7 @@
import java.io.Serializable;
import com.jme.bounding.BoundingVolume;
+import com.jme.math.Plane;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
@@ -73,6 +74,18 @@
public static final int INSIDE_FRUSTUM = 2;
/**
+ * MAX_WORLD_PLANES holds the maximum planes allowed by the system.
+ * Moved here from AbstractCamera.
+ */
+ public static final int MAX_WORLD_PLANES = 32;
+
+ /**
+ * FRUSTUM_PLANES represents the number of planes of the camera frustum.
+ * Moved here from AbstractCamera.
+ */
+ public static final int FRUSTUM_PLANES = 6;
+
+ /**
*
* <code>getLocation</code> returns the position of the camera.
*
@@ -448,8 +461,6 @@
*/
public void lookAt(Vector3f pos);
-
-
/**
* <code>resize</code> resizes this cameras view with the given width/height.
* This is similar to constructing a new camera, but reusing the same
@@ -458,4 +469,21 @@
* @param height int
*/
public void resize(int width, int height);
+
+ /**
+ * <code>pushPlane</code> is used to add another check plane to the camera
+ * frustum. Up to MAX_WORLD_PLANES - FRUSTUM_PLANES can be added. This is
+ * used eg. by portals to limit the view through them.
+ * @param newPlane The new plane which further limits the view frustum.
+ * @return true if the plane could be pushed, false if the maximum number
+ * of planes already has been reached and the plane could not be added.
+ */
+ public boolean pushPlane(Plane newPlane);
+
+ /**
+ * <code>popPlane</code> pops the last plane added. The standard view planes
+ * cannot be popped.
+ */
+ public void popPlane();
+
}
Here is the code for the bounding volumes so that they only use the check planes for index 0 to MAX_WORLD_PLANES.
Index: BoundingBox.java
===================================================================
RCS file: /cvs/jme/src/com/jme/bounding/BoundingBox.java,v
retrieving revision 1.24
diff -u -r1.24 BoundingBox.java
--- BoundingBox.java 6 Dec 2004 19:04:10 -0000 1.24
+++ BoundingBox.java 14 Dec 2004 22:22:18 -0000
@@ -32,6 +32,7 @@
package com.jme.bounding;
+import com.jme.renderer.Camera;
import com.jme.scene.shape.*;
import com.jme.math.*;
@@ -52,7 +53,7 @@
private static final long serialVersionUID = 1L;
/** These define the array of planes that are check during view culling. */
- public int[] checkPlanes = new int[6];
+ public int[] checkPlanes = new int[Camera.MAX_WORLD_PLANES];
private Vector3f minPnt = new Vector3f();
@@ -115,12 +116,9 @@
* the AABB.
*/
public void initCheckPlanes() {
- checkPlanes[0] = 0;
- checkPlanes[1] = 1;
- checkPlanes[2] = 2;
- checkPlanes[3] = 3;
- checkPlanes[4] = 4;
- checkPlanes[5] = 5;
+ for (int i = 0; i < Camera.MAX_WORLD_PLANES; i++) {
+ checkPlanes[i] = i;
+ }
}
/**
@@ -446,7 +444,9 @@
* for intersection.
*/
public void setCheckPlane(int index, int value) {
- checkPlanes[index] = value;
+ if (index < Camera.FRUSTUM_PLANES && value < Camera.FRUSTUM_PLANES) {
+ checkPlanes[index] = value;
+ }
}
/**
Index: BoundingSphere.java
===================================================================
RCS file: /cvs/jme/src/com/jme/bounding/BoundingSphere.java,v
retrieving revision 1.22
diff -u -r1.22 BoundingSphere.java
--- BoundingSphere.java 6 Dec 2004 19:04:10 -0000 1.22
+++ BoundingSphere.java 14 Dec 2004 22:22:20 -0000
@@ -34,16 +34,16 @@
import java.util.logging.Level;
import com.jme.math.*;
+import com.jme.renderer.Camera;
import com.jme.scene.shape.Sphere;
import com.jme.util.LoggingSystem;
/**
- * <code>BoundingSphere</code> defines a sphere that defines a container for a
- * group of vertices of a particular piece of geometry. This sphere defines a
- * radius and a center. <br>
+ * <code>BoundingSphere</code> defines a sphere that defines a container for a group of vertices
+ * of a particular piece of geometry. This sphere defines a radius and a center. <br>
* <br>
- * A typical usage is to allow the class define the center and radius by calling
- * either <code>containAABB</code> or <code>averagePoints</code>. A call to
+ * A typical usage is to allow the class define the center and radius by calling either
+ * <code>containAABB</code> or <code>averagePoints</code>. A call to
* <code>computeFramePoint</code> in turn calls <code>containAABB</code>.
*
* @author Mark Powell
@@ -52,12 +52,12 @@
public class BoundingSphere extends Sphere implements BoundingVolume {
/**
- * When this flag is true, updateModelBound() for BoundingSphere will
- * calculate the smallest bounding volume.
+ * When this flag is true, updateModelBound() for BoundingSphere will calculate the smallest
+ * bounding volume.
*/
static public boolean useExactBounds = false;
- public int[] checkPlanes = new int[6];
+ public int[] checkPlanes = new int[Camera.MAX_WORLD_PLANES];
private float oldRadius;
@@ -72,13 +72,13 @@
private static final Vector3f tempVecb = new Vector3f();
- private static final Vector3f[] tempVarray = { new Vector3f(),
- new Vector3f(), new Vector3f(), new Vector3f(), new Vector3f(),
- new Vector3f(), new Vector3f(), new Vector3f() };
+ private static final Vector3f[] tempVarray = {
+ new Vector3f(), new Vector3f(), new Vector3f(), new Vector3f(), new Vector3f(),
+ new Vector3f(), new Vector3f(), new Vector3f()
+ };
/**
- * Default contstructor instantiates a new <code>BoundingSphere</code>
- * object.
+ * Default contstructor instantiates a new <code>BoundingSphere</code> object.
*/
public BoundingSphere() {
super("bsphere");
@@ -88,10 +88,8 @@
/**
* Constructor instantiates a new <code>BoundingSphere</code> object.
*
- * @param radius
- * the radius of the sphere.
- * @param center
- * the center of the sphere.
+ * @param radius the radius of the sphere.
+ * @param center the center of the sphere.
*/
public BoundingSphere(float radius, Vector3f center) {
super("bsphere", center, 10, 10, radius);
@@ -101,10 +99,8 @@
/**
* Constructor instantiates a new <code>BoundingSphere</code> object.
*
- * @param radius
- * the radius of the sphere.
- * @param center
- * the center of the sphere.
+ * @param radius the radius of the sphere.
+ * @param center the center of the sphere.
*/
public BoundingSphere(String name, float radius, Vector3f center) {
super(name, center, 10, 10, radius);
@@ -112,12 +108,9 @@
}
public void initCheckPlanes() {
- checkPlanes[0] = 0;
- checkPlanes[1] = 1;
- checkPlanes[2] = 2;
- checkPlanes[3] = 3;
- checkPlanes[4] = 4;
- checkPlanes[5] = 5;
+ for (int i = 0; i < Camera.MAX_WORLD_PLANES; i++) {
+ checkPlanes[i] = i;
+ }
}
/**
@@ -141,8 +134,7 @@
/**
* <code>setRadius</code> sets the radius of this bounding sphere.
*
- * @param radius
- * the new radius of the bounding sphere.
+ * @param radius the new radius of the bounding sphere.
*/
public void setRadius(float radius) {
this.radius = radius;
@@ -151,20 +143,17 @@
/**
* <code>setCenter</code> sets the center of the bounding sphere.
*
- * @param center
- * the new center of the bounding sphere.
+ * @param center the new center of the bounding sphere.
*/
public void setCenter(Vector3f center) {
this.center = center;
}
/**
- * <code>computeFromPoints</code> creates a new Bounding Sphere from a
- * given set of points. It uses the <code>containAABB</code> method as
- * default.
+ * <code>computeFromPoints</code> creates a new Bounding Sphere from a given set of points. It
+ * uses the <code>containAABB</code> method as default.
*
- * @param points
- * the points to contain.
+ * @param points the points to contain.
*/
public void computeFromPoints(Vector3f[] points) {
if (useExactBounds)
@@ -174,16 +163,16 @@
}
/**
- * Calculates a minimum bounding sphere for the set of points. The algorithm
- * was originally found at
+ * Calculates a minimum bounding sphere for the set of points. The algorithm was originally
+ * found at
* http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-SmallestEnclosingSpheres&forum=cotd&id=-1
* in C++ and translated to java by Cep21
*
- * @param points
- * The points to calculate the minimum bounds from.
+ * @param points The points to calculate the minimum bounds from.
*/
public void calcWelzl(Vector3f[] points) {
- if (center == null) center = new Vector3f();
+ if (center == null)
+ center = new Vector3f();
Vector3f[] newRef = new Vector3f[points.length];
for (int i = 0; i < points.length; i++)
newRef[i] = points[i];
@@ -191,19 +180,14 @@
}
/**
- * Used from calcWelzl. This function recurses to calculate a minimum
- * bounding sphere a few points at a time.
+ * Used from calcWelzl. This function recurses to calculate a minimum bounding sphere a few
+ * points at a time.
*
- * @param points
- * The array of points to look through.
- * @param p
- * The size of the list to be used.
- * @param b
- * The number of points currently considering to include with the
- * sphere.
- * @param ap
- * A variable simulating pointer arithmatic from C++, and offset
- * in <code>points</code>.
+ * @param points The array of points to look through.
+ * @param p The size of the list to be used.
+ * @param b The number of points currently considering to include with the sphere.
+ * @param ap A variable simulating pointer arithmatic from C++, and offset in
+ * <code>points</code>.
*/
private void recurseMini(Vector3f[] points, int p, int b, int ap) {
switch (b) {
@@ -222,8 +206,7 @@
setSphere(points[ap - 1], points[ap - 2], points[ap - 3]);
break;
case 4:
- setSphere(points[ap - 1], points[ap - 2], points[ap - 3],
- points[ap - 4]);
+ setSphere(points[ap - 1], points[ap - 2], points[ap - 3], points[ap - 4]);
return;
}
for (int i = 0; i < p; i++) {
@@ -239,17 +222,12 @@
}
/**
- * Calculates the minimum bounding sphere of 4 points. Used in welzl's
- * algorithm.
+ * Calculates the minimum bounding sphere of 4 points. Used in welzl's algorithm.
*
- * @param O
- * The 1st point inside the sphere.
- * @param A
- * The 2nd point inside the sphere.
- * @param B
- * The 3rd point inside the sphere.
- * @param C
- * The 4th point inside the sphere.
+ * @param O The 1st point inside the sphere.
+ * @param A The 2nd point inside the sphere.
+ * @param B The 3rd point inside the sphere.
+ * @param C The 4th point inside the sphere.
* @see #calcWelzl(com.jme.math.Vector3f[])
*/
private void setSphere(Vector3f O, Vector3f A, Vector3f B, Vector3f C) {
@@ -257,27 +235,22 @@
Vector3f b = B.subtract(O);
Vector3f c = C.subtract(O);
- float Denominator = 2.0f * (a.x * (b.y * c.z - c.y * b.z) - b.x
- * (a.y * c.z - c.y * a.z) + c.x * (a.y * b.z - b.y * a.z));
+ float Denominator = 2.0f * (a.x * (b.y * c.z - c.y * b.z) - b.x * (a.y * c.z - c.y * a.z) + c.x
+ * (a.y * b.z - b.y * a.z));
Vector3f o = a.cross(b).multLocal(c.lengthSquared()).addLocal(
c.cross(a).multLocal(b.lengthSquared())).addLocal(
- b.cross(c).multLocal(a.lengthSquared())).divideLocal(
- Denominator);
+ b.cross(c).multLocal(a.lengthSquared())).divideLocal(Denominator);
radius = o.length() * radiusEpsilon;
O.add(o, center);
}
/**
- * Calculates the minimum bounding sphere of 3 points. Used in welzl's
- * algorithm.
+ * Calculates the minimum bounding sphere of 3 points. Used in welzl's algorithm.
*
- * @param O
- * The 1st point inside the sphere.
- * @param A
- * The 2nd point inside the sphere.
- * @param B
- * The 3rd point inside the sphere.
+ * @param O The 1st point inside the sphere.
+ * @param A The 2nd point inside the sphere.
+ * @param B The 3rd point inside the sphere.
* @see #calcWelzl(com.jme.math.Vector3f[])
*/
private void setSphere(Vector3f O, Vector3f A, Vector3f B) {
@@ -288,39 +261,36 @@
float Denominator = 2.0f * acrossB.dot(acrossB);
Vector3f o = acrossB.cross(a).multLocal(b.lengthSquared()).addLocal(
- b.cross(acrossB).multLocal(a.lengthSquared())).divideLocal(
- Denominator);
+ b.cross(acrossB).multLocal(a.lengthSquared())).divideLocal(Denominator);
radius = o.length() * radiusEpsilon;
O.add(o, center);
}
/**
- * Calculates the minimum bounding sphere of 2 points. Used in welzl's
- * algorithm.
+ * Calculates the minimum bounding sphere of 2 points. Used in welzl's algorithm.
*
- * @param O
- * The 1st point inside the sphere.
- * @param A
- * The 2nd point inside the sphere.
+ * @param O The 1st point inside the sphere.
+ * @param A The 2nd point inside the sphere.
* @see #calcWelzl(com.jme.math.Vector3f[])
*/
private void setSphere(Vector3f O, Vector3f A) {
- radius = FastMath.sqrt(((A.x - O.x) * (A.x - O.x) + (A.y - O.y)
- * (A.y - O.y) + (A.z - O.z) * (A.z - O.z)) / 4);
+ radius = FastMath.sqrt(((A.x - O.x) * (A.x - O.x) + (A.y - O.y) * (A.y - O.y) + (A.z - O.z)
+ * (A.z - O.z)) / 4);
center.interpolate(O, A, .5f);
}
/**
- * <code>containAABB</code> creates a minimum-volume axis-aligned bounding
- * box of the points, then selects the smallest enclosing sphere of the box
- * with the sphere centered at the boxes center.
+ * <code>containAABB</code> creates a minimum-volume axis-aligned bounding box of the points,
+ * then selects the smallest enclosing sphere of the box with the sphere centered at the boxes
+ * center.
*
- * @param points
- * the list of points.
+ * @param points the list of points.
*/
public void containAABB(Vector3f[] points) {
- if (points.length <= 0) { return; }
+ if (points.length <= 0) {
+ return;
+ }
Vector3f min = tempVeca.set(points[0]);
Vector3f max = tempVecb.set(tempVeca);
@@ -328,30 +298,32 @@
for (int i = 1; i < points.length; i++) {
if (points[i].x < min.x)
min.x = points[i].x;
- else if (points[i].x > max.x) max.x = points[i].x;
+ else if (points[i].x > max.x)
+ max.x = points[i].x;
if (points[i].y < min.y)
min.y = points[i].y;
- else if (points[i].y > max.y) max.y = points[i].y;
+ else if (points[i].y > max.y)
+ max.y = points[i].y;
if (points[i].z < min.z)
min.z = points[i].z;
- else if (points[i].z > max.z) max.z = points[i].z;
+ else if (points[i].z > max.z)
+ max.z = points[i].z;
}
- if (center == null) center = new Vector3f();
+ if (center == null)
+ center = new Vector3f();
max.add(min, center).multLocal(.5f);
radius = max.subtractLocal(min).multLocal(.5f).length();
}
/**
- * <code>averagePoints</code> selects the sphere center to be the average
- * of the points and the sphere radius to be the smallest value to enclose
- * all points.
+ * <code>averagePoints</code> selects the sphere center to be the average of the points and
+ * the sphere radius to be the smallest value to enclose all points.
*
- * @param points
- * the list of points to contain.
+ * @param points the list of points to contain.
*/
public void averagePoints(Vector3f[] points) {
LoggingSystem.getLogger().log(Level.INFO,
@@ -367,54 +339,46 @@
for (int i = 0; i < points.length; i++) {
Vector3f diff = points[i].subtract(center);
float radiusSqr = diff.lengthSquared();
- if (radiusSqr > maxRadiusSqr) maxRadiusSqr = radiusSqr;
+ if (radiusSqr > maxRadiusSqr)
+ maxRadiusSqr = radiusSqr;
}
- radius = (float) Math.sqrt(maxRadiusSqr);
+ radius = (float)Math.sqrt(maxRadiusSqr);
}
/**
- * <code>transform</code> modifies the center of the sphere to reflect the
- * change made via a rotation, translation and scale.
+ * <code>transform</code> modifies the center of the sphere to reflect the change made via a
+ * rotation, translation and scale.
*
- * @param rotate
- * the rotation change.
- * @param translate
- * the translation change.
- * @param scale
- * the size change.
+ * @param rotate the rotation change.
+ * @param translate the translation change.
+ * @param scale the size change.
* @return BoundingVolume
*/
- public BoundingVolume transform(Quaternion rotate, Vector3f translate,
- Vector3f scale) {
- Vector3f newCenter = rotate.mult(center).multLocal(scale).addLocal(
- translate);
+ public BoundingVolume transform(Quaternion rotate, Vector3f translate, Vector3f scale) {
+ Vector3f newCenter = rotate.mult(center).multLocal(scale).addLocal(translate);
return new BoundingSphere(getMaxAxis(scale) * radius, newCenter);
}
/**
- * <code>transform</code> modifies the center of the sphere to reflect the
- * change made via a rotation, translation and scale.
+ * <code>transform</code> modifies the center of the sphere to reflect the change made via a
+ * rotation, translation and scale.
*
- * @param rotate
- * the rotation change.
- * @param translate
- * the translation change.
- * @param scale
- * the size change.
- * @param store
- * sphere to store result in
+ * @param rotate the rotation change.
+ * @param translate the translation change.
+ * @param scale the size change.
+ * @param store sphere to store result in
* @return BoundingVolume
* @return ref
*/
- public BoundingVolume transform(Quaternion rotate, Vector3f translate,
- Vector3f scale, BoundingVolume store) {
+ public BoundingVolume transform(Quaternion rotate, Vector3f translate, Vector3f scale,
+ BoundingVolume store) {
BoundingSphere sphere;
if (store == null || !(store instanceof BoundingSphere)) {
sphere = new BoundingSphere(1, new Vector3f(0, 0, 0));
} else {
- sphere = (BoundingSphere) store;
+ sphere = (BoundingSphere)store;
}
rotate.mult(center, sphere.center);
@@ -438,11 +402,10 @@
}
/**
- * <code>whichSide</code> takes a plane (typically provided by a view
- * frustum) to determine which side this bound is on.
+ * <code>whichSide</code> takes a plane (typically provided by a view frustum) to determine
+ * which side this bound is on.
*
- * @param plane
- * the plane to check against.
+ * @param plane the plane to check against.
* @return side
*/
public int whichSide(Plane plane) {
@@ -458,31 +421,31 @@
}
/**
- * <code>merge</code> combines this sphere with a second bounding sphere.
- * This new sphere contains both bounding spheres and is returned.
+ * <code>merge</code> combines this sphere with a second bounding sphere. This new sphere
+ * contains both bounding spheres and is returned.
*
- * @param volume
- * the sphere to combine with this sphere.
+ * @param volume the sphere to combine with this sphere.
* @return the new sphere
*/
public BoundingVolume merge(BoundingVolume volume) {
- if (volume == null) { return this; }
+ if (volume == null) {
+ return this;
+ }
if (volume instanceof BoundingSphere) {
- BoundingSphere sphere = (BoundingSphere) volume;
+ BoundingSphere sphere = (BoundingSphere)volume;
float temp_radius = sphere.getRadius();
Vector3f temp_center = sphere.getCenter();
BoundingSphere rVal = new BoundingSphere();
return merge(temp_radius, temp_center, rVal);
} else if (volume instanceof BoundingBox) {
- BoundingBox box = (BoundingBox) volume;
- Vector3f radVect = new Vector3f(box.xExtent, box.yExtent,
- box.zExtent);
+ BoundingBox box = (BoundingBox)volume;
+ Vector3f radVect = new Vector3f(box.xExtent, box.yExtent, box.zExtent);
Vector3f temp_center = box.getCenter();
BoundingSphere rVal = new BoundingSphere();
return merge(radVect.length(), temp_center, rVal);
} else if (volume instanceof OrientedBoundingBox) {
- OrientedBoundingBox box = (OrientedBoundingBox) volume;
- BoundingSphere rVal = (BoundingSphere) this.clone(null);
+ OrientedBoundingBox box = (OrientedBoundingBox)volume;
+ BoundingSphere rVal = (BoundingSphere)this.clone(null);
return rVal.mergeOBB(box);
} else {
return null;
@@ -490,29 +453,28 @@
}
/**
- * <code>mergeLocal</code> combines this sphere with a second bounding
- * sphere locally. Altering this sphere to contain both the original and the
- * additional sphere volumes;
+ * <code>mergeLocal</code> combines this sphere with a second bounding sphere locally.
+ * Altering this sphere to contain both the original and the additional sphere volumes;
*
- * @param volume
- * the sphere to combine with this sphere.
+ * @param volume the sphere to combine with this sphere.
* @return this
*/
public BoundingVolume mergeLocal(BoundingVolume volume) {
- if (volume == null) { return this; }
+ if (volume == null) {
+ return this;
+ }
if (volume instanceof BoundingSphere) {
- BoundingSphere sphere = (BoundingSphere) volume;
+ BoundingSphere sphere = (BoundingSphere)volume;
float temp_radius = sphere.getRadius();
Vector3f temp_center = sphere.getCenter();
return merge(temp_radius, temp_center, this);
} else if (volume instanceof BoundingBox) {
- BoundingBox box = (BoundingBox) volume;
- Vector3f radVect = new Vector3f(box.xExtent, box.yExtent,
- box.zExtent);
+ BoundingBox box = (BoundingBox)volume;
+ Vector3f radVect = new Vector3f(box.xExtent, box.yExtent, box.zExtent);
Vector3f temp_center = box.getCenter();
return merge(radVect.length(), temp_center, this);
} else if (volume instanceof OrientedBoundingBox) {
- return mergeOBB((OrientedBoundingBox) volume);
+ return mergeOBB((OrientedBoundingBox)volume);
} else {
return null;
}
@@ -521,38 +483,29 @@
/**
* Merges this sphere with the given OBB.
*
- * @param volume
- * The OBB to merge.
+ * @param volume The OBB to merge.
* @return This sphere, after merging.
*/
private BoundingSphere mergeOBB(OrientedBoundingBox volume) {
- if (!volume.correctCorners) volume.computeCorners();
+ if (!volume.correctCorners)
+ volume.computeCorners();
Vector3f[] mergeArray = new Vector3f[16];
for (int i = 0; i < 8; i++) {
mergeArray[i] = volume.vectorStore[i];
}
- mergeArray[8] = tempVarray[0].set(center).addLocal(radius, radius,
- radius);
- mergeArray[9] = tempVarray[1].set(center).addLocal(-radius, radius,
- radius);
- mergeArray[10] = tempVarray[2].set(center).addLocal(radius, -radius,
- radius);
- mergeArray[11] = tempVarray[3].set(center).addLocal(radius, radius,
- -radius);
- mergeArray[12] = tempVarray[4].set(center).addLocal(-radius, -radius,
- radius);
- mergeArray[13] = tempVarray[5].set(center).addLocal(-radius, radius,
- -radius);
- mergeArray[14] = tempVarray[6].set(center).addLocal(radius, -radius,
- -radius);
- mergeArray[15] = tempVarray[7].set(center).addLocal(-radius, -radius,
- -radius);
+ mergeArray[8] = tempVarray[0].set(center).addLocal(radius, radius, radius);
+ mergeArray[9] = tempVarray[1].set(center).addLocal(-radius, radius, radius);
+ mergeArray[10] = tempVarray[2].set(center).addLocal(radius, -radius, radius);
+ mergeArray[11] = tempVarray[3].set(center).addLocal(radius, radius, -radius);
+ mergeArray[12] = tempVarray[4].set(center).addLocal(-radius, -radius, radius);
+ mergeArray[13] = tempVarray[5].set(center).addLocal(-radius, radius, -radius);
+ mergeArray[14] = tempVarray[6].set(center).addLocal(radius, -radius, -radius);
+ mergeArray[15] = tempVarray[7].set(center).addLocal(-radius, -radius, -radius);
computeFromPoints(mergeArray);
return this;
}
- private BoundingVolume merge(float temp_radius, Vector3f temp_center,
- BoundingSphere rVal) {
+ private BoundingVolume merge(float temp_radius, Vector3f temp_center, BoundingSphere rVal) {
Vector3f diff = temp_center.subtract(center, tempVeca);
float lengthSquared = diff.lengthSquared();
float radiusDiff = temp_radius - radius;
@@ -567,7 +520,7 @@
}
}
- float length = (float) Math.sqrt(lengthSquared);
+ float length = (float)Math.sqrt(lengthSquared);
if (length > FastMath.FLT_EPSILON) {
float coeff = (length + radiusDiff) / (2.0f * length);
@@ -581,17 +534,16 @@
}
/**
- * <code>clone</code> creates a new BoundingSphere object containing the
- * same data as this one.
+ * <code>clone</code> creates a new BoundingSphere object containing the same data as this
+ * one.
*
- * @param store
- * where to store the cloned information. if null or wrong class,
- * a new store is created.
+ * @param store where to store the cloned information. if null or wrong class, a new store is
+ * created.
* @return the new BoundingSphere
*/
public Object clone(BoundingVolume store) {
if (store != null && store instanceof BoundingSphere) {
- BoundingSphere rVal = (BoundingSphere) store;
+ BoundingSphere rVal = (BoundingSphere)store;
if (null == rVal.center) {
rVal.center = new Vector3f();
}
@@ -607,30 +559,30 @@
rVal.checkPlanes[5] = checkPlanes[5];
return rVal;
} else
- return new BoundingSphere(radius,
- (center != null ? (Vector3f) center.clone() : null));
+ return new BoundingSphere(radius, (center != null ? (Vector3f)center.clone() : null));
}
/**
- * <code>getCheckPlane</code> returns a specific check plane. This plane
- * identitifies the previous value of the visibility check.
+ * <code>getCheckPlane</code> returns a specific check plane. This plane identitifies the
+ * previous value of the visibility check.
*/
public int getCheckPlane(int index) {
return checkPlanes[index];
}
/**
- * <code>setCheckPlane</code> indentifies the value of one of the spheres
- * checked planes. That is what plane of the view frustum has been checked
- * for intersection.
+ * <code>setCheckPlane</code> indentifies the value of one of the spheres checked planes. That
+ * is what plane of the view frustum has been checked for intersection.
*/
public void setCheckPlane(int index, int value) {
- checkPlanes[index] = value;
+ if (index < Camera.FRUSTUM_PLANES && value < Camera.FRUSTUM_PLANES) {
+ checkPlanes[index] = value;
+ }
}
/**
- * <code>recomputeMesh</code> regenerates the <code>BoundingSphere</code>
- * based on new model information.
+ * <code>recomputeMesh</code> regenerates the <code>BoundingSphere</code> based on new model
+ * information.
*/
public void recomputeMesh() {
if (radius != oldRadius || !center.equals(oldCenter)) {
@@ -641,11 +593,9 @@
}
/**
- * Find the distance from the center of this Bounding Volume to the given
- * point.
+ * Find the distance from the center of this Bounding Volume to the given point.
*
- * @param point
- * The point to get the distance to
+ * @param point The point to get the distance to
* @return distance
*/
public float distanceTo(Vector3f point) {
@@ -655,8 +605,7 @@
/**
* Stores the current center of this BoundingSphere into the store vector.
*
- * @param store
- * The vector to store the center into.
+ * @param store The vector to store the center into.
* @return The store vector, after setting it's contents to the center
*/
public Vector3f getCenter(Vector3f store) {
@@ -664,14 +613,13 @@
}
/**
- * <code>toString</code> returns the string representation of this object.
- * The form is: "Radius: RRR.SSSS Center: <Vector>".
+ * <code>toString</code> returns the string representation of this object. The form is:
+ * "Radius: RRR.SSSS Center: <Vector>".
*
* @return the string representation of this.
*/
public String toString() {
- return "com.jme.scene.BoundingSphere [Radius: " + radius + " Center: "
- + center + "]";
+ return "com.jme.scene.BoundingSphere [Radius: " + radius + " Center: " + center + "]";
}
/*
@@ -697,40 +645,37 @@
return (diff.dot(diff) <= rsum * rsum);
}
- /*
- * (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.jme.bounding.BoundingVolume#intersectsBoundingBox(com.jme.bounding.BoundingBox)
+ */
+ public boolean intersectsBoundingBox(BoundingBox bb) {
+ if (FastMath.abs(bb.center.x - getCenter().x) < getRadius() + bb.xExtent
+ && FastMath.abs(bb.center.y - getCenter().y) < getRadius() + bb.yExtent
+ && FastMath.abs(bb.center.z - getCenter().z) < getRadius() + bb.zExtent)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
*
- * @see com.jme.bounding.BoundingVolume#intersectsBoundingBox(com.jme.bounding.BoundingBox)
- */
- public boolean intersectsBoundingBox(BoundingBox bb) {
- if(FastMath.abs(bb.center.x-getCenter().x)<getRadius()+bb.xExtent
- && FastMath.abs(bb.center.y-getCenter().y)<getRadius()+bb.yExtent
- && FastMath.abs(bb.center.z-getCenter().z)<getRadius()+bb.zExtent)
- return true;
-
- return false;
- }
-
-
- /*
- * (non-Javadoc)
- *
- * @see com.jme.bounding.BoundingVolume#intersectsOrientedBoundingBox(com.jme.bounding.OrientedBoundingBox)
- */
- public boolean intersectsOrientedBoundingBox(OrientedBoundingBox obb) {
- return obb.intersectsSphere(this);
- }
-
-
- /*
- * (non-Javadoc)
- *
- * @see com.jme.bounding.BoundingVolume#intersectsOBB2(com.jme.bounding.OBB2)
- */
- public boolean intersectsOBB2(OBB2 obb) {
- return obb.intersectsSphere(this);
- }
+ * @see com.jme.bounding.BoundingVolume#intersectsOrientedBoundingBox(com.jme.bounding.OrientedBoundingBox)
+ */
+ public boolean intersectsOrientedBoundingBox(OrientedBoundingBox obb) {
+ return obb.intersectsSphere(this);
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.jme.bounding.BoundingVolume#intersectsOBB2(com.jme.bounding.OBB2)
+ */
+ public boolean intersectsOBB2(OBB2 obb) {
+ return obb.intersectsSphere(this);
+ }
/*
* (non-Javadoc)
@@ -748,7 +693,7 @@
if (discr < 0.0) {
return false;
} else if (discr > 0.0) {
- float root = (float) Math.sqrt(discr);
+ float root = (float)Math.sqrt(discr);
float invA = 1.0f / a;
t[0] = (-b - root) * invA;
t[1] = (-b + root) * invA;
Index: OBB2.java
===================================================================
RCS file: /cvs/jme/src/com/jme/bounding/OBB2.java,v
retrieving revision 1.7
diff -u -r1.7 OBB2.java
--- OBB2.java 6 Dec 2004 19:04:10 -0000 1.7
+++ OBB2.java 14 Dec 2004 22:22:22 -0000
@@ -1,6 +1,7 @@
package com.jme.bounding;
import com.jme.math.*;
+import com.jme.renderer.Camera;
/**
* Started Date: Sep 5, 2004 <br>
@@ -423,12 +424,9 @@
}
public void initCheckPlanes() {
- checkPlanes[0] = 0;
- checkPlanes[1] = 1;
- checkPlanes[2] = 2;
- checkPlanes[3] = 3;
- checkPlanes[4] = 4;
- checkPlanes[5] = 5;
+ for (int i = 0; i < Camera.MAX_WORLD_PLANES; i++) {
+ checkPlanes[i] = i;
+ }
}
public int getCheckPlane(int index) {
@@ -436,7 +434,9 @@
}
public void setCheckPlane(int index, int value) {
- checkPlanes[index] = value;
+ if (index < Camera.FRUSTUM_PLANES && value < Camera.FRUSTUM_PLANES) {
+ checkPlanes[index] = value;
+ }
}
public void recomputeMesh() {
Index: OrientedBoundingBox.java
===================================================================
RCS file: /cvs/jme/src/com/jme/bounding/OrientedBoundingBox.java,v
retrieving revision 1.10
diff -u -r1.10 OrientedBoundingBox.java
--- OrientedBoundingBox.java 6 Dec 2004 19:04:10 -0000 1.10
+++ OrientedBoundingBox.java 14 Dec 2004 22:22:24 -0000
@@ -1,5 +1,6 @@
package com.jme.bounding;
+import com.jme.renderer.Camera;
import com.jme.scene.shape.OrientedBox;
import com.jme.math.*;
@@ -379,12 +380,9 @@
}
public void initCheckPlanes() {
- checkPlanes[0] = 0;
- checkPlanes[1] = 1;
- checkPlanes[2] = 2;
- checkPlanes[3] = 3;
- checkPlanes[4] = 4;
- checkPlanes[5] = 5;
+ for (int i = 0; i < Camera.MAX_WORLD_PLANES; i++) {
+ checkPlanes[i] = i;
+ }
}
public int getCheckPlane(int index) {
@@ -392,7 +390,9 @@
}
public void setCheckPlane(int index, int value) {
- &nbs