// /** // * 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; }
/** * <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. */ public void averagePoints(Vector3f[] points) { logger.info("Bounding Sphere calculated using average points."); center = points[0]; for (int i = 1; i < points.length; i++) { center.addLocal(points[i]); } float quantity = 1.0f / points.length; center.multLocal(quantity); float maxRadiusSqr = 0; for (int i = 0; i < points.length; i++) { Vector3f diff = points[i].subtract(center); float radiusSqr = diff.lengthSquared(); if (radiusSqr > maxRadiusSqr) { maxRadiusSqr = radiusSqr; } } radius = (float) Math.sqrt(maxRadiusSqr) + RADIUS_EPSILON - 1f; }