Wednesday, July 20, 2022
HomeGame Development3d meshes - Raycasting to find out level inside or exterior mesh,...

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


I am making an attempt to find out if some extent is inside or exterior a (triangle) mesh.
One of the best ways I discovered was to solid a ray from the purpose and depend what number of triangles intersect. (Odd and even).

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

However I now have a state of affairs the place level is exterior the dice. But it surely touches the facet. So the ray intersects the triangle, however does 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 improper.

Interactive instance of the case (white triangles doesn’t intersect, yellow triangles intersect, intersection and begin level in crimson. And in addition the ray in crimson):
https://coffee-wrennie-15.tiiny.website/

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) {
            uniques.add(intersect);
        }
    }

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

non-public static VectorMM rayIntersectsTriangle2(VectorMM rayOrigin, 
                                            VectorMM rayVector,
                                            VectorMM[] triangle) {
    // supply: https://en.wikipedia.org/wiki/MpercentC3percentB6llerpercentE2percent80percent93Trumbore_intersection_algorithm

    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 = VectorMMLong.dot(edge1, 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 * (VectorMMLong.dot(s,h));
    if (u < -EPSILON || u > 1.0+EPSILON) {
        return null;
    }
    VectorMMLong q = VectorMM.crossproductPrecise(s, edge1);
    double v = f * VectorMMLong.dot(rayVector, q);
    if (v < -EPSILON || u + v > 1.0+EPSILON) {
        return null;
    }
    
    double t = f * VectorMMLong.dot(edge2, q);

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

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

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments