我已如下实现了Möller-TrumboreRay-Tri交叉算法;

注意:我对vec3-dot-cross-sub使用了GLM。 。 。

    bool intersect_triangle( vec3 &O, vec3& D, vec3 &vert0, vec3 &vert1, vec3 &vert2, vec3 & P, bool cull )
{
    static const float eps = 0.000001;
    vec3 edge1( 0.0f, 0.0f, 0.0f );
    vec3 edge2( 0.0f, 0.0f, 0.0f );
    vec3 tvec( 0.0f, 0.0f, 0.0f );
    vec3 pvec( 0.0f, 0.0f, 0.0f );
    vec3 qvec( 0.0f, 0.0f, 0.0f );
    float det, inv_det;

    edge1 = vert1 - vert0;
    edge2 = vert2 - vert0;
    pvec = cross( D, edge2 );
    det = dot( edge1, pvec );

    if( cull )
    {
        if( det < eps )
        {
            cout << "cull test failed" << endl;
            return false;
        }

        tvec = O - vert0;

        P.x = dot( tvec, pvec );

        if( P.x < 0.0f || P.x > det )
        {
            cout << "U test failed" << endl;
            return false;
        }

        qvec = cross( tvec, edge1 );
        P.y = dot( D, qvec );

        if( P.y < 0.0f || ( P.x + P.y ) > det )
        {
            cout << "V test failed" << endl;
            return false;
        }

        P.z = dot( edge2, qvec );
        inv_det = 1.0f / det;
        P.x *= inv_det;
        P.y *= inv_det;
        P.z *= inv_det;
    }
    else
    {
        if( det > - eps && det < eps )
        {
            return false;
        }

        inv_det = 1.0f / det;
        tvec = O - vert0;
        P.x = dot( tvec, pvec ) * inv_det;

        if( P.x < 0.0f || P.x > 1.0f )
        {
            return false;
        }

        qvec = cross( tvec, edge1 );
        P.y = dot( D, qvec ) * inv_det;

        if( P.y < 0.0f || P.x + P.y > 1.0f )
        {
            return false;
        }

        P.z = dot( edge2, qvec ) * inv_det;
    }

    return true;
}

并且我正在使用以下实现;
        for( size_t i = 0; i < tris.size(); i++ )
        {
            mat4 mvp_inverse = inverse( tris[i]->_mvp );
            vec4 origin = mvp_inverse * vec4(
                              ( _lastEvent.motion.x - _width / 2.0f ) / _width / 2.0f, ( _height / 2.0f - _lastEvent.motion.y ) / _height / 2.0f, -1, 1 );
            vec4 dir = mvp_inverse * vec4( 0, 0, 1, 0 );
            vec3 O = vec3( origin.x, origin.y, origin.z );
            vec3 D = normalize( vec3( dir.x, dir.y, dir.z ) );
            vec3 P;

            for( size_t j = 0; j < tris[i]->_indices.size(); j += 3 )
            {
                bool intersection = intersect_triangle( O, D,
                                                        tris[i]->_vertices[tris[i]->_indices[j]],
                                                        tris[i]->_vertices[tris[i]->_indices[j + 1]],
                                                        tris[i]->_vertices[tris[i]->_indices[j + 2]],
                                                        P, true );

                if( intersection )
                {
                    cout << P.x << " " << P.y << " " << P.z << endl;
                }
                else
                {
                    cout << "no intersection" << endl;
                }
            }
        }

该实现在某些地方有效。当光标指向tri内部时,它可以正确检测。它在tri以外的某些地方不起作用。
我不知道为什么 ?我已经使用“快速,最小存储射线/三角形相交”纸来实现。


测试屏幕截图;

屏幕截图1:
c&#43;&#43; - Möller-TrumboreRay-Tri相交算法-LMLPHP

屏幕截图2
c&#43;&#43; - Möller-TrumboreRay-Tri相交算法-LMLPHP

最佳答案

问题在于构造射线原点和方向

解决方案:

            vec4 viewport( 0.0f, 0.0f, 800.0f, 600.0f );

            vec3 unProjectedNear = unProject( vec3( _lastEvent.motion.x, 600 - _lastEvent.motion.y, -1.0f ),  _view * tris[i]->_model, _proj, viewport );
            vec3 unProjectedFar = unProject( vec3( _lastEvent.motion.x, 600 - _lastEvent.motion.y, +1.0f ),  _view * tris[i]->_model, _proj, viewport );
            vec3 D = normalize(unProjectedFar-unProjectedNear);
            vec3 O = unProjectedNear;

关于c++ - Möller-TrumboreRay-Tri相交算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37652337/

10-11 04:37