How to determine thickness by width? (Using Raycasting)

Visual Aids
Thickness and Width: here

Please view the short gif.
The thickness here differs from the width, since there are several walls, since there are external and internal cylinders. Thickness is a measurement of the distance between the outer / inner wall of either side of the cylinder, where thickness is the distance from one end to the other that encloses the empty space between them.

Gif files provided at a glance
-On each click, start points (blue) and destination points (orange) are generated to indicate where the user clicks and interprets the end point used to calculate the distance (displayed in the GUI).

The origin defines where the user clicks on the surface of the object collider, and the destination defines the point perpendicular to the world Y-axis of the origin where the second ray, applied to the first ray, hits the other side of the collider.

Current:

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{

//obtain the vector where the ray hit the collider.
    hitPoint = hit.point; //origin point
//offset the ray, keeping it along the XZ plane of the hit
    Vector3 offsetDirection = -1 * hit.normal;
//offset a long way, minimum thickness of the object
    ray.origin = hit.point  + offsetDirection * 100;
//point the ray back at the first hit point
    ray.direction = (hit.point - ray.origin).normalized;
//raycast all, because there might be other objects in the way
    RaycastHit[] hits = Physics.RaycastAll(ray);
    foreach (RaycastHit h in hits)
    {
        if (h.collider == hit.collider)
        {
            hitBack = h.point; //destination point
        }
    }
}

      

Width is a functionality nowadays. I want to calculate the thickness without going inside the object (as seen in the gif).

Awesome link
http://answers.unity3d.com/questions/386698/detecting-how-many-times-a-raycast-collides-with-a.html

This guy basically had the same question as me and had a solution that might work. I'm not sure how Linecasting vs Raycasting works.

+1


source to share


1 answer


Holds:

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{

//obtain the vector where the ray hit the collider.
    hitPoint = hit.point; //origin point
//offset the ray, keeping it along the XZ plane of the hit
    Vector3 offsetDirection = -1 * hit.normal;
//offset a long way, minimum thickness of the object
    ray.origin = hit.point  + offsetDirection * 100;
//point the ray back at the first hit point
    ray.direction = (hit.point - ray.origin).normalized;

      

Replace:

//raycast all, because there might be other objects in the way
    RaycastHit[] hits = Physics.RaycastAll(ray);
    foreach (RaycastHit h in hits)
    {
        if (h.collider == hit.collider)
        {
            hitBack = h.point; //destination point
        }
    }

      

From (credits to an insightful post by MirrorMirror and @ryemoss for his instrumental advice and help):

int counter = 0;
bool calculating = false; //set this to true on click
Vector3 Point, PreviousPoint, Goal, Direction;
Point = ray.origin;
Goal = hit.point;
Direction = ray.direction;

PreviousPoint = Vector3.zero;
while (calculating == true)
{
    counter++;
    RaycastHit hit2;
    if (Physics.Linecast(Point, Goal, out hit2))
    {
        if(counter > 100)
        {
            hitBack = hitPoint;
            counter = 0;
            calculating = false;
            break;
        }
        PreviousPoint = hit2.point;
        Point = hit2.point + (Direction / 10000f);
    }
    else
    {
        if (PreviousPoint == Vector3.zero)
            hitBack = hitPoint;
        else
            hitBack = PreviousPoint;

        calculating = false;
        counter = 0;
    }
}

      



Linecast vs Raycast
With raycast you set the start point, direction and distance to check in that direction, with linecast you just set the start and end points and check between these two points.

So, if you know the final destination specifically, use a linecast, if you want to scan in a specific direction but don't have a specific endpoint, use a raycast.

Solution
First, use the initial raycast to get the first hit.point. Then set ray.origin to a point in world space outside the collider (the collider of the object we first collided with to get the hit.point) and set ray.direction to look back at the first point, press .point.

Finally, use a while loop to create a new linecast at a new position of ray.origins (updating the while loop each time until the linecast reaches hit.point), each time the object collides until it reaches the Linecast hit.point. Once the hit.point is reached, it means that every surface of the object was hit, and on each hit, a new line was created until the line reaches the first starting point of the hit.point. To calculate the thickness, take the distance between the first hit, hit.point and the hit preceding Linue hit.point, PreviousPoint.

UPDATE
1-Revise your code to properly handle one-way objects (like Planes).
2-Added counter to prevent special cases when calculation is not possible.
3 - Improved readability.

+1


source







All Articles