我正在使用 OpenGL ES 2.0 和最新的 iOS。
我有一个 3D 模型,我希望用户能够通过点击屏幕来选择模型的不同部分。我发现本教程将像素空间屏幕坐标转换为世界空间射线,并实施了射线-AABB 相交测试以确定模型的相交部分。
我在模型的看似随机的部分得到了一些点击。所以我需要调试这个功能,但我真的不知道从哪里开始。
我不能准确地画一条代表射线的线(因为它是从相机出来的,所以它会显示为一个点),所以我可以看到几种调试方法:
检查模型部分的边界框。那么 OGL ES 有没有一种简单的方法可以在给定最小和最大点的情况下绘制边界框?
沿着光线的路径绘制一些 3D 对象。这似乎更复杂。
实际调试光线投射和交集代码。这似乎是最难完成的,因为算法是众所周知的(我直接从我的实时碰撞检测一书中进行了交叉测试)。
如果有人可以提供帮助,或者希望我发布一些代码,我真的可以使用它。
这是我转换为世界空间的代码:
- (IBAction)tappedBody:(UITapGestureRecognizer *)sender
{
if ( !editMode )
{
return;
}
CGPoint tapPoint = [sender locationOfTouch:0 inView:self.view];
const float tanFOV = tanf(GLKMathDegreesToRadians(65.0f*0.5f));
const float width = self.view.frame.size.width,
height = self.view.frame.size.height,
aspect = width/height,
w_2 = width * 0.5,
h_2 = height * 0.5;
CGPoint screenPoint;
screenPoint.x = tanFOV * ( tapPoint.x / w_2 - 1 ) / aspect;
screenPoint.y = tanFOV * ( 1.0 - tapPoint.y / h_2 );
GLKVector3 nearPoint = GLKVector3Make(screenPoint.x * NEAR_PLANE, screenPoint.y * NEAR_PLANE, NEAR_PLANE );
GLKVector3 farPoint = GLKVector3Make(screenPoint.x * FAR_PLANE, screenPoint.y * FAR_PLANE, FAR_PLANE );
GLKVector3 nearWorldPoint = GLKMatrix4MultiplyVector3( _invViewMatrix, nearPoint );
GLKVector3 farWorldPoint = GLKMatrix4MultiplyVector3( _invViewMatrix, farPoint );
GLKVector3 worldRay = GLKVector3Subtract(farWorldPoint, nearWorldPoint);
NSLog(@"Model matrix: %@", NSStringFromGLKMatrix4(_modelMatrix));
worldRay = GLKVector4Normalize(worldRay);
[male intersectWithRay:worldRay fromStartPoint:nearWorldPoint];
for ( int i =0; i < 3; ++i )
{
touchPoint[i] = nearWorldPoint.v[i];
}
}
这是我获得矩阵的方法:
- (void)update
{
// _rotation = 0;
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, NEAR_PLANE, FAR_PLANE);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -5.0f);
// Compute the model view matrix for the object rendered with ES2
_viewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 0.0f);
_modelMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
_modelViewMatrix = GLKMatrix4Rotate(_viewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
_modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, _modelViewMatrix);
_invViewMatrix = GLKMatrix4Invert(_viewMatrix, NULL);
_invMVMatrix = GLKMatrix4Invert(_modelViewMatrix, NULL);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(_modelViewMatrix), NULL);
_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, _modelViewMatrix);
male.modelTransform = _modelMatrix;
if ( !editMode )
{
_rotation += self.timeSinceLastUpdate * 0.5f;
}
}