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 "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
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
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
00118
00119
00120
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
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
00183
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
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
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
00230
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
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
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
00326
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
00359
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
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
00380
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
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
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 float dist3D_Segment_to_Segment( const Pnt3f& s1p, const Vec3f& s1d,
00477 const Pnt3f& s2p, const Vec3f& s2d)
00478 {
00479 const float SMALL_NUM = 1e-9f;
00480 const Vec3f& u = s1d;
00481 const Vec3f& v = s2d;
00482 Vec3f w = s1p - s2p;
00483
00484 float a = u.dot(u);
00485 float b = u.dot(v);
00486 float c = v.dot(v);
00487 float d = u.dot(w);
00488 float e = v.dot(w);
00489 float D = a*c - b*b;
00490 float sc, sN, sD = D;
00491 float tc, tN, tD = D;
00492
00493
00494 if (D < SMALL_NUM) {
00495 sN = 0.0;
00496 sD = 1.0;
00497 tN = e;
00498 tD = c;
00499 }
00500 else {
00501 sN = (b*e - c*d);
00502 tN = (a*e - b*d);
00503 if (sN < 0.0) {
00504 sN = 0.0;
00505 tN = e;
00506 tD = c;
00507 }
00508 else if (sN > sD) {
00509 sN = sD;
00510 tN = e + b;
00511 tD = c;
00512 }
00513 }
00514
00515 if (tN < 0.0) {
00516 tN = 0.0;
00517
00518 if (-d < 0.0)
00519 sN = 0.0;
00520 else if (-d > a)
00521 sN = sD;
00522 else {
00523 sN = -d;
00524 sD = a;
00525 }
00526 }
00527 else if (tN > tD) {
00528 tN = tD;
00529
00530 if ((-d + b) < 0.0)
00531 sN = 0;
00532 else if ((-d + b) > a)
00533 sN = sD;
00534 else {
00535 sN = (-d + b);
00536 sD = a;
00537 }
00538 }
00539
00540 sc = (osgabs(sN) < SMALL_NUM ? 0.0 : sN / sD);
00541 tc = (osgabs(tN) < SMALL_NUM ? 0.0 : tN / tD);
00542
00543
00544 Vec3f dP = w + (sc * u) - (tc * v);
00545
00546 return dP.length();
00547 }
00548
00549 OSG_BASE_DLLMAPPING
00550 bool intersect(const CylinderVolume &cyl1,
00551 const CylinderVolume &cyl2)
00552 {
00553 Pnt3f p1, p2;
00554 Vec3f v1, v2;
00555 cyl1.getAxis(p1, v1);
00556 cyl2.getAxis(p2, v2);
00557 return dist3D_Segment_to_Segment(p1, v1, p2, v2) <=
00558 (cyl1.getRadius() + cyl2.getRadius());
00559 }
00560
00561
00562 OSG_BASE_DLLMAPPING
00563 bool intersect(const CylinderVolume &cylinder, const FrustumVolume &frustum)
00564 {
00565 Pnt3f min, max;
00566 cylinder.getBounds(min, max);
00567
00568 const Plane *frust = frustum.getPlanes();
00569
00570
00571
00572 for(Int32 i = 0; i < 6; i++)
00573 {
00574 if(frust[i].isOutHalfSpace(min, max))
00575 return false;
00576 }
00577
00578 return true;
00579 }
00580
00581
00582 OSG_BASE_DLLMAPPING
00583 bool intersect(const CylinderVolume &cylinder, const Volume &vol)
00584 {
00585 bool retCode = false;
00586
00587 const DynamicVolume *dv = dynamic_cast<const DynamicVolume *>(&vol);
00588 const Volume *v = dv ? &(dv->getInstance()) : &vol;
00589 const BoxVolume *bv;
00590 const SphereVolume *sv;
00591 const CylinderVolume *cv;
00592 const FrustumVolume *fv;
00593
00594 if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
00595 {
00596 retCode = intersect(cylinder, *bv);
00597 }
00598 else if((sv = dynamic_cast<const SphereVolume *>(v)) != NULL)
00599 {
00600 retCode = intersect(cylinder, *sv);
00601 }
00602 else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
00603 {
00604 retCode = intersect(cylinder, *cv);
00605 }
00606 else if((fv = dynamic_cast<const FrustumVolume *>(v)) != NULL)
00607 {
00608 retCode = intersect(cylinder, *fv);
00609 }
00610
00611 return retCode;
00612 }
00613
00614
00615
00616
00617 OSG_BASE_DLLMAPPING
00618 bool intersect(const FrustumVolume &OSG_CHECK_ARG(frustum1),
00619 const FrustumVolume &OSG_CHECK_ARG(frustum2))
00620 {
00621 FFATAL(("intersect (frustum/frustum) is not impl.\n"));
00622 return false;
00623 }
00624
00625 OSG_BASE_DLLMAPPING
00626 bool intersect(const FrustumVolume &frustum, const Volume &vol)
00627 {
00628 bool retCode = false;
00629
00630 const DynamicVolume *dv = dynamic_cast<const DynamicVolume *>(&vol);
00631 const Volume *v = dv ? &(dv->getInstance()) : &vol;
00632 const BoxVolume *bv;
00633 const SphereVolume *sv;
00634 const CylinderVolume *cv;
00635 const FrustumVolume *fv;
00636
00637 if((bv = dynamic_cast<const BoxVolume *>(v)) != NULL)
00638 {
00639 retCode = intersect(frustum, *bv);
00640 }
00641 else if((sv = dynamic_cast<const SphereVolume *>(v)) != NULL)
00642 {
00643 retCode = intersect(frustum, *sv);
00644 }
00645 else if((cv = dynamic_cast<const CylinderVolume *>(v)) != NULL)
00646 {
00647 retCode = intersect(frustum, *cv);
00648 }
00649 else if((fv = dynamic_cast<const FrustumVolume *>(v)) != NULL)
00650 {
00651 retCode = intersect(frustum, *fv);
00652 }
00653
00654 return retCode;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663 OSG_BASE_DLLMAPPING
00664 void extend(Volume &OSG_CHECK_ARG(srcVol), const Volume &OSG_CHECK_ARG(vol))
00665 {
00666 FFATAL(("extend (frustum/volume) is not impl.\n"));
00667 return;
00668 }
00669
00670
00671
00672
00673 OSG_BASE_DLLMAPPING
00674 void extend(BoxVolume &srcVol, const BoxVolume &vol)
00675 {
00676 if( (!srcVol.isValid () && !srcVol.isEmpty()) ||
00677 srcVol.isInfinite() ||
00678 srcVol.isStatic () )
00679 {
00680 return;
00681 }
00682
00683 if(!vol.isValid())
00684 return;
00685
00686 if(srcVol.isEmpty())
00687 {
00688 if(vol.isEmpty())
00689 {
00690 return;
00691 }
00692 else
00693 {
00694 srcVol = vol;
00695 return;
00696 }
00697 }
00698 else if(vol.isEmpty())
00699 {
00700 return;
00701 }
00702
00703 srcVol.setBounds(osgMin(vol.getMin().x(), srcVol.getMin().x()),
00704 osgMin(vol.getMin().y(), srcVol.getMin().y()),
00705 osgMin(vol.getMin().z(), srcVol.getMin().z()),
00706 osgMax(vol.getMax().x(), srcVol.getMax().x()),
00707 osgMax(vol.getMax().y(), srcVol.getMax().y()),
00708 osgMax(vol.getMax().z(), srcVol.getMax().z()));
00709
00710 if(vol.isInfinite())
00711 srcVol.setInfinite(true);
00712
00713 return;
00714 }
00715
00716
00717 OSG_BASE_DLLMAPPING
00718 void extend(BoxVolume &srcVol, const SphereVolume &vol)
00719 {
00720 Pnt3f min, max;
00721
00722 if((!srcVol.isValid () && !srcVol.isEmpty()) ||
00723 srcVol.isInfinite() ||
00724 srcVol.isStatic () )
00725 {
00726 return;
00727 }
00728
00729 if(!vol.isValid())
00730 return;
00731
00732 if(srcVol.isEmpty())
00733 {
00734 if(vol.isEmpty())
00735 {
00736 return;
00737 }
00738 else
00739 {
00740 vol .getBounds(min, max);
00741 srcVol.setBounds(min, max);
00742
00743 return;
00744 }
00745 }
00746 else if(vol.isEmpty())
00747 {
00748 return;
00749 }
00750
00751 vol.getBounds(min, max);
00752
00753 srcVol.setBounds(osgMin(min.x(), srcVol.getMin().x()),
00754 osgMin(min.y(), srcVol.getMin().y()),
00755 osgMin(min.z(), srcVol.getMin().z()),
00756 osgMax(max.x(), srcVol.getMax().x()),
00757 osgMax(max.y(), srcVol.getMax().y()),
00758 osgMax(max.z(), srcVol.getMax().z()));
00759
00760 if(vol.isInfinite())
00761 srcVol.setInfinite(true);
00762
00763 return;
00764 }
00765
00766
00767 OSG_BASE_DLLMAPPING
00768 void extend(BoxVolume &srcVol, const CylinderVolume &vol)
00769 {
00770 Pnt3f min, max;
00771
00772 if((!srcVol.isValid () && !srcVol.isEmpty()) ||
00773 srcVol.isInfinite() ||
00774 srcVol.isStatic () )
00775 {
00776 return;
00777 }
00778
00779 if(!vol.isValid())
00780 return;
00781
00782 if(srcVol.isEmpty())
00783 {
00784 if(vol.isEmpty())
00785 {
00786 return;
00787 }
00788 else
00789 {
00790 vol .getBounds(min, max);
00791 srcVol.setBounds(min, max);
00792
00793 return;
00794 }
00795 }
00796 else if(vol.isEmpty())
00797 {
00798 return;
00799 }
00800
00801 vol.getBounds(min, max);
00802
00803 srcVol.setBounds(osgMin(min.x(), srcVol.getMin().x()),
00804 osgMin(min.y(), srcVol.getMin().y()),
00805 osgMin(min.z(), srcVol.getMin().z()),
00806 osgMax(max.x(), srcVol.getMax().x()),
00807 osgMax(max.y(), srcVol.getMax().y()),
00808 osgMax(max.z(), srcVol.getMax().z()));
00809
00810 if(vol.isInfinite())
00811 srcVol.setInfinite(true);
00812
00813 return;
00814 }
00815
00816
00817 OSG_BASE_DLLMAPPING
00818 void extend( BoxVolume &OSG_CHECK_ARG(srcVol),
00819 const FrustumVolume &OSG_CHECK_ARG(vol ))
00820 {
00821 FFATAL(("extend (box/frustum) is not impl.\n"));
00822 return;
00823 }
00824
00825
00826 #ifdef __sgi
00827 # pragma set woff 1174, 1552
00828 #endif
00829
00830
00831 OSG_BASE_DLLMAPPING
00832 void extend(BoxVolume &srcVol, const Volume &vol)
00833 {
00834 const Volume *v = &vol;
00835 const BoxVolume *box;
00836 const DynamicVolume *dynamic = dynamic_cast<const DynamicVolume *>(v);
00837
00838 if(dynamic)
00839 {
00840 v = &(dynamic->getInstance());
00841 }
00842
00843 if((box = dynamic_cast<const BoxVolume *>(v)))
00844 {
00845 OSG::extend(srcVol, *box);
00846 }
00847 else
00848 {
00849 BoxVolume localBox;
00850 Pnt3f min, max;
00851
00852 v->getBounds(min, max);
00853
00854 localBox.setBounds(min, max);
00855
00856 OSG::extend(srcVol, localBox);
00857 }
00858 }
00859
00860
00861 #ifdef __sgi
00862 # pragma reset woff 1174, 1552
00863 #endif
00864
00865
00866
00867 OSG_BASE_DLLMAPPING
00868 void extend(SphereVolume &srcVol, const BoxVolume &vol)
00869 {
00870 Pnt3f min, max, min1, max1, c;
00871 Real32 r;
00872 BoxVolume vol1;
00873
00874 vol.getBounds(min, max);
00875
00876 if((!srcVol.isValid () && !srcVol.isEmpty()) ||
00877 srcVol.isInfinite() ||
00878 srcVol.isStatic () )
00879 {
00880 return;
00881 }
00882
00883 if(!vol.isValid())
00884 return;
00885
00886 if(srcVol.isEmpty())
00887 {
00888 if(vol.isEmpty())
00889 {
00890 return;
00891 }
00892 else
00893 {
00894 c = Pnt3f((min.x() + max.x()) * 0.5f,
00895 (min.y() + max.y()) * 0.5f,
00896 (min.z() + max.z()) * 0.5f);
00897
00898 r = ((max - min).length()) / 2;
00899
00900 srcVol.setValue(c, r);
00901
00902 return;
00903 }
00904 }
00905 else if(vol.isEmpty())
00906 {
00907 return;
00908 }
00909
00910 srcVol.getBounds(min1, max1);
00911
00912 vol1.setBounds(osgMin(min.x(), min1.x()), osgMin(min.y(), min1.y()),
00913 osgMin(min.z(), min1.z()), osgMax(max.x(), max1.x()),
00914 osgMax(max.y(), max1.y()), osgMax(max.z(), max1.z()));
00915
00916 vol1.getBounds(min, max);
00917
00918 c = Pnt3f((min.x() + max.x()) * 0.5f,
00919 (min.y() + max.y()) * 0.5f,
00920 (min.z() + max.z()) * 0.5f);
00921
00922 r = ((max - min).length()) / 2;
00923
00924 srcVol.setValue(c, r);
00925
00926 return;
00927 }
00928
00929
00930 OSG_BASE_DLLMAPPING
00931 void extend(SphereVolume &srcVol, const SphereVolume &vol)
00932 {
00933 Pnt3f min, max, min1, max1, min2, max2, c;
00934 Real32 r;
00935
00936 if((!srcVol.isValid () && !srcVol.isEmpty()) ||
00937 srcVol.isInfinite() ||
00938 srcVol.isStatic () )
00939 {
00940 return;
00941 }
00942
00943 if(!vol.isValid())
00944 return;
00945
00946 if(srcVol.isEmpty())
00947 {
00948 if(vol.isEmpty())
00949 {
00950 return;
00951 }
00952 else
00953 {
00954 srcVol = vol;
00955
00956 return;
00957 }
00958 }
00959 else if(vol.isEmpty())
00960 {
00961 return;
00962 }
00963
00964 srcVol.getBounds(min, max );
00965 vol .getBounds(min1, max1);
00966
00967 min2 = Pnt3f(osgMin(min.x(), min1.x()),
00968 osgMin(min.y(), min1.y()),
00969 osgMin(min.z(), min1.z()));
00970
00971 max2 = Pnt3f(osgMax(max.x(), max1.x()),
00972 osgMax(max.y(), max1.y()),
00973 osgMax(max.z(), max1.z()));
00974
00975 c = Pnt3f((min2.x() + max2.x()) * 0.5f,
00976 (min2.y() + max2.y()) * 0.5f,
00977 (min2.z() + max2.z()) * 0.5f);
00978
00979 r = ((max2 - min2).length()) * 0.5f;
00980
00981 srcVol.setValue(c, r);
00982
00983 return;
00984 }
00985
00986
00987 OSG_BASE_DLLMAPPING
00988 void extend(SphereVolume &srcVol, const CylinderVolume &vol)
00989 {
00990 Pnt3f min, max, min1, max1, min2, max2, c;
00991 Real32 r;
00992
00993 if((!srcVol.isValid () && !srcVol.isEmpty()) ||
00994 srcVol.isInfinite() ||
00995 srcVol.isStatic () )
00996 {
00997 return;
00998 }
00999
01000 if(!vol.isValid())
01001 return;
01002
01003 if(srcVol.isEmpty())
01004 {
01005 if(vol.isEmpty())
01006 {
01007 return;
01008 }
01009 else
01010 {
01011 vol.getBounds(min, max);
01012 vol.getCenter(c);
01013
01014 r = (min - c).length();
01015
01016 srcVol.setValue(c, r);
01017
01018 return;
01019 }
01020 }
01021 else if(vol.isEmpty())
01022 {
01023 return;
01024 }
01025
01026 srcVol.getBounds(min, max);
01027 vol .getBounds(min1, max1);
01028
01029 min2 = Pnt3f(osgMin(min.x(), min1.x()),
01030 osgMin(min.y(), min1.y()),
01031 osgMin(min.z(), min1.z()));
01032
01033 max2 = Pnt3f(osgMax(max.x(), max1.x()),
01034 osgMax(max.y(), max1.y()),
01035 osgMax(max.z(), max1.z()));
01036
01037 c = Pnt3f((min2.x() + max2.x()) * 0.5f,
01038 (min2.y() + max2.y()) * 0.5f,
01039 (min2.z() + max2.z()) * 0.5f);
01040
01041 r = ((max2 - min2).length()) * 0.5f;
01042
01043 srcVol.setValue(c, r);
01044
01045 return;
01046 }
01047
01048
01049 OSG_BASE_DLLMAPPING
01050 void extend( SphereVolume &OSG_CHECK_ARG(srcVol),
01051 const FrustumVolume &OSG_CHECK_ARG(vol ))
01052 {
01053 FFATAL(("extend (sphere/frustum) is not impl.\n"));
01054 return;
01055 }
01056
01057
01058 OSG_BASE_DLLMAPPING
01059 void extend(SphereVolume &srcVol, const Volume &vol)
01060 {
01061 const Volume *v = &vol;
01062 const SphereVolume *sphere;
01063 const DynamicVolume *dynamic = dynamic_cast<const DynamicVolume *>(v);
01064
01065 if(dynamic)
01066 {
01067 v = &(dynamic->getInstance());
01068 }
01069
01070 if((sphere = dynamic_cast<const SphereVolume *>(v)) != NULL)
01071 {
01072 OSG::extend(srcVol, *sphere);
01073 }
01074 else
01075 {
01076 SphereVolume localSphere;
01077 Pnt3f min, max, c;
01078 Real32 r;
01079
01080 v->getBounds(min, max);
01081
01082 c = Pnt3f((min.x() + max.x()) * 0.5f,
01083 (min.y() + max.y()) * 0.5f,
01084 (min.z() + max.z()) * 0.5f);
01085
01086 r = ((max - min).length()) * 0.5f;
01087
01088 localSphere.setValue(c, r);
01089
01090 OSG::extend(srcVol, localSphere);
01091 }
01092
01093 return;
01094 }
01095
01096
01097
01098
01099 OSG_BASE_DLLMAPPING
01100 void extend(CylinderVolume &srcVol, const BoxVolume &vol)
01101 {
01102 Pnt3f min, max, min1, max1, min2, max2, apos;
01103 Vec2f p;
01104 Vec3f adir;
01105 Real32 r;
01106
01107 if((!srcVol.isValid () && !srcVol.isEmpty()) ||
01108 srcVol.isInfinite() ||
01109 srcVol.isStatic () )
01110 {
01111 return;
01112 }
01113
01114 if(!vol.isValid())
01115 {
01116 return;
01117 }
01118
01119 if(srcVol.isEmpty())
01120 {
01121 if(vol.isEmpty())
01122 {
01123 return;
01124 }
01125 else
01126 {
01127 vol.getBounds(min, max);
01128
01129 p = Vec2f(max.x() - min.x(), max.y() - min.y());
01130 r = (p.length()) * 0.5f;
01131
01132 adir = Vec3f(0.f, 0.f, max.z() - min.z());
01133 apos = Pnt3f(p.x(), p.y(), min.z());
01134
01135 srcVol.setValue(apos, adir, r);
01136
01137 return;
01138 }
01139 }
01140 else if(vol.isEmpty())
01141 {
01142 return;
01143 }
01144
01145 srcVol.getBounds(min, max );
01146 vol .getBounds(min1, max1);
01147
01148 min2 = Pnt3f(osgMin(min.x(), min1.x()),
01149 osgMin(min.y(), min1.y()),
01150 osgMin(min.z(), min1.z()));
01151 max2 = Pnt3f(osgMax(max.x(), max1.x()),
01152 osgMax(max.y(), max1.y()),
01153 osgMax(max.z(), max1.z()));
01154
01155 p = Vec2f(max2.x() - min2.x(), max2.y() - min2.y());
01156 r = (p.length()) * 0.5f;
01157
01158 adir = Vec3f(0.f, 0.f, max2.z() - min2.z());
01159 apos = Pnt3f(p.x(), p.y(), min2.z());
01160
01161 srcVol.setValue(apos, adir, r);
01162
01163 return;
01164 }
01165
01166
01167 OSG_BASE_DLLMAPPING
01168 void extend(CylinderVolume &srcVol, const SphereVolume &vol)
01169 {
01170 Pnt3f min, max, min1, max1, min2, max2, apos;
01171 Vec2f p;
01172 Vec3f adir;
01173 Real32 r;
01174
01175 if((!srcVol.isValid () && !srcVol.isEmpty()) ||
01176 srcVol.isInfinite() ||
01177 srcVol.isStatic () )
01178 {
01179 return;
01180 }
01181
01182 if(!vol.isValid())
01183 return;
01184
01185 if(srcVol.isEmpty())
01186 {
01187 if(vol.isEmpty())
01188 {
01189 return;
01190 }
01191 else
01192 {
01193 r = vol.getRadius();
01194
01195 apos = Pnt3f(vol.getCenter().x() - r,
01196 vol.getCenter().y() - r,
01197 vol.getCenter().z() - r);
01198 adir = Vec3f(vol.getCenter().x() + r - apos.x(),
01199 vol.getCenter().y() + r - apos.y(),
01200 vol.getCenter().z() + r - apos.z());
01201
01202 srcVol.setValue(apos, adir, r);
01203
01204 return;
01205 }
01206 }
01207 else if(vol.isEmpty())
01208 {
01209 return;
01210 }
01211
01212 srcVol.getBounds(min, max);
01213 vol .getBounds(min1, max1);
01214
01215 min2 = Pnt3f(osgMin(min.x(), min1.x()),
01216 osgMin(min.y(), min1.y()),
01217 osgMin(min.z(), min1.z()));
01218 max2 = Pnt3f(osgMax(max.x(), max1.x()),
01219 osgMax(max.y(), max1.y()),
01220 osgMax(max.z(), max1.z()));
01221
01222 p = Vec2f(max2.x() - min2.x(), max2.y() - min2.y());
01223 r = (p.length()) * 0.5f;
01224
01225 adir = Vec3f(0.f, 0.f, max2.z() - min2.z());
01226 apos = Pnt3f(p.x(), p.y(), min2.z());
01227
01228 srcVol.setValue(apos, adir, r);
01229
01230 return;
01231 }
01232
01233
01234 OSG_BASE_DLLMAPPING
01235 void extend(CylinderVolume &srcVol, const CylinderVolume &vol)
01236 {
01237 Pnt3f min, max, min1, max1, min2, max2, apos;
01238 Vec2f p;
01239 Vec3f adir;
01240 Real32 r;
01241
01242 if((!srcVol.isValid () && !srcVol.isEmpty()) ||
01243 srcVol.isInfinite() ||
01244 srcVol.isStatic () )
01245 {
01246 return;
01247 }
01248
01249 if(!vol.isValid())
01250 return;
01251
01252 if(srcVol.isEmpty())
01253 {
01254 if(vol.isEmpty())
01255 {
01256 return;
01257 }
01258 else
01259 {
01260 srcVol = vol;
01261 return;
01262 }
01263 }
01264 else if(vol.isEmpty())
01265 {
01266 return;
01267 }
01268
01269 srcVol.getBounds(min, max);
01270 vol .getBounds(min1, max1);
01271
01272 min2 = Pnt3f(osgMin(min.x(), min1.x()),
01273 osgMin(min.y(), min1.y()),
01274 osgMin(min.z(), min1.z()));
01275 max2 = Pnt3f(osgMax(max.x(), max1.x()),
01276 osgMax(max.y(), max1.y()),
01277 osgMax(max.z(), max1.z()));
01278
01279 p = Vec2f(max2.x() - min2.x(), max2.y() - min2.y());
01280 r = (p.length()) * 0.5f;
01281
01282 adir = Vec3f(0.f, 0.f, max2.z() - min2.z());
01283 apos = Pnt3f(p.x(), p.y(), min2.z());
01284
01285 srcVol.setValue(apos, adir, r);
01286
01287 return;
01288 }
01289
01290
01291 OSG_BASE_DLLMAPPING
01292 void extend( CylinderVolume &OSG_CHECK_ARG(srcVol),
01293 const FrustumVolume &OSG_CHECK_ARG(vol ))
01294 {
01295 FFATAL(("extend (cylinder/frustum) is not impl.\n"));
01296 return;
01297 }
01298
01299
01300 OSG_BASE_DLLMAPPING
01301 void extend(CylinderVolume &srcVol, const Volume &vol)
01302 {
01303 const Volume *v = &vol;
01304 const CylinderVolume *cylinder;
01305 const DynamicVolume *dynamic = dynamic_cast<const DynamicVolume *>(v);
01306
01307 if(dynamic)
01308 {
01309 v = &(dynamic->getInstance());
01310 }
01311
01312 if((cylinder = dynamic_cast<const CylinderVolume *>(v)) != NULL)
01313 {
01314 OSG::extend(srcVol, *cylinder);
01315 }
01316 else
01317 {
01318 CylinderVolume localCylinder;
01319 Pnt3f min, max, apos;
01320 Vec3f adir;
01321 Real32 r;
01322 Vec2f p;
01323
01324 v->getBounds(min, max);
01325
01326 p = Vec2f(max.x() - min.x(), max.y() - min.y());
01327 r = (p.length()) * 0.5f;
01328
01329 adir = Vec3f(0.f, 0.f, max.z() - min.z());
01330 apos = Pnt3f(p.x(), p.y(), min.z());
01331
01332 localCylinder.setValue(apos, adir, r);
01333
01334 OSG::extend(srcVol, localCylinder);
01335 }
01336
01337 return;
01338 }
01339
01340
01341
01342
01343 OSG_BASE_DLLMAPPING
01344 void extend( FrustumVolume &OSG_CHECK_ARG(srcVol),
01345 const BoxVolume &OSG_CHECK_ARG(vol ))
01346 {
01347 FFATAL(("extend (frustum/box) is not impl.\n"));
01348 return;
01349 }
01350
01351
01352 OSG_BASE_DLLMAPPING
01353 void extend( FrustumVolume &OSG_CHECK_ARG(srcVol),
01354 const SphereVolume &OSG_CHECK_ARG(vol ))
01355 {
01356 FFATAL(("extend (frustum/sphere) is not impl.\n"));
01357 return;
01358 }
01359
01360
01361 OSG_BASE_DLLMAPPING
01362 void extend( FrustumVolume &OSG_CHECK_ARG(srcVol),
01363 const CylinderVolume &OSG_CHECK_ARG(vol ))
01364 {
01365 FFATAL(("extend (frustum/cylinder) is not impl.\n"));
01366 return;
01367 }
01368
01369
01370 OSG_BASE_DLLMAPPING
01371 void extend( FrustumVolume &OSG_CHECK_ARG(srcVol),
01372 const FrustumVolume &OSG_CHECK_ARG(vol ))
01373 {
01374 FFATAL(("extend (frustum/frustum) is not impl.\n"));
01375 return;
01376 }
01377
01378
01379 OSG_BASE_DLLMAPPING
01380 void extend( FrustumVolume &OSG_CHECK_ARG(srcVol),
01381 const Volume &OSG_CHECK_ARG(vol ))
01382 {
01383 FFATAL(("extend (frustum/volume) is not impl.\n"));
01384 return;
01385 }
01386
01387 OSG_END_NAMESPACE
01388