gpt4 book ai didi

c++ - Möller-Trumbore Ray-Tri 交集算法

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:06:05 25 4
gpt4 key购买 nike

我已经实现了 Möller-Trumbore Ray-Tri 相交算法如下;

注意:我将 GLM 用于 vec3 - dot - cross - sub 。 . .

    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: Screenshoot 1

截图 2 Screenshoot 2

最佳答案

问题是构建射线原点和方向

解决方案:

            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-Trumbore Ray-Tri 交集算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37652337/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com