Saturday, May 6, 2023
HomeGame Development3d meshes - Raycasting to find out level inside or outdoors mesh,...

3d meshes – Raycasting to find out level inside or outdoors mesh, edge case?

I am making an attempt to find out if a degree is inside or outdoors a (triangle) mesh.
One of the simplest ways I discovered was to solid a ray from the purpose and rely what number of triangles intersect. (Odd and even).

I used Möller–Trumbore algo to verify the ray/triangle-intersection.

However I now have a scenario the place level is outdoors the dice. However it touches the aspect. So the ray intersects the triangle, however would not go contained in the dice. So I get just one intersection with a triangle. What usually means, it’s contained in the dice. What is certainly flawed.

Interactive instance of the case (white triangles doesn’t intersect, yellow triangles intersect, intersection and begin level in purple. And in addition the ray in purple):

Are there methods to differentiate circumstances that simply brush the mesh? Or are there extra strong algorithms?

Simply to be full, the code

non-public boolean isInsideInner2(VectorMM level) {
    VectorMM route = createSafeRay(); // Create ray that is not parallel with any triangle
    HashSet<VectorMM> uniques = new HashSet<>();

    for(int i = 0; i!= triangles.size ; i++) {  
        VectorMM intersect = rayIntersectsTriangle2(level, route, triangles[i]);
        if(intersect == level) {
            return true;
        if(intersect != null) {

    return (uniques.measurement() % 2) == 1 ? true : false;

non-public static VectorMM rayIntersectsTriangle2(VectorMM rayOrigin, 
                                            VectorMM rayVector,
                                            VectorMM[] triangle) {
    // supply:

    VectorMM vertex0 = triangle[0];
    VectorMM vertex1 = triangle[1];
    VectorMM vertex2 = triangle[2];
    VectorMM edge1 = VectorMM.sub(vertex1, vertex0);
    VectorMM edge2 = VectorMM.sub(vertex2, vertex0);
    VectorMMLong h = VectorMM.crossproductPrecise(rayVector, edge2);

    double a =, h);
    if (a > -EPSILON && a < EPSILON) {
        throw new AssertionError("Mustn't occur as we eliminated all parallell rays by creating the rayVector"); 

    double f = 1.0 / a;
    VectorMM s = VectorMM.sub(rayOrigin, vertex0);
    double u = f * (,h));
    if (u < -EPSILON || u > 1.0+EPSILON) {
        return null;
    VectorMMLong q = VectorMM.crossproductPrecise(s, edge1);
    double v = f *, q);
    if (v < -EPSILON || u + v > 1.0+EPSILON) {
        return null;
    double t = f *, q);

    if(t >= 0) {
        if(t == 0) {
            return rayOrigin;

        return VectorMM.add(rayOrigin, VectorMM.mul(rayVector, t));
    return null;



Please enter your comment!
Please enter your name here

Most Popular

Recent Comments