作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经实现了 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 之外的某些地方不起作用。我不知道为什么 ?我已使用“快速、最小存储射线/三角形相交”论文来实现。
测试截图;
最佳答案
问题是构建射线原点和方向
解决方案:
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/
我是一名优秀的程序员,十分优秀!