Advertisement
Guest User

Untitled

a guest
Jun 11th, 2022
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 13.45 KB | None | 0 0
  1. commit 0962c43915dc6c07110b6826e43891bc826ec049
  2. Author: Aron Granberg <aron.granberg@gmail.com>
  3. Date:   Fri May 20 16:10:32 2022 +0200
  4.  
  5.     [ALINE] Fixed some edge cases in Draw.WireCapsule and Draw.WireCapsule which could cause NaNs and other subtle errors.
  6.  
  7. diff --git a/Assets/AstarPathfindingProject/Drawing/CommandBuilder.cs b/Assets/AstarPathfindingProject/Drawing/CommandBuilder.cs
  8. index 3b27ddd9..4690b3f3 100644
  9. --- a/Assets/AstarPathfindingProject/Drawing/CommandBuilder.cs
  10. +++ b/Assets/AstarPathfindingProject/Drawing/CommandBuilder.cs
  11. @@ -944,8 +944,10 @@ namespace Pathfinding.Drawing {
  12.         }
  13.  
  14.         /** Draws a cylinder.
  15. -        * The cylinder's bottom circle will be centered at the \a position parameter.
  16. -        * The cylinder's orientation will be determined by the \a up and \a height parameters.
  17. +        * \param position The center of the cylinder's "bottom" circle.
  18. +        * \param up The cylinder's main axis. Does not have to be normalized. If zero, nothing will be drawn.
  19. +        * \param height The length of the cylinder, as measured along it's main axis.
  20. +        * \param radius The radius of the cylinder.
  21.          *
  22.          * \snippet DrawingSnippets.cs Draw.WireCylinder2
  23.          *
  24. @@ -955,18 +957,28 @@ namespace Pathfinding.Drawing {
  25.             var tangent = math.normalizesafe(math.cross(up, new float3(1, 1, 1)));
  26.  
  27.             // Note: second parameter is normalized (-1,1,1)
  28. -           if (math.all(tangent == float3.zero)) tangent = math.cross(up, new float3(-0.577350269f, 0.577350269f, 0.577350269f));
  29. +           const float SQRT_ONE_THIRD = 0.577350269f;
  30. +           if (math.all(tangent == float3.zero)) tangent = math.cross(up, new float3(-SQRT_ONE_THIRD, SQRT_ONE_THIRD, SQRT_ONE_THIRD));
  31.  
  32. -           PushMatrix(Matrix4x4.TRS(position, Quaternion.LookRotation(tangent, up), new Vector3(radius, height, radius)));
  33. -           CircleXZ(float3.zero, 1);
  34. -           if (height > 0) {
  35. -               CircleXZ(new float3(0, 1, 0), 1);
  36. -               Line(new float3(1, 0, 0), new float3(1, 1, 0));
  37. -               Line(new float3(-1, 0, 0), new float3(-1, 1, 0));
  38. -               Line(new float3(0, 0, 1), new float3(0, 1, 1));
  39. -               Line(new float3(0, 0, -1), new float3(0, 1, -1));
  40. +           var rotation = quaternion.LookRotation(tangent, up);
  41. +
  42. +           // If we get a NaN here then either
  43. +           // * one of the input parameters contained nans (bad)
  44. +           // * up is zero, or very close to zero
  45. +           //
  46. +           // In any case, we cannot draw anything.
  47. +           if (!math.any(math.isnan(rotation.value))) {
  48. +               PushMatrix(float4x4.TRS(position, rotation, new float3(radius, height, radius)));
  49. +               CircleXZ(float3.zero, 1);
  50. +               if (height > 0) {
  51. +                   CircleXZ(new float3(0, 1, 0), 1);
  52. +                   Line(new float3(1, 0, 0), new float3(1, 1, 0));
  53. +                   Line(new float3(-1, 0, 0), new float3(-1, 1, 0));
  54. +                   Line(new float3(0, 0, 1), new float3(0, 1, 1));
  55. +                   Line(new float3(0, 0, -1), new float3(0, 1, -1));
  56. +               }
  57. +               PopMatrix();
  58.             }
  59. -           PopMatrix();
  60.         }
  61.  
  62.         /** Draws a capsule with a (start,end) parameterization.
  63. @@ -998,7 +1010,7 @@ namespace Pathfinding.Drawing {
  64.         // TODO: Change to center, up, height parameterization
  65.         /** Draws a capsule with a (position,direction/length) parameterization.
  66.          * \param position One endpoint of the capsule. This is at the edge of the capsule, not at the center of one of the hemispheres.
  67. -        * \param direction The main axis of the capsule.
  68. +        * \param direction The main axis of the capsule. Does not have to be normalized. If zero, nothing will be drawn.
  69.          * \param length Distance between the two endpoints of the capsule. The length will be clamped to be at least 2*radius.
  70.          * \param radius The radius of the capsule.
  71.          *
  72. @@ -1008,37 +1020,48 @@ namespace Pathfinding.Drawing {
  73.          */
  74.         public void WireCapsule (float3 position, float3 direction, float length, float radius) {
  75.             direction = math.normalizesafe(direction);
  76. +
  77.             if (radius <= 0) {
  78.                 Line(position, position + direction * length);
  79.             } else {
  80. +               const float SQRT_ONE_THIRD = 0.577350269f;
  81.                 // Note; second parameter is normalized (1,1,1)
  82. -               var tangent = math.cross(direction, new float3(0.577350269f, 0.577350269f, 0.577350269f));
  83. +               var tangent = math.cross(direction, new float3(SQRT_ONE_THIRD, SQRT_ONE_THIRD, SQRT_ONE_THIRD));
  84.  
  85.                 // Note: second parameter is normalized (-1,1,1)
  86. -               if (math.all(tangent == float3.zero)) tangent = math.cross(direction, new float3(-0.577350269f, 0.577350269f, 0.577350269f));
  87. +               if (math.all(tangent == float3.zero)) tangent = math.cross(direction, new float3(-SQRT_ONE_THIRD, SQRT_ONE_THIRD, SQRT_ONE_THIRD));
  88.  
  89.                 length = math.max(length, radius*2);
  90.  
  91. -               PushMatrix(Matrix4x4.TRS(position, Quaternion.LookRotation(tangent, direction), Vector3.one));
  92. -               CircleXZ(new float3(0, radius, 0), radius);
  93. -               CircleXY(new float3(0, radius, 0), radius, Mathf.PI, 2 * Mathf.PI);
  94. -               PushMatrix(XZtoYZPlaneMatrix);
  95. -               CircleXZ(new float3(radius, 0, 0), radius, Mathf.PI*0.5f, Mathf.PI*1.5f);
  96. -               PopMatrix();
  97. -               if (length > 0) {
  98. -                   var upperY = length - radius;
  99. -                   var lowerY = radius;
  100. -                   CircleXZ(new float3(0, upperY, 0), radius);
  101. -                   CircleXY(new float3(0, upperY, 0), radius, 0, Mathf.PI);
  102. +               var rotation = quaternion.LookRotation(tangent, direction);
  103. +
  104. +               // If we get a NaN here then either
  105. +               // * one of the input parameters contained nans (bad)
  106. +               // * direction is zero, or very close to zero
  107. +               //
  108. +               // In any case, we cannot draw anything.
  109. +               if (!math.any(math.isnan(rotation.value))) {
  110. +                   PushMatrix(float4x4.TRS(position, rotation, 1));
  111. +                   CircleXZ(new float3(0, radius, 0), radius);
  112. +                   CircleXY(new float3(0, radius, 0), radius, Mathf.PI, 2 * Mathf.PI);
  113.                     PushMatrix(XZtoYZPlaneMatrix);
  114. -                   CircleXZ(new float3(upperY, 0, 0), radius, -Mathf.PI*0.5f, Mathf.PI*0.5f);
  115. +                   CircleXZ(new float3(radius, 0, 0), radius, Mathf.PI*0.5f, Mathf.PI*1.5f);
  116. +                   PopMatrix();
  117. +                   if (length > 0) {
  118. +                       var upperY = length - radius;
  119. +                       var lowerY = radius;
  120. +                       CircleXZ(new float3(0, upperY, 0), radius);
  121. +                       CircleXY(new float3(0, upperY, 0), radius, 0, Mathf.PI);
  122. +                       PushMatrix(XZtoYZPlaneMatrix);
  123. +                       CircleXZ(new float3(upperY, 0, 0), radius, -Mathf.PI*0.5f, Mathf.PI*0.5f);
  124. +                       PopMatrix();
  125. +                       Line(new float3(radius, lowerY, 0), new float3(radius, upperY, 0));
  126. +                       Line(new float3(-radius, lowerY, 0), new float3(-radius, upperY, 0));
  127. +                       Line(new float3(0, lowerY, radius), new float3(0, upperY, radius));
  128. +                       Line(new float3(0, lowerY, -radius), new float3(0, upperY, -radius));
  129. +                   }
  130.                     PopMatrix();
  131. -                   Line(new float3(radius, lowerY, 0), new float3(radius, upperY, 0));
  132. -                   Line(new float3(-radius, lowerY, 0), new float3(-radius, upperY, 0));
  133. -                   Line(new float3(0, lowerY, radius), new float3(0, upperY, radius));
  134. -                   Line(new float3(0, lowerY, -radius), new float3(0, upperY, -radius));
  135.                 }
  136. -               PopMatrix();
  137.             }
  138.         }
  139.  
  140. @@ -1855,7 +1878,8 @@ namespace Pathfinding.Drawing {
  141.             PopMatrix();
  142.         }
  143.  
  144. -       private float3 calculateTangent (float3 normal) {
  145. +       /** Returns an arbitrary vector which is orthogonal to the given one */
  146. +       private static float3 calculateTangent (float3 normal) {
  147.             var tangent = math.cross(new float3(0, 1, 0), normal);
  148.  
  149.             if (math.all(tangent == 0)) tangent = math.cross(new float3(1, 0, 0), normal);
  150. diff --git a/Assets/AstarPathfindingProject/Drawing/CommandBuilderExtensions.cs b/Assets/AstarPathfindingProject/Drawing/CommandBuilderExtensions.cs
  151. index be852a63..bbfbefb6 100644
  152. --- a/Assets/AstarPathfindingProject/Drawing/CommandBuilderExtensions.cs
  153. +++ b/Assets/AstarPathfindingProject/Drawing/CommandBuilderExtensions.cs
  154. @@ -176,24 +176,36 @@ namespace Pathfinding.Drawing {
  155.             WireCylinder(bottom, top - bottom, math.length(top - bottom), radius, color);
  156.         }
  157.  
  158. -       /** \copydocref{WireCylinder(float3,float3,float,float)} */
  159. +       /** \copydocref{WireCylinder(float3,float3,float,float)}
  160. +        * \param color Color of the object
  161. +        */
  162.         public void WireCylinder (float3 position, float3 up, float height, float radius, Color color) {
  163.             PushColor(color);
  164.             var tangent = math.normalizesafe(math.cross(up, new float3(1, 1, 1)));
  165.  
  166.             // Note: second parameter is normalized (-1,1,1)
  167. -           if (math.all(tangent == float3.zero)) tangent = math.cross(up, new float3(-0.577350269f, 0.577350269f, 0.577350269f));
  168. +           const float SQRT_ONE_THIRD = 0.577350269f;
  169. +           if (math.all(tangent == float3.zero)) tangent = math.cross(up, new float3(-SQRT_ONE_THIRD, SQRT_ONE_THIRD, SQRT_ONE_THIRD));
  170. +
  171. +           var rotation = quaternion.LookRotation(tangent, up);
  172.  
  173. -           PushMatrix(Matrix4x4.TRS(position, Quaternion.LookRotation(tangent, up), new Vector3(radius, height, radius)));
  174. -           CircleXZ(float3.zero, 1);
  175. -           if (height > 0) {
  176. -               CircleXZ(new float3(0, 1, 0), 1);
  177. -               Line(new float3(1, 0, 0), new float3(1, 1, 0));
  178. -               Line(new float3(-1, 0, 0), new float3(-1, 1, 0));
  179. -               Line(new float3(0, 0, 1), new float3(0, 1, 1));
  180. -               Line(new float3(0, 0, -1), new float3(0, 1, -1));
  181. +           // If we get a NaN here then either
  182. +           // * one of the input parameters contained nans (bad)
  183. +           // * up is zero, or very close to zero
  184. +           //
  185. +           // In any case, we cannot draw anything.
  186. +           if (!math.any(math.isnan(rotation.value))) {
  187. +               PushMatrix(float4x4.TRS(position, rotation, new float3(radius, height, radius)));
  188. +               CircleXZ(float3.zero, 1);
  189. +               if (height > 0) {
  190. +                   CircleXZ(new float3(0, 1, 0), 1);
  191. +                   Line(new float3(1, 0, 0), new float3(1, 1, 0));
  192. +                   Line(new float3(-1, 0, 0), new float3(-1, 1, 0));
  193. +                   Line(new float3(0, 0, 1), new float3(0, 1, 1));
  194. +                   Line(new float3(0, 0, -1), new float3(0, 1, -1));
  195. +               }
  196. +               PopMatrix();
  197.             }
  198. -           PopMatrix();
  199.             PopColor();
  200.         }
  201.  
  202. @@ -223,37 +235,48 @@ namespace Pathfinding.Drawing {
  203.         public void WireCapsule (float3 position, float3 direction, float length, float radius, Color color) {
  204.             PushColor(color);
  205.             direction = math.normalizesafe(direction);
  206. +
  207.             if (radius <= 0) {
  208.                 Line(position, position + direction * length);
  209.             } else {
  210. +               const float SQRT_ONE_THIRD = 0.577350269f;
  211.                 // Note; second parameter is normalized (1,1,1)
  212. -               var tangent = math.cross(direction, new float3(0.577350269f, 0.577350269f, 0.577350269f));
  213. +               var tangent = math.cross(direction, new float3(SQRT_ONE_THIRD, SQRT_ONE_THIRD, SQRT_ONE_THIRD));
  214.  
  215.                 // Note: second parameter is normalized (-1,1,1)
  216. -               if (math.all(tangent == float3.zero)) tangent = math.cross(direction, new float3(-0.577350269f, 0.577350269f, 0.577350269f));
  217. +               if (math.all(tangent == float3.zero)) tangent = math.cross(direction, new float3(-SQRT_ONE_THIRD, SQRT_ONE_THIRD, SQRT_ONE_THIRD));
  218.  
  219.                 length = math.max(length, radius*2);
  220.  
  221. -               PushMatrix(Matrix4x4.TRS(position, Quaternion.LookRotation(tangent, direction), Vector3.one));
  222. -               CircleXZ(new float3(0, radius, 0), radius);
  223. -               CircleXY(new float3(0, radius, 0), radius, Mathf.PI, 2 * Mathf.PI);
  224. -               PushMatrix(XZtoYZPlaneMatrix);
  225. -               CircleXZ(new float3(radius, 0, 0), radius, Mathf.PI*0.5f, Mathf.PI*1.5f);
  226. -               PopMatrix();
  227. -               if (length > 0) {
  228. -                   var upperY = length - radius;
  229. -                   var lowerY = radius;
  230. -                   CircleXZ(new float3(0, upperY, 0), radius);
  231. -                   CircleXY(new float3(0, upperY, 0), radius, 0, Mathf.PI);
  232. +               var rotation = quaternion.LookRotation(tangent, direction);
  233. +
  234. +               // If we get a NaN here then either
  235. +               // * one of the input parameters contained nans (bad)
  236. +               // * direction is zero, or very close to zero
  237. +               //
  238. +               // In any case, we cannot draw anything.
  239. +               if (!math.any(math.isnan(rotation.value))) {
  240. +                   PushMatrix(float4x4.TRS(position, rotation, 1));
  241. +                   CircleXZ(new float3(0, radius, 0), radius);
  242. +                   CircleXY(new float3(0, radius, 0), radius, Mathf.PI, 2 * Mathf.PI);
  243.                     PushMatrix(XZtoYZPlaneMatrix);
  244. -                   CircleXZ(new float3(upperY, 0, 0), radius, -Mathf.PI*0.5f, Mathf.PI*0.5f);
  245. +                   CircleXZ(new float3(radius, 0, 0), radius, Mathf.PI*0.5f, Mathf.PI*1.5f);
  246. +                   PopMatrix();
  247. +                   if (length > 0) {
  248. +                       var upperY = length - radius;
  249. +                       var lowerY = radius;
  250. +                       CircleXZ(new float3(0, upperY, 0), radius);
  251. +                       CircleXY(new float3(0, upperY, 0), radius, 0, Mathf.PI);
  252. +                       PushMatrix(XZtoYZPlaneMatrix);
  253. +                       CircleXZ(new float3(upperY, 0, 0), radius, -Mathf.PI*0.5f, Mathf.PI*0.5f);
  254. +                       PopMatrix();
  255. +                       Line(new float3(radius, lowerY, 0), new float3(radius, upperY, 0));
  256. +                       Line(new float3(-radius, lowerY, 0), new float3(-radius, upperY, 0));
  257. +                       Line(new float3(0, lowerY, radius), new float3(0, upperY, radius));
  258. +                       Line(new float3(0, lowerY, -radius), new float3(0, upperY, -radius));
  259. +                   }
  260.                     PopMatrix();
  261. -                   Line(new float3(radius, lowerY, 0), new float3(radius, upperY, 0));
  262. -                   Line(new float3(-radius, lowerY, 0), new float3(-radius, upperY, 0));
  263. -                   Line(new float3(0, lowerY, radius), new float3(0, upperY, radius));
  264. -                   Line(new float3(0, lowerY, -radius), new float3(0, upperY, -radius));
  265.                 }
  266. -               PopMatrix();
  267.             }
  268.             PopColor();
  269.         }
  270. diff --git a/Assets/AstarPathfindingProject/Drawing/changelog.cs b/Assets/AstarPathfindingProject/Drawing/changelog.cs
  271. index 42662d41..74788cf5 100644
  272. --- a/Assets/AstarPathfindingProject/Drawing/changelog.cs
  273. +++ b/Assets/AstarPathfindingProject/Drawing/changelog.cs
  274. @@ -1,6 +1,9 @@
  275.  /** \page changelog Changelog
  276.  \order{-10}
  277.  
  278. +- 1.5.4
  279. +    - Fixed some edge cases in \reflink{Draw.WireCapsule} and \reflink{Draw.WireCapsule} which could cause NaNs and other subtle errors.
  280. +
  281.  - 1.5.3 (2022-05-14)
  282.      - Breaking changes
  283.          - The minimum supported Unity version is now 2020.3.
  284.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement