OSG_BASE_DLLMAPPING void extend(SphereVolume &srcVol, const CylinderVolume &vol) { Pnt3f min, max, min1, max1, min2, max2, c; Real32 r; if((!srcVol.isValid () && !srcVol.isEmpty()) || srcVol.isInfinite() || srcVol.isStatic () ) { return; } if(!vol.isValid()) return; if(srcVol.isEmpty()) { if(vol.isEmpty()) { return; } else { vol.getBounds(min, max); vol.getCenter(c); r = (min - c).length(); srcVol.setValue(c, r); return; } } else if(vol.isEmpty()) { return; } srcVol.getBounds(min, max); vol .getBounds(min1, max1); min2 = Pnt3f(osgMin(min.x(), min1.x()), osgMin(min.y(), min1.y()), osgMin(min.z(), min1.z())); max2 = Pnt3f(osgMax(max.x(), max1.x()), osgMax(max.y(), max1.y()), osgMax(max.z(), max1.z())); c = Pnt3f((min2.x() + max2.x()) * 0.5f, (min2.y() + max2.y()) * 0.5f, (min2.z() + max2.z()) * 0.5f); r = ((max2 - min2).length()) * 0.5f; srcVol.setValue(c, r); return; }
OSG_BASE_DLLMAPPING bool intersect(const SphereVolume &sphere1, const SphereVolume &sphere2) { bool retCode = false; Real32 dist = (sphere2.getCenter() - sphere1.getCenter()).length(); if(sphere1.isEmpty() || sphere2.isEmpty()) { retCode = false; } else if(sphere1.isInfinite() || sphere2.isInfinite()) { retCode = true; } else if(dist < sphere1.getRadius() + sphere2.getRadius()) { // the distance between the center of the 2 spheres is bigger // than the sum of the 2 radiuses retCode = true; } return retCode; }
OSG_BASE_DLLMAPPING void extend(BoxVolume &srcVol, const SphereVolume &vol) { Pnt3f min, max; if((!srcVol.isValid () && !srcVol.isEmpty()) || srcVol.isInfinite() || srcVol.isStatic () ) { return; } if(!vol.isValid()) return; if(srcVol.isEmpty()) { if(vol.isEmpty()) { return; } else { vol .getBounds(min, max); srcVol.setBounds(min, max); return; } } else if(vol.isEmpty()) { return; } vol.getBounds(min, max); srcVol.setBounds(osgMin(min.x(), srcVol.getMin().x()), osgMin(min.y(), srcVol.getMin().y()), osgMin(min.z(), srcVol.getMin().z()), osgMax(max.x(), srcVol.getMax().x()), osgMax(max.y(), srcVol.getMax().y()), osgMax(max.z(), srcVol.getMax().z())); if(vol.isInfinite()) srcVol.setInfinite(true); return; }
OSG_BASE_DLLMAPPING bool intersect(const BoxVolume &box, const SphereVolume &sphere) { // source: // J. Arvo. A simple method for box-sphere intersection testing. // In A. Glassner, editor, Graphics Gems, pp. 335-339, // Academic Press, Boston, MA, 1990 bool retCode; if(box.isEmpty() == true || sphere.isEmpty() == true) { retCode = false; } else if(box.isInfinite() == true || sphere.isInfinite() == true) { retCode = true; } else { Real32 s; Real32 d = 0.f; //find the square of the distance from the sphere to the box for(Int32 i = 0; i < 3; i++) { if(sphere.getCenter()[i] < box.getMin()[i]) { s = sphere.getCenter()[i] - box.getMin()[i]; d += s * s; } else if(sphere.getCenter()[i] > box.getMax()[i]) { s = sphere.getCenter()[i] - box.getMax()[i]; d += s * s; } } retCode = (d <= (sphere.getRadius() * sphere.getRadius())); } return retCode; }
OSG_BASE_DLLMAPPING void extend(SphereVolume &srcVol, const BoxVolume &vol) { Pnt3f min, max, min1, max1, c; Real32 r; BoxVolume vol1; vol.getBounds(min, max); if((!srcVol.isValid () && !srcVol.isEmpty()) || srcVol.isInfinite() || srcVol.isStatic () ) { return; } if(!vol.isValid()) return; if(srcVol.isEmpty()) { if(vol.isEmpty()) { return; } else { c = Pnt3f((min.x() + max.x()) * 0.5f, (min.y() + max.y()) * 0.5f, (min.z() + max.z()) * 0.5f); r = ((max - min).length()) / 2; srcVol.setValue(c, r); return; } } else if(vol.isEmpty()) { return; } srcVol.getBounds(min1, max1); vol1.setBounds(osgMin(min.x(), min1.x()), osgMin(min.y(), min1.y()), osgMin(min.z(), min1.z()), osgMax(max.x(), max1.x()), osgMax(max.y(), max1.y()), osgMax(max.z(), max1.z())); vol1.getBounds(min, max); c = Pnt3f((min.x() + max.x()) * 0.5f, (min.y() + max.y()) * 0.5f, (min.z() + max.z()) * 0.5f); r = ((max - min).length()) / 2; srcVol.setValue(c, r); return; }
OSG_BASE_DLLMAPPING bool intersect(const SphereVolume &sphere, const CylinderVolume &cylinder) { bool retCode; Pnt3f apos; Vec3f adir; cylinder.getAxis(apos, adir); if(sphere.isEmpty() || cylinder.isEmpty()) { retCode = false; } else if(sphere.isInfinite() || cylinder.isInfinite()) { retCode = true; } else { Real32 d = 0.f, s1 = 0.f, s2 = 0.f; Pnt3f c; Vec3f u, u1, u2; //get the distance between the upper and lower point of the cylinder // and the sphere center s1 = (apos - sphere.getCenter()).length(); s2 = (apos + adir - sphere.getCenter()).length(); if ((s1<=DBL_EPSILON) || (s2<=DBL_EPSILON)) return true; //check the smallest distance and set the vector coordinate if(s1 <= s2) { d = s1; c = apos; } else { d = s2; c = apos + adir; } // decompose the vector in u1 and u2 which are parallel and // perpendicular to the cylinder axis respectively u = ((d - sphere.getRadius()) / d) * (c - sphere.getCenter()); u1 = (u[0] * adir[0] + u[1] * adir[1] + u[2] * adir[2]) / (adir.length() * adir.length()) * adir; u2 = u - u1; if(u2.length() <= 10e-6) { retCode = (d <= sphere.getRadius()); } else { retCode = (u2.length() <= cylinder.getRadius()); } } return retCode; }