4

私はiOS用のOpenGL ES 2.0を学んでおり、いくつかのチュートリアルの助けを借りて、クォータニオンを使用して単純な球体オブジェクトを回転およびズームできます。ユーザーがスワイプを完了した後に画面から指を離したときに、球体が速度を落としながら回転し続けるようにしたいので、球体に勢いをつけたいと思います。このブログを使用して、回転について学びました: http://www.raywenderlich.com/12667/how-to-rotate-a-3d-object-using-touches-with-opengl . 誰かが勢いのいくつかの読書や例を提供できますか? 四元数で運動量を実装するにはどうすればよいですか? ありがとう!

    // Set up the frustrum and projection matrix
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
self.effect.transform.projectionMatrix = projectionMatrix;

// Now perform the interpolation step
//[self slerpToNewLocation];

// Move the globe back so we can see it
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, GLOBAL_EARTH_Z_LOCATION);

// In update, we convert the quaternion into a rotation matrix, and apply it to the model view matrix as usual.
GLKMatrix4 rotation = GLKMatrix4MakeWithQuaternion(_quat);
GLKMatrix4 rotateMatrix = GLKMatrix4RotateWithVector3(rotation,momentumVar/200,GLKQuaternionAxis(_quat));
_quat = GLKQuaternionMakeWithMatrix4(rotateMatrix);

modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, rotateMatrix);

// Cap the zoom scale factor max and mins
// only if slerping so that the auto-zoom out and back
// in still works during auto-rotation
if ( !_slerping ) {
    if ( scale > 2.0 ) {
        scale = 2.0;
    }
    if ( scale < 1.15 ) {
        scale = 1.15;
    }
}

// Apply the zoom factors
if ( _slerping ) {
    //NSLog(@"final scale %f",scale);
}

modelViewMatrix = GLKMatrix4Scale(modelViewMatrix, scale, scale, scale);

// Assign the drawer modelViewMatrix
self.effect.transform.modelviewMatrix = modelViewMatrix;

次の質問を見まし: ここでいくつかのヒントをいただければ幸いです-ありがとう。

// Called when touches are ended
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    // The momentum var is initialized to a value
    momentumVar = 0.025;

    // Now since we stopped touching, decay the rotation to simulate momentum
    momentumTimer = [NSTimer scheduledTimerWithTimeInterval:0.01
                                     target:self
                                   selector:@selector(decayGLKQuaternion)
                                   userInfo:nil
                                    repeats:YES];

}

// Slerp about the current axis after touches ended but for a greater angle ( radians )
- (void)decayGLKQuaternion {

    if ( momentumVar < 0.001 ) {

        // Stop the momentum and timer
        momentumVar = 1.0;
        [momentumTimer invalidate];

    }
    else {

        // What is the current angle for the quaternion?
        float currentQuatAngle = GLKQuaternionAngle(_quat);

        // Decay the value each time
        momentumVar = currentQuatAngle * 0.95;

    }

}

更新:私はまだこれを理解しようとしています.更新メソッドの現在のクォータニオンをMatrix4に変換し、そのマトリックスをクォータニオン軸を中心に回転させて、TouchesEnded内で起動を開始するタイマーから更新およびデクリメントされる値を取得しようとしました私のアプリ。結果は回転しますが、軸は正しく見えず (近いようです)、角度は予想とは反対の回転方向を作成します。したがって、下にスワイプして指を離すと、地球は減速しながら上向きに回転します。角度値の符号を変更しても役に立ちません。クォータニオンから回転軸を正しく抽出し、適切な角度で回転させ、速度を下げて回転させるにはどうすればよいですか? ありがとう -

// In update, we convert the quaternion into a rotation matrix, and apply it to the model view matrix as usual.
    GLKMatrix4 rotation = GLKMatrix4MakeWithQuaternion(_quat);
    GLKMatrix4 rotateMatrix = GLKMatrix4RotateWithVector3(rotation,momentumVar/200,GLKQuaternionAxis(_quat));
    _quat = GLKQuaternionMakeWithMatrix4(rotateMatrix);

    modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, rotateMatrix);
4

1 に答える 1

4

UIKit の UIScrollView クラスを利用することで、運動量物理を実装する必要を完全に回避できます。実際には OpenGL ビュー上にコンテンツを描画しない UIScrollView を配置し、必要な contentSize (スクロール可能領域) とスクロール プロパティを持つように構成できます。次に、クラスの 1 つをUIScrollViewDelegateに準拠させ、そのクラスのインスタンスを UIScrollView のデリゲートにすることができます。次に、ユーザーが非表示のスクロール ビュー (OpenGL ビューの上) を操作すると、スクロール ビュー デリゲート クラスにユーザーの操作が通知されます。次のデリゲート メソッドは、実装すると特に役立つ場合があります。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

そこで、新しく更新されたcontentOffsetを取得し、それを使用して 3D モデルを更新し、OpenGL を使用して OpenGL ビューにレンダリングできます。したがって、ユーザーの操作を検出するメカニズムとしてスクロール ビューのみを使用しているため、iOS ユーザーが慣れ親しんでいるすべてのスムーズな更新と運動量物理を処理できます。

Josh Shafferによる WWDC 2012 セッション 223「スクロール ビューによるユーザー エクスペリエンスの強化」を視聴することを強くお勧めします。その講演の中で、彼はこのテクニックの使用について非常に詳細に例を挙げて説明しています。

于 2013-05-08T07:08:26.333 に答える