Detecting how many times a raycast collides with a single concave meshcollider

Hello all,

I am attempting to create an anti-mesh destructible terrain engine similar to that of the original Red Faction. The system uses meshes to cut into other meshes by taking all vertices of the original mesh that intersect with an “eraser mesh” or anti-mesh deleting said vertices. Afterwards, it takes all of the vertices of the anti-mesh and add them to the vertices of the original mesh, essentially taking a “bite” out of it.

Here is a picture that demonstrates this concept. Where the red is the original mesh, and the green is the anti-mesh, and cyan is the vertices of interest.

alt text

The system, however, requires the ability to see if an individual point is within a collision mesh. I have researched the topic a bit and found that the best way to do this in the traditional sense is to use a raycast algorithm to look and see how many intersects a raycast has with a mesh. If you have an odd number of intersects, you know for certain that the point is within the mesh; an even number of intersects implies the point lies outside of the mesh (where zero is also even).

Here is another image to demonstrate this concept. Here green is the mesh, and the line running through it is red and blue. Cyan are the intersects with the polygon “skin”.

alt text

Problem is, using a simple RaycastAll only gives ONE intersect per meshCollider. I was wondering what the function would be in unity c# in order to see how many intersects a ray has with a given mesh.

Thanks in advance.

Thanks to alucardj for helping with the logic.

Note that this solution doesn’t work if you have one sided 2 dimensional objects such as the default unity plane. It will be unable to tell if the object is actually inside anything or not.

How you solve the problem is you have to make multiple a new raycast every time you collide with the object. You repeat this until you reach your target, at which point you reverse direction to try and return from an arbitrary point in world space which is outside the collider in question. You must do the return check to get all the “backfaces” which the first raycast direction will miss. Here is the final code.

using UnityEngine;
using System.Collections;

public class CollisionTest : MonoBehaviour {
    void Update() {
		Vector3 Point;
		Vector3 Start = new Vector3(0,100,0); // This is defined to be some arbitrary point far away from the collider.
		Vector3 Goal = transform.position; // This is the point we want to determine whether or not is inside or outside the collider.
		Vector3 Direction = Goal-Start; // This is the direction from start to goal.
		Direction.Normalize();
		int Itterations = 0; // If we know how many times the raycast has hit faces on its way to the target and back, we can tell through logic whether or not it is inside.
		Point = Start;
		
		
		while(Point != Goal) // Try to reach the point starting from the far off point.  This will pass through faces to reach its objective.
		{
	        RaycastHit hit;
	        if( Physics.Linecast(Point, Goal, out hit)) // Progressively move the point forward, stopping everytime we see a new plane in the way.
			{
				Itterations ++;
				Point = hit.point + (Direction/100.0f); // Move the Point to hit.point and push it forward just a touch to move it through the skin of the mesh (if you don't push it, it will read that same point indefinately).
			}
			else
			{
				Point = Goal; // If there is no obstruction to our goal, then we can reach it in one step.
			}
		}
		while(Point != Start) // Try to return to where we came from, this will make sure we see all the back faces too.
		{
	        RaycastHit hit;
	        if( Physics.Linecast(Point, Start, out hit))
			{
				Itterations ++;
				Point = hit.point + (-Direction/100.0f);
			}
			else
			{
				Point = Start;
			}
		}
		if(Itterations % 2 == 0)
		{
			print("Point is Outside");
		}
		if(Itterations % 2 == 1)
		{
			print("Point is Inside");
		}
    }
}

It is actually remarkably similar to the original picture I posted.

alt text

Hello, I’ve been having a similar problem recently and this thread helped me a lot to solve it. I just wanted to share my code, which is a bit smaller than MirrorIrorriM’s but uses the exact same logic, in case anyone is interested. Let me know if anyone has any feedback.

bool InsideCollider(Vector3 point) 
    {
        int count = 0;
        RaycastHit hit;

        Vector3 rayStart =  new Vector3(100, 100, 100);
        Vector3 direction = point - rayStart;
        Vector3 hitPoint = rayStart;

        while (Physics.Raycast(hitPoint, direction, out hit, direction.magnitude) && count < 100)         // count < 100 Just in case you accidentally enter an infinite loop
        {
            hitPoint = hit.point + (direction.normalized / 100.0f);
            count++;
        }

        hitPoint = point;

        while (Physics.Raycast(hitPoint, -direction, out hit, direction.magnitude) && count < 100)
        {
            hitPoint = hit.point + (-direction.normalized / 100.0f);
            count++;
        }

        // Checking how many intersections there are
        if (count % 2 == 0)     // if count is even
            return false;
        else   // if count is odd
            return true;
    }

[155378-屏幕快照-2020-03-29-下午75057.png|155378]

This Japanese commented code solves all problems, it was recently released

alt text

This Japanese commented code solves all problems, it was recently released,alt text