WhiteBoxTextureUtil.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "WhiteBoxTextureUtil.h"
  9. #include <AzCore/Casting/lossy_cast.h>
  10. #include <AzCore/Math/Plane.h>
  11. namespace WhiteBox
  12. {
  13. int FindLargestElement(const AZ::Vector3& vector)
  14. {
  15. AZ::Vector3 absVector = vector.GetAbs();
  16. // if any components are equal, for convention, favor components in increasing order
  17. if (absVector.GetElement(0) >= absVector.GetElement(1) && absVector.GetElement(0) >= absVector.GetElement(2))
  18. {
  19. return 0;
  20. }
  21. else if (
  22. absVector.GetElement(1) >= absVector.GetElement(0) && absVector.GetElement(1) >= absVector.GetElement(2))
  23. {
  24. return 1;
  25. }
  26. else
  27. {
  28. return 2;
  29. }
  30. }
  31. AZ::Vector2 CreatePlanarUVFromVertex(
  32. const AZ::Vector3& normal, const AZ::Vector3& position, const AZ::Vector2& offset, const AZ::Vector2& scale)
  33. {
  34. // truncates a float to 3 decimal places
  35. // note: there are the Round and Round3 methods in ManipulatorSnapping.h (which may very well be the
  36. // source of the noise) but for this specific issue, we want to discard the information after 3 decimal
  37. // places to ensure consistent behaviour (rounding could cause flipping between planes when the noise is
  38. // around the rounding threshold)
  39. auto truncateComponent = [](const float f)
  40. {
  41. const float factor3Places = 1000.0f;
  42. AZ::s32 i = azlossy_cast<AZ::s32, float>(f * factor3Places);
  43. return i / factor3Places;
  44. };
  45. // noise from grid snapping can manifest in the normal even if the positioning itself does not change so
  46. // truncate the normal to 3 decimal places in order to ensure that the favoured component order for equal
  47. // component values is consistent
  48. const AZ::Vector3 truncatedNormal = AZ::Vector3(
  49. truncateComponent(normal.GetX()), truncateComponent(normal.GetY()), truncateComponent(normal.GetZ()));
  50. const int largestElem = FindLargestElement(truncatedNormal);
  51. // swizzled vertex positions for each of the basis vector planes
  52. const AZ::Vector2 uvX(position.GetZ(), position.GetY());
  53. const AZ::Vector2 uvY(position.GetX(), position.GetZ());
  54. const AZ::Vector2 uvZ(position.GetX(), position.GetY());
  55. AZ::Vector2 uv;
  56. if (largestElem == 0)
  57. {
  58. uv = uvX;
  59. }
  60. else if (largestElem == 1)
  61. {
  62. uv = uvY;
  63. }
  64. else
  65. {
  66. uv = uvZ;
  67. }
  68. return uv * scale + offset;
  69. }
  70. } // namespace WhiteBox