Sphere.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Copyright (C) 2009-present, 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.length();
  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).length() / 2.0f);
  24. }
  25. void Sphere::setFromPointCloud(const Vec3* pointBuffer, U pointCount, PtrSize pointStride, [[maybe_unused]] PtrSize buffSize)
  26. {
  27. // Calc center
  28. {
  29. Vec4 min(Vec3(kMaxF32), 0.0f);
  30. Vec4 max(Vec3(kMinF32), 0.0f);
  31. // Iterate
  32. const U8* ptr = reinterpret_cast<const U8*>(pointBuffer);
  33. while(pointCount-- != 0)
  34. {
  35. ANKI_ASSERT((ptrToNumber(ptr) + sizeof(Vec3) - ptrToNumber(pointBuffer)) <= buffSize);
  36. const Vec4 pos = (*reinterpret_cast<const Vec3*>(ptr)).xyz0;
  37. max = max.max(pos);
  38. min = min.min(pos);
  39. ptr += pointStride;
  40. }
  41. m_center = (min + max) * 0.5f; // average
  42. }
  43. // Calc radius
  44. {
  45. F32 maxDist = kMinF32;
  46. const U8* ptr = reinterpret_cast<const U8*>(pointBuffer);
  47. while(pointCount-- != 0)
  48. {
  49. ANKI_ASSERT((ptrToNumber(ptr) + sizeof(Vec3) - ptrToNumber(pointBuffer)) <= buffSize);
  50. const Vec3& pos = *reinterpret_cast<const Vec3*>(ptr);
  51. const F32 dist = (Vec4(pos, 0.0f) - m_center).lengthSquared();
  52. if(dist > maxDist)
  53. {
  54. maxDist = dist;
  55. }
  56. ptr += pointStride;
  57. }
  58. m_radius = sqrt(maxDist);
  59. }
  60. }
  61. } // end namespace anki