2

OpenGLES2.0と最新のiOSを使用しています。

ユーザーが画面をタップしてモデルのさまざまな部分を選択できるようにしたいと考えている3Dモデルがあります。ピクセル空間の画面座標を世界空間の光線に変換するこのチュートリアルを見つけ、モデルの交差部分を決定するために光線-AABB交差テストを実装しました。

モデルの一見ランダムなセクションで、モデルにいくつかのヒットがあります。したがって、この機能をデバッグする必要がありますが、どこから始めればよいのかよくわかりません。

光線を表す線を正確に描くことはできません(カメラから出ているため、点として表示されます)。そのため、これをデバッグするいくつかの方法を見ることができます。

  1. モデルセクションのバウンディングボックスをチェックします。では、OGL ESを使用して、最小点と最大点を指定してバウンディングボックスを描画する簡単な方法はありますか?

  2. 光線のパスに沿って3Dオブジェクトを描画します。これはもっと複雑に思えます。

  3. 実際にレイキャストと交差点のコードをデバッグします。アルゴリズムはかなりよく知られているので、これを達成するのは最も難しいようです(私はリアルタイム衝突検出の本の交差テストをまっすぐに受けました)。

誰かが助けてくれるか、コードを投稿してほしいと思ったら、私はそれを本当に使うことができます。

これが世界空間に変換するための私のコードです:

- (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;
    }
}
4

2 に答える 2

0

光線を表す線を正確に描くことはできません(カメラから出ているため、点として表示されます)

これをすぐに捨てないでください。それはあなたがテストしようとしていることではありませんか?つまり、あなたが物事を正しく投影していないのであれば、そうなるでしょう。ただし、バグがある場合は発生しません。

最初にこれを使用します...指のすぐ下にポイントが表示された場合、変換は正しく、指摘した他のより複雑なオプションの調査を開始できます。

于 2012-12-19T21:40:21.610 に答える
0

なぜこれが私が抱えていた問題を修正したのかわかりませんが、変更しました

screenPoint.x = tanFOV * ( tapPoint.x / w_2 - 1 ) / aspect;

screenPoint.x = tanFOV * ( tapPoint.x / w_2 - 1 ) * aspect;

GLKVector4 nearPoint = GLKVector4Make(screenPoint.x * NEAR_PLANE, screenPoint.y * NEAR_PLANE, NEAR_PLANE, 1 );
GLKVector4 farPoint = GLKVector4Make(screenPoint.x * FAR_PLANE, screenPoint.y * FAR_PLANE, FAR_PLANE, 1 );

GLKVector4 nearPoint = GLKVector4Make(screenPoint.x * NEAR_PLANE, screenPoint.y * NEAR_PLANE, -NEAR_PLANE, 1 );
GLKVector4 farPoint = GLKVector4Make(screenPoint.x * FAR_PLANE, screenPoint.y * FAR_PLANE, -FAR_PLANE, 1 );

レイキャスティングの問題が修正されたようです。ビュー マトリックスが、カメラが正の Z 軸を見下ろしていることを示しているように見える理由はまだわかりませんが、オブジェクトは z 軸に沿って負に変換されます。

于 2012-12-21T16:02:40.357 に答える