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