Sphere.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright (C) 2009-2023, 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. Sphere Sphere::getCompoundShape(const Sphere& b) const
  8. {
  9. const Sphere& a = *this;
  10. const Vec4 c = b.getCenter() - a.getCenter();
  11. const F32 cLen = c.getLength();
  12. if(cLen + b.getRadius() < a.getRadius())
  13. {
  14. return a;
  15. }
  16. else if(cLen + a.getRadius() < b.getRadius())
  17. {
  18. return b;
  19. }
  20. const Vec4 bnorm = c / cLen;
  21. const Vec4 ca = (-bnorm) * a.getRadius() + a.getCenter();
  22. const Vec4 cb = (bnorm)*b.getRadius() + b.getCenter();
  23. return Sphere((ca + cb) / 2.0f, (ca - cb).getLength() / 2.0f);
  24. }
  25. void Sphere::setFromPointCloud(const Vec3* pointBuffer, U pointCount, PtrSize pointStride,
  26. [[maybe_unused]] PtrSize buffSize)
  27. {
  28. // Calc center
  29. {
  30. Vec4 min(Vec3(kMaxF32), 0.0f);
  31. Vec4 max(Vec3(kMinF32), 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 = kMinF32;
  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