Search Unity

DOTS Draw Wire Box, Arc, Circle, Sphere, Capsule, Sphere Cast

Discussion in 'Entity Component System' started by toomasio, Apr 13, 2022.

  1. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    199
    physics.jpg

    Needed some physics debugging lines so I made this. Don't know if its the most efficient but it works with Jobs and Burst.

    Code (CSharp):
    1. public static void DrawWireBox(float3 center, quaternion rotation, float3 size, Color color = default)
    2.         {
    3.             if (color.Equals(default)) color = Color.white;
    4.  
    5.             var matrix = float4x4.TRS(center, rotation, 1);
    6.             //front corners
    7.             var forwardRightUpper = math.transform(matrix, new float3(size.x / 2, size.y / 2, size.z / 2));
    8.             var forwardRightLower = math.transform(matrix, new float3(size.x / 2, -size.y / 2, size.z / 2));
    9.             var forwardLeftUpper = math.transform(matrix, new float3(-size.x / 2, size.y / 2, size.z / 2));
    10.             var forwardLeftLower = math.transform(matrix, new float3(-size.x / 2, -size.y / 2, size.z / 2));
    11.             //back corners
    12.             var backRightUpper = math.transform(matrix, new float3(size.x / 2, size.y / 2, -size.z / 2));
    13.             var backRightLower = math.transform(matrix, new float3(size.x / 2, -size.y / 2, -size.z / 2));
    14.             var backLeftUpper = math.transform(matrix, new float3(-size.x / 2, size.y / 2, -size.z / 2));
    15.             var backLeftLower = math.transform(matrix, new float3(-size.x / 2, -size.y / 2, -size.z / 2));
    16.             //square front
    17.             Debug.DrawLine(forwardRightUpper, forwardRightLower, color);
    18.             Debug.DrawLine(forwardRightUpper, forwardLeftUpper, color);
    19.             Debug.DrawLine(forwardRightLower, forwardLeftLower, color);
    20.             Debug.DrawLine(forwardLeftLower, forwardLeftUpper, color);
    21.             //square back
    22.             Debug.DrawLine(backRightUpper, backRightLower, color);
    23.             Debug.DrawLine(backRightUpper, backLeftUpper, color);
    24.             Debug.DrawLine(backRightLower, backLeftLower, color);
    25.             Debug.DrawLine(backLeftLower, backLeftUpper, color);
    26.             //attach squares
    27.             Debug.DrawLine(backRightUpper, forwardRightUpper, color);
    28.             Debug.DrawLine(backLeftUpper, forwardLeftUpper, color);
    29.             Debug.DrawLine(backRightLower, forwardRightLower, color);
    30.             Debug.DrawLine(backLeftLower, forwardLeftLower, color);
    31.         }
    32.  
    33.         public static void DrawSphereCast(float3 origin, float3 direction, float radius, float maxDistance, Color color = default)
    34.         {
    35.             if (color.Equals(default)) color = Color.white;
    36.             var rot =
    37.                 direction.Equals(math.down()) ? quaternion.Euler(math.radians(90), 0, 0) :
    38.                 direction.Equals(math.up()) ? quaternion.Euler(math.radians(-90), 0, 0) :
    39.                 quaternion.LookRotation(direction, math.up());
    40.             float height = (radius * 2) + maxDistance;
    41.             DrawWireCapsule(origin + (direction * ((height / 2) - radius)), rot, radius, height, color);
    42.         }
    43.  
    44.         public static void DrawWireCapsule(float3 center, quaternion rotation, float radius, float height, Color color = default)
    45.         {
    46.             if (color.Equals(default)) color = Color.white;
    47.  
    48.             var matrix = float4x4.TRS(center, rotation, 1);
    49.             var originPoint = math.transform(matrix, new float3(0, 0, height / 2 - radius));
    50.             var destinationPoint = math.transform(matrix, -new float3(0, 0, height / 2 - radius));
    51.             //set new rotation offset for domes
    52.             var rot = math.mul(rotation, quaternion.Euler(math.radians(90), 0, 0));
    53.             //draw upper dome
    54.             DrawWireArc(originPoint, rot, radius, 180, 0, color: color);
    55.             DrawWireArc(originPoint, rot, radius, 180, 0, mapXYTo: MapXYToType.ZY, color: color);
    56.             DrawWireCircle(originPoint, rot, radius, mapXYTo: MapXYToType.XZ, color);
    57.             //draw lower dome
    58.             DrawWireArc(destinationPoint, rot, radius, 360, 180, color: color);
    59.             DrawWireArc(destinationPoint, rot, radius, 360, 180, mapXYTo: MapXYToType.ZY, color: color);
    60.             DrawWireCircle(destinationPoint, rot, radius, mapXYTo: MapXYToType.XZ, color);
    61.             //connect domes
    62.             matrix = float4x4.TRS(originPoint, rotation, 1);
    63.             var farFront = math.transform(matrix, math.up() * radius);
    64.             var farBack = math.transform(matrix, math.down() * radius);
    65.             var farLeft = math.transform(matrix, math.left() * radius);
    66.             var farRight = math.transform(matrix, math.right() * radius);
    67.             matrix = float4x4.TRS(destinationPoint, rotation, 1);
    68.             var closeFront = math.transform(matrix, math.up() * radius);
    69.             var closeBack = math.transform(matrix, math.down() * radius);
    70.             var closeLeft = math.transform(matrix, math.left() * radius);
    71.             var closeRight = math.transform(matrix, math.right() * radius);
    72.             Debug.DrawLine(farFront, closeFront, color);
    73.             Debug.DrawLine(farBack, closeBack, color);
    74.             Debug.DrawLine(farLeft, closeLeft, color);
    75.             Debug.DrawLine(farRight, closeRight, color);
    76.         }
    77.  
    78.         public static void DrawWireSphere(float3 center, quaternion rotation, float radius, Color color = default)
    79.         {
    80.             if (color.Equals(default)) color = Color.white;
    81.             DrawWireCircle(center, rotation, radius, MapXYToType.XY, color);
    82.             DrawWireCircle(center, rotation, radius, MapXYToType.XZ, color);
    83.             DrawWireCircle(center, rotation, radius, MapXYToType.ZY, color);
    84.         }
    85.  
    86.         public static void DrawWireCircle(float3 center, quaternion rotation, float radius,
    87.             MapXYToType mapXYTo = MapXYToType.XY, Color color = default)
    88.         {
    89.             if (color.Equals(default)) color = Color.white;
    90.             DrawWireArc(center, rotation, radius, 360, 0, mapXYTo: mapXYTo, color: color);
    91.         }
    92.  
    93.         public static void DrawWireArc(float3 center, quaternion rotation, float radius, float angle, float startAngle,
    94.             MapXYToType mapXYTo = MapXYToType.XY, float quality = 18, Color color = default)
    95.         {
    96.             if (color.Equals(default)) color = Color.white;
    97.             var matrix = float4x4.TRS(center, rotation, 1);
    98.  
    99.             float step = startAngle;
    100.             float inc = math.distance(angle, startAngle) / quality;
    101.             for (int i = 0; step < angle; i++)
    102.             {
    103.                 var startPoint = GetCirclePoint(matrix, radius, step, mapXYTo);
    104.  
    105.                 step += inc;
    106.                 var endPoint = GetCirclePoint(matrix, radius, step, mapXYTo);
    107.  
    108.                 Debug.DrawLine(startPoint, endPoint, color);
    109.             }
    110.         }
    111.  
    112.         private static float3 GetCirclePoint(float4x4 matrix, float radius, float step, MapXYToType mapXYTo)
    113.         {
    114.             var x = radius * math.cos(math.radians(step));
    115.             var y = radius * math.sin(math.radians(step));
    116.  
    117.             return
    118.                 mapXYTo == MapXYToType.XZ ? math.transform(matrix, new float3(x, 0, y)) :
    119.                 mapXYTo == MapXYToType.ZY ? math.transform(matrix, new float3(0, y, x)) :
    120.                 math.transform(matrix, new float3(x, y, 0));
    121.         }
    Will update if something doesn't work.
     
    Last edited: Apr 13, 2022
    lclemens likes this.
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    It's actually extremely inefficient if you're drawing a lot of stuff.

    I highly recommend getting a proper draw library, it will save you so much time debugging, I personally wrote my own that works with burst and is magnitudes faster.

    If you don't want to spend the time developing it yourself, Aron Granberg has a fantastic implementation called ALINE (author of the popular A* pathfinding package, it's included in that if you happen to own it already.) https://assetstore.unity.com/packages/tools/gui/aline-162772

    It can draw wire, solid and text and again is magnitudes faster. From the store page

    upload_2022-4-14_7-49-34.png
     
    Last edited: Apr 14, 2022
    bb8_1, PhilSA, Anthiese and 3 others like this.
  3. Occuros

    Occuros

    Joined:
    Sep 4, 2018
    Posts:
    300
    I agree Aline is highly recommended. Especially if you work with VR you can debug in a build in an efficient way.
     
    toomasio likes this.
  4. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    199
    Awesome thanks guys I will check it out
     
  5. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    199
    Yeah Aline is very nice. Thanks guys. I just happened to already have A* and I like that A* can be downloaded via UPM.
     
  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,270
    Last I looked at Aline it required a context object for use in jobs, which breaks any existing job and function interfaces if you just need to debug some part of the job quickly. Is this still the case?

    Anyways, here's my rushed version I made for myself. I'll eventually make it work with a custom render pass and shared statics using a double-buffered RewindableAllocator. The main thing my version right now does is that it skips a bunch of trigonometric operations by using complex arithmetic instead.
    https://github.com/Dreaming381/lsss...cs/Physics/Debug/PhysicsDebug.DrawCollider.cs
     
    Krajca, bb8_1, Anthiese and 1 other person like this.