/** * <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. * @return this */ public BoundingVolume mergeLocal(BoundingVolume volume) { if (volume == null) { return this; } switch (volume.getType()) { case Sphere: { BoundingSphere sphere = (BoundingSphere) volume; float temp_radius = sphere.getRadius(); Vector3f temp_center = sphere.center; return merge(temp_radius, temp_center, this); } case AABB: { BoundingBox box = (BoundingBox) volume; Vector3f radVect = Vector3f.newInstance(); radVect.set(box.xExtent, box.yExtent, box.zExtent); Vector3f temp_center = box.center; float len = radVect.length(); Vector3f.recycle(radVect); return merge(len, temp_center, this); } // case OBB: { // return mergeOBB((OrientedBoundingBox) volume); // } default: return null; } }
/** * <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. * @return a new sphere */ public BoundingVolume merge(BoundingVolume volume) { if (volume == null) { return this; } switch (volume.getType()) { case Sphere: { BoundingSphere sphere = (BoundingSphere) volume; float temp_radius = sphere.getRadius(); Vector3f temp_center = sphere.center; BoundingSphere rVal = new BoundingSphere(); return merge(temp_radius, temp_center, rVal); } case AABB: { BoundingBox box = (BoundingBox) volume; Vector3f radVect = new Vector3f(box.xExtent, box.yExtent, box.zExtent); Vector3f temp_center = box.center; BoundingSphere rVal = new BoundingSphere(); return merge(radVect.length(), temp_center, rVal); } // case OBB: { // OrientedBoundingBox box = (OrientedBoundingBox) volume; // BoundingSphere rVal = (BoundingSphere) this.clone(null); // return rVal.mergeOBB(box); // } default: return null; } }
/** * <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. * @return the new BoundingSphere */ public BoundingVolume clone(BoundingVolume store) { if (store != null && store.getType() == Type.Sphere) { BoundingSphere rVal = (BoundingSphere) store; if (null == rVal.center) { rVal.center = new Vector3f(); } rVal.center.set(center); rVal.radius = radius; rVal.checkPlane = checkPlane; return rVal; } return new BoundingSphere(radius, (center != null ? (Vector3f) center.clone() : null)); }
public BoundingVolume transform(Matrix4f trans, BoundingVolume store) { BoundingSphere sphere; if (store == null || store.getType() != BoundingVolume.Type.Sphere) { sphere = new BoundingSphere(1, new Vector3f(0, 0, 0)); } else { sphere = (BoundingSphere) store; } trans.mult(center, sphere.center); Vector3f axes = new Vector3f(1, 1, 1); trans.mult(axes, axes); float ax = getMaxAxis(axes); sphere.radius = FastMath.abs(ax * radius) + RADIUS_EPSILON - 1f; return sphere; }
/* * (non-Javadoc) * @see com.jme.bounding.BoundingVolume#intersectsSphere(com.jme.bounding.BoundingSphere) */ public boolean intersectsSphere(BoundingSphere bs) { assert Vector3f.isValidVector(center) && Vector3f.isValidVector(bs.center); Vector3f vect1 = Vector3f.newInstance(); Vector3f diff = center.subtract(bs.center, vect1); float rsum = getRadius() + bs.getRadius(); boolean eq = (diff.dot(diff) <= rsum * rsum); Vector3f.recycle(vect1); return eq; }
// /** // * Merges this sphere with the given OBB. // * // * @param volume // * The OBB to merge. // * @return This sphere, after merging. // */ // private BoundingSphere mergeOBB(OrientedBoundingBox volume) { // // compute edge points from the obb // if (!volume.correctCorners) // volume.computeCorners(); // _mergeBuf.rewind(); // for (int i = 0; i < 8; i++) { // _mergeBuf.put(volume.vectorStore[i].x); // _mergeBuf.put(volume.vectorStore[i].y); // _mergeBuf.put(volume.vectorStore[i].z); // } // // // remember old radius and center // float oldRadius = radius; // Vector3f oldCenter = _compVect2.set( center ); // // // compute new radius and center from obb points // computeFromPoints(_mergeBuf); // Vector3f newCenter = _compVect3.set( center ); // float newRadius = radius; // // // restore old center and radius // center.set( oldCenter ); // radius = oldRadius; // // //merge obb points result // merge( newRadius, newCenter, this ); // // return this; // } private BoundingVolume merge(float temp_radius, Vector3f temp_center, BoundingSphere rVal) { Vector3f vect1 = Vector3f.newInstance(); Vector3f diff = temp_center.subtract(center, vect1); float lengthSquared = diff.lengthSquared(); float radiusDiff = temp_radius - radius; float fRDiffSqr = radiusDiff * radiusDiff; if (fRDiffSqr >= lengthSquared) { if (radiusDiff <= 0.0f) { Vector3f.recycle(vect1); return this; } Vector3f rCenter = rVal.center; if (rCenter == null) { rVal.setCenter(rCenter = new Vector3f()); } rCenter.set(temp_center); rVal.setRadius(temp_radius); Vector3f.recycle(vect1); return rVal; } float length = (float) Math.sqrt(lengthSquared); Vector3f rCenter = rVal.center; if (rCenter == null) { rVal.setCenter(rCenter = new Vector3f()); } if (length > RADIUS_EPSILON) { float coeff = (length + radiusDiff) / (2.0f * length); rCenter.set(center.addLocal(diff.multLocal(coeff))); } else { rCenter.set(center); } rVal.setRadius(0.5f * (length + radius + temp_radius)); Vector3f.recycle(vect1); return rVal; }