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 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
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
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
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
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
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
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
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
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
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