Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGVolumeFunctions.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *                 Copyright (C) 2000 by the OpenSG Forum                    *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the impclied warranty of               *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028  \*--------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 #include "OSGVolume.h"
00040 #include "OSGBoxVolume.h"
00041 #include "OSGSphereVolume.h"
00042 #include "OSGCylinderVolume.h"
00043 #include "OSGFrustumVolume.h"
00044 #include "OSGDynamicVolume.h"
00045 
00046 OSG_BEGIN_NAMESPACE
00047 
00048 // ###################################################################
00049 // # Volume Interesect Functions #####################################
00050 // ###################################################################
00051 
00052 OSG_BASE_DLLMAPPING 
00053 bool intersect(const Volume &vol1, const Volume &vol2)
00054 {
00055     bool                  retCode = false;
00056 
00057     const DynamicVolume  *dv      = dynamic_cast<const DynamicVolume *>(&vol1);
00058     const Volume         *v       = dv ? &(dv->getInstance()) : &vol1;
00059     const BoxVolume      *bv;
00060     const SphereVolume   *sv;
00061     const CylinderVolume *cv;
00062     const FrustumVolume  *fv;
00063 
00064     if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
00065     {
00066         retCode = intersect(*bv, vol2);
00067     }
00068     else if((sv = dynamic_cast<const SphereVolume   *>(v)) != NULL)
00069     {
00070         retCode = intersect(*sv, vol2);
00071     }
00072     else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
00073     {
00074         retCode = intersect(*cv, vol2);
00075     }
00076     else if((fv = dynamic_cast<const FrustumVolume  *>(v)) != NULL)
00077     {
00078         retCode = intersect(*fv, vol2);
00079     }
00080 
00081     return retCode;
00082 }
00083 
00084 // # Box #############################################################
00085 
00086 OSG_BASE_DLLMAPPING 
00087 bool intersect(const BoxVolume &box1, const BoxVolume &box2)
00088 {
00089     bool retCode = false;
00090 
00091     if(box1.isEmpty() == true || box2.isEmpty() == true)
00092     {
00093         retCode = false;
00094     }
00095     else if(box1.isInfinite() == true || box2.isInfinite() == true)
00096     {
00097         retCode = true;
00098     }
00099     else
00100     {
00101         retCode =
00102             (box1.getMin()[0] <= box2.getMax()[0] &&
00103              box1.getMax()[0] >= box2.getMin()[0]   ) &&
00104             (box1.getMin()[1] <= box2.getMax()[1] &&
00105              box1.getMax()[1] >= box2.getMin()[1]   ) &&
00106             (box1.getMin()[2] <= box2.getMax()[2] &&
00107              box1.getMax()[2] >= box2.getMin()[2]   );
00108     }
00109 
00110     return retCode;
00111 }
00112 
00113 
00114 OSG_BASE_DLLMAPPING 
00115 bool intersect(const BoxVolume &box, const SphereVolume &sphere)
00116 {
00117     // source:
00118     // J. Arvo. A simple method for box-sphere intersection testing.
00119     // In A. Glassner, editor, Graphics Gems, pp. 335-339,
00120     // Academic Press, Boston, MA, 1990
00121 
00122     bool    retCode;
00123    
00124     if(box.isEmpty() == true || sphere.isEmpty() == true)
00125     {
00126         retCode = false;
00127     }
00128     else if(box.isInfinite() == true || sphere.isInfinite() == true)
00129     {
00130         retCode = true;
00131     }
00132     else
00133     {
00134         Real32  s;
00135         Real32  d = 0.f;
00136 
00137         //find the square of the distance from the sphere to the box
00138 
00139         for(Int32 i = 0; i < 3; i++)
00140         {
00141             if(sphere.getCenter()[i] < box.getMin()[i])
00142             {
00143                 s  = sphere.getCenter()[i] - box.getMin()[i];
00144                 d += s * s;
00145             }
00146             else if(sphere.getCenter()[i] > box.getMax()[i])
00147             {
00148                 s  = sphere.getCenter()[i] - box.getMax()[i];
00149                 d += s * s;
00150             }
00151         }
00152 
00153         retCode = (d <= (sphere.getRadius() * sphere.getRadius()));
00154     }
00155 
00156     return retCode;
00157 }
00158 
00159 OSG_BASE_DLLMAPPING 
00160 bool intersect(const BoxVolume &box, const CylinderVolume &cylinder)
00161 {
00162     bool  retCode;
00163     Pnt3f apos;
00164     Vec3f adir;
00165 
00166     cylinder.getAxis(apos, adir);
00167 
00168     if(box.isEmpty() == true || cylinder.isEmpty() == true)
00169     {
00170         retCode = false;
00171     }
00172     else if(box.isInfinite() == true || cylinder.isInfinite() == true)
00173     {
00174         retCode = true;
00175     }
00176     else
00177     {
00178         Real32  s1 = 0, s2 = 0, s3 = 0, s4 = 0, d = 0, d1 = 0, d2 = 0;
00179         Pnt3f   c, p, p1, p2;
00180         Vec3f   u, u1, u2;
00181 
00182         // find the distance between the min and the max of the box
00183         //with the lower point and the upper point of the cylinder respectively
00184 
00185         s1 = (apos - box.getMin()).length();
00186         s2 = (apos - box.getMax()).length();
00187 
00188         s3 = (apos + adir - box.getMin()).length();
00189         s4 = (apos + adir - box.getMax()).length();
00190 
00191         //Check the minimum of the above distances
00192 
00193         if(s1 <= s2)
00194         {
00195             d1 = s1;
00196             p1 = box.getMin();
00197         }
00198         else
00199         {
00200             d1 = s2;
00201             p1 = box.getMax();
00202         }
00203 
00204         if(s3 <= s4)
00205         {
00206             d2 = s3;
00207             p2 = box.getMin();
00208         }
00209         else
00210         {
00211             d2 = s4;
00212             p2 = box.getMax();
00213         }
00214 
00215         //set the value of the vector corresponding to the shortest distance
00216         if(d1 <= d2)
00217         {
00218             d = d1;
00219             c = apos;
00220             p = p1;
00221         }
00222         else
00223         {
00224             d = d2;
00225             c = apos + adir;
00226             p = p2;
00227         }
00228 
00229         // decompose the vector in u1 and u2 which are parallel and 
00230         // perpendicular to the cylinder axis respectively
00231         u  = p - c;
00232         u1 = (u[0] * adir[0] + u[1] * adir[1] + u[2] * adir[2]) /
00233             (adir.length() * adir.length()) * adir;
00234 
00235         u2 = u - u1;
00236 
00237         if(u1.length() <= 10e-6)
00238         {
00239             retCode = true;
00240         }
00241         else if(u2.length() <= 10e-6)
00242         {
00243             retCode = (d <= 10e-6);
00244         }
00245         else
00246         {
00247             retCode = (u2.length() <= cylinder.getRadius());
00248         }
00249     }
00250 
00251     return retCode;
00252 }
00253 
00254 
00255 OSG_BASE_DLLMAPPING 
00256 bool intersect(const BoxVolume &box, const FrustumVolume &frustum)
00257 {
00258     Pnt3f min, max;
00259     box.getBounds(min, max);
00260 
00261     const Plane       *frust = frustum.getPlanes();
00262 
00263     // check each point of the box to the 6 planes
00264 
00265     for(Int32 i = 0; i < 6; i++)
00266     {
00267         if(frust[i].isOutHalfSpace(min, max))
00268             return false;
00269     }
00270 
00271     return true;
00272 }
00273 
00274 OSG_BASE_DLLMAPPING 
00275 bool intersect(const BoxVolume &box, const Volume &vol)
00276 {
00277     bool                 retCode = false;
00278 
00279     const DynamicVolume  *dv     = dynamic_cast<const DynamicVolume *>(&vol);
00280     const Volume         *v      = dv ? &(dv->getInstance()) : &vol;
00281     const BoxVolume      *bv;
00282     const SphereVolume   *sv;
00283     const CylinderVolume *cv;
00284     const FrustumVolume  *fv;
00285 
00286     if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
00287     {
00288         retCode = intersect(box, *bv);
00289     }
00290     else if((sv = dynamic_cast<const SphereVolume   *>(v)) != NULL)
00291     {
00292         retCode = intersect(box, *sv);
00293     }
00294     else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
00295     {
00296         retCode = intersect(box, *cv);
00297     }
00298     else if((fv = dynamic_cast<const FrustumVolume  *>(v)) != NULL)
00299     {
00300         retCode = intersect(box, *fv);
00301     }
00302 
00303     return retCode;
00304 }
00305 
00306 
00307 // # Sphere ###########################################################
00308 
00309 OSG_BASE_DLLMAPPING 
00310 bool intersect(const SphereVolume &sphere1, const SphereVolume &sphere2)
00311 {
00312     bool    retCode = false;
00313     Real32  dist    = (sphere2.getCenter() - sphere1.getCenter()).length();
00314 
00315     if(sphere1.isEmpty() || sphere2.isEmpty())
00316     {
00317         retCode = false;
00318     }
00319     else if(sphere1.isInfinite() || sphere2.isInfinite())
00320     {
00321         retCode = true;
00322     }
00323     else if(dist < sphere1.getRadius() + sphere2.getRadius())
00324     {
00325         // the distance between the center of the 2 spheres is bigger
00326         // than the sum of the 2 radiuses
00327 
00328         retCode = true;
00329     }
00330 
00331     return retCode;
00332 }
00333 
00334 
00335 OSG_BASE_DLLMAPPING 
00336 bool intersect(const SphereVolume &sphere, const CylinderVolume &cylinder)
00337 {
00338     bool  retCode;
00339     Pnt3f apos;
00340     Vec3f adir;
00341 
00342     cylinder.getAxis(apos, adir);
00343 
00344     if(sphere.isEmpty() || cylinder.isEmpty())
00345     {
00346         retCode = false;
00347     }
00348     else if(sphere.isInfinite() || cylinder.isInfinite())
00349     {
00350         retCode = true;
00351     }
00352     else
00353     {
00354         Real32  d = 0.f, s1 = 0.f, s2 = 0.f;
00355         Pnt3f   c;
00356         Vec3f   u, u1, u2;
00357 
00358         //get the distance between the upper and lower point of the cylinder
00359         // and the sphere center
00360 
00361         s1 = (apos        - sphere.getCenter()).length();
00362         s2 = (apos + adir - sphere.getCenter()).length();
00363 
00364         if ((s1<=DBL_EPSILON) || (s2<=DBL_EPSILON)) 
00365             return true;
00366         
00367         //check the smallest distance and set the vector coordinate
00368         if(s1 <= s2)
00369         {
00370             d = s1;
00371             c = apos;
00372         }
00373         else
00374         {
00375             d = s2;
00376             c = apos + adir;
00377         }
00378 
00379         // decompose the vector in u1 and u2 which are parallel and 
00380         // perpendicular to the cylinder axis respectively
00381 
00382         u  = ((d - sphere.getRadius()) / d) * (c - sphere.getCenter());
00383 
00384         u1 = (u[0] * adir[0] + u[1] * adir[1] + u[2] * adir[2]) / 
00385              (adir.length() * adir.length()) * adir;
00386         u2 = u - u1;
00387 
00388         if(u2.length() <= 10e-6)
00389         {
00390             retCode = (d <= sphere.getRadius());
00391         }
00392         else
00393         {
00394             retCode = (u2.length() <= cylinder.getRadius());
00395         }
00396     }
00397 
00398     return retCode;
00399 }
00400 
00401 
00402 OSG_BASE_DLLMAPPING 
00403 bool intersect(const SphereVolume &sphere, const FrustumVolume &frustum)
00404 {
00405     const Plane             *frust = frustum.getPlanes();
00406 
00407     //check the center of the sphere with each plane of the frustum
00408     for(Int32 i = 0; i < 6; i++)
00409     {
00410         if(frust[i].distance(sphere.getCenter()) < -sphere.getRadius())
00411             return false;
00412     }
00413 
00414     return true;
00415 }
00416 
00417 
00418 OSG_BASE_DLLMAPPING 
00419 bool intersect(const SphereVolume &sphere, const Volume &vol)
00420 {
00421     bool                 retCode = false;
00422 
00423     const DynamicVolume  *dv     = dynamic_cast<const DynamicVolume *>(&vol);
00424     const Volume         *v      = dv ? &(dv->getInstance()) : &vol;
00425     const BoxVolume      *bv;
00426     const SphereVolume   *sv;
00427     const CylinderVolume *cv;
00428     const FrustumVolume  *fv;
00429 
00430     if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
00431     {
00432         retCode = intersect(sphere, *bv);
00433     }
00434     else if((sv = dynamic_cast<const SphereVolume   *>(v)) != NULL)
00435     {
00436         retCode = intersect(sphere, *sv);
00437     }
00438     else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
00439     {
00440         retCode = intersect(sphere, *cv);
00441     }
00442     else if((fv = dynamic_cast<const FrustumVolume  *>(v)) != NULL)
00443     {
00444         retCode = intersect(sphere, *fv);
00445     }
00446 
00447     return retCode;
00448 }
00449 
00450 
00451 // # Cylinder ########################################################
00452 
00453 OSG_BASE_DLLMAPPING 
00454 bool intersect(const CylinderVolume &cylinder1, 
00455                const CylinderVolume &cylinder2)
00456 {
00457     Vec3f   adir1, adir2, n, p;
00458     Pnt3f   apos1, apos2;
00459     double  d;
00460     bool    retCode = false;
00461 
00462     cylinder1.getAxis(apos1, adir1);
00463     cylinder2.getAxis(apos2, adir2);
00464 
00465     //get the shortest distance between the two axes of the cylinders
00466 
00467     n = adir1.cross(adir2);
00468     n.normalize();
00469 
00470     p = apos1 - apos2;
00471     d = fabs(n.dot(p.addToZero()));
00472 
00473     if(cylinder1.isEmpty() == true || cylinder2.isEmpty() == true)
00474     {
00475         retCode = false;
00476     }
00477     else if(cylinder1.isInfinite() == true || cylinder2.isInfinite() == true)
00478     {
00479         retCode = true;
00480     }
00481     else if(d <= cylinder1.getRadius() + cylinder2.getRadius())
00482     {
00483         // the distance is smaller than the sum of the 2 radiuses
00484         retCode = true;
00485     }
00486 
00487     return retCode;
00488 }
00489 
00490 
00491 OSG_BASE_DLLMAPPING 
00492 bool intersect(const CylinderVolume &cylinder, const FrustumVolume &frustum)
00493 {
00494     Pnt3f min, max;
00495     cylinder.getBounds(min, max);
00496 
00497     const Plane       *frust = frustum.getPlanes();
00498 
00499     // check each point of the box to the 6 planes
00500 
00501     for(Int32 i = 0; i < 6; i++)
00502     {
00503         if(frust[i].isOutHalfSpace(min, max))
00504             return false;
00505     }
00506 
00507     return true;
00508 }
00509 
00510 
00511 OSG_BASE_DLLMAPPING 
00512 bool intersect(const CylinderVolume &cylinder, const Volume &vol)
00513 {
00514     bool                 retCode = false;
00515 
00516     const DynamicVolume  *dv     = dynamic_cast<const DynamicVolume *>(&vol);
00517     const Volume         *v      = dv ? &(dv->getInstance()) : &vol;
00518     const BoxVolume      *bv;
00519     const SphereVolume   *sv;
00520     const CylinderVolume *cv;
00521     const FrustumVolume  *fv;
00522 
00523     if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
00524     {
00525         retCode = intersect(cylinder, *bv);
00526     }
00527     else if((sv = dynamic_cast<const SphereVolume *>(v)) != NULL)
00528     {
00529         retCode = intersect(cylinder, *sv);
00530     }
00531     else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
00532     {
00533         retCode = intersect(cylinder, *cv);
00534     }
00535     else if((fv = dynamic_cast<const FrustumVolume *>(v)) != NULL)
00536     {
00537         retCode = intersect(cylinder, *fv);
00538     }
00539 
00540     return retCode;
00541 }
00542 
00543 
00544 // # Frustum ########################################################
00545 
00546 OSG_BASE_DLLMAPPING 
00547 bool intersect(const FrustumVolume &OSG_CHECK_ARG(frustum1),
00548                const FrustumVolume &OSG_CHECK_ARG(frustum2))
00549 {
00550     FFATAL(("intersect (frustum/frustum) is not impl.\n"));
00551     return false;
00552 }
00553 
00554 OSG_BASE_DLLMAPPING 
00555 bool intersect(const FrustumVolume &frustum, const Volume &vol)
00556 {
00557     bool                  retCode = false;
00558 
00559     const DynamicVolume  *dv      = dynamic_cast<const DynamicVolume *>(&vol);
00560     const Volume         *v       = dv ? &(dv->getInstance()) : &vol;
00561     const BoxVolume      *bv;
00562     const SphereVolume   *sv;
00563     const CylinderVolume *cv;
00564     const FrustumVolume  *fv;
00565 
00566     if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
00567     {
00568         retCode = intersect(frustum, *bv);
00569     }
00570     else if((sv = dynamic_cast<const SphereVolume *>(v)) != NULL)
00571     {
00572         retCode = intersect(frustum, *sv);
00573     }
00574     else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
00575     {
00576         retCode = intersect(frustum, *cv);
00577     }
00578     else if((fv = dynamic_cast<const FrustumVolume *>(v)) != NULL)
00579     {
00580         retCode = intersect(frustum, *fv);
00581     }
00582 
00583     return retCode;
00584 }
00585 
00586 
00587 // ###################################################################
00588 // # Volume Extend Functions #########################################
00589 // ###################################################################
00590 
00591 
00592 OSG_BASE_DLLMAPPING 
00593 void extend(Volume &OSG_CHECK_ARG(srcVol), const Volume &OSG_CHECK_ARG(vol))
00594 {
00595     FFATAL(("extend (frustum/volume) is not impl.\n"));
00596     return;
00597 }
00598 
00599 
00600 // # Box #############################################################
00601 
00602 OSG_BASE_DLLMAPPING 
00603 void extend(BoxVolume &srcVol, const BoxVolume &vol)
00604 {
00605     if( (!srcVol.isValid   () && !srcVol.isEmpty()) ||
00606           srcVol.isInfinite()                       ||
00607           srcVol.isStatic  ()                         )
00608     {
00609         return;
00610     }
00611 
00612     if(!vol.isValid())
00613         return;
00614 
00615     if(srcVol.isEmpty())
00616     {
00617         if(vol.isEmpty())
00618         {
00619             return;
00620         }
00621         else
00622         {
00623             srcVol = vol;
00624             return;
00625         }
00626     }
00627     else if(vol.isEmpty())
00628     {
00629         return;
00630     }
00631 
00632     srcVol.setBounds(osgMin(vol.getMin().x(), srcVol.getMin().x()),
00633                      osgMin(vol.getMin().y(), srcVol.getMin().y()),
00634                      osgMin(vol.getMin().z(), srcVol.getMin().z()),
00635                      osgMax(vol.getMax().x(), srcVol.getMax().x()),
00636                      osgMax(vol.getMax().y(), srcVol.getMax().y()),
00637                      osgMax(vol.getMax().z(), srcVol.getMax().z()));
00638 
00639     if(vol.isInfinite())
00640         srcVol.setInfinite(true);
00641 
00642     return;
00643 }
00644 
00645 
00646 OSG_BASE_DLLMAPPING 
00647 void extend(BoxVolume &srcVol, const SphereVolume &vol)
00648 {
00649     Pnt3f   min, max;
00650 
00651     if((!srcVol.isValid   () && !srcVol.isEmpty()) ||
00652          srcVol.isInfinite()                       ||
00653          srcVol.isStatic  ()                         )
00654     {
00655         return;
00656     }
00657 
00658     if(!vol.isValid())
00659         return;
00660 
00661     if(srcVol.isEmpty())
00662     {
00663         if(vol.isEmpty())
00664         {
00665             return;
00666         }
00667         else
00668         {
00669             vol   .getBounds(min, max);
00670             srcVol.setBounds(min, max);
00671 
00672             return;
00673         }
00674     }
00675     else if(vol.isEmpty())
00676     {
00677         return;
00678     }
00679 
00680     vol.getBounds(min, max);
00681 
00682     srcVol.setBounds(osgMin(min.x(), srcVol.getMin().x()),
00683                      osgMin(min.y(), srcVol.getMin().y()),
00684                      osgMin(min.z(), srcVol.getMin().z()),
00685                      osgMax(max.x(), srcVol.getMax().x()),
00686                      osgMax(max.y(), srcVol.getMax().y()),
00687                      osgMax(max.z(), srcVol.getMax().z()));
00688 
00689     if(vol.isInfinite())
00690         srcVol.setInfinite(true);
00691 
00692     return;
00693 }
00694 
00695 
00696 OSG_BASE_DLLMAPPING 
00697 void extend(BoxVolume &srcVol, const CylinderVolume &vol)
00698 {
00699     Pnt3f min, max;
00700 
00701     if((!srcVol.isValid   () && !srcVol.isEmpty()) ||
00702          srcVol.isInfinite()                       ||
00703          srcVol.isStatic  ()                         )
00704     {
00705         return;
00706     }
00707 
00708     if(!vol.isValid())
00709         return;
00710 
00711     if(srcVol.isEmpty())
00712     {
00713         if(vol.isEmpty())
00714         {
00715             return;
00716         }
00717         else
00718         {
00719             vol   .getBounds(min, max);
00720             srcVol.setBounds(min, max);
00721 
00722             return;
00723         }
00724     }
00725     else if(vol.isEmpty())
00726     {
00727         return;
00728     }
00729 
00730     vol.getBounds(min, max);
00731 
00732     srcVol.setBounds(osgMin(min.x(), srcVol.getMin().x()),
00733                      osgMin(min.y(), srcVol.getMin().y()),
00734                      osgMin(min.z(), srcVol.getMin().z()),
00735                      osgMax(max.x(), srcVol.getMax().x()),
00736                      osgMax(max.y(), srcVol.getMax().y()),
00737                      osgMax(max.z(), srcVol.getMax().z()));
00738 
00739     if(vol.isInfinite())
00740         srcVol.setInfinite(true);
00741 
00742     return;
00743 }
00744 
00745 
00746 OSG_BASE_DLLMAPPING 
00747 void extend(      BoxVolume     &OSG_CHECK_ARG(srcVol), 
00748             const FrustumVolume &OSG_CHECK_ARG(vol   ))
00749 {
00750     FFATAL(("extend (box/frustum) is not impl.\n"));
00751     return;
00752 }
00753 
00754 
00755 #ifdef __sgi
00756 #   pragma set woff 1174, 1552
00757 #endif
00758 
00759 
00760 OSG_BASE_DLLMAPPING 
00761 void extend(BoxVolume &srcVol, const Volume &vol)
00762 {
00763     const Volume        *v       = &vol;
00764     const BoxVolume     *box;
00765     const DynamicVolume *dynamic = dynamic_cast<const DynamicVolume *>(v);
00766 
00767     if(dynamic)
00768     {
00769         v = &(dynamic->getInstance());
00770     }
00771 
00772     if((box = dynamic_cast<const BoxVolume *>(v)))
00773     {
00774         OSG::extend(srcVol, *box);
00775     }
00776     else
00777     {
00778         BoxVolume   localBox;
00779         Pnt3f       min, max;
00780 
00781         v->getBounds(min, max);
00782 
00783         localBox.setBounds(min, max);
00784 
00785         OSG::extend(srcVol, localBox);
00786     }
00787 }
00788 
00789 
00790 #ifdef __sgi
00791 #   pragma reset woff 1174, 1552
00792 #endif
00793 
00794 // # Sphere ###########################################################
00795 
00796 OSG_BASE_DLLMAPPING 
00797 void extend(SphereVolume &srcVol, const BoxVolume &vol)
00798 {
00799     Pnt3f     min, max, min1, max1, c;
00800     Real32    r;
00801     BoxVolume vol1;
00802 
00803     vol.getBounds(min, max);
00804 
00805     if((!srcVol.isValid   () && !srcVol.isEmpty()) ||
00806          srcVol.isInfinite()                       ||
00807          srcVol.isStatic  ()                         )
00808     {
00809         return;
00810     }
00811 
00812     if(!vol.isValid())
00813         return;
00814 
00815     if(srcVol.isEmpty())
00816     {
00817         if(vol.isEmpty())
00818         {
00819             return;
00820         }
00821         else
00822         {
00823             c = Pnt3f((min.x() + max.x()) * 0.5f, 
00824                       (min.y() + max.y()) * 0.5f,
00825                       (min.z() + max.z()) * 0.5f);
00826 
00827             r = ((max - min).length()) / 2;
00828 
00829             srcVol.setValue(c, r);
00830 
00831             return;
00832         }
00833     }
00834     else if(vol.isEmpty())
00835     {
00836         return;
00837     }
00838 
00839     srcVol.getBounds(min1, max1);
00840 
00841     vol1.setBounds(osgMin(min.x(), min1.x()), osgMin(min.y(), min1.y()),
00842                    osgMin(min.z(), min1.z()), osgMax(max.x(), max1.x()),
00843                    osgMax(max.y(), max1.y()), osgMax(max.z(), max1.z()));
00844 
00845     vol1.getBounds(min, max);
00846 
00847     c = Pnt3f((min.x() + max.x()) * 0.5f, 
00848               (min.y() + max.y()) * 0.5f,
00849               (min.z() + max.z()) * 0.5f);
00850 
00851     r = ((max - min).length()) / 2;
00852 
00853     srcVol.setValue(c, r);
00854 
00855     return;
00856 }
00857 
00858 
00859 OSG_BASE_DLLMAPPING 
00860 void extend(SphereVolume &srcVol, const SphereVolume &vol)
00861 {
00862     Pnt3f   min, max, min1, max1, min2, max2, c;
00863     Real32  r;
00864 
00865     if((!srcVol.isValid   () && !srcVol.isEmpty()) ||
00866          srcVol.isInfinite()                       ||
00867          srcVol.isStatic  ()                         )
00868     {
00869         return;
00870     }
00871 
00872     if(!vol.isValid())
00873         return;
00874 
00875     if(srcVol.isEmpty())
00876     {
00877         if(vol.isEmpty())
00878         {
00879             return;
00880         }
00881         else
00882         {
00883             srcVol = vol;
00884 
00885             return;
00886         }
00887     }
00888     else if(vol.isEmpty())
00889     {
00890         return;
00891     }
00892 
00893     srcVol.getBounds(min,  max );
00894     vol   .getBounds(min1, max1);
00895 
00896     min2 = Pnt3f(osgMin(min.x(), min1.x()), 
00897                  osgMin(min.y(), min1.y()),
00898                  osgMin(min.z(), min1.z()));
00899 
00900     max2 = Pnt3f(osgMax(max.x(), max1.x()), 
00901                  osgMax(max.y(), max1.y()),
00902                  osgMax(max.z(), max1.z()));
00903 
00904     c = Pnt3f((min2.x() + max2.x()) * 0.5f, 
00905               (min2.y() + max2.y()) * 0.5f,
00906               (min2.z() + max2.z()) * 0.5f);
00907 
00908     r = ((max2 - min2).length()) * 0.5f;
00909 
00910     srcVol.setValue(c, r);
00911 
00912     return;
00913 }
00914 
00915 
00916 OSG_BASE_DLLMAPPING 
00917 void extend(SphereVolume &srcVol, const CylinderVolume &vol)
00918 {
00919     Pnt3f   min, max, min1, max1, min2, max2, c;
00920     Real32  r;
00921 
00922     if((!srcVol.isValid   () && !srcVol.isEmpty()) ||
00923          srcVol.isInfinite()                       ||
00924          srcVol.isStatic  ()                         )
00925     {
00926         return;
00927     }
00928 
00929     if(!vol.isValid())
00930         return;
00931 
00932     if(srcVol.isEmpty())
00933     {
00934         if(vol.isEmpty())
00935         {
00936             return;
00937         }
00938         else
00939         {
00940             vol.getBounds(min, max);
00941             vol.getCenter(c);
00942 
00943             r = (min - c).length();
00944 
00945             srcVol.setValue(c, r);
00946 
00947             return;
00948         }
00949     }
00950     else if(vol.isEmpty())
00951     {
00952         return;
00953     }
00954 
00955     srcVol.getBounds(min,  max);
00956     vol   .getBounds(min1, max1);
00957 
00958     min2 = Pnt3f(osgMin(min.x(), min1.x()), 
00959                  osgMin(min.y(), min1.y()),
00960                  osgMin(min.z(), min1.z()));
00961 
00962     max2 = Pnt3f(osgMax(max.x(), max1.x()), 
00963                  osgMax(max.y(), max1.y()),
00964                  osgMax(max.z(), max1.z()));
00965 
00966     c = Pnt3f((min2.x() + max2.x()) * 0.5f, 
00967               (min2.y() + max2.y()) * 0.5f,
00968               (min2.z() + max2.z()) * 0.5f);
00969 
00970     r = ((max2 - min2).length()) * 0.5f;
00971 
00972     srcVol.setValue(c, r);
00973 
00974     return;
00975 }
00976 
00977 
00978 OSG_BASE_DLLMAPPING 
00979 void extend(      SphereVolume  &OSG_CHECK_ARG(srcVol), 
00980             const FrustumVolume &OSG_CHECK_ARG(vol   ))
00981 {
00982     FFATAL(("extend (sphere/frustum) is not impl.\n"));
00983     return;
00984 }
00985 
00986 
00987 OSG_BASE_DLLMAPPING 
00988 void extend(SphereVolume &srcVol, const Volume &vol)
00989 {
00990     const Volume        *v       = &vol;
00991     const SphereVolume  *sphere;
00992     const DynamicVolume *dynamic = dynamic_cast<const DynamicVolume *>(v);
00993 
00994     if(dynamic)
00995     {
00996         v = &(dynamic->getInstance());
00997     }
00998 
00999     if((sphere = dynamic_cast<const SphereVolume *>(v)) != NULL)
01000     {
01001         OSG::extend(srcVol, *sphere);
01002     }
01003     else
01004     {
01005         SphereVolume localSphere;
01006         Pnt3f        min, max, c;
01007         Real32       r;
01008 
01009         v->getBounds(min, max);
01010 
01011         c = Pnt3f((min.x() + max.x()) * 0.5f, 
01012                   (min.y() + max.y()) * 0.5f,
01013                   (min.z() + max.z()) * 0.5f);
01014 
01015         r = ((max - min).length()) * 0.5f;
01016 
01017         localSphere.setValue(c, r);
01018 
01019         OSG::extend(srcVol, localSphere);
01020     }
01021 
01022     return;
01023 }
01024 
01025 
01026 // # Cylinder ########################################################
01027 
01028 OSG_BASE_DLLMAPPING 
01029 void extend(CylinderVolume &srcVol, const BoxVolume &vol)
01030 {
01031     Pnt3f   min, max, min1, max1, min2, max2, apos;
01032     Vec2f   p;
01033     Vec3f   adir;
01034     Real32  r;
01035 
01036     if((!srcVol.isValid   () && !srcVol.isEmpty()) ||
01037          srcVol.isInfinite()                       ||
01038          srcVol.isStatic  ()                         )
01039     {
01040         return;
01041     }
01042 
01043     if(!vol.isValid())
01044     {
01045         return;
01046     }
01047 
01048     if(srcVol.isEmpty())
01049     {
01050         if(vol.isEmpty())
01051         {
01052             return;
01053         }
01054         else
01055         {
01056             vol.getBounds(min, max);
01057 
01058             p = Vec2f(max.x() - min.x(), max.y() - min.y());
01059             r = (p.length()) * 0.5f;
01060 
01061             adir = Vec3f(0.f, 0.f, max.z() - min.z());
01062             apos = Pnt3f(p.x(), p.y(), min.z());
01063 
01064             srcVol.setValue(apos, adir, r);
01065 
01066             return;
01067         }
01068     }
01069     else if(vol.isEmpty())
01070     {
01071         return;
01072     }
01073 
01074     srcVol.getBounds(min,  max );
01075     vol   .getBounds(min1, max1);
01076 
01077     min2 = Pnt3f(osgMin(min.x(), min1.x()), 
01078                  osgMin(min.y(), min1.y()),
01079                  osgMin(min.z(), min1.z()));
01080     max2 = Pnt3f(osgMax(max.x(), max1.x()), 
01081                  osgMax(max.y(), max1.y()),
01082                  osgMax(max.z(), max1.z()));
01083 
01084     p = Vec2f(max2.x() - min2.x(), max2.y() - min2.y());
01085     r = (p.length()) * 0.5f;
01086 
01087     adir = Vec3f(0.f, 0.f, max2.z() - min2.z());
01088     apos = Pnt3f(p.x(), p.y(), min2.z());
01089 
01090     srcVol.setValue(apos, adir, r);
01091 
01092     return;
01093 }
01094 
01095 
01096 OSG_BASE_DLLMAPPING 
01097 void extend(CylinderVolume &srcVol, const SphereVolume &vol)
01098 {
01099     Pnt3f  min, max, min1, max1, min2, max2, apos;
01100     Vec2f  p;
01101     Vec3f  adir;
01102     Real32 r;
01103 
01104     if((!srcVol.isValid   () && !srcVol.isEmpty()) ||
01105          srcVol.isInfinite()                       ||
01106          srcVol.isStatic  ()                         )
01107     {
01108         return;
01109     }
01110 
01111     if(!vol.isValid())
01112         return;
01113 
01114     if(srcVol.isEmpty())
01115     {
01116         if(vol.isEmpty())
01117         {
01118             return;
01119         }
01120         else
01121         {
01122             r = vol.getRadius();
01123 
01124             apos = Pnt3f(vol.getCenter().x() - r, 
01125                          vol.getCenter().y() - r,
01126                          vol.getCenter().z() - r);
01127             adir = Vec3f(vol.getCenter().x() + r - apos.x(),
01128                          vol.getCenter().y() + r - apos.y(),
01129                          vol.getCenter().z() + r - apos.z());
01130 
01131             srcVol.setValue(apos, adir, r);
01132 
01133             return;
01134         }
01135     }
01136     else if(vol.isEmpty())
01137     {
01138         return;
01139     }
01140 
01141     srcVol.getBounds(min,  max);
01142     vol   .getBounds(min1, max1);
01143 
01144     min2 = Pnt3f(osgMin(min.x(), min1.x()), 
01145                  osgMin(min.y(), min1.y()),
01146                  osgMin(min.z(), min1.z()));
01147     max2 = Pnt3f(osgMax(max.x(), max1.x()), 
01148                  osgMax(max.y(), max1.y()),
01149                  osgMax(max.z(), max1.z()));
01150 
01151     p = Vec2f(max2.x() - min2.x(), max2.y() - min2.y());
01152     r = (p.length()) * 0.5f;
01153 
01154     adir = Vec3f(0.f, 0.f, max2.z() - min2.z());
01155     apos = Pnt3f(p.x(), p.y(), min2.z());
01156 
01157     srcVol.setValue(apos, adir, r);
01158 
01159     return;
01160 }
01161 
01162 
01163 OSG_BASE_DLLMAPPING 
01164 void extend(CylinderVolume &srcVol, const CylinderVolume &vol)
01165 {
01166     Pnt3f  min, max, min1, max1, min2, max2, apos;
01167     Vec2f  p;
01168     Vec3f  adir;
01169     Real32 r;
01170 
01171     if((!srcVol.isValid   () && !srcVol.isEmpty()) ||
01172          srcVol.isInfinite()                       ||
01173          srcVol.isStatic  ()                         )
01174     {
01175         return;
01176     }
01177 
01178     if(!vol.isValid())
01179         return;
01180 
01181     if(srcVol.isEmpty())
01182     {
01183         if(vol.isEmpty())
01184         {
01185             return;
01186         }
01187         else
01188         {
01189             srcVol = vol;
01190             return;
01191         }
01192     }
01193     else if(vol.isEmpty())
01194     {
01195         return;
01196     }
01197 
01198     srcVol.getBounds(min,  max);
01199     vol   .getBounds(min1, max1);
01200 
01201     min2 = Pnt3f(osgMin(min.x(), min1.x()), 
01202                  osgMin(min.y(), min1.y()),
01203                  osgMin(min.z(), min1.z()));
01204     max2 = Pnt3f(osgMax(max.x(), max1.x()), 
01205                  osgMax(max.y(), max1.y()),
01206                  osgMax(max.z(), max1.z()));
01207 
01208     p = Vec2f(max2.x() - min2.x(), max2.y() - min2.y());
01209     r = (p.length()) * 0.5f;
01210 
01211     adir = Vec3f(0.f, 0.f, max2.z() - min2.z());
01212     apos = Pnt3f(p.x(), p.y(), min2.z());
01213 
01214     srcVol.setValue(apos, adir, r);
01215 
01216     return;
01217 }
01218 
01219 
01220 OSG_BASE_DLLMAPPING 
01221 void extend(      CylinderVolume &OSG_CHECK_ARG(srcVol),
01222             const FrustumVolume  &OSG_CHECK_ARG(vol   ))
01223 {
01224     FFATAL(("extend (cylinder/frustum) is not impl.\n"));
01225     return;
01226 }
01227 
01228 
01229 OSG_BASE_DLLMAPPING 
01230 void extend(CylinderVolume &srcVol, const Volume &vol)
01231 {
01232     const Volume         *v       = &vol;
01233     const CylinderVolume *cylinder;
01234     const DynamicVolume  *dynamic = dynamic_cast<const DynamicVolume *>(v);
01235 
01236     if(dynamic)
01237     {
01238         v = &(dynamic->getInstance());
01239     }
01240 
01241     if((cylinder = dynamic_cast<const CylinderVolume *>(v)) != NULL)
01242     {
01243         OSG::extend(srcVol, *cylinder);
01244     }
01245     else
01246     {
01247         CylinderVolume localCylinder;
01248         Pnt3f          min, max, apos;
01249         Vec3f          adir;
01250         Real32         r;
01251         Vec2f          p;
01252 
01253         v->getBounds(min, max);
01254 
01255         p = Vec2f(max.x() - min.x(), max.y() - min.y());
01256         r = (p.length()) * 0.5f;
01257 
01258         adir = Vec3f(0.f, 0.f, max.z() - min.z());
01259         apos = Pnt3f(p.x(), p.y(), min.z());
01260 
01261         localCylinder.setValue(apos, adir, r);
01262 
01263         OSG::extend(srcVol, localCylinder);
01264     }
01265 
01266     return;
01267 }
01268 
01269 
01270 // # Frustum ########################################################
01271 
01272 OSG_BASE_DLLMAPPING 
01273 void extend(      FrustumVolume &OSG_CHECK_ARG(srcVol), 
01274             const BoxVolume     &OSG_CHECK_ARG(vol   ))
01275 {
01276     FFATAL(("extend (frustum/box) is not impl.\n"));
01277     return;
01278 }
01279 
01280 
01281 OSG_BASE_DLLMAPPING 
01282 void extend(      FrustumVolume &OSG_CHECK_ARG(srcVol), 
01283             const SphereVolume  &OSG_CHECK_ARG(vol   ))
01284 {
01285     FFATAL(("extend (frustum/sphere) is not impl.\n"));
01286     return;
01287 }
01288 
01289 
01290 OSG_BASE_DLLMAPPING 
01291 void extend(      FrustumVolume  &OSG_CHECK_ARG(srcVol),
01292             const CylinderVolume &OSG_CHECK_ARG(vol   ))
01293 {
01294     FFATAL(("extend (frustum/cylinder) is not impl.\n"));
01295     return;
01296 }
01297 
01298 
01299 OSG_BASE_DLLMAPPING 
01300 void extend(      FrustumVolume &OSG_CHECK_ARG(srcVol),
01301             const FrustumVolume &OSG_CHECK_ARG(vol   ))
01302 {
01303     FFATAL(("extend (frustum/frustum) is not impl.\n"));
01304     return;
01305 }
01306 
01307 
01308 OSG_BASE_DLLMAPPING 
01309 void extend(      FrustumVolume &OSG_CHECK_ARG(srcVol),
01310             const Volume        &OSG_CHECK_ARG(vol   ))
01311 {
01312     FFATAL(("extend (frustum/volume) is not impl.\n"));
01313     return;
01314 }
01315 
01316 OSG_END_NAMESPACE
01317 

Generated on Thu Aug 25 04:12:05 2005 for OpenSG by  doxygen 1.4.3