Sphere.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Collision/Sphere.h>
  6. namespace anki
  7. {
  8. Sphere Sphere::getCompoundShape(const Sphere& b) const
  9. {
  10. const Sphere& a = *this;
  11. const Vec4 c = b.getCenter() - a.getCenter();
  12. const F32 cLen = c.getLength();
  13. if(cLen + b.getRadius() < a.getRadius())
  14. {
  15. return a;
  16. }
  17. else if(cLen + a.getRadius() < b.getRadius())
  18. {
  19. return b;
  20. }
  21. const Vec4 bnorm = c / cLen;
  22. const Vec4 ca = (-bnorm) * a.getRadius() + a.getCenter();
  23. const Vec4 cb = (bnorm)*b.getRadius() + b.getCenter();
  24. return Sphere((ca + cb) / 2.0f, (ca - cb).getLength() / 2.0f);
  25. }
  26. void Sphere::setFromPointCloud(const Vec3* pointBuffer, U pointCount, PtrSize pointStride, PtrSize buffSize)
  27. {
  28. // Calc center
  29. {
  30. Vec4 min(Vec3(MAX_F32), 0.0f);
  31. Vec4 max(Vec3(MIN_F32), 0.0f);
  32. // Iterate
  33. const U8* ptr = reinterpret_cast<const U8*>(pointBuffer);
  34. while(pointCount-- != 0)
  35. {
  36. ANKI_ASSERT((ptrToNumber(ptr) + sizeof(Vec3) - ptrToNumber(pointBuffer)) <= buffSize);
  37. const Vec4 pos = (*reinterpret_cast<const Vec3*>(ptr)).xyz0();
  38. max = max.max(pos);
  39. min = min.min(pos);
  40. ptr += pointStride;
  41. }
  42. m_center = (min + max) * 0.5f; // average
  43. }
  44. // Calc radius
  45. {
  46. F32 maxDist = MIN_F32;
  47. const U8* ptr = reinterpret_cast<const U8*>(pointBuffer);
  48. while(pointCount-- != 0)
  49. {
  50. ANKI_ASSERT((ptrToNumber(ptr) + sizeof(Vec3) - ptrToNumber(pointBuffer)) <= buffSize);
  51. const Vec3& pos = *reinterpret_cast<const Vec3*>(ptr);
  52. const F32 dist = (Vec4(pos, 0.0f) - m_center).getLengthSquared();
  53. if(dist > maxDist)
  54. {
  55. maxDist = dist;
  56. }
  57. ptr += pointStride;
  58. }
  59. m_radius = sqrt(maxDist);
  60. }
  61. }
  62. } // end namespace anki